@lion/ui 0.6.1 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/core/src/browserDetection.js +27 -17
- package/components/form-core/test-suites/form-group/FormGroupMixin.suite.js +1 -1
- package/components/helpers/src/SbActionLogger.js +1 -0
- package/components/input-amount/src/parsers.js +11 -3
- package/components/input-amount/test/formatters.test.js +11 -0
- package/components/input-amount/test/parsers.test.js +32 -4
- package/components/input-date/src/LionInputDate.js +1 -1
- package/components/input-tel-dropdown/src/LionInputTelDropdown.js +1 -13
- package/components/input-tel-dropdown/test-suites/LionInputTelDropdown.suite.js +2 -0
- package/components/input-tel-dropdown/types/index.ts +1 -0
- package/components/localize/src/date/getDateFormatBasedOnLocale.js +4 -3
- package/components/localize/src/date/parseDate.js +7 -2
- package/components/localize/src/date/utils/sanitizedDateTimeFormat.js +3 -2
- package/components/localize/src/number/formatNumber.js +1 -1
- package/components/localize/test/date/getDateFormatBasedOnLocale.test.js +6 -2
- package/components/localize/test/date/parseDate.test.js +8 -1
- package/components/localize/test/number/formatNumber.test.js +9 -0
- package/components/overlays/test/local-positioning.test.js +13 -21
- package/components/overlays/test/utils-tests/contain-focus.test.js +2 -2
- package/components/overlays/test/utils-tests/deep-contains.test.js +3 -3
- package/components/overlays/test/utils-tests/get-focusable-elements.test.js +1 -1
- package/components/select-rich/src/LionSelectRich.js +8 -1
- package/components/select-rich/test/lion-select-rich-interaction.test.js +27 -41
- package/components/select-rich/test/lion-select-rich.test.js +16 -14
- package/components/select-rich/test-helpers/getSelectRichMembers.js +18 -0
- package/custom-elements.json +531 -463
- package/dist-types/components/core/src/browserDetection.d.ts +3 -3
- package/dist-types/components/core/src/types.d.ts +1 -1
- package/dist-types/components/core/src/types.d.ts.map +1 -1
- package/dist-types/components/core/types/DisabledMixinTypes.d.ts +1 -1
- package/dist-types/components/core/types/DisabledMixinTypes.d.ts.map +1 -1
- package/dist-types/components/core/types/DisabledWithTabIndexMixinTypes.d.ts +1 -1
- package/dist-types/components/core/types/DisabledWithTabIndexMixinTypes.d.ts.map +1 -1
- package/dist-types/components/core/types/SlotMixinTypes.d.ts +4 -4
- package/dist-types/components/core/types/SlotMixinTypes.d.ts.map +1 -1
- package/dist-types/components/form-core/src/registration/FormControlsCollection.d.ts.map +1 -1
- package/dist-types/components/form-core/types/FocusMixinTypes.d.ts +1 -1
- package/dist-types/components/form-core/types/FocusMixinTypes.d.ts.map +1 -1
- package/dist-types/components/form-core/types/FormControlMixinTypes.d.ts +2 -2
- package/dist-types/components/form-core/types/FormControlMixinTypes.d.ts.map +1 -1
- package/dist-types/components/form-core/types/FormatMixinTypes.d.ts +2 -2
- package/dist-types/components/form-core/types/FormatMixinTypes.d.ts.map +1 -1
- package/dist-types/components/form-core/types/InteractionStateMixinTypes.d.ts +2 -2
- package/dist-types/components/form-core/types/InteractionStateMixinTypes.d.ts.map +1 -1
- package/dist-types/components/form-core/types/NativeTextFieldMixinTypes.d.ts +1 -1
- package/dist-types/components/form-core/types/NativeTextFieldMixinTypes.d.ts.map +1 -1
- package/dist-types/components/form-core/types/choice-group/ChoiceGroupMixinTypes.d.ts +1 -1
- package/dist-types/components/form-core/types/choice-group/ChoiceGroupMixinTypes.d.ts.map +1 -1
- package/dist-types/components/form-core/types/choice-group/ChoiceInputMixinTypes.d.ts +1 -1
- package/dist-types/components/form-core/types/choice-group/ChoiceInputMixinTypes.d.ts.map +1 -1
- package/dist-types/components/form-core/types/choice-group/CustomChoiceGroupMixinTypes.d.ts +1 -1
- package/dist-types/components/form-core/types/choice-group/CustomChoiceGroupMixinTypes.d.ts.map +1 -1
- package/dist-types/components/form-core/types/form-group/FormGroupMixinTypes.d.ts +1 -1
- package/dist-types/components/form-core/types/form-group/FormGroupMixinTypes.d.ts.map +1 -1
- package/dist-types/components/form-core/types/registration/FormRegisteringMixinTypes.d.ts +1 -1
- package/dist-types/components/form-core/types/registration/FormRegisteringMixinTypes.d.ts.map +1 -1
- package/dist-types/components/form-core/types/registration/FormRegistrarMixinTypes.d.ts +1 -1
- package/dist-types/components/form-core/types/registration/FormRegistrarMixinTypes.d.ts.map +1 -1
- package/dist-types/components/form-core/types/registration/FormRegistrarPortalMixinTypes.d.ts +1 -1
- package/dist-types/components/form-core/types/registration/FormRegistrarPortalMixinTypes.d.ts.map +1 -1
- package/dist-types/components/form-core/types/utils/SyncUpdatableMixinTypes.d.ts +2 -2
- package/dist-types/components/form-core/types/utils/SyncUpdatableMixinTypes.d.ts.map +1 -1
- package/dist-types/components/form-core/types/validate/ValidateMixinTypes.d.ts +5 -5
- package/dist-types/components/form-core/types/validate/ValidateMixinTypes.d.ts.map +1 -1
- package/dist-types/components/form-core/types/validate/validate.d.ts +5 -5
- package/dist-types/components/form-core/types/validate/validate.d.ts.map +1 -1
- package/dist-types/components/helpers/src/SbActionLogger.d.ts.map +1 -1
- package/dist-types/components/input-amount/src/parsers.d.ts.map +1 -1
- package/dist-types/components/input-date/src/LionInputDate.d.ts.map +1 -1
- package/dist-types/components/input-file/types/input-file.d.ts +4 -4
- package/dist-types/components/input-file/types/input-file.d.ts.map +1 -1
- package/dist-types/components/input-stepper/src/LionInputStepper.d.ts +0 -1
- package/dist-types/components/input-stepper/src/LionInputStepper.d.ts.map +1 -1
- package/dist-types/components/input-tel/types/index.d.ts +1 -1
- package/dist-types/components/input-tel/types/index.d.ts.map +1 -1
- package/dist-types/components/input-tel-dropdown/src/LionInputTelDropdown.d.ts.map +1 -1
- package/dist-types/components/input-tel-dropdown/test-suites/LionInputTelDropdown.suite.d.ts.map +1 -1
- package/dist-types/components/input-tel-dropdown/types/index.d.ts +6 -5
- package/dist-types/components/input-tel-dropdown/types/index.d.ts.map +1 -1
- package/dist-types/components/listbox/types/ListboxMixinTypes.d.ts +1 -1
- package/dist-types/components/listbox/types/ListboxMixinTypes.d.ts.map +1 -1
- package/dist-types/components/localize/src/date/getDateFormatBasedOnLocale.d.ts +2 -1
- package/dist-types/components/localize/src/date/getDateFormatBasedOnLocale.d.ts.map +1 -1
- package/dist-types/components/localize/src/date/parseDate.d.ts +3 -1
- package/dist-types/components/localize/src/date/parseDate.d.ts.map +1 -1
- package/dist-types/components/localize/src/date/utils/sanitizedDateTimeFormat.d.ts +2 -1
- package/dist-types/components/localize/src/date/utils/sanitizedDateTimeFormat.d.ts.map +1 -1
- package/dist-types/components/localize/types/LocalizeMixinTypes.d.ts +4 -4
- package/dist-types/components/localize/types/LocalizeMixinTypes.d.ts.map +1 -1
- package/dist-types/components/overlays/src/utils/adopt-styles.d.ts +6 -8
- package/dist-types/components/overlays/src/utils/adopt-styles.d.ts.map +1 -1
- package/dist-types/components/overlays/types/ArrowMixinTypes.d.ts +1 -1
- package/dist-types/components/overlays/types/ArrowMixinTypes.d.ts.map +1 -1
- package/dist-types/components/overlays/types/OverlayConfig.d.ts +1 -1
- package/dist-types/components/overlays/types/OverlayConfig.d.ts.map +1 -1
- package/dist-types/components/overlays/types/OverlayMixinTypes.d.ts +1 -1
- package/dist-types/components/overlays/types/OverlayMixinTypes.d.ts.map +1 -1
- package/dist-types/components/select-rich/src/LionSelectRich.d.ts +1 -0
- package/dist-types/components/select-rich/src/LionSelectRich.d.ts.map +1 -1
- package/dist-types/components/select-rich/test/lion-select-rich-interaction.test.d.ts.map +1 -1
- package/dist-types/components/select-rich/test/lion-select-rich.test.d.ts.map +1 -1
- package/dist-types/components/select-rich/test-helpers/getSelectRichMembers.d.ts +19 -0
- package/dist-types/components/select-rich/test-helpers/getSelectRichMembers.d.ts.map +1 -0
- package/dist-types/exports/select-rich-test-helpers.d.ts +2 -0
- package/dist-types/exports/select-rich-test-helpers.d.ts.map +1 -0
- package/dist-types/tsconfig.tsbuildinfo +1 -1
- package/docs/components/checkbox-group/overview.md +2 -2
- package/docs/components/collapsible/overview.md +1 -1
- package/docs/components/combobox/overview.md +1 -1
- package/docs/components/combobox/src/gh-combobox/gh-combobox.js +1 -1
- package/docs/components/combobox/src/google-combobox/google-combobox.js +1 -1
- package/docs/components/combobox/use-cases.md +1 -1
- package/docs/components/dialog/overview.md +1 -1
- package/docs/components/fieldset/overview.md +5 -5
- package/docs/components/form/overview.md +3 -3
- package/docs/components/icon/use-cases.md +1 -1
- package/docs/components/input/overview.md +1 -1
- package/docs/components/input-amount/overview.md +4 -4
- package/docs/components/input-date/overview.md +5 -5
- package/docs/components/input-datepicker/overview.md +5 -5
- package/docs/components/input-email/overview.md +2 -2
- package/docs/components/input-file/overview.md +1 -1
- package/docs/components/input-iban/overview.md +2 -2
- package/docs/components/input-range/overview.md +2 -2
- package/docs/components/input-stepper/overview.md +1 -1
- package/docs/components/input-tel/overview.md +1 -1
- package/docs/components/input-tel/use-cases.md +6 -6
- package/docs/components/input-tel-dropdown/overview.md +1 -1
- package/docs/components/input-tel-dropdown/src/intl-input-tel-dropdown.js +1 -0
- package/docs/components/listbox/use-cases.md +1 -1
- package/docs/components/radio-group/overview.md +3 -3
- package/docs/components/select/use-cases.md +1 -1
- package/docs/components/select-rich/use-cases.md +1 -1
- package/docs/components/tabs/examples.md +1 -1
- package/docs/fundamentals/index.md +4 -4
- package/docs/fundamentals/node-tools/providence-analytics/LocalConfiguration.md +1 -1
- package/docs/fundamentals/node-tools/providence-analytics/QueryResult.md +1 -1
- package/docs/fundamentals/node-tools/providence-analytics/analyzer.md +1 -1
- package/docs/fundamentals/node-tools/providence-analytics/dashboard.md +1 -1
- package/docs/fundamentals/node-tools/providence-analytics/overview.md +3 -3
- package/docs/fundamentals/node-tools/publish-docs/overview.md +3 -3
- package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +2 -2
- package/docs/fundamentals/rationales/accessibility.md +1 -1
- package/docs/fundamentals/systems/core/SlotMixin.md +1 -1
- package/docs/fundamentals/systems/core/overview.md +1 -1
- package/docs/fundamentals/systems/form/assets/h-output.js +1 -0
- package/docs/fundamentals/systems/form/formatting-and-parsing.md +4 -4
- package/docs/fundamentals/systems/form/interaction-states.md +6 -0
- package/docs/fundamentals/systems/form/model-value.md +10 -1
- package/docs/fundamentals/systems/form/overview.md +28 -28
- package/docs/fundamentals/systems/form/validate.md +2 -2
- package/docs/fundamentals/systems/localize/overview.md +4 -4
- package/docs/fundamentals/systems/overlays/configuration.md +2 -2
- package/docs/fundamentals/systems/overlays/overview.md +5 -5
- package/docs/fundamentals/systems/overlays/use-cases.md +2 -2
- package/docs/fundamentals/tools/helpers/overview.md +1 -1
- package/docs/fundamentals/tools/singleton-manager/overview.md +4 -4
- package/docs/guides/how-to/create-a-custom-field.md +5 -5
- package/docs/guides/how-to/create-a-form.md +4 -4
- package/docs/guides/how-to/extend-a-native-input.md +2 -2
- package/docs/guides/index.md +8 -8
- package/docs/guides/principles/index.md +5 -5
- package/docs/guides/principles/styling.md +1 -1
- package/exports/select-rich-test-helpers.js +1 -0
- package/package.json +1 -1
- package/select-rich-test-helpers.js +1 -0
|
@@ -1,17 +1,27 @@
|
|
|
1
|
+
import { isServer } from 'lit';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* From https://stackoverflow.com/questions/4565112/javascript-how-to-find-out-if-the-user-browser-is-chrome
|
|
3
|
-
* @param {string} [flavor]
|
|
5
|
+
* @param {string} [flavor='google-chrome']
|
|
4
6
|
*/
|
|
5
7
|
function checkChrome(flavor = 'google-chrome') {
|
|
6
|
-
|
|
8
|
+
if (isServer) {
|
|
9
|
+
return flavor === 'google-chrome';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const isChromium = /** @type {window & { chrome?: boolean}} */ (globalThis).chrome;
|
|
13
|
+
|
|
7
14
|
if (flavor === 'chromium') {
|
|
8
15
|
return isChromium;
|
|
9
16
|
}
|
|
10
|
-
const winNav =
|
|
11
|
-
const vendorName = winNav
|
|
12
|
-
const isOpera =
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
const winNav = globalThis.navigator;
|
|
18
|
+
const vendorName = winNav?.vendor;
|
|
19
|
+
const isOpera =
|
|
20
|
+
typeof (/** @type {window & { opr?: boolean}} */ (globalThis).opr) !== 'undefined';
|
|
21
|
+
// @ts-ignore
|
|
22
|
+
const isIEedge = globalThis.userAgent?.indexOf('Edge') > -1;
|
|
23
|
+
// @ts-ignore
|
|
24
|
+
const isIOSChrome = globalThis.userAgent?.match('CriOS');
|
|
15
25
|
|
|
16
26
|
if (flavor === 'ios') {
|
|
17
27
|
return isIOSChrome;
|
|
@@ -31,18 +41,18 @@ function checkChrome(flavor = 'google-chrome') {
|
|
|
31
41
|
}
|
|
32
42
|
|
|
33
43
|
export const browserDetection = {
|
|
34
|
-
isIE11: /Trident/.test(
|
|
44
|
+
isIE11: /Trident/.test(globalThis.navigator?.userAgent),
|
|
35
45
|
isChrome: checkChrome(),
|
|
36
46
|
isIOSChrome: checkChrome('ios'),
|
|
37
47
|
isChromium: checkChrome('chromium'),
|
|
38
|
-
isFirefox: navigator
|
|
39
|
-
isMac: navigator
|
|
40
|
-
isIOS: /iPhone|iPad|iPod/i.test(navigator
|
|
48
|
+
isFirefox: globalThis.navigator?.userAgent.toLowerCase().indexOf('firefox') > -1,
|
|
49
|
+
isMac: globalThis.navigator?.appVersion?.indexOf('Mac') !== -1,
|
|
50
|
+
isIOS: /iPhone|iPad|iPod/i.test(globalThis.navigator?.userAgent),
|
|
41
51
|
isMacSafari:
|
|
42
|
-
navigator
|
|
43
|
-
navigator
|
|
44
|
-
navigator
|
|
45
|
-
navigator
|
|
46
|
-
navigator
|
|
47
|
-
navigator
|
|
52
|
+
globalThis.navigator?.vendor &&
|
|
53
|
+
globalThis.navigator?.vendor.indexOf('Apple') > -1 &&
|
|
54
|
+
globalThis.navigator?.userAgent &&
|
|
55
|
+
globalThis.navigator?.userAgent.indexOf('CriOS') === -1 &&
|
|
56
|
+
globalThis.navigator?.userAgent.indexOf('FxiOS') === -1 &&
|
|
57
|
+
globalThis.navigator?.appVersion.indexOf('Mac') !== -1,
|
|
48
58
|
};
|
|
@@ -666,7 +666,7 @@ export function runFormGroupMixinSuite(cfg = {}) {
|
|
|
666
666
|
|
|
667
667
|
await triggerFocusFor(hobbyInputNode);
|
|
668
668
|
await triggerFocusFor(genderInputNode);
|
|
669
|
-
const button = /** @type {FormGroup} */ (await fixture(html`<button
|
|
669
|
+
const button = /** @type {FormGroup} */ (await fixture(html`<button>Button</button>`));
|
|
670
670
|
button.focus();
|
|
671
671
|
|
|
672
672
|
expect(el.touched).to.be.true;
|
|
@@ -11,7 +11,8 @@ import { parseNumber, getFractionDigits } from '@lion/ui/localize-no-side-effect
|
|
|
11
11
|
* @return {number} new value with rounded up decimals
|
|
12
12
|
*/
|
|
13
13
|
function round(value, decimals) {
|
|
14
|
-
|
|
14
|
+
const numberContainsExponent = value?.toString().includes('e');
|
|
15
|
+
if (typeof decimals === 'undefined' || numberContainsExponent) {
|
|
15
16
|
return Number(value);
|
|
16
17
|
}
|
|
17
18
|
return Number(`${Math.round(Number(`${value}e${decimals}`))}e-${decimals}`);
|
|
@@ -30,10 +31,17 @@ function round(value, decimals) {
|
|
|
30
31
|
* @param {FormatOptions} [givenOptions] Locale Options
|
|
31
32
|
*/
|
|
32
33
|
export function parseAmount(value, givenOptions) {
|
|
34
|
+
const unmatchedInput = value.match(/[^0-9,.\- ]/g);
|
|
35
|
+
// for the full paste behavior documentation:
|
|
36
|
+
// ./docs/components/input-amount/use-cases.md#paste-behavior
|
|
37
|
+
if (unmatchedInput && givenOptions?.mode !== 'pasted') {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
|
|
33
41
|
const number = parseNumber(value, givenOptions);
|
|
34
42
|
|
|
35
|
-
if (typeof number !== 'number') {
|
|
36
|
-
return
|
|
43
|
+
if (typeof number !== 'number' || Number.isNaN(number)) {
|
|
44
|
+
return undefined;
|
|
37
45
|
}
|
|
38
46
|
|
|
39
47
|
/** @type {FormatOptions} */
|
|
@@ -74,4 +74,15 @@ describe('formatAmount()', () => {
|
|
|
74
74
|
localizeManager.locale = 'nl-NL';
|
|
75
75
|
expect(formatAmount(12345678)).to.equal('12.345.678,00');
|
|
76
76
|
});
|
|
77
|
+
|
|
78
|
+
// TODO: make it work with big numbers, e.g. make use of BigInt
|
|
79
|
+
it.skip('rounds up big numbers', async () => {
|
|
80
|
+
expect(formatAmount(1e21, { locale: 'en-GB', currency: 'EUR' })).to.equal(
|
|
81
|
+
'1,000,000,000,000,000,000,000.00',
|
|
82
|
+
);
|
|
83
|
+
// eslint-disable-next-line no-loss-of-precision
|
|
84
|
+
expect(formatAmount(12345678987654321.42, { locale: 'en-GB', currency: 'EUR' })).to.equal(
|
|
85
|
+
'12,345,678,987,654,321.42',
|
|
86
|
+
);
|
|
87
|
+
});
|
|
77
88
|
});
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import { expect } from '@open-wc/testing';
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { getLocalizeManager } from '@lion/ui/localize-no-side-effects.js';
|
|
3
|
+
import { localizeTearDown } from '@lion/ui/localize-test-helpers.js';
|
|
4
4
|
import { parseAmount } from '@lion/ui/input-amount.js';
|
|
5
5
|
|
|
6
6
|
describe('parseAmount()', async () => {
|
|
7
|
+
const localizeManager = getLocalizeManager();
|
|
8
|
+
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
localizeManager.locale = 'en-GB';
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
afterEach(() => {
|
|
14
|
+
localizeTearDown();
|
|
15
|
+
});
|
|
16
|
+
|
|
7
17
|
it('with currency set to correct amount of decimals', async () => {
|
|
8
|
-
localize.locale = 'en-GB';
|
|
9
18
|
expect(
|
|
10
19
|
parseAmount('1.015', {
|
|
11
20
|
currency: 'EUR',
|
|
@@ -29,7 +38,26 @@ describe('parseAmount()', async () => {
|
|
|
29
38
|
});
|
|
30
39
|
|
|
31
40
|
it('with no currency keeps all decimals', async () => {
|
|
32
|
-
localize.locale = 'en-GB';
|
|
33
41
|
expect(parseAmount('1.015')).to.equal(1.015);
|
|
34
42
|
});
|
|
43
|
+
|
|
44
|
+
// TODO: make it work with big numbers, e.g. make use of BigInt
|
|
45
|
+
it.skip('rounds up big numbers', async () => {
|
|
46
|
+
// eslint-disable-next-line no-loss-of-precision
|
|
47
|
+
expect(parseAmount('999999999999999999999,42')).to.equal(999999999999999999999.42);
|
|
48
|
+
// eslint-disable-next-line no-loss-of-precision
|
|
49
|
+
expect(parseAmount('12,345,678,987,654,321.42')).to.equal(12345678987654321.42);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('returns undefined if an invalid value is entered', async () => {
|
|
53
|
+
expect(parseAmount('foo')).to.equal(undefined);
|
|
54
|
+
expect(parseAmount('foo1')).to.equal(undefined);
|
|
55
|
+
expect(parseAmount('EUR 1,50')).to.equal(undefined);
|
|
56
|
+
expect(parseAmount('--1')).to.equal(undefined);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('ignores letters when "pasted" mode used', async () => {
|
|
60
|
+
expect(parseAmount('foo1', { mode: 'pasted' })).to.equal(1);
|
|
61
|
+
expect(parseAmount('EUR 1,50', { mode: 'pasted' })).to.equal(1.5);
|
|
62
|
+
});
|
|
35
63
|
});
|
|
@@ -21,7 +21,7 @@ export class LionInputDate extends LocalizeMixin(LionInput) {
|
|
|
21
21
|
/**
|
|
22
22
|
* @param {string} value
|
|
23
23
|
*/
|
|
24
|
-
this.parser = value => (value === '' ? undefined : parseDate(value));
|
|
24
|
+
this.parser = value => (value === '' ? undefined : parseDate(value, this.formatOptions));
|
|
25
25
|
this.formatter = formatDate;
|
|
26
26
|
this.defaultValidators.push(new IsDate());
|
|
27
27
|
// Just explicitly make clear we shouldn't use type 'date'
|
|
@@ -100,6 +100,7 @@ export class LionInputTelDropdown extends LionInputTel {
|
|
|
100
100
|
localizeManager.msg('lion-input-tel:suggestedCountries'),
|
|
101
101
|
},
|
|
102
102
|
},
|
|
103
|
+
input: this._inputNode,
|
|
103
104
|
};
|
|
104
105
|
|
|
105
106
|
return {
|
|
@@ -357,19 +358,6 @@ export class LionInputTelDropdown extends LionInputTel {
|
|
|
357
358
|
}
|
|
358
359
|
}
|
|
359
360
|
}
|
|
360
|
-
|
|
361
|
-
// Put focus on text box
|
|
362
|
-
//
|
|
363
|
-
// A LionSelectRich with interactionMode set on windows/linux
|
|
364
|
-
// will set each item on arrow key up/down to activeElement
|
|
365
|
-
// which causes the focus to jump every time to the inputNode
|
|
366
|
-
const overlayController = dropdownElement._overlayCtrl;
|
|
367
|
-
// @ts-ignore interactionMode only exists on LionSelectRich not on HTMLSelectElement
|
|
368
|
-
if (overlayController?.isShown && dropdownElement.interactionMode !== 'windows/linux') {
|
|
369
|
-
setTimeout(() => {
|
|
370
|
-
this._inputNode.focus();
|
|
371
|
-
});
|
|
372
|
-
}
|
|
373
361
|
}
|
|
374
362
|
|
|
375
363
|
/**
|
|
@@ -3,9 +3,10 @@ import { splitDate } from './utils/splitDate.js';
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* To compute the localized date format
|
|
6
|
+
* @param {string} [locale]
|
|
6
7
|
* @returns {string}
|
|
7
8
|
*/
|
|
8
|
-
export function getDateFormatBasedOnLocale() {
|
|
9
|
+
export function getDateFormatBasedOnLocale(locale) {
|
|
9
10
|
/**
|
|
10
11
|
*
|
|
11
12
|
* @param {ArrayLike.<string>} dateParts
|
|
@@ -35,9 +36,9 @@ export function getDateFormatBasedOnLocale() {
|
|
|
35
36
|
date.setDate(20);
|
|
36
37
|
date.setMonth(11);
|
|
37
38
|
date.setFullYear(2012);
|
|
38
|
-
|
|
39
|
+
const options = locale ? { locale } : {};
|
|
39
40
|
// Strange characters added by IE11 need to be taken into account here
|
|
40
|
-
const formattedDate = sanitizedDateTimeFormat(date);
|
|
41
|
+
const formattedDate = sanitizedDateTimeFormat(date, options);
|
|
41
42
|
|
|
42
43
|
// For Dutch locale, dateParts would match: [ 1:'20', 2:'-', 3:'12', 4:'-', 5:'2012' ]
|
|
43
44
|
const dateParts = splitDate(formattedDate);
|
|
@@ -2,6 +2,10 @@ import { getDateFormatBasedOnLocale } from './getDateFormatBasedOnLocale.js';
|
|
|
2
2
|
import { getLocalizeManager } from '../getLocalizeManager.js';
|
|
3
3
|
import { addLeadingZero } from './utils/addLeadingZero.js';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {import('../../types/LocalizeMixinTypes.js').FormatDateOptions} FormatDateOptions
|
|
7
|
+
*/
|
|
8
|
+
|
|
5
9
|
/**
|
|
6
10
|
* @param {function} fn
|
|
7
11
|
*/
|
|
@@ -26,15 +30,16 @@ const memoizedGetDateFormatBasedOnLocale = memoize(getDateFormatBasedOnLocale);
|
|
|
26
30
|
* To parse a date into the right format
|
|
27
31
|
*
|
|
28
32
|
* @param {string} dateString
|
|
33
|
+
* @param {FormatDateOptions} [options] Intl options are available
|
|
29
34
|
* @returns {Date | undefined}
|
|
30
35
|
*/
|
|
31
|
-
export function parseDate(dateString) {
|
|
36
|
+
export function parseDate(dateString, options) {
|
|
32
37
|
const localizeManager = getLocalizeManager();
|
|
33
38
|
|
|
34
39
|
const stringToParse = addLeadingZero(dateString);
|
|
35
40
|
let parsedString;
|
|
36
41
|
|
|
37
|
-
switch (memoizedGetDateFormatBasedOnLocale(localizeManager.locale)) {
|
|
42
|
+
switch (memoizedGetDateFormatBasedOnLocale(options?.locale || localizeManager.locale)) {
|
|
38
43
|
case 'day-month-year':
|
|
39
44
|
parsedString = `${stringToParse.slice(6, 10)}/${stringToParse.slice(
|
|
40
45
|
3,
|
|
@@ -5,9 +5,10 @@ import { clean } from './clean.js';
|
|
|
5
5
|
* To sanitize a date from IE11 handling
|
|
6
6
|
*
|
|
7
7
|
* @param {Date} date
|
|
8
|
+
* @param {import('../../../types/LocalizeMixinTypes.js').FormatDateOptions} [options] Intl options are available
|
|
8
9
|
* @returns {string}
|
|
9
10
|
*/
|
|
10
|
-
export function sanitizedDateTimeFormat(date) {
|
|
11
|
-
const fDate = formatDate(date);
|
|
11
|
+
export function sanitizedDateTimeFormat(date, options) {
|
|
12
|
+
const fDate = formatDate(date, options);
|
|
12
13
|
return clean(fDate);
|
|
13
14
|
}
|
|
@@ -26,7 +26,7 @@ export function formatNumber(number, options = /** @type {FormatOptions} */ ({})
|
|
|
26
26
|
}
|
|
27
27
|
let printNumberOfParts = '';
|
|
28
28
|
// update numberOfParts because there may be some parts added
|
|
29
|
-
const numberOfParts = formattedToParts
|
|
29
|
+
const numberOfParts = formattedToParts ? formattedToParts.length : 0;
|
|
30
30
|
for (let i = 0; i < numberOfParts; i += 1) {
|
|
31
31
|
const part = /** @type {FormatNumberPart} */ (formattedToParts[i]);
|
|
32
32
|
printNumberOfParts += part.value;
|
|
@@ -7,15 +7,19 @@ import { localizeTearDown } from '@lion/ui/localize-test-helpers.js';
|
|
|
7
7
|
|
|
8
8
|
describe('getDateFormatBasedOnLocale()', () => {
|
|
9
9
|
const localizeManager = getLocalizeManager();
|
|
10
|
-
|
|
11
10
|
beforeEach(() => {
|
|
12
11
|
localizeTearDown();
|
|
13
12
|
});
|
|
14
13
|
|
|
15
|
-
it('returns the positions of day, month and year', async () => {
|
|
14
|
+
it('returns the positions of day, month and year with locale set globally', async () => {
|
|
16
15
|
localizeManager.locale = 'en-GB';
|
|
17
16
|
expect(getDateFormatBasedOnLocale()).to.equal('day-month-year');
|
|
18
17
|
localizeManager.locale = 'en-US';
|
|
19
18
|
expect(getDateFormatBasedOnLocale()).to.equal('month-day-year');
|
|
20
19
|
});
|
|
20
|
+
|
|
21
|
+
it('returns the positions of day, month and year with given locale', async () => {
|
|
22
|
+
expect(getDateFormatBasedOnLocale('en-GB')).to.equal('day-month-year');
|
|
23
|
+
expect(getDateFormatBasedOnLocale('en-US')).to.equal('month-day-year');
|
|
24
|
+
});
|
|
21
25
|
});
|
|
@@ -51,13 +51,20 @@ describe('parseDate()', () => {
|
|
|
51
51
|
expect(equalsDate(parseDate('14.12.1976 r.'), new Date('1976/12/14'))).to.equal(true);
|
|
52
52
|
});
|
|
53
53
|
|
|
54
|
-
it('handles different locales', () => {
|
|
54
|
+
it('handles different locales globally set', () => {
|
|
55
55
|
localizeManager.locale = 'en-GB';
|
|
56
56
|
expect(equalsDate(parseDate('31-12-1976'), new Date('1976/12/31'))).to.equal(true);
|
|
57
57
|
localizeManager.locale = 'en-US';
|
|
58
58
|
expect(equalsDate(parseDate('12-31-1976'), new Date('1976/12/31'))).to.equal(true);
|
|
59
59
|
});
|
|
60
60
|
|
|
61
|
+
it('handles different locales as option', () => {
|
|
62
|
+
const optionEnGb = { locale: 'en-GB' };
|
|
63
|
+
expect(equalsDate(parseDate('31-12-1976', optionEnGb), new Date('1976/12/31'))).to.equal(true);
|
|
64
|
+
const optionEnUs = { locale: 'en-US' };
|
|
65
|
+
expect(equalsDate(parseDate('12-31-1976', optionEnUs), new Date('1976/12/31'))).to.equal(true);
|
|
66
|
+
});
|
|
67
|
+
|
|
61
68
|
it('handles timezones of the browser and parsed date correctly', () => {
|
|
62
69
|
const referenceDate = new Date('2020/01/30');
|
|
63
70
|
localizeManager.locale = 'nl-NL';
|
|
@@ -246,6 +246,15 @@ Please specify .groupSeparator / .decimalSeparator on the formatOptions object t
|
|
|
246
246
|
});
|
|
247
247
|
});
|
|
248
248
|
|
|
249
|
+
// TODO: make it work with big numbers, e.g. make use of BigInt
|
|
250
|
+
it.skip('can handle big numbers', async () => {
|
|
251
|
+
expect(formatNumber(1e21)).to.equal('1,000,000,000,000,000,000,000');
|
|
252
|
+
// eslint-disable-next-line no-loss-of-precision
|
|
253
|
+
expect(formatNumber(999999999999999999999.42)).to.equal('999,999,999,999,999,999,999.42');
|
|
254
|
+
// eslint-disable-next-line no-loss-of-precision
|
|
255
|
+
expect(formatNumber(12345678987654321.42)).to.equal('12,345,678,987,654,321.42');
|
|
256
|
+
});
|
|
257
|
+
|
|
249
258
|
describe('normalization', () => {
|
|
250
259
|
describe('en-GB', () => {
|
|
251
260
|
it('supports basics', () => {
|
|
@@ -75,7 +75,7 @@ describe('Local Positioning', () => {
|
|
|
75
75
|
),
|
|
76
76
|
invokerNode: /** @type {HTMLElement} */ (
|
|
77
77
|
fixtureSync(html`
|
|
78
|
-
<div role="button" style="width: 20px; height: 10px; background: orange;"
|
|
78
|
+
<div role="button" style="width: 20px; height: 10px; background: orange;">Button</div>
|
|
79
79
|
`)
|
|
80
80
|
),
|
|
81
81
|
});
|
|
@@ -104,11 +104,9 @@ describe('Local Positioning', () => {
|
|
|
104
104
|
),
|
|
105
105
|
invokerNode: /** @type {HTMLElement} */ (
|
|
106
106
|
fixtureSync(html`
|
|
107
|
-
<div
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
@click=${() => ctrl.show()}
|
|
111
|
-
></div>
|
|
107
|
+
<div role="button" style="width: 100px; height: 20px;" @click=${() => ctrl.show()}>
|
|
108
|
+
Button
|
|
109
|
+
</div>
|
|
112
110
|
`)
|
|
113
111
|
),
|
|
114
112
|
});
|
|
@@ -129,11 +127,9 @@ describe('Local Positioning', () => {
|
|
|
129
127
|
),
|
|
130
128
|
invokerNode: /** @type {HTMLElement} */ (
|
|
131
129
|
fixtureSync(html`
|
|
132
|
-
<div
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
@click=${() => ctrl.show()}
|
|
136
|
-
></div>
|
|
130
|
+
<div role="button" style="width: 100px; height: 20px;" @click=${() => ctrl.show()}>
|
|
131
|
+
Button
|
|
132
|
+
</div>
|
|
137
133
|
`)
|
|
138
134
|
),
|
|
139
135
|
popperConfig: {
|
|
@@ -185,11 +181,9 @@ describe('Local Positioning', () => {
|
|
|
185
181
|
),
|
|
186
182
|
invokerNode: /** @type {HTMLElement} */ (
|
|
187
183
|
fixtureSync(html`
|
|
188
|
-
<div
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
@click=${() => ctrl.show()}
|
|
192
|
-
></div>
|
|
184
|
+
<div role="button" style="width: 100px; height: 20px;" @click=${() => ctrl.show()}>
|
|
185
|
+
Button
|
|
186
|
+
</div>
|
|
193
187
|
`)
|
|
194
188
|
),
|
|
195
189
|
popperConfig: {
|
|
@@ -257,11 +251,9 @@ describe('Local Positioning', () => {
|
|
|
257
251
|
),
|
|
258
252
|
invokerNode: /** @type {HTMLElement} */ (
|
|
259
253
|
fixtureSync(html`
|
|
260
|
-
<div
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
@click=${() => ctrl.show()}
|
|
264
|
-
></div>
|
|
254
|
+
<div role="button" style="width: 100px; height: 20px;" @click=${() => ctrl.show()}>
|
|
255
|
+
Button
|
|
256
|
+
</div>
|
|
265
257
|
`)
|
|
266
258
|
),
|
|
267
259
|
popperConfig: {
|
|
@@ -25,7 +25,7 @@ function simulateTabInWindow(elToRecieveFocus) {
|
|
|
25
25
|
|
|
26
26
|
const interactionElementsNode = renderLitAsNode(html`
|
|
27
27
|
<div>
|
|
28
|
-
<button id="el1"
|
|
28
|
+
<button id="el1">Button</button>
|
|
29
29
|
<a id="el2" href="#">foo</a>
|
|
30
30
|
<div id="el3" tabindex="0"></div>
|
|
31
31
|
<input id="el4" />
|
|
@@ -50,7 +50,7 @@ const lightDomAutofocusTemplate = html`
|
|
|
50
50
|
<button id="outside-1">outside 1</button>
|
|
51
51
|
|
|
52
52
|
<div id="rootElement">
|
|
53
|
-
<button id="el1"
|
|
53
|
+
<button id="el1">Button</button>
|
|
54
54
|
<a id="el2" href="#">foo</a>
|
|
55
55
|
<div id="el3" tabindex="0"></div>
|
|
56
56
|
<input id="el4" autofocus />
|
|
@@ -17,7 +17,7 @@ describe('deepContains()', () => {
|
|
|
17
17
|
await fixture(html`
|
|
18
18
|
<div id="light">
|
|
19
19
|
${shadowElement}
|
|
20
|
-
<button id="light-el-1"
|
|
20
|
+
<button id="light-el-1">Button</button>
|
|
21
21
|
</div>
|
|
22
22
|
`)
|
|
23
23
|
);
|
|
@@ -65,7 +65,7 @@ describe('deepContains()', () => {
|
|
|
65
65
|
await fixture(html`
|
|
66
66
|
<div id="light">
|
|
67
67
|
${shadowElement} ${shadowElement2}
|
|
68
|
-
<button id="light-el-1"
|
|
68
|
+
<button id="light-el-1">Button</button>
|
|
69
69
|
</div>
|
|
70
70
|
`)
|
|
71
71
|
);
|
|
@@ -101,7 +101,7 @@ describe('deepContains()', () => {
|
|
|
101
101
|
await fixture(html`
|
|
102
102
|
<div id="light">
|
|
103
103
|
${shadowElement}
|
|
104
|
-
<button id="light-el-1"
|
|
104
|
+
<button id="light-el-1">Button</button>
|
|
105
105
|
</div>
|
|
106
106
|
`)
|
|
107
107
|
);
|
|
@@ -477,7 +477,7 @@ export class LionSelectRich extends SlotMixin(ScopedElementsMixin(OverlayMixin(L
|
|
|
477
477
|
*/
|
|
478
478
|
// TODO: rename to _onKeyUp in v1
|
|
479
479
|
__onKeyUp(ev) {
|
|
480
|
-
if (this.disabled) {
|
|
480
|
+
if (this.disabled || this.readOnly) {
|
|
481
481
|
return;
|
|
482
482
|
}
|
|
483
483
|
|
|
@@ -485,6 +485,13 @@ export class LionSelectRich extends SlotMixin(ScopedElementsMixin(OverlayMixin(L
|
|
|
485
485
|
return;
|
|
486
486
|
}
|
|
487
487
|
|
|
488
|
+
this._isHandlingUserInput = true;
|
|
489
|
+
setTimeout(() => {
|
|
490
|
+
// Since we can't control when subclasses are done handling keyboard input, we
|
|
491
|
+
// schedule a timeout to reset _isHandlingUserInput
|
|
492
|
+
this._isHandlingUserInput = false;
|
|
493
|
+
});
|
|
494
|
+
|
|
488
495
|
const { key } = ev;
|
|
489
496
|
switch (key) {
|
|
490
497
|
case 'ArrowUp':
|