@lion/ui 0.6.1 → 0.7.0
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/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-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/number/formatNumber.js +1 -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 +1 -1
- package/components/select-rich/test/lion-select-rich-interaction.test.js +16 -40
- 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 +50 -7
- package/dist-types/components/core/src/browserDetection.d.ts +3 -3
- package/dist-types/components/input-amount/src/parsers.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 +1 -0
- package/dist-types/components/input-tel-dropdown/types/index.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 +3 -3
- 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/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
|
});
|
|
@@ -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
|
/**
|
|
@@ -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;
|
|
@@ -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
|
);
|
|
@@ -7,6 +7,7 @@ import '@lion/ui/define/lion-option.js';
|
|
|
7
7
|
|
|
8
8
|
import '@lion/ui/define/lion-listbox.js';
|
|
9
9
|
import '@lion/ui/define/lion-select-rich.js';
|
|
10
|
+
import { getSelectRichMembers } from '@lion/ui/select-rich-test-helpers.js';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* @typedef {import('../src/LionSelectRich.js').LionSelectRich} LionSelectRich
|
|
@@ -23,32 +24,6 @@ function mimicKeyPress(el, key, code = '') {
|
|
|
23
24
|
el.dispatchEvent(new KeyboardEvent('keyup', { key, code }));
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
/**
|
|
27
|
-
* @param {LionSelectRich} lionSelectEl
|
|
28
|
-
*/
|
|
29
|
-
function getNodes(lionSelectEl) {
|
|
30
|
-
const {
|
|
31
|
-
// @ts-ignore protected members allowed in test
|
|
32
|
-
_invokerNode: invoker,
|
|
33
|
-
// @ts-ignore protected members allowed in test
|
|
34
|
-
_feedbackNode: feedback,
|
|
35
|
-
// @ts-ignore protected members allowed in test
|
|
36
|
-
_labelNode: label,
|
|
37
|
-
// @ts-ignore protected members allowed in test
|
|
38
|
-
_helpTextNode: helpText,
|
|
39
|
-
// @ts-ignore protected members allowed in test
|
|
40
|
-
_listboxNode: listbox,
|
|
41
|
-
// @ts-ignore protected members allowed in test
|
|
42
|
-
} = lionSelectEl;
|
|
43
|
-
return {
|
|
44
|
-
invoker,
|
|
45
|
-
feedback,
|
|
46
|
-
label,
|
|
47
|
-
helpText,
|
|
48
|
-
listbox,
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
|
|
52
27
|
describe('lion-select-rich interactions', () => {
|
|
53
28
|
describe('Interaction mode', () => {
|
|
54
29
|
it('autodetects interactionMode if not defined', async () => {
|
|
@@ -187,8 +162,8 @@ describe('lion-select-rich interactions', () => {
|
|
|
187
162
|
</lion-select-rich>
|
|
188
163
|
`)
|
|
189
164
|
);
|
|
190
|
-
const {
|
|
191
|
-
expect(
|
|
165
|
+
const { _invokerNode } = getSelectRichMembers(el);
|
|
166
|
+
expect(_invokerNode.tabIndex).to.equal(-1);
|
|
192
167
|
});
|
|
193
168
|
|
|
194
169
|
it('cannot be opened via click if disabled', async () => {
|
|
@@ -199,8 +174,9 @@ describe('lion-select-rich interactions', () => {
|
|
|
199
174
|
</lion-select-rich>
|
|
200
175
|
`)
|
|
201
176
|
);
|
|
202
|
-
const {
|
|
203
|
-
|
|
177
|
+
const { _invokerNode, _overlayCtrl } = getSelectRichMembers(el);
|
|
178
|
+
_invokerNode.click();
|
|
179
|
+
await _overlayCtrl._showComplete;
|
|
204
180
|
expect(el.opened).to.be.false;
|
|
205
181
|
});
|
|
206
182
|
|
|
@@ -212,11 +188,11 @@ describe('lion-select-rich interactions', () => {
|
|
|
212
188
|
</lion-select-rich>
|
|
213
189
|
`)
|
|
214
190
|
);
|
|
215
|
-
const {
|
|
216
|
-
expect(
|
|
191
|
+
const { _invokerNode } = getSelectRichMembers(el);
|
|
192
|
+
expect(_invokerNode.hasAttribute('disabled')).to.be.true;
|
|
217
193
|
el.removeAttribute('disabled');
|
|
218
194
|
await el.updateComplete;
|
|
219
|
-
expect(
|
|
195
|
+
expect(_invokerNode.hasAttribute('disabled')).to.be.false;
|
|
220
196
|
});
|
|
221
197
|
});
|
|
222
198
|
|
|
@@ -232,10 +208,10 @@ describe('lion-select-rich interactions', () => {
|
|
|
232
208
|
</lion-select-rich>
|
|
233
209
|
`)
|
|
234
210
|
);
|
|
235
|
-
const {
|
|
211
|
+
const { _invokerNode } = getSelectRichMembers(el);
|
|
236
212
|
expect(el.touched).to.be.false;
|
|
237
|
-
await triggerFocusFor(
|
|
238
|
-
await triggerBlurFor(
|
|
213
|
+
await triggerFocusFor(_invokerNode);
|
|
214
|
+
await triggerBlurFor(_invokerNode);
|
|
239
215
|
expect(el.touched).to.be.true;
|
|
240
216
|
});
|
|
241
217
|
});
|
|
@@ -252,21 +228,21 @@ describe('lion-select-rich interactions', () => {
|
|
|
252
228
|
</lion-select-rich>
|
|
253
229
|
`)
|
|
254
230
|
);
|
|
255
|
-
const {
|
|
231
|
+
const { _invokerNode } = getSelectRichMembers(el);
|
|
256
232
|
const options = el.formElements;
|
|
257
233
|
await el.feedbackComplete;
|
|
258
234
|
await el.updateComplete;
|
|
259
|
-
expect(
|
|
235
|
+
expect(_invokerNode.getAttribute('aria-invalid')).to.equal('false');
|
|
260
236
|
|
|
261
237
|
options[0].checked = true;
|
|
262
238
|
await el.feedbackComplete;
|
|
263
239
|
await el.updateComplete;
|
|
264
|
-
expect(
|
|
240
|
+
expect(_invokerNode.getAttribute('aria-invalid')).to.equal('true');
|
|
265
241
|
|
|
266
242
|
options[1].checked = true;
|
|
267
243
|
await el.feedbackComplete;
|
|
268
244
|
await el.updateComplete;
|
|
269
|
-
expect(
|
|
245
|
+
expect(_invokerNode.getAttribute('aria-invalid')).to.equal('false');
|
|
270
246
|
});
|
|
271
247
|
});
|
|
272
248
|
});
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { LitElement } from 'lit';
|
|
2
2
|
import { LionOption } from '@lion/ui/listbox.js';
|
|
3
|
-
import { getListboxMembers } from '@lion/ui/listbox-test-helpers.js';
|
|
4
3
|
import { OverlayController } from '@lion/ui/overlays.js';
|
|
5
4
|
import { mimicClick } from '@lion/ui/overlays-test-helpers.js';
|
|
6
5
|
import { LionSelectInvoker, LionSelectRich } from '@lion/ui/select-rich.js';
|
|
@@ -17,6 +16,7 @@ import {
|
|
|
17
16
|
nextFrame,
|
|
18
17
|
unsafeStatic,
|
|
19
18
|
} from '@open-wc/testing';
|
|
19
|
+
import { getSelectRichMembers } from '@lion/ui/select-rich-test-helpers.js';
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* @typedef {import('../../listbox/src/LionOptions.js').LionOptions} LionOptions
|
|
@@ -24,19 +24,6 @@ import {
|
|
|
24
24
|
* @typedef {import('../../form-core/types/FormControlMixinTypes.js').FormControlHost} FormControlHost
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
|
-
/**
|
|
28
|
-
* @param { LionSelectRich } el
|
|
29
|
-
*/
|
|
30
|
-
function getSelectRichMembers(el) {
|
|
31
|
-
const obj = getListboxMembers(el);
|
|
32
|
-
// eslint-disable-next-line no-return-assign
|
|
33
|
-
return {
|
|
34
|
-
...obj,
|
|
35
|
-
// @ts-ignore [allow-protected] in test
|
|
36
|
-
...{ _invokerNode: el._invokerNode, _overlayCtrl: el._overlayCtrl },
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
|
|
40
27
|
/**
|
|
41
28
|
* @typedef {import('lit').TemplateResult} TemplateResult
|
|
42
29
|
*/
|
|
@@ -329,6 +316,21 @@ describe('lion-select-rich', () => {
|
|
|
329
316
|
expect(elSingleoption.opened).to.be.false;
|
|
330
317
|
});
|
|
331
318
|
|
|
319
|
+
it('stays closed with [ArrowUp] or [ArrowDown] key in readonly mode', async () => {
|
|
320
|
+
const elReadOnly = await fixture(html`
|
|
321
|
+
<lion-select-rich readonly>
|
|
322
|
+
<lion-option .choiceValue=${10}>Item 1</lion-option>
|
|
323
|
+
<lion-option .choiceValue=${20} checked>Item 2</lion-option>
|
|
324
|
+
</lion-select-rich>
|
|
325
|
+
`);
|
|
326
|
+
|
|
327
|
+
elReadOnly.dispatchEvent(new KeyboardEvent('keyup', { key: 'ArrowDown' }));
|
|
328
|
+
expect(elReadOnly.opened).to.be.false;
|
|
329
|
+
|
|
330
|
+
elReadOnly.dispatchEvent(new KeyboardEvent('keyup', { key: 'ArrowUp' }));
|
|
331
|
+
expect(elReadOnly.opened).to.be.false;
|
|
332
|
+
});
|
|
333
|
+
|
|
332
334
|
it('sets inheritsReferenceWidth to min by default', async () => {
|
|
333
335
|
const el = await fixture(html`
|
|
334
336
|
<lion-select-rich name="favoriteColor" label="Favorite color">
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { getListboxMembers } from '@lion/ui/listbox-test-helpers.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {import('../src/LionSelectRich.js').LionSelectRich} LionSelectRich
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @param { LionSelectRich } el
|
|
9
|
+
*/
|
|
10
|
+
export function getSelectRichMembers(el) {
|
|
11
|
+
const obj = getListboxMembers(el);
|
|
12
|
+
// eslint-disable-next-line no-return-assign
|
|
13
|
+
return {
|
|
14
|
+
...obj,
|
|
15
|
+
// @ts-ignore [allow-protected] in test
|
|
16
|
+
...{ _invokerNode: el._invokerNode, _overlayCtrl: el._overlayCtrl },
|
|
17
|
+
};
|
|
18
|
+
}
|