diff --git a/.changeset/stupid-falcons-drop.md b/.changeset/stupid-falcons-drop.md
new file mode 100644
index 0000000000..9a08b223c9
--- /dev/null
+++ b/.changeset/stupid-falcons-drop.md
@@ -0,0 +1,5 @@
+---
+'@lion/ui': patch
+---
+
+[input-file] improve a11y labels
diff --git a/packages/ui/components/input-file/src/LionInputFile.js b/packages/ui/components/input-file/src/LionInputFile.js
index 894ab36bf4..094565c989 100644
--- a/packages/ui/components/input-file/src/LionInputFile.js
+++ b/packages/ui/components/input-file/src/LionInputFile.js
@@ -77,6 +77,7 @@ export class LionInputFile extends ScopedElementsMixin(LocalizeMixin(LionField))
>
${this.buttonLabel}
`,
+ after: () => html`
`,
'selected-file-list': () => ({
template: html`
{
+ if (file.status === 'FAIL') {
+ errorMessage = file.validationFeedback ? file.validationFeedback[0].message.toString() : '';
+ erroneousFilesNames.push(/** @type {string} */ (file.systemFile.name));
+ }
+ });
+
+ const selectedFiles = this.querySelector('[slot="after"]');
+ if (selectedFiles) {
+ if (!this._selectedFilesMetaData || this._selectedFilesMetaData.length === 0) {
+ selectedFiles.textContent = /** @type {string} */ (
+ this.msgLit('lion-input-file:noFilesSelected')
+ );
+ } else if (this._selectedFilesMetaData.length === 1) {
+ selectedFiles.textContent = /** @type {string} */ (
+ errorMessage || this._selectedFilesMetaData[0].systemFile.name
+ );
+ } else {
+ selectedFiles.textContent = `${this.msgLit('lion-input-file:numberOfFiles', {
+ numberOfFiles: this._selectedFilesMetaData.length,
+ })} ${
+ errorMessage
+ ? this.msgLit('lion-input-file:generalValidatorMessage', {
+ validatorMessage: errorMessage,
+ listOfErroneousFiles: erroneousFilesNames.join(', '),
+ })
+ : ''
+ }`;
+ }
+ }
+ }
+
/**
* @private
* @param {InputFile} removedFile
@@ -755,6 +780,7 @@ export class LionInputFile extends ScopedElementsMixin(LocalizeMixin(LionField))
}
this._inputNode.value = '';
this._handleErrors();
+ this._updateUploadButtonDescription();
}
/**
@@ -847,6 +873,7 @@ export class LionInputFile extends ScopedElementsMixin(LocalizeMixin(LionField))
_inputGroupInputTemplate() {
return html`
+
${this.enableDropZone && this._isDragAndDropSupported
? this._dropZoneTemplate()
: html`
@@ -891,6 +918,19 @@ export class LionInputFile extends ScopedElementsMixin(LocalizeMixin(LionField))
border: dashed 2px black;
padding: 24px 0;
}
+
+ .input-group__container ::slotted([slot='after']) {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ overflow: hidden;
+ clip-path: inset(100%);
+ clip: rect(1px, 1px, 1px, 1px);
+ white-space: nowrap;
+ border: 0;
+ margin: 0;
+ padding: 0;
+ }
`,
];
}
diff --git a/packages/ui/components/input-file/test/lion-input-file.test.js b/packages/ui/components/input-file/test/lion-input-file.test.js
index 8ac170ed60..85750eb5fe 100644
--- a/packages/ui/components/input-file/test/lion-input-file.test.js
+++ b/packages/ui/components/input-file/test/lion-input-file.test.js
@@ -1133,7 +1133,7 @@ describe('lion-input-file', () => {
);
});
- it('select-button has aria-describedby set to the help-text, selected list and the feedback message', async () => {
+ it('select-button has aria-describedby set to the help-text, after and the feedback message', async () => {
const uploadResponse = [
{
name: 'file1.txt',
@@ -1159,11 +1159,73 @@ describe('lion-input-file', () => {
// @ts-expect-error [allow-protected-in-test]
`feedback-${el._inputId}`,
);
- await el.updateComplete;
// @ts-expect-error [allow-protected-in-test]
expect(el._buttonNode?.getAttribute('aria-describedby')).to.contain(
// @ts-expect-error [allow-protected-in-test]
- `selected-file-list-${el._inputId}`,
+ `after-${el._inputId}`,
+ );
+ });
+
+ it('after contains upload name of file when SUCCESS', async () => {
+ const uploadResponse = [
+ {
+ name: 'file1.txt',
+ status: 'SUCCESS',
+ errorMessage: '',
+ downloadUrl: '/downloadFile',
+ },
+ ];
+ const el = await fixture(html` `);
+
+ expect(el.querySelector('[slot="after"]')?.textContent).to.equal('No files selected.');
+ // @ts-expect-error
+ el.uploadResponse = uploadResponse;
+ await el.updateComplete;
+ expect(el.querySelector('[slot="after"]')?.textContent).to.equal('file1.txt');
+ });
+
+ it('after contains upload validator message of file when FAIL', async () => {
+ const uploadResponse = [
+ {
+ name: 'file1.txt',
+ status: 'FAIL',
+ errorMessage: 'something went wrong',
+ downloadUrl: '/downloadFile',
+ },
+ ];
+ const el = await fixture(html` `);
+
+ expect(el.querySelector('[slot="after"]')?.textContent).to.equal('No files selected.');
+ // @ts-expect-error
+ el.uploadResponse = uploadResponse;
+ await el.updateComplete;
+ expect(el.querySelector('[slot="after"]')?.textContent).to.equal('something went wrong');
+ });
+
+ it('after contains upload status of files when multiple files have been uploaded', async () => {
+ const uploadResponse = [
+ {
+ name: 'file1.txt',
+ status: 'SUCCESS',
+ errorMessage: '',
+ downloadUrl: '/downloadFile',
+ },
+ {
+ name: 'file2.txt',
+ status: 'FAIL',
+ errorMessage: 'something went wrong',
+ downloadUrl: '/downloadFile',
+ },
+ ];
+ const el = await fixture(html`
+
+ `);
+ // @ts-expect-error
+ el.uploadResponse = uploadResponse;
+
+ await el.updateComplete;
+ expect(el.querySelector('[slot="after"]')?.textContent?.trim()).to.equal(
+ '2 files. "something went wrong", for file2.txt.',
);
});
});
diff --git a/packages/ui/components/input-file/translations/bg.js b/packages/ui/components/input-file/translations/bg.js
index aeb71cb10f..5ae2a9dfb6 100644
--- a/packages/ui/components/input-file/translations/bg.js
+++ b/packages/ui/components/input-file/translations/bg.js
@@ -5,6 +5,9 @@ export default {
'Моля, качете файл от тип {allowedTypesArray} или {allowedTypesLastItem} с макс. размер {maxSize}.',
dragAndDropText: 'Плъзнете и пуснете Вашите файлове тук или',
fileNameDescriptionLabel: 'Име на файл: {fileName}',
+ generalValidatorMessage: '"{validatorMessage}", за {listOfErroneousFiles}.',
+ noFilesSelected: 'Не са избрани файлове.',
+ numberOfFiles: '{numberOfFiles} файла.',
removeButtonLabel: 'Отстраняване на файла {fileName}',
selectTextDuplicateFileName: 'Файл със същото име на файл вече е налице.',
selectTextMultipleFile: 'Избор на файлове',
diff --git a/packages/ui/components/input-file/translations/cs.js b/packages/ui/components/input-file/translations/cs.js
index a3ddfbb95d..8557272c7a 100644
--- a/packages/ui/components/input-file/translations/cs.js
+++ b/packages/ui/components/input-file/translations/cs.js
@@ -6,6 +6,9 @@ export default {
'Nahrajte soubor typu {allowedTypesArray} nebo {allowedTypesLastItem} s max. velikostí {maxSize}.',
dragAndDropText: 'Přetáhněte soubory sem nebo',
fileNameDescriptionLabel: 'Název souboru: {fileName}',
+ generalValidatorMessage: '"{validatorMessage}", pro {listOfErroneousFiles}.',
+ noFilesSelected: 'Nebyly vybrány žádné soubory.',
+ numberOfFiles: '{numberOfFiles} soubory/souborů.',
removeButtonLabel: 'Odebrat soubor {fileName}',
selectTextDuplicateFileName: 'Soubor se stejným názvem byl již přítomen.',
selectTextMultipleFile: 'Vybrat soubory',
diff --git a/packages/ui/components/input-file/translations/de.js b/packages/ui/components/input-file/translations/de.js
index 1ca7a7746b..375cb676ec 100644
--- a/packages/ui/components/input-file/translations/de.js
+++ b/packages/ui/components/input-file/translations/de.js
@@ -5,6 +5,9 @@ export default {
'Laden Sie eine {allowedTypesArray} oder {allowedTypesLastItem}-Datei mit max. {maxSize} hoch.',
dragAndDropText: 'Ziehen Sie Ihre Dateien per Drag & Drop hierher oder',
fileNameDescriptionLabel: 'Dateiname: {fileName}',
+ generalValidatorMessage: '"{validatorMessage}", für {listOfErroneousFiles}.',
+ noFilesSelected: 'Keine Dateien ausgewählt.',
+ numberOfFiles: '{numberOfFiles} Dateien.',
removeButtonLabel: 'Datei {fileName} entfernen',
selectTextDuplicateFileName: 'Eine Datei mit demselben Dateinamen war bereits vorhanden.',
selectTextMultipleFile: 'Dateien auswählen',
diff --git a/packages/ui/components/input-file/translations/en.js b/packages/ui/components/input-file/translations/en.js
index 7dfaf51ddc..9362bc084b 100644
--- a/packages/ui/components/input-file/translations/en.js
+++ b/packages/ui/components/input-file/translations/en.js
@@ -5,6 +5,9 @@ export default {
'Please select a {allowedTypesArray} or {allowedTypesLastItem} file with max {maxSize}.',
dragAndDropText: 'Drag & Drop your files here or', // TODO: or what? Why is Drag & Drop capitalized?
fileNameDescriptionLabel: 'File name: {fileName}',
+ generalValidatorMessage: '"{validatorMessage}", for {listOfErroneousFiles}.',
+ noFilesSelected: 'No files selected.',
+ numberOfFiles: '{numberOfFiles} files.',
removeButtonLabel: 'Remove {fileName} file',
selectTextDuplicateFileName: 'A file with same filename was already present.',
selectTextMultipleFile: 'Select files',
diff --git a/packages/ui/components/input-file/translations/es.js b/packages/ui/components/input-file/translations/es.js
index 5ea291dd86..7718c4fda1 100644
--- a/packages/ui/components/input-file/translations/es.js
+++ b/packages/ui/components/input-file/translations/es.js
@@ -5,6 +5,9 @@ export default {
'Cargue un archivo {allowedTypesArray} o {allowedTypesLastItem} de {maxSize} como máximo.',
dragAndDropText: 'Arrastre y suelte los archivos aquí o',
fileNameDescriptionLabel: 'Nombre de archivo: {fileName}',
+ generalValidatorMessage: '"{validatorMessage}", para {listOfErroneousFiles}.',
+ noFilesSelected: 'No se han seleccionado archivos.',
+ numberOfFiles: '{numberOfFiles} archivos.',
removeButtonLabel: 'Elimine el archivo: {fileName}',
selectTextDuplicateFileName: 'Ya había un archivo con el mismo nombre de archivo.',
selectTextMultipleFile: 'Seleccionar archivos',
diff --git a/packages/ui/components/input-file/translations/fr.js b/packages/ui/components/input-file/translations/fr.js
index d3af1c0352..1d702f5927 100644
--- a/packages/ui/components/input-file/translations/fr.js
+++ b/packages/ui/components/input-file/translations/fr.js
@@ -6,6 +6,9 @@ export default {
'Veuillez télécharger un fichier {allowedTypesArray} ou {allowedTypesLastItem} avec une taille maximale de {maxSize}.',
dragAndDropText: 'Glissez et déposez vos fichiers ici ou',
fileNameDescriptionLabel: 'Nom de fichier: {fileName}',
+ generalValidatorMessage: '"{validatorMessage}", pour {listOfErroneousFiles}.',
+ noFilesSelected: 'Aucun fichier sélectionné.',
+ numberOfFiles: '{numberOfFiles} fichiers.',
removeButtonLabel: 'Supprimer le fichier {fileName}',
selectTextDuplicateFileName: 'Un fichier portant le même nom de fichier était déjà présent.',
selectTextMultipleFile: 'Sélectionnez des fichiers',
diff --git a/packages/ui/components/input-file/translations/hu.js b/packages/ui/components/input-file/translations/hu.js
index e7c26518e3..7540a82698 100644
--- a/packages/ui/components/input-file/translations/hu.js
+++ b/packages/ui/components/input-file/translations/hu.js
@@ -5,6 +5,9 @@ export default {
'Töltsön fel egy legfeljebb {maxSize} méretű {allowedTypesArray} vagy {allowedTypesLastItem} fájlt.',
dragAndDropText: 'Húzza át a fájlokat ide vagy',
fileNameDescriptionLabel: 'Fájlnév: {fileName}',
+ generalValidatorMessage: '"{validatorMessage}", ehhez: {listOfErroneousFiles}.',
+ noFilesSelected: 'Nincs fájl kiválasztva.',
+ numberOfFiles: '{numberOfFiles} fájl.',
removeButtonLabel: 'A(z) {fileName} fájl eltávolítása',
selectTextDuplicateFileName: 'Már volt ilyen nevű fájl.',
selectTextMultipleFile: 'Fájl(ok) kiválasztása',
diff --git a/packages/ui/components/input-file/translations/it.js b/packages/ui/components/input-file/translations/it.js
index 0321377896..48bfc86c40 100644
--- a/packages/ui/components/input-file/translations/it.js
+++ b/packages/ui/components/input-file/translations/it.js
@@ -5,6 +5,9 @@ export default {
'Caricare un file {allowedTypesArray} o {allowedTypesLastItem} di {maxSize} max.',
dragAndDropText: 'Trascinare i file qui o',
fileNameDescriptionLabel: 'Nome file: {fileName}',
+ generalValidatorMessage: '"{validatorMessage}", per {listOfErroneousFiles}.',
+ noFilesSelected: 'Nessun file selezionato.',
+ numberOfFiles: '{numberOfFiles} file.',
removeButtonLabel: 'Rimuovere il file {fileName}',
selectTextDuplicateFileName: 'Un file con lo stesso nome file era già presente.',
selectTextMultipleFile: 'Seleziona file',
diff --git a/packages/ui/components/input-file/translations/nl.js b/packages/ui/components/input-file/translations/nl.js
index b035173fce..71e8414f9e 100644
--- a/packages/ui/components/input-file/translations/nl.js
+++ b/packages/ui/components/input-file/translations/nl.js
@@ -5,6 +5,9 @@ export default {
'Upload een {allowedTypesArray} of {allowedTypesLastItem}-bestand van maximaal {maxSize}.',
dragAndDropText: 'Sleep uw bestanden hierheen of',
fileNameDescriptionLabel: 'Bestandsnaam: {fileName}',
+ generalValidatorMessage: '"{validatorMessage}", voor {listOfErroneousFiles}.',
+ noFilesSelected: 'Geen bestanden geselecteerd.',
+ numberOfFiles: '{numberOfFiles} bestanden.',
removeButtonLabel: 'Verwijder het bestand {fileName}',
selectTextDuplicateFileName: 'Er bestaat al een bestand met dezelfde bestandsnaam.',
selectTextMultipleFile: 'Selecteer bestanden',
diff --git a/packages/ui/components/input-file/translations/pl.js b/packages/ui/components/input-file/translations/pl.js
index 0e7c87cce5..ec899f89e5 100644
--- a/packages/ui/components/input-file/translations/pl.js
+++ b/packages/ui/components/input-file/translations/pl.js
@@ -5,6 +5,9 @@ export default {
'Prześlij plik {allowedTypesArray} lub {allowedTypesLastItem} o maks. rozmiarze {maxSize}.',
dragAndDropText: 'Przeciągnij i upuść pliki tutaj lub',
fileNameDescriptionLabel: 'Nazwa pliku: {fileName}',
+ generalValidatorMessage: '"{validatorMessage}", dla {listOfErroneousFiles}.',
+ noFilesSelected: 'Nie wybrano żadnych plików.',
+ numberOfFiles: 'Liczba plików: {numberOfFiles}.',
removeButtonLabel: 'Usuń plik {fileName}',
selectTextDuplicateFileName: 'Plik o tej samej nazwie już istnieje.',
selectTextMultipleFile: 'Wybierz pliki',
diff --git a/packages/ui/components/input-file/translations/ro.js b/packages/ui/components/input-file/translations/ro.js
index f04bc15862..ddd573b759 100644
--- a/packages/ui/components/input-file/translations/ro.js
+++ b/packages/ui/components/input-file/translations/ro.js
@@ -5,6 +5,9 @@ export default {
'Încărcaţi un fişier {allowedTypesArray} sau {allowedTypesLastItem} de max. {maxSize}.',
dragAndDropText: 'Glisaţi şi fixaţi fişierele aici sau',
fileNameDescriptionLabel: 'Nume fişier: {fileName}',
+ generalValidatorMessage: '"{validatorMessage}", pentru {listOfErroneousFiles}.',
+ noFilesSelected: 'Niciun fișier selectat.',
+ numberOfFiles: '{numberOfFiles} fișiere.',
removeButtonLabel: 'Eliminaţi fişierul {filename}',
selectTextDuplicateFileName: 'Există deja un fişier cu acelaşi nume de fişier.',
selectTextMultipleFile: 'Selectare fișiere',
diff --git a/packages/ui/components/input-file/translations/ru.js b/packages/ui/components/input-file/translations/ru.js
index 62e4a8521e..32cf5df976 100644
--- a/packages/ui/components/input-file/translations/ru.js
+++ b/packages/ui/components/input-file/translations/ru.js
@@ -5,6 +5,9 @@ export default {
'Загрузите файл {allowedTypesArray} или {allowedTypesLastItem} размером не более {maxSize}.',
dragAndDropText: 'Перетащите файлы сюда или',
fileNameDescriptionLabel: 'Название файла: {fileName}',
+ generalValidatorMessage: '"{validatorMessage}", для {listOfErroneousFiles}.',
+ noFilesSelected: 'Файлы не выбраны.',
+ numberOfFiles: 'Файлов: {numberOfFiles}.',
removeButtonLabel: 'Удалить файл {fileName}',
selectTextDuplicateFileName: 'Файл с таким названием уже существует.',
selectTextMultipleFile: 'Выберите файлы',
diff --git a/packages/ui/components/input-file/translations/sk.js b/packages/ui/components/input-file/translations/sk.js
index ad9903c50c..e03f96ac88 100644
--- a/packages/ui/components/input-file/translations/sk.js
+++ b/packages/ui/components/input-file/translations/sk.js
@@ -5,6 +5,9 @@ export default {
'Nahrajte súbor {allowedTypesArray} alebo {allowedTypesLastItem} s maximálnou veľkosťou {maxSize}.',
dragAndDropText: 'Súbory presuňte sem alebo',
fileNameDescriptionLabel: 'Názov súboru: {fileName}',
+ generalValidatorMessage: '"{validatorMessage}", pre {listOfErroneousFiles}.',
+ noFilesSelected: 'Neboli vybrané žiadne súbory.',
+ numberOfFiles: 'Počet súborov: {numberOfFiles}.',
removeButtonLabel: 'Odstrániť súbor {fileName}',
selectTextDuplicateFileName: 'Súbor s rovnakým názvom súboru už existoval.',
selectTextMultipleFile: 'Vybrať súbory',
diff --git a/packages/ui/components/input-file/translations/uk.js b/packages/ui/components/input-file/translations/uk.js
index 45379d7877..fedfdbec6f 100644
--- a/packages/ui/components/input-file/translations/uk.js
+++ b/packages/ui/components/input-file/translations/uk.js
@@ -5,6 +5,9 @@ export default {
'Завантажте файл {allowedTypesArray} або {allowedTypesLastItem} розміром до {maxSize}.',
dragAndDropText: 'Перетягніть файли сюди або',
fileNameDescriptionLabel: 'Ім’я файлу: {fileName}',
+ generalValidatorMessage: '"{validatorMessage}", для {listOfErroneousFiles}.',
+ noFilesSelected: 'Не вибрано жодного файлу.',
+ numberOfFiles: '{numberOfFiles} файли(-ів).',
removeButtonLabel: 'Видалення файлу {fileName}',
selectTextDuplicateFileName: 'Файл із такою назвою вже існував.',
selectTextMultipleFile: 'Виберіть файли',
diff --git a/packages/ui/components/input-file/translations/zh.js b/packages/ui/components/input-file/translations/zh.js
index ee2ad6cd8d..ac7f1e4163 100644
--- a/packages/ui/components/input-file/translations/zh.js
+++ b/packages/ui/components/input-file/translations/zh.js
@@ -5,6 +5,9 @@ export default {
'请上传最大 {maxSize} 的 {allowedTypesArray} 或 {allowedTypesLastItem} 文件。',
dragAndDropText: '将您的文件拖放到此处,或',
fileNameDescriptionLabel: '文件名: {fileName}',
+ generalValidatorMessage: '"{validatorMessage}", 例如 {listOfErroneousFiles}。',
+ noFilesSelected: '未选择任何文件。',
+ numberOfFiles: '{numberOfFiles} 个文件。',
removeButtonLabel: '删除 {fileName} 文件',
selectTextDuplicateFileName: '已存在具有相同文件名的文件。',
selectTextMultipleFile: '选择多个文件',