diff --git a/.changeset/sour-oranges-matter.md b/.changeset/sour-oranges-matter.md new file mode 100644 index 000000000..9311133dc --- /dev/null +++ b/.changeset/sour-oranges-matter.md @@ -0,0 +1,6 @@ +--- +'@lion/form-core': minor +'@lion/localize': minor +--- + +Make ValidateMixin feedback message wait for localize loadingComplete, to ensure getting the right fieldName if this refers to a localized label. diff --git a/docs/docs/systems/localize/features.md b/docs/docs/systems/localize/features.md index f51693751..3801f23b6 100644 --- a/docs/docs/systems/localize/features.md +++ b/docs/docs/systems/localize/features.md @@ -98,7 +98,7 @@ Let's look at both cases in depth. ```js // use the dynamic import to load static assets localize.loadNamespace({ - 'my-hello-component': locale => { + 'my-hello-component': async locale => { // resolves to a module with the module.default `{ greeting: 'Hallo {name}!' }` return import(`./translations/${locale}.js`); }, diff --git a/packages/form-core/src/validate/ValidateMixin.js b/packages/form-core/src/validate/ValidateMixin.js index 65f8ea1e5..05a1d7143 100644 --- a/packages/form-core/src/validate/ValidateMixin.js +++ b/packages/form-core/src/validate/ValidateMixin.js @@ -644,6 +644,7 @@ export const ValidateMixinImplementation = superclass => * @private */ async __getFeedbackMessages(validators) { + await localize.loadingComplete; let fieldName = await this.fieldName; return Promise.all( validators.map(async validator => { diff --git a/packages/form-integrations/test/form-validation-integrations.test.js b/packages/form-integrations/test/form-validation-integrations.test.js index cf06c28bc..ace537830 100644 --- a/packages/form-integrations/test/form-validation-integrations.test.js +++ b/packages/form-integrations/test/form-validation-integrations.test.js @@ -1,6 +1,7 @@ import { expect, fixture, defineCE } from '@open-wc/testing'; import { html, unsafeStatic } from 'lit/static-html.js'; import { Required, DefaultSuccess, Validator } from '@lion/form-core'; +import { localize } from '@lion/localize'; import { loadDefaultFeedbackMessages } from '@lion/validate-messages'; import { LionInput } from '@lion/input'; import sinon from 'sinon'; @@ -117,5 +118,62 @@ describe('Form Validation Integrations', () => { await el.feedbackComplete; expect(spy.called).to.be.false; }); + + it('correctly renders localized fieldName (label), even on locale changes', async () => { + class DefaultLabelInput extends LionInput { + constructor() { + super(); + this.setDefaultLabel(); + } + + async updateLabel() { + await localize.loadingComplete; + this.label = localize.msg('test-default-label:label'); + } + + async setDefaultLabel() { + localize.loadNamespace({ + 'test-default-label': /** @param {string} locale */ async locale => { + switch (locale) { + case 'nl-NL': + return { label: 'Tekst' }; + default: + return { label: 'Text' }; + } + }, + }); + this.boundUpdateLabel = this.updateLabel.bind(this); + this.boundUpdateLabel(); + localize.addEventListener('localeChanged', this.boundUpdateLabel); + } + } + const elTagString = defineCE(DefaultLabelInput); + const elTag = unsafeStatic(elTagString); + const el = /** @type {LionInput} */ ( + await fixture(html` + <${elTag} + .validators=${[new Required()]} + >${lightDom} + `) + ); + el.touched = true; + el.dirty = true; + await el.updateComplete; + await el.feedbackComplete; + const { _feedbackNode } = getFormControlMembers(el); + expect(_feedbackNode.feedbackData?.[0].message).to.equal('Please enter a(n) Text.'); + + localize.locale = 'nl-NL'; + await el.updateComplete; + await el.feedbackComplete; + expect(el.label).to.equal('Tekst'); + expect(_feedbackNode.feedbackData?.[0].message).to.equal('Vul een Tekst in.'); + + localize.locale = 'en-GB'; + await el.updateComplete; + await el.feedbackComplete; + expect(el.label).to.equal('Text'); + expect(_feedbackNode.feedbackData?.[0].message).to.equal('Please enter a(n) Text.'); + }); }); }); diff --git a/packages/localize/src/LocalizeManager.js b/packages/localize/src/LocalizeManager.js index feb9db563..a4dbdbc4f 100644 --- a/packages/localize/src/LocalizeManager.js +++ b/packages/localize/src/LocalizeManager.js @@ -173,10 +173,13 @@ export class LocalizeManager { } /** - * @returns {Promise.} + * @returns {Promise.} */ get loadingComplete() { - return Promise.all(Object.values(this.__namespaceLoaderPromisesCache[this.locale])); + if (typeof this.__namespaceLoaderPromisesCache[this.locale] === 'object') { + return Promise.all(Object.values(this.__namespaceLoaderPromisesCache[this.locale])); + } + return Promise.resolve(); } reset() {