diff --git a/.changeset/calm-chicken-obey.md b/.changeset/calm-chicken-obey.md new file mode 100644 index 0000000000..eaeba073e6 --- /dev/null +++ b/.changeset/calm-chicken-obey.md @@ -0,0 +1,5 @@ +--- +'@lion/ui': patch +--- + +[FeedbackValidation] add a translation of the validation feedback type to the beginning of the validation message diff --git a/packages/ui/components/form-core/src/localizeNamespaceLoader.js b/packages/ui/components/form-core/src/localizeNamespaceLoader.js new file mode 100644 index 0000000000..4ebde40c8e --- /dev/null +++ b/packages/ui/components/form-core/src/localizeNamespaceLoader.js @@ -0,0 +1,75 @@ +/* eslint-disable import/no-extraneous-dependencies */ +export const localizeNamespaceLoader = /** @param {string} locale */ locale => { + switch (locale) { + case 'bg-BG': + return import('@lion/ui/form-core-translations/bg-BG.js'); + case 'bg': + return import('@lion/ui/form-core-translations/bg.js'); + case 'cs-CZ': + return import('@lion/ui/form-core-translations/cs-CZ.js'); + case 'cs': + return import('@lion/ui/form-core-translations/cs.js'); + case 'de-DE': + return import('@lion/ui/form-core-translations/de-DE.js'); + case 'de': + return import('@lion/ui/form-core-translations/de.js'); + case 'en-AU': + return import('@lion/ui/form-core-translations/en-AU.js'); + case 'en-GB': + return import('@lion/ui/form-core-translations/en-GB.js'); + case 'en-US': + return import('@lion/ui/form-core-translations/en-US.js'); + case 'en-PH': + case 'en': + return import('@lion/ui/form-core-translations/en.js'); + case 'es-ES': + return import('@lion/ui/form-core-translations/es-ES.js'); + case 'es': + return import('@lion/ui/form-core-translations/es.js'); + case 'fr-FR': + return import('@lion/ui/form-core-translations/fr-FR.js'); + case 'fr-BE': + return import('@lion/ui/form-core-translations/fr-BE.js'); + case 'fr': + return import('@lion/ui/form-core-translations/fr.js'); + case 'hu-HU': + return import('@lion/ui/form-core-translations/hu-HU.js'); + case 'hu': + return import('@lion/ui/form-core-translations/hu.js'); + case 'it-IT': + return import('@lion/ui/form-core-translations/it-IT.js'); + case 'it': + return import('@lion/ui/form-core-translations/it.js'); + case 'nl-BE': + return import('@lion/ui/form-core-translations/nl-BE.js'); + case 'nl-NL': + return import('@lion/ui/form-core-translations/nl-NL.js'); + case 'nl': + return import('@lion/ui/form-core-translations/nl.js'); + case 'pl-PL': + return import('@lion/ui/form-core-translations/pl-PL.js'); + case 'pl': + return import('@lion/ui/form-core-translations/pl.js'); + case 'ro-RO': + return import('@lion/ui/form-core-translations/ro-RO.js'); + case 'ro': + return import('@lion/ui/form-core-translations/ro.js'); + case 'ru-RU': + return import('@lion/ui/form-core-translations/ru-RU.js'); + case 'ru': + return import('@lion/ui/form-core-translations/ru.js'); + case 'sk-SK': + return import('@lion/ui/form-core-translations/sk-SK.js'); + case 'sk': + return import('@lion/ui/form-core-translations/sk.js'); + case 'uk-UA': + return import('@lion/ui/form-core-translations/uk-UA.js'); + case 'uk': + return import('@lion/ui/form-core-translations/uk.js'); + case 'zh-CN': + case 'zh': + return import('@lion/ui/form-core-translations/zh.js'); + default: + return import('@lion/ui/form-core-translations/en.js'); + } +}; diff --git a/packages/ui/components/form-core/src/validate/LionValidationFeedback.js b/packages/ui/components/form-core/src/validate/LionValidationFeedback.js index 290f4758b6..9f6b4a4d05 100644 --- a/packages/ui/components/form-core/src/validate/LionValidationFeedback.js +++ b/packages/ui/components/form-core/src/validate/LionValidationFeedback.js @@ -1,4 +1,6 @@ -import { html, LitElement } from 'lit'; +import { css, html, LitElement } from 'lit'; +import { LocalizeMixin } from '@lion/ui/localize-no-side-effects.js'; +import { localizeNamespaceLoader } from '../localizeNamespaceLoader.js'; /** * @typedef {import('./Validator.js').Validator} Validator @@ -6,17 +8,46 @@ import { html, LitElement } from 'lit'; * @typedef {import('../../types/validate/ValidateMixinTypes.js').FeedbackMessage} FeedbackMessage */ +/** + * @param {string} string + */ +const capitalize = string => `${string[0].toUpperCase()}${string.slice(1)}`; + /** * @desc Takes care of accessible rendering of error messages * Should be used in conjunction with FormControl having ValidateMixin applied */ -export class LionValidationFeedback extends LitElement { +export class LionValidationFeedback extends LocalizeMixin(LitElement) { static get properties() { return { feedbackData: { attribute: false }, }; } + static localizeNamespaces = [ + { 'lion-form-core': localizeNamespaceLoader }, + ...super.localizeNamespaces, + ]; + + static get styles() { + return [ + css` + .validation-feedback__type { + 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; + } + `, + ]; + } + /** * @overridable * @param {Object} opts @@ -58,6 +89,9 @@ export class LionValidationFeedback extends LitElement { ${this.feedbackData && this.feedbackData.map( ({ message, type, validator }) => html` +
+ ${this._localizeManager.msg(`lion-form-core:validation${capitalize(type)}`)} +
${this._messageTemplate({ message, type, validator })} `, )} diff --git a/packages/ui/components/form-core/test-suites/ValidateMixin.suite.js b/packages/ui/components/form-core/test-suites/ValidateMixin.suite.js index e9bdea79f8..f89d4fd3a4 100644 --- a/packages/ui/components/form-core/test-suites/ValidateMixin.suite.js +++ b/packages/ui/components/form-core/test-suites/ValidateMixin.suite.js @@ -800,7 +800,7 @@ export function runValidateMixinSuite(customConfig) { expect(el.hasFeedbackFor).to.deep.equal(['error']); const { _feedbackNode } = getFormControlMembers(el); await el.updateComplete; - await el.updateComplete; + await _feedbackNode.updateComplete; const messageHtmlNode = _feedbackNode.shadowRoot?.querySelector(`#${messageHtmlId}`); expect(messageHtmlNode?.outerHTML).to.equal(messageHtml); expect(messageHtmlNode?.tagName).to.equal('DIV'); diff --git a/packages/ui/components/form-core/test/validate/lion-validation-feedback.test.js b/packages/ui/components/form-core/test/validate/lion-validation-feedback.test.js index 5a335db03d..bdc19810f7 100644 --- a/packages/ui/components/form-core/test/validate/lion-validation-feedback.test.js +++ b/packages/ui/components/form-core/test/validate/lion-validation-feedback.test.js @@ -14,10 +14,10 @@ describe('lion-validation-feedback', () => { const el = /** @type {LionValidationFeedback} */ ( await fixture(html``) ); - expect(el).shadowDom.to.equal(''); + expect(el.shadowRoot?.textContent).to.not.include('hello'); el.feedbackData = [{ message: 'hello', type: 'error', validator: new AlwaysInvalid() }]; await el.updateComplete; - expect(el).shadowDom.to.equal('hello'); + expect(el.shadowRoot?.textContent).to.include('hello'); }); it('renders the validation type attribute', async () => { @@ -73,4 +73,32 @@ describe('lion-validation-feedback', () => { clock.restore(); }); + + it('shares to the user the type of validation feedback', async () => { + const el = /** @type {LionValidationFeedback} */ ( + await fixture(html``) + ); + + el.feedbackData = [{ message: 'hello', type: 'error', validator: new AlwaysInvalid() }]; + await el.updateComplete; + + const validationFeedbackType = el.shadowRoot?.querySelector('.validation-feedback__type'); + expect(validationFeedbackType?.textContent?.trim()).to.equal('Error'); + + el.feedbackData = [{ message: 'hello', type: 'info', validator: new AlwaysInvalid() }]; + await el.updateComplete; + + expect(validationFeedbackType?.textContent?.trim()).to.equal('Info'); + }); + + describe('accessibility', () => { + it('passes a11y audit when with a message', async () => { + const el = /** @type {LionValidationFeedback} */ ( + await fixture(html``) + ); + el.feedbackData = [{ message: 'hello', type: 'error', validator: new AlwaysInvalid() }]; + await el.updateComplete; + await expect(el).to.be.accessible(); + }); + }); }); diff --git a/packages/ui/components/form-core/translations/bg-BG.js b/packages/ui/components/form-core/translations/bg-BG.js new file mode 100644 index 0000000000..00f5e5f613 --- /dev/null +++ b/packages/ui/components/form-core/translations/bg-BG.js @@ -0,0 +1,5 @@ +import bg from './bg.js'; + +export default { + ...bg, +}; diff --git a/packages/ui/components/form-core/translations/bg.js b/packages/ui/components/form-core/translations/bg.js new file mode 100644 index 0000000000..a840e7bb93 --- /dev/null +++ b/packages/ui/components/form-core/translations/bg.js @@ -0,0 +1,6 @@ +export default { + validationError: 'Грешка', + validationWarning: 'Предупреждение', + validationSuccess: 'Успех', + validationInfo: 'Информация', +}; diff --git a/packages/ui/components/form-core/translations/cs-CZ.js b/packages/ui/components/form-core/translations/cs-CZ.js new file mode 100644 index 0000000000..2cac51aa8e --- /dev/null +++ b/packages/ui/components/form-core/translations/cs-CZ.js @@ -0,0 +1,5 @@ +import cs from './cs.js'; + +export default { + ...cs, +}; diff --git a/packages/ui/components/form-core/translations/cs.js b/packages/ui/components/form-core/translations/cs.js new file mode 100644 index 0000000000..e7a1c71e1e --- /dev/null +++ b/packages/ui/components/form-core/translations/cs.js @@ -0,0 +1,6 @@ +export default { + validationError: 'Chyba', + validationWarning: 'Varování', + validationSuccess: 'Úspěch', + validationInfo: 'Informace', +}; diff --git a/packages/ui/components/form-core/translations/de-DE.js b/packages/ui/components/form-core/translations/de-DE.js new file mode 100644 index 0000000000..8e3fb7c867 --- /dev/null +++ b/packages/ui/components/form-core/translations/de-DE.js @@ -0,0 +1,5 @@ +import de from './de.js'; + +export default { + ...de, +}; diff --git a/packages/ui/components/form-core/translations/de.js b/packages/ui/components/form-core/translations/de.js new file mode 100644 index 0000000000..a13a983169 --- /dev/null +++ b/packages/ui/components/form-core/translations/de.js @@ -0,0 +1,6 @@ +export default { + validationError: 'Fehler', + validationWarning: 'Warnhinweis', + validationSuccess: 'Erfolgreich', + validationInfo: 'Info', +}; diff --git a/packages/ui/components/form-core/translations/en-AU.js b/packages/ui/components/form-core/translations/en-AU.js new file mode 100644 index 0000000000..e164dab30c --- /dev/null +++ b/packages/ui/components/form-core/translations/en-AU.js @@ -0,0 +1,5 @@ +import en from './en.js'; + +export default { + ...en, +}; diff --git a/packages/ui/components/form-core/translations/en-GB.js b/packages/ui/components/form-core/translations/en-GB.js new file mode 100644 index 0000000000..e164dab30c --- /dev/null +++ b/packages/ui/components/form-core/translations/en-GB.js @@ -0,0 +1,5 @@ +import en from './en.js'; + +export default { + ...en, +}; diff --git a/packages/ui/components/form-core/translations/en-US.js b/packages/ui/components/form-core/translations/en-US.js new file mode 100644 index 0000000000..e164dab30c --- /dev/null +++ b/packages/ui/components/form-core/translations/en-US.js @@ -0,0 +1,5 @@ +import en from './en.js'; + +export default { + ...en, +}; diff --git a/packages/ui/components/form-core/translations/en.js b/packages/ui/components/form-core/translations/en.js new file mode 100644 index 0000000000..6b814e841d --- /dev/null +++ b/packages/ui/components/form-core/translations/en.js @@ -0,0 +1,6 @@ +export default { + validationError: 'Error', + validationWarning: 'Warning', + validationSuccess: 'Success', + validationInfo: 'Info', +}; diff --git a/packages/ui/components/form-core/translations/es-ES.js b/packages/ui/components/form-core/translations/es-ES.js new file mode 100644 index 0000000000..94a009944a --- /dev/null +++ b/packages/ui/components/form-core/translations/es-ES.js @@ -0,0 +1,5 @@ +import es from './es.js'; + +export default { + ...es, +}; diff --git a/packages/ui/components/form-core/translations/es.js b/packages/ui/components/form-core/translations/es.js new file mode 100644 index 0000000000..2337fe71ea --- /dev/null +++ b/packages/ui/components/form-core/translations/es.js @@ -0,0 +1,6 @@ +export default { + validationError: 'Error', + validationWarning: 'Advertencia', + validationSuccess: 'Satisfactorio', + validationInfo: 'Información', +}; diff --git a/packages/ui/components/form-core/translations/fr-BE.js b/packages/ui/components/form-core/translations/fr-BE.js new file mode 100644 index 0000000000..da02615dea --- /dev/null +++ b/packages/ui/components/form-core/translations/fr-BE.js @@ -0,0 +1,5 @@ +import fr from './fr.js'; + +export default { + ...fr, +}; diff --git a/packages/ui/components/form-core/translations/fr-FR.js b/packages/ui/components/form-core/translations/fr-FR.js new file mode 100644 index 0000000000..da02615dea --- /dev/null +++ b/packages/ui/components/form-core/translations/fr-FR.js @@ -0,0 +1,5 @@ +import fr from './fr.js'; + +export default { + ...fr, +}; diff --git a/packages/ui/components/form-core/translations/fr.js b/packages/ui/components/form-core/translations/fr.js new file mode 100644 index 0000000000..7e9b4c04d3 --- /dev/null +++ b/packages/ui/components/form-core/translations/fr.js @@ -0,0 +1,6 @@ +export default { + validationError: 'Erreur', + validationWarning: 'Avertissement', + validationSuccess: 'Succès', + validationInfo: 'Info', +}; diff --git a/packages/ui/components/form-core/translations/hu-HU.js b/packages/ui/components/form-core/translations/hu-HU.js new file mode 100644 index 0000000000..130ba8f669 --- /dev/null +++ b/packages/ui/components/form-core/translations/hu-HU.js @@ -0,0 +1,5 @@ +import hu from './hu.js'; + +export default { + ...hu, +}; diff --git a/packages/ui/components/form-core/translations/hu.js b/packages/ui/components/form-core/translations/hu.js new file mode 100644 index 0000000000..615849468b --- /dev/null +++ b/packages/ui/components/form-core/translations/hu.js @@ -0,0 +1,6 @@ +export default { + validationError: 'Hiba', + validationWarning: 'Figyelmeztetés', + validationSuccess: 'Sikeres', + validationInfo: 'Információ', +}; diff --git a/packages/ui/components/form-core/translations/it-IT.js b/packages/ui/components/form-core/translations/it-IT.js new file mode 100644 index 0000000000..397b5a03bf --- /dev/null +++ b/packages/ui/components/form-core/translations/it-IT.js @@ -0,0 +1,5 @@ +import it from './it.js'; + +export default { + ...it, +}; diff --git a/packages/ui/components/form-core/translations/it.js b/packages/ui/components/form-core/translations/it.js new file mode 100644 index 0000000000..9d617e9ce3 --- /dev/null +++ b/packages/ui/components/form-core/translations/it.js @@ -0,0 +1,6 @@ +export default { + validationError: 'Errore', + validationWarning: 'Avvertenza', + validationSuccess: 'Operazione riuscita', + validationInfo: 'Info', +}; diff --git a/packages/ui/components/form-core/translations/nl-BE.js b/packages/ui/components/form-core/translations/nl-BE.js new file mode 100644 index 0000000000..93467cea62 --- /dev/null +++ b/packages/ui/components/form-core/translations/nl-BE.js @@ -0,0 +1,5 @@ +import nl from './nl.js'; + +export default { + ...nl, +}; diff --git a/packages/ui/components/form-core/translations/nl-NL.js b/packages/ui/components/form-core/translations/nl-NL.js new file mode 100644 index 0000000000..93467cea62 --- /dev/null +++ b/packages/ui/components/form-core/translations/nl-NL.js @@ -0,0 +1,5 @@ +import nl from './nl.js'; + +export default { + ...nl, +}; diff --git a/packages/ui/components/form-core/translations/nl.js b/packages/ui/components/form-core/translations/nl.js new file mode 100644 index 0000000000..96feb4a040 --- /dev/null +++ b/packages/ui/components/form-core/translations/nl.js @@ -0,0 +1,6 @@ +export default { + validationError: 'Fout', + validationWarning: 'Waarschuwing', + validationSuccess: 'Succes', + validationInfo: 'Informatie', +}; diff --git a/packages/ui/components/form-core/translations/pl-PL.js b/packages/ui/components/form-core/translations/pl-PL.js new file mode 100644 index 0000000000..cb0d0b8b67 --- /dev/null +++ b/packages/ui/components/form-core/translations/pl-PL.js @@ -0,0 +1,5 @@ +import pl from './pl.js'; + +export default { + ...pl, +}; diff --git a/packages/ui/components/form-core/translations/pl.js b/packages/ui/components/form-core/translations/pl.js new file mode 100644 index 0000000000..cf4537d943 --- /dev/null +++ b/packages/ui/components/form-core/translations/pl.js @@ -0,0 +1,6 @@ +export default { + validationError: 'Błąd', + validationWarning: 'Ostrzeżenie', + validationSuccess: 'Zrealizowano pomyślnie', + validationInfo: 'Informacja', +}; diff --git a/packages/ui/components/form-core/translations/ro-RO.js b/packages/ui/components/form-core/translations/ro-RO.js new file mode 100644 index 0000000000..8acc92b29f --- /dev/null +++ b/packages/ui/components/form-core/translations/ro-RO.js @@ -0,0 +1,5 @@ +import ro from './ro.js'; + +export default { + ...ro, +}; diff --git a/packages/ui/components/form-core/translations/ro.js b/packages/ui/components/form-core/translations/ro.js new file mode 100644 index 0000000000..3ee0d50afd --- /dev/null +++ b/packages/ui/components/form-core/translations/ro.js @@ -0,0 +1,6 @@ +export default { + validationError: 'Eroare', + validationWarning: 'Atenție', + validationSuccess: 'Succes', + validationInfo: 'Informații', +}; diff --git a/packages/ui/components/form-core/translations/ru-RU.js b/packages/ui/components/form-core/translations/ru-RU.js new file mode 100644 index 0000000000..e5f8f2aa1b --- /dev/null +++ b/packages/ui/components/form-core/translations/ru-RU.js @@ -0,0 +1,5 @@ +import ru from './ru.js'; + +export default { + ...ru, +}; diff --git a/packages/ui/components/form-core/translations/ru.js b/packages/ui/components/form-core/translations/ru.js new file mode 100644 index 0000000000..76d3e222d2 --- /dev/null +++ b/packages/ui/components/form-core/translations/ru.js @@ -0,0 +1,6 @@ +export default { + validationError: 'Ошибка', + validationWarning: 'Предупреждение', + validationSuccess: 'Успешно', + validationInfo: 'Информация', +}; diff --git a/packages/ui/components/form-core/translations/sk-SK.js b/packages/ui/components/form-core/translations/sk-SK.js new file mode 100644 index 0000000000..3000b323f6 --- /dev/null +++ b/packages/ui/components/form-core/translations/sk-SK.js @@ -0,0 +1,5 @@ +import sk from './sk.js'; + +export default { + ...sk, +}; diff --git a/packages/ui/components/form-core/translations/sk.js b/packages/ui/components/form-core/translations/sk.js new file mode 100644 index 0000000000..f287090064 --- /dev/null +++ b/packages/ui/components/form-core/translations/sk.js @@ -0,0 +1,6 @@ +export default { + validationError: 'Chyba', + validationWarning: 'Varovanie', + validationSuccess: 'Úspešné', + validationInfo: 'Info', +}; diff --git a/packages/ui/components/form-core/translations/uk-UA.js b/packages/ui/components/form-core/translations/uk-UA.js new file mode 100644 index 0000000000..e255cc021d --- /dev/null +++ b/packages/ui/components/form-core/translations/uk-UA.js @@ -0,0 +1,5 @@ +import uk from './uk.js'; + +export default { + ...uk, +}; diff --git a/packages/ui/components/form-core/translations/uk.js b/packages/ui/components/form-core/translations/uk.js new file mode 100644 index 0000000000..3ad008f320 --- /dev/null +++ b/packages/ui/components/form-core/translations/uk.js @@ -0,0 +1,6 @@ +export default { + validationError: 'Помилка', + validationWarning: 'Попередження', + validationSuccess: 'Успішно', + validationInfo: 'Інформація', +}; diff --git a/packages/ui/components/form-core/translations/zh.js b/packages/ui/components/form-core/translations/zh.js new file mode 100644 index 0000000000..32ef915e2b --- /dev/null +++ b/packages/ui/components/form-core/translations/zh.js @@ -0,0 +1,6 @@ +export default { + validationError: '错误', + validationWarning: '警告', + validationSuccess: '成功', + validationInfo: '信息', +}; diff --git a/packages/ui/components/input-amount/test/lion-input-amount.test.js b/packages/ui/components/input-amount/test/lion-input-amount.test.js index 8cb38ebcd8..6e37394e24 100644 --- a/packages/ui/components/input-amount/test/lion-input-amount.test.js +++ b/packages/ui/components/input-amount/test/lion-input-amount.test.js @@ -195,6 +195,9 @@ describe('', () => { expect(el.formattedValue).to.equal('123.45'); localize.locale = 'nl-NL'; await el.updateComplete; + // TODO find out why the localize needs to be loaded for the feedbackNode + // @ts-ignore [allow-protected] in test + await el._feedbackNode.localizeNamespacesLoaded; expect(el.formattedValue).to.equal('123,45'); }); diff --git a/packages/ui/components/input-file/test/lion-selected-file-list.test.js b/packages/ui/components/input-file/test/lion-selected-file-list.test.js index e5e0e779a7..bd0a0524ed 100644 --- a/packages/ui/components/input-file/test/lion-selected-file-list.test.js +++ b/packages/ui/components/input-file/test/lion-selected-file-list.test.js @@ -108,9 +108,10 @@ describe('lion-selected-file-list', () => { `); const fileItems = el.shadowRoot?.querySelectorAll('.selected__list__item'); const feedback = fileItems ? fileItems[0].querySelector('lion-validation-feedback') : undefined; + // @ts-ignore expect(feedback).to.exist; - expect(feedback).shadowDom.to.equal('foobar'); + expect(el.shadowRoot?.textContent).to.include('foobar'); }); it('should call removeFile method on click of remove button', async () => { diff --git a/packages/ui/package.json b/packages/ui/package.json index f8285f18d1..c32e1a6544 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -18,8 +18,7 @@ }, "./calendar-translations/*": "./components/calendar/translations/*", "./combobox-translations/*": "./components/combobox/translations/*", - "./pagination-translations/*": "./components/pagination/translations/*", - "./progress-indicator-translations/*": "./components/progress-indicator/translations/*", + "./form-core-translations/*": "./components/form-core/translations/*", "./input-datepicker-translations/*": "./components/input-datepicker/translations/*", "./input-file-translations/*": "./components/input-file/translations/*", "./input-iban-translations/*": "./components/input-iban/translations/*", @@ -27,6 +26,8 @@ "./input-stepper-translations/*": "./components/input-stepper/translations/*", "./input-tel-translations/*": "./components/input-tel/translations/*", "./overlays-translations/*": "./components/overlays/translations/*", + "./pagination-translations/*": "./components/pagination/translations/*", + "./progress-indicator-translations/*": "./components/progress-indicator/translations/*", "./validate-messages-translations/*": "./components/validate-messages/translations/*", "./docs/*": "./docs/*" },