Merge pull request #1459 from ing-bank/input-amount-locale

Input amount locale
This commit is contained in:
gerjanvangeest 2021-07-19 16:08:25 +02:00 committed by GitHub
commit 2abb04cddd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 111 additions and 30 deletions

View file

@ -0,0 +1,5 @@
---
'@lion/input-amount': patch
---
Reformat input-amount's formattedValue on locale changes, also respond to locale property.

View file

@ -0,0 +1,5 @@
---
'@lion/localize': patch
---
Fix onLocaleChanged method missing param types

View file

@ -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`
<lion-input-amount
label="Price"
currency="JOD"
.formatOptions=${{ locale: 'nl-NL' }}
.locale="nl-NL"
.modelValue=${123456.78}
></lion-input-amount>
`;
`;
};
```
> 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.

View file

@ -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();
}
}

View file

@ -70,6 +70,30 @@ describe('<lion-input-amount>', () => {
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`
<lion-input-amount .modelValue=${123456.78} .locale="${'en-GB'}"></lion-input-amount>
`)
);
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`
<lion-input-amount .modelValue=${123456.78} .locale="${'nl-NL'}"></lion-input-amount>
`)
);
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(`<lion-input-amount></lion-input-amount>`)
@ -157,7 +181,44 @@ describe('<lion-input-amount>', () => {
).to.equal('my-currency');
});
it('reformats on locale changes', async () => {
const el = /** @type {LionInputAmount} */ (
await fixture(
html`<lion-input-amount
label="Price"
currency="EUR"
.modelValue=${123.45}
></lion-input-amount>`,
)
);
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(
`<lion-input-amount><label slot="label">Label</label></lion-input-amount>`,
);
await expect(el).to.be.accessible();
});
it('is accessible when readonly', async () => {
const el = await fixture(
`<lion-input-amount readonly .modelValue=${'123'}><label slot="label">Label</label></lion-input-amount>`,
);
await expect(el).to.be.accessible();
});
it('is accessible when disabled', async () => {
const el = await fixture(
`<lion-input-amount disabled><label slot="label">Label</label></lion-input-amount>`,
);
await expect(el).to.be.accessible();
});
it('adds currency id to aria-labelledby of input', async () => {
const el = /** @type {LionInputAmount} */ (
await fixture(`<lion-input-amount currency="EUR"></lion-input-amount>`)
@ -182,25 +243,4 @@ describe('<lion-input-amount>', () => {
// expect(el._currencyDisplayNode?.getAttribute('aria-label')).to.equal('Philippine pisos');
});
});
it('is accessible', async () => {
const el = await fixture(
`<lion-input-amount><label slot="label">Label</label></lion-input-amount>`,
);
await expect(el).to.be.accessible();
});
it('is accessible when readonly', async () => {
const el = await fixture(
`<lion-input-amount readonly .modelValue=${'123'}><label slot="label">Label</label></lion-input-amount>`,
);
await expect(el).to.be.accessible();
});
it('is accessible when disabled', async () => {
const el = await fixture(
`<lion-input-amount disabled><label slot="label">Label</label></lion-input-amount>`,
);
await expect(el).to.be.accessible();
});
});

View file

@ -68,7 +68,7 @@ declare class LocalizeMixinHost {
public performUpdate(): Promise<void>;
public onLocaleReady(): void;
public onLocaleChanged(): void;
public onLocaleChanged(newLocale: string, oldLocale: string): void;
public onLocaleUpdated(): void;
public connectedCallback(): void;
public disconnectedCallback(): void;