diff --git a/.changeset/long-eels-guess.md b/.changeset/long-eels-guess.md new file mode 100644 index 000000000..9dafb58c0 --- /dev/null +++ b/.changeset/long-eels-guess.md @@ -0,0 +1,5 @@ +--- +'@lion/input-amount': patch +--- + +Reformat input-amount's formattedValue on locale changes, also respond to locale property. diff --git a/docs/components/inputs/input-amount/features.md b/docs/components/inputs/input-amount/features.md index 4e6faf784..b337ae9b9 100644 --- a/docs/components/inputs/input-amount/features.md +++ b/docs/components/inputs/input-amount/features.md @@ -35,14 +35,16 @@ export const currencySuffix = () => html` Locale can be forced for a specific `lion-input-amount`. It will format the amount according to this locale. ```js preview-story -export const forceLocale = () => html` - -`; +export const forceLocale = () => { + return html` + + `; +}; ``` > The separators are now flipped due to Dutch locale. On top of that, due to JOD currency, the minimum amount of decimals is 3 by default for this currency. diff --git a/packages/input-amount/src/LionInputAmount.js b/packages/input-amount/src/LionInputAmount.js index 746c2e1a4..d09fd3da7 100644 --- a/packages/input-amount/src/LionInputAmount.js +++ b/packages/input-amount/src/LionInputAmount.js @@ -26,6 +26,7 @@ export class LionInputAmount extends LocalizeMixin(LionInput) { * validators. */ modelValue: Number, + locale: { attribute: false }, }; } @@ -68,6 +69,8 @@ export class LionInputAmount extends LocalizeMixin(LionInput) { this.formatter = formatAmount; /** @type {string | undefined} */ this.currency = undefined; + /** @type {string | undefined} */ + this.locale = undefined; this.defaultValidators.push(new IsNumber()); } @@ -88,6 +91,28 @@ export class LionInputAmount extends LocalizeMixin(LionInput) { if (changedProperties.has('currency') && this.currency) { this._onCurrencyChanged({ currency: this.currency }); } + + if (changedProperties.has('locale') && this.locale !== changedProperties.get('locale')) { + if (this.locale) { + this.formatOptions.locale = this.locale; + } else { + delete this.formatOptions.locale; + } + this.__reformat(); + } + } + + /** + * @param {string} newLocale + * @param {string} oldLocale + * @enhance LocalizeMixin + */ + onLocaleChanged(newLocale, oldLocale) { + super.onLocaleChanged(newLocale, oldLocale); + // If locale property is used, no need to respond to global locale changes + if (!this.locale) { + this.__reformat(); + } } /** @@ -126,4 +151,8 @@ export class LionInputAmount extends LocalizeMixin(LionInput) { get __currencyLabel() { return this.currency ? formatCurrencyLabel(this.currency, localize.locale) : ''; } + + __reformat() { + this.formattedValue = this._callFormatter(); + } } diff --git a/packages/input-amount/test/lion-input-amount.test.js b/packages/input-amount/test/lion-input-amount.test.js index 0fef018a5..14cb160b4 100644 --- a/packages/input-amount/test/lion-input-amount.test.js +++ b/packages/input-amount/test/lion-input-amount.test.js @@ -70,6 +70,30 @@ describe('', () => { expect(el.formattedValue).to.equal('123,456.78'); // should stay British }); + it('reformats the formattedValue when locale property changes', async () => { + const el = /** @type {LionInputAmount} */ ( + await fixture(html` + + `) + ); + expect(el.formattedValue).to.equal('123,456.78'); + el.locale = 'nl-NL'; + await el.updateComplete; + expect(el.formattedValue).to.equal('123.456,78'); + }); + + it('reformats the formattedValue with global locale if locale property is unset', async () => { + const el = /** @type {LionInputAmount} */ ( + await fixture(html` + + `) + ); + expect(el.formattedValue).to.equal('123.456,78'); + el.locale = ''; + await el.updateComplete; + expect(el.formattedValue).to.equal('123,456.78'); + }); + it('uses parseAmount for parsing', async () => { const el = /** @type {LionInputAmount} */ ( await fixture(``) @@ -157,7 +181,44 @@ describe('', () => { ).to.equal('my-currency'); }); + it('reformats on locale changes', async () => { + const el = /** @type {LionInputAmount} */ ( + await fixture( + html``, + ) + ); + expect(el.formattedValue).to.equal('123.45'); + localize.locale = 'nl-NL'; + await el.updateComplete; + expect(el.formattedValue).to.equal('123,45'); + }); + describe('Accessibility', () => { + it('is accessible', async () => { + const el = await fixture( + ``, + ); + await expect(el).to.be.accessible(); + }); + + it('is accessible when readonly', async () => { + const el = await fixture( + ``, + ); + await expect(el).to.be.accessible(); + }); + + it('is accessible when disabled', async () => { + const el = await fixture( + ``, + ); + await expect(el).to.be.accessible(); + }); + it('adds currency id to aria-labelledby of input', async () => { const el = /** @type {LionInputAmount} */ ( await fixture(``) @@ -182,25 +243,4 @@ describe('', () => { // expect(el._currencyDisplayNode?.getAttribute('aria-label')).to.equal('Philippine pisos'); }); }); - - it('is accessible', async () => { - const el = await fixture( - ``, - ); - await expect(el).to.be.accessible(); - }); - - it('is accessible when readonly', async () => { - const el = await fixture( - ``, - ); - await expect(el).to.be.accessible(); - }); - - it('is accessible when disabled', async () => { - const el = await fixture( - ``, - ); - await expect(el).to.be.accessible(); - }); });