@lion/ui 0.4.2 → 0.5.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/button/src/LionButton.js +2 -2
- package/components/calendar/src/LionCalendar.js +1 -1
- package/components/calendar/test-helpers/DayObject.js +2 -2
- package/components/collapsible/src/LionCollapsible.js +1 -0
- package/components/combobox/src/LionCombobox.js +79 -28
- package/components/combobox/test/lion-combobox-integrations.test.js +5 -0
- package/components/combobox/test/lion-combobox.test.js +290 -23
- package/components/combobox/test-helpers/combobox-helpers.js +5 -2
- package/components/core/src/browserDetection.js +8 -0
- package/components/drawer/src/LionDrawer.js +2 -0
- package/components/form-core/src/FocusMixin.js +2 -0
- package/components/form-core/src/FormControlMixin.js +1 -1
- package/components/form-core/src/choice-group/ChoiceGroupMixin.js +1 -0
- package/components/form-core/src/choice-group/CustomChoiceGroupMixin.js +173 -0
- package/components/form-core/src/utils/getAriaElementsInRightDomOrder.js +7 -14
- package/components/form-core/src/validate/validators/Required.js +2 -2
- package/components/form-core/test/choice-group/CustomChoiceGroupMixin.integrations.test.js +55 -0
- package/components/form-core/test/choice-group/CustomChoiceGroupMixin.test.js +16 -0
- package/components/form-core/test/utils/getAriaElementsInRightDomOrder.test.js +0 -25
- package/components/form-core/test/validate/StringValidators.test.js +1 -1
- package/components/form-core/test-helpers/ExampleValidators.js +1 -3
- package/components/form-core/test-suites/FormRegistrationMixins.suite.js +2 -0
- package/components/form-core/test-suites/NativeTextFieldMixin.suite.js +4 -4
- package/components/form-core/test-suites/ValidateMixin.suite.js +27 -0
- package/components/form-core/test-suites/ValidateMixinFeedbackPart.suite.js +11 -2
- package/components/form-core/test-suites/choice-group/ChoiceGroupMixin.suite.js +1 -0
- package/components/form-core/test-suites/choice-group/CustomChoiceGroupMixin.suite.js +265 -0
- package/components/form-core/types/choice-group/ChoiceGroupMixinTypes.ts +1 -1
- package/components/form-core/types/choice-group/CustomChoiceGroupMixinTypes.ts +30 -0
- package/components/form-core/types/choice-group/index.ts +1 -0
- package/components/helpers/src/SbActionLogger.js +1 -0
- package/components/icon/src/LionIcon.js +1 -9
- package/components/icon/test/lion-icon.test.js +2 -0
- package/components/input-datepicker/src/LionInputDatepicker.js +2 -6
- package/components/input-range/test/lion-input-range.test.js +12 -6
- package/components/listbox/src/LionOptions.js +5 -5
- package/components/listbox/src/ListboxMixin.js +1 -16
- package/components/listbox/test/lion-options.test.js +1 -1
- package/components/listbox/test-suites/ListboxMixin.suite.js +1 -1
- package/components/localize/src/date/getMonthNames.js +3 -0
- package/components/localize/src/date/parseDate.js +5 -1
- package/components/localize/src/date/utils/forceDotsForNlnl.js +11 -0
- package/components/localize/src/number/utils/normalize-format-number-to-parts/forceAddGroupSeparators.js +3 -1
- package/components/localize/src/number/utils/normalize-format-number-to-parts/forceSymbols.js +2 -0
- package/components/localize/src/number/utils/normalize-format-number-to-parts/normalizeIntl.js +1 -0
- package/components/localize/test/date/getMonthNames.test.js +1 -0
- package/components/localize/test/date/parseDate.test.js +6 -0
- package/components/localize/test-helpers/fake-imports.js +1 -0
- package/components/overlays/src/OverlaysManager.js +4 -15
- package/components/overlays/src/utils/adopt-styles.js +6 -1
- package/components/overlays/test/OverlaysManager.test.js +12 -11
- package/components/overlays/test/utils-tests/adopt-styles.test.js +61 -0
- package/components/overlays/test-suites/OverlayMixin.suite.js +2 -2
- package/components/radio-group/src/LionRadioGroup.js +1 -1
- package/components/radio-group/test/lion-radio-group.test.js +29 -0
- package/components/select/test/lion-select.test.js +1 -1
- package/components/switch/src/LionSwitch.js +3 -1
- package/components/switch/src/LionSwitchButton.js +2 -5
- package/components/tabs/src/LionTabs.js +7 -7
- package/components/textarea/src/LionTextarea.js +1 -1
- package/components/validate-messages/translations/de.js +3 -3
- package/custom-elements.json +103123 -61806
- package/dist-types/components/button/src/LionButton.d.ts.map +1 -1
- package/dist-types/components/collapsible/src/LionCollapsible.d.ts.map +1 -1
- package/dist-types/components/combobox/src/LionCombobox.d.ts +13 -8
- package/dist-types/components/combobox/src/LionCombobox.d.ts.map +1 -1
- package/dist-types/components/combobox/test-helpers/combobox-helpers.d.ts.map +1 -1
- package/dist-types/components/core/src/browserDetection.d.ts +2 -0
- package/dist-types/components/drawer/src/LionDrawer.d.ts.map +1 -1
- package/dist-types/components/form-core/src/FocusMixin.d.ts.map +1 -1
- package/dist-types/components/form-core/src/choice-group/ChoiceGroupMixin.d.ts.map +1 -1
- package/dist-types/components/form-core/src/choice-group/CustomChoiceGroupMixin.d.ts +4 -0
- package/dist-types/components/form-core/src/choice-group/CustomChoiceGroupMixin.d.ts.map +1 -0
- package/dist-types/components/form-core/src/utils/getAriaElementsInRightDomOrder.d.ts +5 -5
- package/dist-types/components/form-core/src/utils/getAriaElementsInRightDomOrder.d.ts.map +1 -1
- package/dist-types/components/form-core/test/choice-group/CustomChoiceGroupMixin.integrations.test.d.ts +2 -0
- package/dist-types/components/form-core/test/choice-group/CustomChoiceGroupMixin.integrations.test.d.ts.map +1 -0
- package/dist-types/components/form-core/test/choice-group/CustomChoiceGroupMixin.test.d.ts +6 -0
- package/dist-types/components/form-core/test/choice-group/CustomChoiceGroupMixin.test.d.ts.map +1 -0
- package/dist-types/components/form-core/test-helpers/ExampleValidators.d.ts +0 -1
- package/dist-types/components/form-core/test-helpers/ExampleValidators.d.ts.map +1 -1
- package/dist-types/components/form-core/test-suites/FormRegistrationMixins.suite.d.ts.map +1 -1
- package/dist-types/components/form-core/test-suites/ValidateMixin.suite.d.ts.map +1 -1
- package/dist-types/components/form-core/test-suites/ValidateMixinFeedbackPart.suite.d.ts.map +1 -1
- package/dist-types/components/form-core/test-suites/choice-group/ChoiceGroupMixin.suite.d.ts.map +1 -1
- package/dist-types/components/form-core/test-suites/choice-group/CustomChoiceGroupMixin.suite.d.ts +14 -0
- package/dist-types/components/form-core/test-suites/choice-group/CustomChoiceGroupMixin.suite.d.ts.map +1 -0
- 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/CustomChoiceGroupMixinTypes.d.ts +18 -0
- package/dist-types/components/form-core/types/choice-group/CustomChoiceGroupMixinTypes.d.ts.map +1 -0
- package/dist-types/components/form-core/types/choice-group/index.d.ts +1 -0
- package/dist-types/components/form-core/types/choice-group/index.d.ts.map +1 -1
- package/dist-types/components/helpers/src/SbActionLogger.d.ts.map +1 -1
- package/dist-types/components/icon/src/LionIcon.d.ts +0 -9
- package/dist-types/components/icon/src/LionIcon.d.ts.map +1 -1
- package/dist-types/components/input-datepicker/src/LionInputDatepicker.d.ts +0 -2
- package/dist-types/components/input-datepicker/src/LionInputDatepicker.d.ts.map +1 -1
- package/dist-types/components/listbox/src/LionOptions.d.ts +0 -5
- package/dist-types/components/listbox/src/LionOptions.d.ts.map +1 -1
- package/dist-types/components/listbox/src/ListboxMixin.d.ts.map +1 -1
- package/dist-types/components/localize/src/date/getMonthNames.d.ts.map +1 -1
- package/dist-types/components/localize/src/date/parseDate.d.ts.map +1 -1
- package/dist-types/components/localize/src/date/utils/forceDotsForNlnl.d.ts +5 -0
- package/dist-types/components/localize/src/date/utils/forceDotsForNlnl.d.ts.map +1 -0
- package/dist-types/components/localize/src/number/utils/normalize-format-number-to-parts/forceAddGroupSeparators.d.ts.map +1 -1
- package/dist-types/components/localize/src/number/utils/normalize-format-number-to-parts/forceSymbols.d.ts.map +1 -1
- package/dist-types/components/localize/src/number/utils/normalize-format-number-to-parts/normalizeIntl.d.ts.map +1 -1
- package/dist-types/components/localize/test-helpers/fake-imports.d.ts.map +1 -1
- package/dist-types/components/overlays/src/OverlaysManager.d.ts +0 -4
- package/dist-types/components/overlays/src/OverlaysManager.d.ts.map +1 -1
- package/dist-types/components/overlays/src/utils/adopt-styles.d.ts.map +1 -1
- package/dist-types/components/overlays/test/OverlaysManager.test.d.ts.map +1 -1
- package/dist-types/components/switch/src/LionSwitch.d.ts.map +1 -1
- package/dist-types/components/switch/src/LionSwitchButton.d.ts +0 -5
- package/dist-types/components/switch/src/LionSwitchButton.d.ts.map +1 -1
- package/dist-types/components/tabs/src/LionTabs.d.ts.map +1 -1
- package/dist-types/exports/types/form-core.d.ts +1 -1
- package/dist-types/exports/types/form-core.d.ts.map +1 -1
- package/dist-types/tsconfig.tsbuildinfo +1 -1
- package/docs/components/checkbox-group/overview.md +2 -2
- package/docs/components/collapsible/assets/CustomCollapsible.js +4 -0
- package/docs/components/collapsible/overview.md +1 -1
- package/docs/components/combobox/overview.md +1 -1
- package/docs/components/combobox/src/demo-selection-display.js +8 -35
- package/docs/components/combobox/use-cases.md +24 -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 +3 -3
- 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/radio-group/overview.md +3 -3
- 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 +3 -3
- 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/model-value.md +1 -1
- package/docs/fundamentals/systems/form/overview.md +28 -28
- package/docs/fundamentals/systems/form/validate.md +18 -2
- package/docs/fundamentals/systems/localize/overview.md +4 -4
- package/docs/fundamentals/systems/overlays/configuration.md +3 -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/example-complex/overlayCompatibility.js +1 -2
- 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/types/form-core.ts +5 -1
- package/package.json +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { html, LitElement, css } from 'lit';
|
|
2
|
-
import { browserDetection, DisabledWithTabIndexMixin } from '@lion/ui/core.js';
|
|
2
|
+
import { browserDetection, DisabledWithTabIndexMixin, uuid } from '@lion/ui/core.js';
|
|
3
3
|
|
|
4
4
|
const isKeyboardClickEvent = (/** @type {KeyboardEvent} */ e) => e.key === ' ' || e.key === 'Enter';
|
|
5
5
|
const isSpaceKeyboardClickEvent = (/** @type {KeyboardEvent} */ e) => e.key === ' ';
|
|
@@ -124,7 +124,7 @@ export class LionButton extends DisabledWithTabIndexMixin(LitElement) {
|
|
|
124
124
|
this.type = 'button';
|
|
125
125
|
this.active = false;
|
|
126
126
|
|
|
127
|
-
this._buttonId =
|
|
127
|
+
this._buttonId = uuid('button');
|
|
128
128
|
if (browserDetection.isIE11) {
|
|
129
129
|
this.updateComplete.then(() => {
|
|
130
130
|
if (!this.hasAttribute('aria-labelledby')) {
|
|
@@ -63,7 +63,7 @@ export class DayObject {
|
|
|
63
63
|
|
|
64
64
|
get weekdayNameShort() {
|
|
65
65
|
const weekdayEls = Array.from(
|
|
66
|
-
/** @type {HTMLElement} */ (this.el.parentElement?.parentElement)
|
|
66
|
+
/** @type {HTMLElement} */ (this.el.parentElement?.parentElement)?.querySelectorAll(
|
|
67
67
|
'.calendar__day-cell',
|
|
68
68
|
),
|
|
69
69
|
);
|
|
@@ -73,7 +73,7 @@ export class DayObject {
|
|
|
73
73
|
|
|
74
74
|
get weekdayNameLong() {
|
|
75
75
|
const weekdayEls = Array.from(
|
|
76
|
-
/** @type {HTMLElement} */ (this.el.parentElement?.parentElement)
|
|
76
|
+
/** @type {HTMLElement} */ (this.el.parentElement?.parentElement)?.querySelectorAll(
|
|
77
77
|
'.calendar__day-cell',
|
|
78
78
|
),
|
|
79
79
|
);
|
|
@@ -6,6 +6,7 @@ import { OverlayMixin, withDropdownConfig } from '@lion/ui/overlays.js';
|
|
|
6
6
|
import { css, html } from 'lit';
|
|
7
7
|
import { makeMatchingTextBold, unmakeMatchingTextBold } from './utils/makeMatchingTextBold.js';
|
|
8
8
|
import { MatchesOption } from './validators.js';
|
|
9
|
+
import { CustomChoiceGroupMixin } from '../../form-core/src/choice-group/CustomChoiceGroupMixin.js';
|
|
9
10
|
|
|
10
11
|
const matchA11ySpanReverseFns = new WeakMap();
|
|
11
12
|
|
|
@@ -27,7 +28,7 @@ const matchA11ySpanReverseFns = new WeakMap();
|
|
|
27
28
|
* LionCombobox: implements the wai-aria combobox design pattern and integrates it as a Lion
|
|
28
29
|
* FormControl
|
|
29
30
|
*/
|
|
30
|
-
export class LionCombobox extends LocalizeMixin(OverlayMixin(LionListbox)) {
|
|
31
|
+
export class LionCombobox extends LocalizeMixin(OverlayMixin(CustomChoiceGroupMixin(LionListbox))) {
|
|
31
32
|
/** @type {any} */
|
|
32
33
|
static get properties() {
|
|
33
34
|
return {
|
|
@@ -43,6 +44,10 @@ export class LionCombobox extends LocalizeMixin(OverlayMixin(LionListbox)) {
|
|
|
43
44
|
requireOptionMatch: {
|
|
44
45
|
type: Boolean,
|
|
45
46
|
},
|
|
47
|
+
allowCustomChoice: {
|
|
48
|
+
type: Boolean,
|
|
49
|
+
attribute: 'allow-custom-choice',
|
|
50
|
+
},
|
|
46
51
|
__shouldAutocompleteNextUpdate: Boolean,
|
|
47
52
|
};
|
|
48
53
|
}
|
|
@@ -316,7 +321,9 @@ export class LionCombobox extends LocalizeMixin(OverlayMixin(LionListbox)) {
|
|
|
316
321
|
*/
|
|
317
322
|
get _inputNode() {
|
|
318
323
|
if (this._ariaVersion === '1.1' && this._comboboxNode) {
|
|
319
|
-
return /** @type {HTMLInputElement} */ (
|
|
324
|
+
return /** @type {HTMLInputElement} */ (
|
|
325
|
+
this._comboboxNode.querySelector('input') || this._comboboxNode
|
|
326
|
+
);
|
|
320
327
|
}
|
|
321
328
|
return /** @type {HTMLInputElement} */ (this._comboboxNode);
|
|
322
329
|
}
|
|
@@ -364,6 +371,20 @@ export class LionCombobox extends LocalizeMixin(OverlayMixin(LionListbox)) {
|
|
|
364
371
|
return this._inputNode;
|
|
365
372
|
}
|
|
366
373
|
|
|
374
|
+
/**
|
|
375
|
+
* @returns {boolean}
|
|
376
|
+
*/
|
|
377
|
+
get requireOptionMatch() {
|
|
378
|
+
return !this.allowCustomChoice;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* @param {boolean} value
|
|
383
|
+
*/
|
|
384
|
+
set requireOptionMatch(value) {
|
|
385
|
+
this.allowCustomChoice = !value;
|
|
386
|
+
}
|
|
387
|
+
|
|
367
388
|
constructor() {
|
|
368
389
|
super();
|
|
369
390
|
/**
|
|
@@ -486,14 +507,20 @@ export class LionCombobox extends LocalizeMixin(OverlayMixin(LionListbox)) {
|
|
|
486
507
|
|
|
487
508
|
/**
|
|
488
509
|
* Converts viewValue to modelValue
|
|
489
|
-
* @
|
|
510
|
+
* @override CustomChoiceGroupMixin
|
|
511
|
+
* @param {string|string[]} value - viewValue: the formatted value inside <input>
|
|
490
512
|
* @returns {*} modelValue
|
|
491
513
|
*/
|
|
492
514
|
parser(value) {
|
|
493
|
-
if (
|
|
515
|
+
if (
|
|
516
|
+
this.requireOptionMatch &&
|
|
517
|
+
this.checkedIndex === -1 &&
|
|
518
|
+
value !== '' &&
|
|
519
|
+
!Array.isArray(value)
|
|
520
|
+
) {
|
|
494
521
|
return new Unparseable(value);
|
|
495
522
|
}
|
|
496
|
-
return value;
|
|
523
|
+
return super.parser(value);
|
|
497
524
|
}
|
|
498
525
|
|
|
499
526
|
/**
|
|
@@ -554,15 +581,6 @@ export class LionCombobox extends LocalizeMixin(OverlayMixin(LionListbox)) {
|
|
|
554
581
|
if (typeof this._selectionDisplayNode?.onComboboxElementUpdated === 'function') {
|
|
555
582
|
this._selectionDisplayNode.onComboboxElementUpdated(changedProperties);
|
|
556
583
|
}
|
|
557
|
-
|
|
558
|
-
if (changedProperties.has('requireOptionMatch') || changedProperties.has('multipleChoice')) {
|
|
559
|
-
if (!this.requireOptionMatch && this.multipleChoice) {
|
|
560
|
-
// TODO implement !requireOptionMatch and multipleChoice flow
|
|
561
|
-
throw new Error(
|
|
562
|
-
"multipleChoice and requireOptionMatch=false can't be used at the same time (yet).",
|
|
563
|
-
);
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
584
|
}
|
|
567
585
|
|
|
568
586
|
/**
|
|
@@ -697,8 +715,8 @@ export class LionCombobox extends LocalizeMixin(OverlayMixin(LionListbox)) {
|
|
|
697
715
|
* @protected
|
|
698
716
|
*/
|
|
699
717
|
_setTextboxValue(v) {
|
|
700
|
-
// Make sure that we don't
|
|
701
|
-
if (this._inputNode.value !== v) {
|
|
718
|
+
// Make sure that we don't lose inputNode.selectionStart and inputNode.selectionEnd
|
|
719
|
+
if (this._inputNode && this._inputNode.value !== v) {
|
|
702
720
|
this._inputNode.value = v;
|
|
703
721
|
}
|
|
704
722
|
}
|
|
@@ -955,6 +973,9 @@ export class LionCombobox extends LocalizeMixin(OverlayMixin(LionListbox)) {
|
|
|
955
973
|
if (autoselect && !hasAutoFilled && !this.multipleChoice) {
|
|
956
974
|
// This means there is no match for checkedIndex
|
|
957
975
|
this.setCheckedIndex(-1);
|
|
976
|
+
if (prevValue !== curValue) {
|
|
977
|
+
this.activeIndex = -1;
|
|
978
|
+
}
|
|
958
979
|
this.modelValue = this.parser(inputValue);
|
|
959
980
|
}
|
|
960
981
|
|
|
@@ -1065,25 +1086,52 @@ export class LionCombobox extends LocalizeMixin(OverlayMixin(LionListbox)) {
|
|
|
1065
1086
|
* @protected
|
|
1066
1087
|
*/
|
|
1067
1088
|
_listboxOnKeyDown(ev) {
|
|
1068
|
-
super._listboxOnKeyDown(ev);
|
|
1069
1089
|
const { key } = ev;
|
|
1070
1090
|
switch (key) {
|
|
1071
1091
|
case 'Escape':
|
|
1072
1092
|
this.opened = false;
|
|
1093
|
+
super._listboxOnKeyDown(ev);
|
|
1073
1094
|
this._setTextboxValue('');
|
|
1074
1095
|
break;
|
|
1096
|
+
case 'Backspace':
|
|
1097
|
+
case 'Delete':
|
|
1098
|
+
if (this.requireOptionMatch) {
|
|
1099
|
+
super._listboxOnKeyDown(ev);
|
|
1100
|
+
} else {
|
|
1101
|
+
this.opened = false;
|
|
1102
|
+
}
|
|
1103
|
+
break;
|
|
1075
1104
|
case 'Enter':
|
|
1076
1105
|
if (this.multipleChoice && this.opened) {
|
|
1077
1106
|
ev.preventDefault();
|
|
1078
1107
|
}
|
|
1079
|
-
|
|
1080
|
-
|
|
1108
|
+
|
|
1109
|
+
if (
|
|
1110
|
+
!this.requireOptionMatch &&
|
|
1111
|
+
this.multipleChoice &&
|
|
1112
|
+
(!this.formElements[this.activeIndex] ||
|
|
1113
|
+
this.formElements[this.activeIndex].hasAttribute('aria-hidden') ||
|
|
1114
|
+
!this.opened)
|
|
1115
|
+
) {
|
|
1116
|
+
ev.preventDefault();
|
|
1117
|
+
|
|
1118
|
+
this.modelValue = this.parser([...this.modelValue, this._inputNode.value]);
|
|
1119
|
+
|
|
1120
|
+
this._inputNode.value = '';
|
|
1121
|
+
this.opened = false;
|
|
1122
|
+
} else {
|
|
1123
|
+
super._listboxOnKeyDown(ev);
|
|
1124
|
+
// TODO: should we clear the input value here when allowCustomChoice is false?
|
|
1125
|
+
// For now, we don't...
|
|
1081
1126
|
}
|
|
1082
1127
|
if (!this.multipleChoice) {
|
|
1083
1128
|
this.opened = false;
|
|
1084
1129
|
}
|
|
1085
1130
|
break;
|
|
1086
|
-
|
|
1131
|
+
default: {
|
|
1132
|
+
super._listboxOnKeyDown(ev);
|
|
1133
|
+
break;
|
|
1134
|
+
}
|
|
1087
1135
|
}
|
|
1088
1136
|
}
|
|
1089
1137
|
|
|
@@ -1110,12 +1158,14 @@ export class LionCombobox extends LocalizeMixin(OverlayMixin(LionListbox)) {
|
|
|
1110
1158
|
*/
|
|
1111
1159
|
// eslint-disable-next-line no-unused-vars
|
|
1112
1160
|
_syncToTextboxMultiple(modelValue, oldModelValue = []) {
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1161
|
+
if (this.requireOptionMatch) {
|
|
1162
|
+
const diff = modelValue.filter(x => !oldModelValue.includes(x));
|
|
1163
|
+
const newValue = this.formElements
|
|
1164
|
+
.filter(option => diff.includes(option.choiceValue))
|
|
1165
|
+
.map(option => this._getTextboxValueFromOption(option))
|
|
1166
|
+
.join(' ');
|
|
1167
|
+
this._setTextboxValue(newValue); // or last selected value?
|
|
1168
|
+
}
|
|
1119
1169
|
}
|
|
1120
1170
|
|
|
1121
1171
|
/**
|
|
@@ -1147,11 +1197,12 @@ export class LionCombobox extends LocalizeMixin(OverlayMixin(LionListbox)) {
|
|
|
1147
1197
|
|
|
1148
1198
|
this._comboboxNode.setAttribute('role', 'combobox');
|
|
1149
1199
|
this._comboboxNode.setAttribute('aria-haspopup', 'listbox');
|
|
1200
|
+
|
|
1150
1201
|
this._inputNode.setAttribute('aria-autocomplete', this.autocomplete);
|
|
1202
|
+
this._comboboxNode.setAttribute('aria-controls', this._listboxNode.id);
|
|
1151
1203
|
|
|
1152
1204
|
if (this._ariaVersion === '1.1') {
|
|
1153
1205
|
this._comboboxNode.setAttribute('aria-owns', this._listboxNode.id);
|
|
1154
|
-
this._inputNode.setAttribute('aria-controls', this._listboxNode.id);
|
|
1155
1206
|
} else {
|
|
1156
1207
|
this._inputNode.setAttribute('aria-owns', this._listboxNode.id);
|
|
1157
1208
|
}
|
|
@@ -1185,8 +1236,8 @@ export class LionCombobox extends LocalizeMixin(OverlayMixin(LionListbox)) {
|
|
|
1185
1236
|
}
|
|
1186
1237
|
|
|
1187
1238
|
clear() {
|
|
1188
|
-
super.clear();
|
|
1189
1239
|
this.value = '';
|
|
1240
|
+
super.clear();
|
|
1190
1241
|
this.__shouldAutocompleteNextUpdate = true;
|
|
1191
1242
|
}
|
|
1192
1243
|
}
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { runListboxMixinSuite } from '@lion/ui/listbox-test-suites.js';
|
|
2
2
|
import '@lion/ui/define/lion-combobox.js';
|
|
3
|
+
import { runCustomChoiceGroupMixinSuite } from '../../form-core/test-suites/choice-group/CustomChoiceGroupMixin.suite.js';
|
|
3
4
|
|
|
4
5
|
runListboxMixinSuite({ tagString: 'lion-combobox' });
|
|
6
|
+
runCustomChoiceGroupMixinSuite({
|
|
7
|
+
parentTagString: 'lion-combobox',
|
|
8
|
+
childTagString: 'lion-option',
|
|
9
|
+
});
|
|
@@ -395,29 +395,6 @@ describe('lion-combobox', () => {
|
|
|
395
395
|
expect(el.formElements[0].checked).to.be.false;
|
|
396
396
|
});
|
|
397
397
|
|
|
398
|
-
it('multiple choice and requireOptionMatch is false do not work together yet', async () => {
|
|
399
|
-
const errorMessage = `multipleChoice and requireOptionMatch=false can't be used at the same time (yet).`;
|
|
400
|
-
let error;
|
|
401
|
-
const el = /** @type {LionCombobox} */ (
|
|
402
|
-
await fixture(html`
|
|
403
|
-
<lion-combobox name="foo" multiple-choice>
|
|
404
|
-
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
405
|
-
<lion-option .choiceValue="${'Chard'}">Chard</lion-option>
|
|
406
|
-
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
407
|
-
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
408
|
-
</lion-combobox>
|
|
409
|
-
`)
|
|
410
|
-
);
|
|
411
|
-
try {
|
|
412
|
-
el.requireOptionMatch = false;
|
|
413
|
-
await el.updateComplete;
|
|
414
|
-
} catch (err) {
|
|
415
|
-
error = err;
|
|
416
|
-
}
|
|
417
|
-
expect(error).to.be.instanceOf(Error);
|
|
418
|
-
expect(/** @type {Error} */ (error).message).to.equal(errorMessage);
|
|
419
|
-
});
|
|
420
|
-
|
|
421
398
|
it('clears modelValue and textbox value on clear()', async () => {
|
|
422
399
|
const el = /** @type {LionCombobox} */ (
|
|
423
400
|
await fixture(html`
|
|
@@ -453,6 +430,32 @@ describe('lion-combobox', () => {
|
|
|
453
430
|
expect(el2._inputNode.value).to.equal('');
|
|
454
431
|
});
|
|
455
432
|
|
|
433
|
+
it('correctly emits event with an empty value when clear() is called', async () => {
|
|
434
|
+
const el = /** @type {LionCombobox} */ (
|
|
435
|
+
await fixture(
|
|
436
|
+
html`<lion-combobox>
|
|
437
|
+
<lion-option .choiceValue=${'red'}>Red</lion-option>
|
|
438
|
+
<lion-option .choiceValue=${'green'}>Green</lion-option>
|
|
439
|
+
<lion-option .choiceValue=${'blue'}>Blue</lion-option>
|
|
440
|
+
</lion-combobox>`,
|
|
441
|
+
)
|
|
442
|
+
);
|
|
443
|
+
|
|
444
|
+
el.modelValue = 'red';
|
|
445
|
+
await el.updateComplete;
|
|
446
|
+
|
|
447
|
+
el.addEventListener('model-value-changed', ({ target }) => {
|
|
448
|
+
expect(target).to.not.be.null;
|
|
449
|
+
|
|
450
|
+
const { modelValue, value } = /** @type {LionCombobox} */ (target);
|
|
451
|
+
expect(value).to.equal('');
|
|
452
|
+
expect(modelValue).to.equal('');
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
el.clear();
|
|
456
|
+
await el.updateComplete;
|
|
457
|
+
});
|
|
458
|
+
|
|
456
459
|
it('updates option list after clear()', async () => {
|
|
457
460
|
const el = /** @type {LionCombobox} */ (
|
|
458
461
|
await fixture(html`
|
|
@@ -565,6 +568,33 @@ describe('lion-combobox', () => {
|
|
|
565
568
|
expect(el.showsFeedbackFor).to.include('error', 'showsFeedbackFor');
|
|
566
569
|
});
|
|
567
570
|
|
|
571
|
+
it('ignores empty string modelValue inputs', async () => {
|
|
572
|
+
const el = /** @type {LionCombobox} */ (
|
|
573
|
+
await fixture(html`
|
|
574
|
+
<lion-combobox name="foo" multiple-choice autocomplete="none">
|
|
575
|
+
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
576
|
+
<lion-option .choiceValue="${'Chard'}">Chard</lion-option>
|
|
577
|
+
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
578
|
+
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
579
|
+
</lion-combobox>
|
|
580
|
+
`)
|
|
581
|
+
);
|
|
582
|
+
|
|
583
|
+
el.requireOptionMatch = false;
|
|
584
|
+
await el.updateComplete;
|
|
585
|
+
const { _inputNode } = getComboboxMembers(el);
|
|
586
|
+
|
|
587
|
+
mimicKeyPress(_inputNode, 'Enter');
|
|
588
|
+
await el.updateComplete;
|
|
589
|
+
expect(el.modelValue).to.eql([]);
|
|
590
|
+
|
|
591
|
+
mimicUserTyping(el, ' ');
|
|
592
|
+
await el.updateComplete;
|
|
593
|
+
mimicKeyPress(_inputNode, 'Enter');
|
|
594
|
+
await el.updateComplete;
|
|
595
|
+
expect(el.modelValue).to.eql([]);
|
|
596
|
+
});
|
|
597
|
+
|
|
568
598
|
it('allows a value outside of the option list when requireOptionMatch is false', async () => {
|
|
569
599
|
const el = /** @type {LionCombobox} */ (
|
|
570
600
|
await fixture(html`
|
|
@@ -589,6 +619,35 @@ describe('lion-combobox', () => {
|
|
|
589
619
|
expect(_inputNode.value).to.equal('Foo');
|
|
590
620
|
});
|
|
591
621
|
|
|
622
|
+
it("doesn't select any similar options after using delete when requireOptionMatch is false", async () => {
|
|
623
|
+
const el = /** @type {LionCombobox} */ (
|
|
624
|
+
await fixture(html`
|
|
625
|
+
<lion-combobox name="foo" .validators=${[new Required()]}>
|
|
626
|
+
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
627
|
+
<lion-option .choiceValue="${'Chard'}">Chard</lion-option>
|
|
628
|
+
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
629
|
+
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
630
|
+
</lion-combobox>
|
|
631
|
+
`)
|
|
632
|
+
);
|
|
633
|
+
el.requireOptionMatch = false;
|
|
634
|
+
const { _inputNode } = getComboboxMembers(el);
|
|
635
|
+
|
|
636
|
+
mimicUserTyping(el, 'Art');
|
|
637
|
+
await el.updateComplete;
|
|
638
|
+
|
|
639
|
+
await mimicUserTypingAdvanced(el, ['Delete']);
|
|
640
|
+
await el.updateComplete;
|
|
641
|
+
await el.updateComplete;
|
|
642
|
+
|
|
643
|
+
mimicKeyPress(_inputNode, 'Enter');
|
|
644
|
+
await el.updateComplete;
|
|
645
|
+
|
|
646
|
+
expect(el.checkedIndex).to.equal(-1);
|
|
647
|
+
expect(el.modelValue).to.equal('Art');
|
|
648
|
+
expect(_inputNode.value).to.equal('Art');
|
|
649
|
+
});
|
|
650
|
+
|
|
592
651
|
it("when removing a letter it won't select the option", async () => {
|
|
593
652
|
// We don't autocomplete when characters are removed
|
|
594
653
|
const el = /** @type {LionCombobox} */ (
|
|
@@ -641,6 +700,173 @@ describe('lion-combobox', () => {
|
|
|
641
700
|
expect(el.modelValue).to.equal('Foo');
|
|
642
701
|
expect(el.formElements[0].checked).to.be.false;
|
|
643
702
|
});
|
|
703
|
+
|
|
704
|
+
it('allows custom selections when multi-choice when requireOptionMatch is false', async () => {
|
|
705
|
+
const el = /** @type {LionCombobox} */ (
|
|
706
|
+
await fixture(html`
|
|
707
|
+
<lion-combobox
|
|
708
|
+
name="foo"
|
|
709
|
+
multiple-choice
|
|
710
|
+
.validators=${[new Required()]}
|
|
711
|
+
autocomplete="none"
|
|
712
|
+
>
|
|
713
|
+
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
714
|
+
<lion-option checked .choiceValue="${'Chard'}">Chard</lion-option>
|
|
715
|
+
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
716
|
+
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
717
|
+
</lion-combobox>
|
|
718
|
+
`)
|
|
719
|
+
);
|
|
720
|
+
|
|
721
|
+
el.requireOptionMatch = false;
|
|
722
|
+
await el.updateComplete;
|
|
723
|
+
|
|
724
|
+
const { _inputNode } = getComboboxMembers(el);
|
|
725
|
+
expect(el.modelValue).to.eql(['Chard']);
|
|
726
|
+
expect(el.checkedIndex).to.eql([1]);
|
|
727
|
+
|
|
728
|
+
mimicUserTyping(el, 'Foo');
|
|
729
|
+
await el.updateComplete;
|
|
730
|
+
mimicKeyPress(_inputNode, 'Enter');
|
|
731
|
+
await el.updateComplete;
|
|
732
|
+
|
|
733
|
+
expect(el.modelValue).to.eql(['Chard', 'Foo']);
|
|
734
|
+
expect(el.checkedIndex).to.eql([1]);
|
|
735
|
+
|
|
736
|
+
mimicUserTyping(el, 'Bar');
|
|
737
|
+
await el.updateComplete;
|
|
738
|
+
mimicKeyPress(_inputNode, 'Enter');
|
|
739
|
+
await el.updateComplete;
|
|
740
|
+
});
|
|
741
|
+
|
|
742
|
+
it('allows manyu custom selections when multi-choice when requireOptionMatch is false', async () => {
|
|
743
|
+
const el = /** @type {LionCombobox} */ (
|
|
744
|
+
await fixture(html`
|
|
745
|
+
<lion-combobox
|
|
746
|
+
name="foo"
|
|
747
|
+
multiple-choice
|
|
748
|
+
.validators=${[new Required()]}
|
|
749
|
+
autocomplete="none"
|
|
750
|
+
>
|
|
751
|
+
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
752
|
+
<lion-option .choiceValue="${'Chard'}">Chard</lion-option>
|
|
753
|
+
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
754
|
+
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
755
|
+
</lion-combobox>
|
|
756
|
+
`)
|
|
757
|
+
);
|
|
758
|
+
|
|
759
|
+
el.requireOptionMatch = false;
|
|
760
|
+
await el.updateComplete;
|
|
761
|
+
|
|
762
|
+
const { _inputNode } = getComboboxMembers(el);
|
|
763
|
+
|
|
764
|
+
mimicUserTyping(el, 'Foo');
|
|
765
|
+
await el.updateComplete;
|
|
766
|
+
mimicKeyPress(_inputNode, 'Enter');
|
|
767
|
+
await el.updateComplete;
|
|
768
|
+
|
|
769
|
+
expect(el.modelValue).to.eql(['Foo']);
|
|
770
|
+
expect(el.checkedIndex).to.eql([]);
|
|
771
|
+
|
|
772
|
+
mimicUserTyping(el, 'Bar');
|
|
773
|
+
await el.updateComplete;
|
|
774
|
+
mimicKeyPress(_inputNode, 'Enter');
|
|
775
|
+
await el.updateComplete;
|
|
776
|
+
|
|
777
|
+
expect(el.modelValue).to.eql(['Foo', 'Bar']);
|
|
778
|
+
expect(el.checkedIndex).to.eql([]);
|
|
779
|
+
});
|
|
780
|
+
|
|
781
|
+
it('allows new options when multi-choice when requireOptionMatch=false and autocomplete="both", without selecting similar values', async () => {
|
|
782
|
+
const el = /** @type {LionCombobox} */ (
|
|
783
|
+
await fixture(html`
|
|
784
|
+
<lion-combobox
|
|
785
|
+
name="foo"
|
|
786
|
+
multiple-choice
|
|
787
|
+
.requireOptionMatch=${false}
|
|
788
|
+
autocomplete="both"
|
|
789
|
+
>
|
|
790
|
+
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
791
|
+
<lion-option .choiceValue="${'Chard'}">Chard</lion-option>
|
|
792
|
+
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
793
|
+
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
794
|
+
</lion-combobox>
|
|
795
|
+
`)
|
|
796
|
+
);
|
|
797
|
+
|
|
798
|
+
await el.updateComplete;
|
|
799
|
+
|
|
800
|
+
const { _inputNode } = getComboboxMembers(el);
|
|
801
|
+
|
|
802
|
+
mimicUserTyping(el, 'Artist');
|
|
803
|
+
await el.updateComplete;
|
|
804
|
+
mimicKeyPress(_inputNode, 'Enter');
|
|
805
|
+
await el.updateComplete;
|
|
806
|
+
|
|
807
|
+
expect(el.modelValue).to.eql(['Artist']);
|
|
808
|
+
});
|
|
809
|
+
|
|
810
|
+
it('allows new options when multi-choice when requireOptionMatch=false and autocomplete="both", when deleting autocomplete values using Backspace', async () => {
|
|
811
|
+
const el = /** @type {LionCombobox} */ (
|
|
812
|
+
await fixture(html`
|
|
813
|
+
<lion-combobox
|
|
814
|
+
name="foo"
|
|
815
|
+
multiple-choice
|
|
816
|
+
.requireOptionMatch=${false}
|
|
817
|
+
autocomplete="both"
|
|
818
|
+
>
|
|
819
|
+
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
820
|
+
<lion-option .choiceValue="${'Chard'}">Chard</lion-option>
|
|
821
|
+
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
822
|
+
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
823
|
+
</lion-combobox>
|
|
824
|
+
`)
|
|
825
|
+
);
|
|
826
|
+
|
|
827
|
+
await el.updateComplete;
|
|
828
|
+
|
|
829
|
+
const { _inputNode } = getComboboxMembers(el);
|
|
830
|
+
mimicUserTyping(el, 'Art');
|
|
831
|
+
await el.updateComplete;
|
|
832
|
+
await mimicUserTypingAdvanced(el, ['Backspace']);
|
|
833
|
+
await el.updateComplete;
|
|
834
|
+
mimicKeyPress(_inputNode, 'Enter');
|
|
835
|
+
await el.updateComplete;
|
|
836
|
+
|
|
837
|
+
expect(el.modelValue).to.eql(['Art']);
|
|
838
|
+
});
|
|
839
|
+
|
|
840
|
+
it('allows new custom options when multi-choice when requireOptionMatch=false and autocomplete="both", when deleting autocompleted values using Delete', async () => {
|
|
841
|
+
const el = /** @type {LionCombobox} */ (
|
|
842
|
+
await fixture(html`
|
|
843
|
+
<lion-combobox
|
|
844
|
+
name="foo"
|
|
845
|
+
multiple-choice
|
|
846
|
+
.requireOptionMatch=${false}
|
|
847
|
+
autocomplete="both"
|
|
848
|
+
>
|
|
849
|
+
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
850
|
+
<lion-option .choiceValue="${'Chard'}">Chard</lion-option>
|
|
851
|
+
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
852
|
+
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
853
|
+
</lion-combobox>
|
|
854
|
+
`)
|
|
855
|
+
);
|
|
856
|
+
|
|
857
|
+
await el.updateComplete;
|
|
858
|
+
|
|
859
|
+
const { _inputNode } = getComboboxMembers(el);
|
|
860
|
+
el.modelValue = [];
|
|
861
|
+
|
|
862
|
+
mimicUserTyping(el, 'Art');
|
|
863
|
+
await el.updateComplete;
|
|
864
|
+
await mimicUserTypingAdvanced(el, ['Delete']);
|
|
865
|
+
await el.updateComplete;
|
|
866
|
+
mimicKeyPress(_inputNode, 'Enter');
|
|
867
|
+
await el.updateComplete;
|
|
868
|
+
expect(el.modelValue).to.eql(['Art']);
|
|
869
|
+
});
|
|
644
870
|
});
|
|
645
871
|
|
|
646
872
|
describe('Overlay visibility', () => {
|
|
@@ -1304,6 +1530,47 @@ describe('lion-combobox', () => {
|
|
|
1304
1530
|
]);
|
|
1305
1531
|
});
|
|
1306
1532
|
|
|
1533
|
+
it('does not autocomplete on [Enter] when textbox content does not match options', async () => {
|
|
1534
|
+
const el = /** @type {LionCombobox} */ (
|
|
1535
|
+
await fixture(html`
|
|
1536
|
+
<lion-combobox name="foo">
|
|
1537
|
+
<lion-option .choiceValue="${'Mango'}">Mango</lion-option>
|
|
1538
|
+
<lion-option .choiceValue="${'Lemon'}">Lemon</lion-option>
|
|
1539
|
+
<lion-option .choiceValue="${'Apple'}">Apple</lion-option>
|
|
1540
|
+
</lion-combobox>
|
|
1541
|
+
`)
|
|
1542
|
+
);
|
|
1543
|
+
const { _inputNode } = getComboboxMembers(el);
|
|
1544
|
+
mimicUserTypingAdvanced(el, ['m', 'a', 'k']);
|
|
1545
|
+
await el.updateComplete;
|
|
1546
|
+
mimicKeyPress(_inputNode, 'Enter');
|
|
1547
|
+
await el.updateComplete;
|
|
1548
|
+
await el.updateComplete;
|
|
1549
|
+
expect(_inputNode.value).to.equal('Mak');
|
|
1550
|
+
});
|
|
1551
|
+
|
|
1552
|
+
it('does not autocomplete on [Enter] when textbox content does not match options and content was cleared via [Backspace]', async () => {
|
|
1553
|
+
const el = /** @type {LionCombobox} */ (
|
|
1554
|
+
await fixture(html`
|
|
1555
|
+
<lion-combobox name="foo">
|
|
1556
|
+
<lion-option .choiceValue="${'Mango'}">Mango</lion-option>
|
|
1557
|
+
<lion-option .choiceValue="${'Lemon'}">Lemon</lion-option>
|
|
1558
|
+
<lion-option .choiceValue="${'Apple'}">Apple</lion-option>
|
|
1559
|
+
</lion-combobox>
|
|
1560
|
+
`)
|
|
1561
|
+
);
|
|
1562
|
+
const { _inputNode } = getComboboxMembers(el);
|
|
1563
|
+
mimicUserTypingAdvanced(el, ['m', 'o', 'Backspace', 'Backspace', 'm', 'o']);
|
|
1564
|
+
await el.updateComplete;
|
|
1565
|
+
await el.updateComplete;
|
|
1566
|
+
await el.updateComplete;
|
|
1567
|
+
await el.updateComplete;
|
|
1568
|
+
mimicKeyPress(_inputNode, 'Enter');
|
|
1569
|
+
await el.updateComplete;
|
|
1570
|
+
await el.updateComplete;
|
|
1571
|
+
expect(_inputNode.value).to.equal('Mo');
|
|
1572
|
+
});
|
|
1573
|
+
|
|
1307
1574
|
it('does not filter options when autocomplete is "inline"', async () => {
|
|
1308
1575
|
const el = /** @type {LionCombobox} */ (
|
|
1309
1576
|
await fixture(html`
|
|
@@ -72,15 +72,18 @@ export async function mimicUserTypingAdvanced(el, values) {
|
|
|
72
72
|
const selectionEnd = _inputNode.selectionEnd || 0;
|
|
73
73
|
const hasSelection = selectionStart !== selectionEnd;
|
|
74
74
|
|
|
75
|
-
if (key === 'Backspace') {
|
|
75
|
+
if (key === 'Backspace' || key === 'Delete') {
|
|
76
76
|
if (hasSelection) {
|
|
77
77
|
_inputNode.value =
|
|
78
78
|
_inputNode.value.slice(0, selectionStart) + _inputNode.value.slice(selectionEnd);
|
|
79
79
|
cursorPosition = selectionStart;
|
|
80
|
-
} else if (cursorPosition > 0) {
|
|
80
|
+
} else if (cursorPosition > 0 && key === 'Backspace') {
|
|
81
81
|
_inputNode.value =
|
|
82
82
|
_inputNode.value.slice(0, cursorPosition - 1) + _inputNode.value.slice(cursorPosition);
|
|
83
83
|
cursorPosition -= 1;
|
|
84
|
+
} else if (cursorPosition < _inputNode.value.length && key === 'Delete') {
|
|
85
|
+
_inputNode.value =
|
|
86
|
+
_inputNode.value.slice(0, cursorPosition) + _inputNode.value.slice(cursorPosition + 1);
|
|
84
87
|
}
|
|
85
88
|
} else if (hasSelection) {
|
|
86
89
|
_inputNode.value =
|
|
@@ -36,4 +36,12 @@ export const browserDetection = {
|
|
|
36
36
|
isIOSChrome: checkChrome('ios'),
|
|
37
37
|
isChromium: checkChrome('chromium'),
|
|
38
38
|
isMac: navigator.appVersion.indexOf('Mac') !== -1,
|
|
39
|
+
isIOS: /iPhone|iPad|iPod/i.test(navigator.userAgent),
|
|
40
|
+
isMacSafari:
|
|
41
|
+
navigator.vendor &&
|
|
42
|
+
navigator.vendor.indexOf('Apple') > -1 &&
|
|
43
|
+
navigator.userAgent &&
|
|
44
|
+
navigator.userAgent.indexOf('CriOS') === -1 &&
|
|
45
|
+
navigator.userAgent.indexOf('FxiOS') === -1 &&
|
|
46
|
+
navigator.appVersion.indexOf('Mac') !== -1,
|
|
39
47
|
};
|