@lion/ui 0.22.0 → 0.24.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/README.md +65 -0
- package/components/accordion/src/LionAccordion.js +31 -42
- package/components/accordion/test/lion-accordion.test.js +108 -134
- package/components/button/src/LionButton.js +9 -12
- package/components/button/src/LionButtonReset.js +0 -5
- package/components/button/src/LionButtonSubmit.js +7 -12
- package/components/button/test/demos.screenshots-test.js +50 -11
- package/components/button/test/lion-button.test.js +0 -1
- package/components/button/test-suites/LionButton.suite.js +135 -145
- package/components/button/test-suites/LionButtonReset.suite.js +54 -72
- package/components/button/test-suites/LionButtonSubmit.suite.js +49 -68
- package/components/calendar/src/LionCalendar.js +151 -104
- package/components/calendar/src/calendarStyle.js +0 -1
- package/components/calendar/src/utils/createMonth.js +3 -4
- package/components/calendar/src/utils/createMultipleMonth.js +15 -7
- package/components/calendar/src/utils/createWeek.js +0 -2
- package/components/calendar/src/utils/dataTemplate.js +8 -4
- package/components/calendar/src/utils/dayTemplate.js +0 -6
- package/components/calendar/src/utils/getDayMonthYear.js +6 -2
- package/components/calendar/test/demos.screenshots-test.js +40 -9
- package/components/calendar/test/lion-calendar.test.js +171 -282
- package/components/calendar/test/utils/createMonth.test.js +61 -22
- package/components/calendar/test/utils/createMultipleMonth.test.js +14 -7
- package/components/calendar/test/utils/createWeek.test.js +51 -17
- package/components/calendar/test/utils/dataTemplate.test.js +3 -4
- package/components/calendar/test/utils/dayTemplate.test.js +106 -34
- package/components/calendar/test/utils/getFirstDayNextMonth.test.js +0 -1
- package/components/calendar/test/utils/getLastDayPreviousMonth.test.js +0 -1
- package/components/calendar/test/utils/isSameDate.test.js +0 -1
- package/components/calendar/test/utils/snapshots/monthTemplate_en-GB_Sunday_2018-12.js +1 -2
- package/components/calendar/test-helpers/CalendarObject.js +31 -62
- package/components/calendar/test-helpers/DayObject.js +7 -15
- package/components/calendar/test-suites/LionCalendar.suite.js +7 -9
- package/components/checkbox-group/src/LionCheckboxIndeterminate.js +17 -30
- package/components/checkbox-group/test/lion-checkbox-group-integrations.test.js +0 -1
- package/components/checkbox-group/test/lion-checkbox-group.test.js +21 -16
- package/components/checkbox-group/test/lion-checkbox-indeterminate-integrations.test.js +3 -3
- package/components/checkbox-group/test/lion-checkbox-integrations.test.js +3 -2
- package/components/checkbox-group/test/lion-checkbox.test.js +30 -16
- package/components/checkbox-group/test-suites/CheckboxIndeterminate.suite.js +147 -191
- package/components/collapsible/src/LionCollapsible.js +10 -15
- package/components/collapsible/test/lion-collapsible.test.js +4 -18
- package/components/combobox/src/LionCombobox.js +45 -55
- package/components/combobox/src/utils/makeMatchingTextBold.js +2 -5
- package/components/combobox/src/validators.js +0 -1
- package/components/combobox/test/lion-combobox-integrations.test.js +6 -6
- package/components/combobox/test/lion-combobox.test.js +598 -860
- package/components/combobox/test/validators.test.js +6 -13
- package/components/combobox/test-helpers/combobox-helpers.js +24 -11
- package/components/core/src/DisabledMixin.js +61 -66
- package/components/core/src/DisabledWithTabIndexMixin.js +76 -83
- package/components/core/src/EventTargetShim.js +1 -4
- package/components/core/src/ScopedElementsMixin.js +4 -15
- package/components/core/src/ScopedStylesController.js +1 -5
- package/components/core/src/SlotMixin.js +236 -239
- package/components/core/src/browserDetection.js +5 -12
- package/components/core/test/DisabledMixin.test.js +24 -39
- package/components/core/test/DisabledWithTabIndexMixin.test.js +21 -34
- package/components/core/test/EventTargetShim.test.js +0 -8
- package/components/core/test/ScopedElementsMixin.test.js +22 -38
- package/components/core/test/ScopedStylesController.test.js +11 -20
- package/components/core/test/SlotMixin.test.js +102 -154
- package/components/core/test-helpers/getCachedFixture.js +5 -11
- package/components/core/types/SlotMixinTypes.ts +8 -3
- package/components/dialog/src/LionDialog.js +4 -3
- package/components/dialog/test/lion-dialog.integration.test.js +10 -20
- package/components/dialog/test/lion-dialog.test.js +48 -62
- package/components/dialog/test-helpers/test-router.js +4 -6
- package/components/drawer/src/LionDrawer.js +18 -34
- package/components/drawer/src/drawerStyle.js +0 -1
- package/components/drawer/test/lion-drawer.test.js +1 -17
- package/components/fieldset/test/lion-fieldset.test.js +6 -4
- package/components/form/src/LionForm.js +18 -13
- package/components/form/test/lion-form.test.js +22 -52
- package/components/form-core/src/FocusMixin.js +172 -174
- package/components/form-core/src/FormControlMixin.js +811 -813
- package/components/form-core/src/FormatMixin.js +537 -537
- package/components/form-core/src/InteractionStateMixin.js +196 -183
- package/components/form-core/src/LionField.js +9 -5
- package/components/form-core/src/NativeTextFieldMixin.js +114 -116
- package/components/form-core/src/choice-group/ChoiceGroupMixin.js +322 -357
- package/components/form-core/src/choice-group/ChoiceInputMixin.js +306 -296
- package/components/form-core/src/choice-group/CustomChoiceGroupMixin.js +114 -139
- package/components/form-core/src/form-group/FormElementsHaveNoError.js +0 -2
- package/components/form-core/src/form-group/FormGroupMixin.js +551 -557
- package/components/form-core/src/registration/FormRegisteringMixin.js +72 -71
- package/components/form-core/src/registration/FormRegistrarMixin.js +201 -217
- package/components/form-core/src/registration/FormRegistrarPortalMixin.js +31 -37
- package/components/form-core/src/utils/SyncUpdatableMixin.js +106 -117
- package/components/form-core/src/utils/getAriaElementsInRightDomOrder.js +1 -2
- package/components/form-core/src/validate/LionValidationFeedback.js +12 -8
- package/components/form-core/src/validate/Unparseable.js +4 -2
- package/components/form-core/src/validate/ValidateMixin.js +829 -883
- package/components/form-core/src/validate/Validator.js +3 -6
- package/components/form-core/src/validate/resultValidators/DefaultSuccess.js +1 -2
- package/components/form-core/src/validate/validators/DateValidators.js +0 -5
- package/components/form-core/src/validate/validators/NumberValidators.js +1 -5
- package/components/form-core/src/validate/validators/Required.js +1 -1
- package/components/form-core/src/validate/validators/StringValidators.js +1 -8
- package/components/form-core/test/FocusMixin.test.js +96 -82
- package/components/form-core/test/FormControlMixin.test.js +120 -176
- package/components/form-core/test/FormRegistrationMixins.test.js +0 -2
- package/components/form-core/test/FormatMixin.test.js +0 -1
- package/components/form-core/test/InteractionStateMixin.test.js +0 -1
- package/components/form-core/test/NativeTextFieldMixin.test.js +0 -1
- package/components/form-core/test/choice-group/ChoiceGroupMixin.test.js +0 -1
- package/components/form-core/test/choice-group/ChoiceInputMixin.test.js +0 -1
- package/components/form-core/test/choice-group/CustomChoiceGroupMixin.integrations.test.js +6 -8
- package/components/form-core/test/choice-group/CustomChoiceGroupMixin.test.js +0 -3
- package/components/form-core/test/form-group/FormGroupMixin.test.js +0 -1
- package/components/form-core/test/lion-field.test.js +88 -98
- package/components/form-core/test/utils/SyncUpdatableMixin.test.js +51 -65
- package/components/form-core/test/utils/getAriaElementsInRightDomOrder.test.js +3 -3
- package/components/form-core/test/validate/DateValidators.test.js +5 -27
- package/components/form-core/test/validate/NumberValidators.test.js +4 -16
- package/components/form-core/test/validate/Required.test.js +8 -21
- package/components/form-core/test/validate/ResultValidator.test.js +1 -2
- package/components/form-core/test/validate/StringValidators.test.js +4 -35
- package/components/form-core/test/validate/ValidateMixin.test.js +0 -1
- package/components/form-core/test/validate/ValidateMixinFeedbackPart.test.js +0 -1
- package/components/form-core/test/validate/Validator.test.js +39 -34
- package/components/form-core/test/validate/lion-validation-feedback.test.js +81 -43
- package/components/form-core/test-helpers/ExampleValidators.js +0 -5
- package/components/form-core/test-helpers/getFormControlMembers.js +2 -2
- package/components/form-core/test-helpers/mimicUserInput.js +5 -1
- package/components/form-core/test-suites/FormRegistrationMixins.suite.js +65 -122
- package/components/form-core/test-suites/FormatMixin.suite.js +202 -227
- package/components/form-core/test-suites/InteractionStateMixin.suite.js +47 -60
- package/components/form-core/test-suites/NativeTextFieldMixin.suite.js +8 -11
- package/components/form-core/test-suites/ValidateMixin.suite.js +280 -359
- package/components/form-core/test-suites/ValidateMixinFeedbackPart.suite.js +112 -163
- package/components/form-core/test-suites/choice-group/ChoiceGroupMixin.suite.js +185 -218
- package/components/form-core/test-suites/choice-group/ChoiceInputMixin.suite.js +116 -109
- package/components/form-core/test-suites/choice-group/CustomChoiceGroupMixin.suite.js +36 -70
- package/components/form-core/test-suites/form-group/FormGroupMixin-input.suite.js +57 -65
- package/components/form-core/test-suites/form-group/FormGroupMixin.suite.js +664 -523
- package/components/form-core/translations/bg-BG.js +0 -1
- package/components/form-core/translations/cs-CZ.js +0 -1
- package/components/form-core/translations/de-DE.js +0 -1
- package/components/form-core/translations/en-AU.js +0 -1
- package/components/form-core/translations/en-GB.js +0 -1
- package/components/form-core/translations/en-US.js +0 -1
- package/components/form-core/translations/es-ES.js +0 -1
- package/components/form-core/translations/fr-BE.js +0 -1
- package/components/form-core/translations/fr-FR.js +0 -1
- package/components/form-core/translations/hu-HU.js +0 -1
- package/components/form-core/translations/it-IT.js +0 -1
- package/components/form-core/translations/nl-BE.js +0 -1
- package/components/form-core/translations/nl-NL.js +0 -1
- package/components/form-core/translations/pl-PL.js +0 -1
- package/components/form-core/translations/ro-RO.js +0 -1
- package/components/form-core/translations/ru-RU.js +0 -1
- package/components/form-core/translations/sk-SK.js +0 -1
- package/components/form-core/translations/tr-TR.js +0 -1
- package/components/form-core/translations/uk-UA.js +0 -1
- package/components/form-core/types/choice-group/ChoiceGroupMixinTypes.ts +5 -0
- package/components/form-integrations/test/dialog-integrations.test.js +1 -4
- package/components/form-integrations/test/form-group-methods.test.js +28 -31
- package/components/form-integrations/test/form-integrations.test.js +27 -28
- package/components/form-integrations/test/form-validation-integrations.test.js +21 -29
- package/components/form-integrations/test/helpers/umbrella-form.js +3 -5
- package/components/form-integrations/test/model-value-consistency.test.js +75 -77
- package/components/form-integrations/test/model-value-event.test.js +10 -20
- package/components/helpers/src/SbActionLogger.js +13 -17
- package/components/helpers/src/SbLocaleSwitcher.js +5 -5
- package/components/helpers/src/sortEachDepth.js +0 -2
- package/components/helpers/test/renderLitAsNode.test.js +0 -4
- package/components/helpers/test/sb-action-logger.test.js +24 -55
- package/components/icon/src/IconManager.js +0 -2
- package/components/icon/src/LionIcon.js +2 -7
- package/components/icon/src/icons.js +0 -2
- package/components/icon/test/IconManager.test.js +0 -15
- package/components/icon/test/hammer.svg.js +3 -4
- package/components/icon/test/heart.svg.js +3 -4
- package/components/icon/test/lion-icon.test.js +14 -43
- package/components/input/src/LionInput.js +2 -8
- package/components/input/test/input-integrations.test.js +0 -5
- package/components/input/test/lion-input-integrations.test.js +0 -4
- package/components/input/test/lion-input.test.js +28 -58
- package/components/input/test-helpers/getInputMembers.js +2 -2
- package/components/input-amount/src/LionInputAmount.js +37 -26
- package/components/input-amount/src/formatters.js +4 -5
- package/components/input-amount/src/parsers.js +0 -3
- package/components/input-amount/test/formatters.test.js +102 -80
- package/components/input-amount/test/lion-input-amount-integrations.test.js +0 -4
- package/components/input-amount/test/lion-input-amount.test.js +155 -164
- package/components/input-amount/test/parsers.test.js +33 -17
- package/components/input-amount/test/preprocessors.test.js +0 -3
- package/components/input-amount-dropdown/src/LionInputAmountDropdown.js +49 -59
- package/components/input-amount-dropdown/src/currencyUtil.js +8 -7
- package/components/input-amount-dropdown/src/parsers.js +0 -1
- package/components/input-amount-dropdown/src/validators.js +0 -1
- package/components/input-amount-dropdown/test/LionInputAmountDropdown.test.js +34 -36
- package/components/input-amount-dropdown/test/lion-input-amount-dropdown-integrations.test.js +18 -13
- package/components/input-amount-dropdown/test-helpers/mimicUserChangingDropdown.js +5 -1
- package/components/input-amount-dropdown/test-suites/LionInputAmountDropdown.suite.js +132 -107
- package/components/input-date/src/LionInputDate.js +4 -3
- package/components/input-date/test/lion-input-date-integrations.test.js +0 -3
- package/components/input-date/test/lion-input-date.test.js +19 -32
- package/components/input-datepicker/src/LionInputDatepicker.js +17 -29
- package/components/input-datepicker/src/localizeNamespaceLoader.js +1 -2
- package/components/input-datepicker/test/lion-input-datepicker-integrations.test.js +0 -3
- package/components/input-datepicker/test/lion-input-datepicker.test.js +88 -153
- package/components/input-datepicker/test-helpers/DatepickerInputObject.js +9 -12
- package/components/input-datepicker/test-suites/LionInputDatepicker.suite.js +6 -4
- package/components/input-datepicker/translations/bg-BG.js +0 -1
- package/components/input-datepicker/translations/cs-CZ.js +0 -1
- package/components/input-datepicker/translations/de-DE.js +0 -1
- package/components/input-datepicker/translations/en-AU.js +0 -1
- package/components/input-datepicker/translations/en-GB.js +0 -1
- package/components/input-datepicker/translations/en-US.js +0 -1
- package/components/input-datepicker/translations/es-ES.js +0 -1
- package/components/input-datepicker/translations/fr-BE.js +0 -1
- package/components/input-datepicker/translations/fr-FR.js +0 -1
- package/components/input-datepicker/translations/hu-HU.js +0 -1
- package/components/input-datepicker/translations/it-IT.js +0 -1
- package/components/input-datepicker/translations/nl-BE.js +0 -1
- package/components/input-datepicker/translations/nl-NL.js +0 -1
- package/components/input-datepicker/translations/pl-PL.js +0 -1
- package/components/input-datepicker/translations/ro-RO.js +0 -1
- package/components/input-datepicker/translations/ru-RU.js +0 -1
- package/components/input-datepicker/translations/sk-SK.js +0 -1
- package/components/input-datepicker/translations/tr-TR.js +0 -1
- package/components/input-datepicker/translations/uk-UA.js +0 -1
- package/components/input-email/test/lion-input-email-integrations.test.js +0 -2
- package/components/input-email/test/lion-input-email.test.js +1 -7
- package/components/input-file/src/FileHandle.js +0 -3
- package/components/input-file/src/LionInputFile.js +85 -83
- package/components/input-file/src/LionSelectedFileList.js +12 -12
- package/components/input-file/src/validators.js +10 -9
- package/components/input-file/test/FileValidators.test.js +170 -80
- package/components/input-file/test/lion-input-file.test.js +160 -244
- package/components/input-file/test/lion-selected-file-list.test.js +13 -22
- package/components/input-file/translations/bg-BG.js +0 -1
- package/components/input-file/translations/cs-CZ.js +0 -1
- package/components/input-file/translations/de-DE.js +0 -1
- package/components/input-file/translations/en-AU.js +0 -1
- package/components/input-file/translations/en-GB.js +0 -1
- package/components/input-file/translations/en-PH.js +0 -1
- package/components/input-file/translations/en-US.js +0 -1
- package/components/input-file/translations/en.js +2 -1
- package/components/input-file/translations/es-ES.js +0 -1
- package/components/input-file/translations/fr-BE.js +0 -1
- package/components/input-file/translations/fr-FR.js +0 -1
- package/components/input-file/translations/hu-HU.js +0 -1
- package/components/input-file/translations/id-ID.js +0 -1
- package/components/input-file/translations/id.js +2 -1
- package/components/input-file/translations/it-IT.js +0 -1
- package/components/input-file/translations/nl-BE.js +0 -1
- package/components/input-file/translations/nl-NL.js +0 -1
- package/components/input-file/translations/pl-PL.js +0 -1
- package/components/input-file/translations/ro-RO.js +0 -1
- package/components/input-file/translations/ru-RU.js +0 -1
- package/components/input-file/translations/sk-SK.js +0 -1
- package/components/input-file/translations/uk-UA.js +0 -1
- package/components/input-file/translations/zh-CN.js +0 -1
- package/components/input-iban/src/validators.js +6 -11
- package/components/input-iban/test/formatters.test.js +0 -3
- package/components/input-iban/test/lion-input-iban-integrations.test.js +0 -2
- package/components/input-iban/test/lion-input-iban.test.js +1 -9
- package/components/input-iban/test/parsers.test.js +0 -2
- package/components/input-iban/test/validators.test.js +0 -12
- package/components/input-iban/translations/bg-BG.js +0 -1
- package/components/input-iban/translations/cs-CZ.js +0 -1
- package/components/input-iban/translations/de-DE.js +0 -1
- package/components/input-iban/translations/en-AU.js +0 -1
- package/components/input-iban/translations/en-GB.js +0 -1
- package/components/input-iban/translations/en-US.js +0 -1
- package/components/input-iban/translations/es-ES.js +0 -1
- package/components/input-iban/translations/fr-BE.js +0 -1
- package/components/input-iban/translations/fr-FR.js +0 -1
- package/components/input-iban/translations/hu-HU.js +0 -1
- package/components/input-iban/translations/it-IT.js +0 -1
- package/components/input-iban/translations/nl-BE.js +0 -1
- package/components/input-iban/translations/nl-NL.js +0 -1
- package/components/input-iban/translations/pl-PL.js +0 -1
- package/components/input-iban/translations/ro-RO.js +0 -1
- package/components/input-iban/translations/ru-RU.js +0 -1
- package/components/input-iban/translations/sk-SK.js +0 -1
- package/components/input-iban/translations/uk-UA.js +0 -1
- package/components/input-range/src/LionInputRange.js +18 -19
- package/components/input-range/test/lion-input-range.test.js +23 -48
- package/components/input-range/translations/bg-BG.js +0 -1
- package/components/input-range/translations/cs-CZ.js +0 -1
- package/components/input-range/translations/de-DE.js +0 -1
- package/components/input-range/translations/en-AU.js +0 -1
- package/components/input-range/translations/en-GB.js +0 -1
- package/components/input-range/translations/en-PH.js +0 -1
- package/components/input-range/translations/en-US.js +0 -1
- package/components/input-range/translations/es-ES.js +0 -1
- package/components/input-range/translations/fr-BE.js +0 -1
- package/components/input-range/translations/fr-FR.js +0 -1
- package/components/input-range/translations/hu-HU.js +0 -1
- package/components/input-range/translations/it-IT.js +0 -1
- package/components/input-range/translations/nl-BE.js +0 -1
- package/components/input-range/translations/nl-NL.js +0 -1
- package/components/input-range/translations/pl-PL.js +0 -1
- package/components/input-range/translations/ro-RO.js +0 -1
- package/components/input-range/translations/ru-RU.js +0 -1
- package/components/input-range/translations/sk-SK.js +0 -1
- package/components/input-range/translations/uk-UA.js +0 -1
- package/components/input-range/translations/zh-CN.js +0 -1
- package/components/input-stepper/src/LionInputStepper.js +19 -38
- package/components/input-stepper/test/lion-input-stepper-integrations.test.js +0 -1
- package/components/input-stepper/test/lion-input-stepper.test.js +0 -1
- package/components/input-stepper/test-suites/lion-input-stepper.integration.suite.js +0 -2
- package/components/input-stepper/test-suites/lion-input-stepper.suite.js +56 -105
- package/components/input-stepper/translations/bg-BG.js +0 -1
- package/components/input-stepper/translations/cs-CZ.js +0 -1
- package/components/input-stepper/translations/de-DE.js +0 -1
- package/components/input-stepper/translations/en-AU.js +0 -1
- package/components/input-stepper/translations/en-GB.js +0 -1
- package/components/input-stepper/translations/en-US.js +0 -1
- package/components/input-stepper/translations/es-ES.js +0 -1
- package/components/input-stepper/translations/fr-BE.js +0 -1
- package/components/input-stepper/translations/fr-FR.js +0 -1
- package/components/input-stepper/translations/hu-HU.js +0 -1
- package/components/input-stepper/translations/it-IT.js +0 -1
- package/components/input-stepper/translations/nl-BE.js +0 -1
- package/components/input-stepper/translations/nl-NL.js +0 -1
- package/components/input-stepper/translations/pl-PL.js +0 -1
- package/components/input-stepper/translations/ro-RO.js +0 -1
- package/components/input-stepper/translations/ru-RU.js +0 -1
- package/components/input-stepper/translations/sk-SK.js +0 -1
- package/components/input-stepper/translations/uk-UA.js +0 -1
- package/components/input-tel/src/LionInputTel.js +53 -37
- package/components/input-tel/src/PhoneUtilManager.js +6 -4
- package/components/input-tel/src/formatters.js +12 -10
- package/components/input-tel/src/parsers.js +3 -3
- package/components/input-tel/src/preprocessors.js +15 -7
- package/components/input-tel/src/validators.js +4 -6
- package/components/input-tel/test/LionInputTel.test.js +4 -2
- package/components/input-tel/test/formatters.test.js +22 -10
- package/components/input-tel/test/parsers.test.js +40 -11
- package/components/input-tel/test/preprocessors.test.js +24 -13
- package/components/input-tel/test/validators.test.js +15 -13
- package/components/input-tel/test-helpers/mockPhoneUtilManager.js +7 -6
- package/components/input-tel/test-suites/LionInputTel.suite.js +33 -73
- package/components/input-tel/translations/bg-BG.js +0 -1
- package/components/input-tel/translations/cs-CZ.js +0 -1
- package/components/input-tel/translations/de-DE.js +0 -1
- package/components/input-tel/translations/en-AU.js +0 -1
- package/components/input-tel/translations/en-GB.js +0 -1
- package/components/input-tel/translations/en-US.js +0 -1
- package/components/input-tel/translations/es-ES.js +0 -1
- package/components/input-tel/translations/fr-BE.js +0 -1
- package/components/input-tel/translations/fr-FR.js +0 -1
- package/components/input-tel/translations/hu-HU.js +0 -1
- package/components/input-tel/translations/it-IT.js +0 -1
- package/components/input-tel/translations/nl-BE.js +0 -1
- package/components/input-tel/translations/nl-NL.js +0 -1
- package/components/input-tel/translations/pl-PL.js +0 -1
- package/components/input-tel/translations/ro-RO.js +0 -1
- package/components/input-tel/translations/ru-RU.js +0 -1
- package/components/input-tel/translations/sk-SK.js +0 -1
- package/components/input-tel/translations/uk-UA.js +0 -1
- package/components/input-tel-dropdown/src/LionInputTelDropdown.js +10 -28
- package/components/input-tel-dropdown/src/regionCodeToLocale.js +3 -1
- package/components/input-tel-dropdown/test/LionInputTelDropdown.test.js +31 -38
- package/components/input-tel-dropdown/test/regionCodeToLocale.test.js +0 -1
- package/components/input-tel-dropdown/test-helpers/mimicUserChangingDropdown.js +5 -1
- package/components/input-tel-dropdown/test-suites/LionInputTelDropdown--parentheses.suite.js +16 -11
- package/components/input-tel-dropdown/test-suites/LionInputTelDropdown.suite.js +54 -79
- package/components/listbox/src/LionListbox.js +4 -1
- package/components/listbox/src/LionOption.js +8 -7
- package/components/listbox/src/LionOptions.js +0 -3
- package/components/listbox/src/ListboxMixin.js +801 -819
- package/components/listbox/test/lion-listbox.test.js +0 -1
- package/components/listbox/test/lion-option.test.js +53 -64
- package/components/listbox/test/lion-options.test.js +3 -4
- package/components/listbox/test-helpers/getListboxMembers.js +6 -3
- package/components/listbox/test-suites/ListboxMixin.suite.js +101 -261
- package/components/listbox/types/ListboxMixinTypes.ts +7 -1
- package/components/localize/src/LocalizeManager.js +40 -40
- package/components/localize/src/LocalizeMixin.js +130 -157
- package/components/localize/src/date/formatDate.js +1 -5
- package/components/localize/src/date/getDateFormatBasedOnLocale.js +5 -3
- package/components/localize/src/date/getMonthNames.js +3 -5
- package/components/localize/src/date/getWeekdayNames.js +1 -5
- package/components/localize/src/date/parseDate.js +5 -20
- package/components/localize/src/date/utils/normalizeIntlDate.js +0 -7
- package/components/localize/src/getLocalizeManager.js +0 -3
- package/components/localize/src/number/formatNumber.js +3 -7
- package/components/localize/src/number/formatNumberToParts.js +52 -18
- package/components/localize/src/number/getCurrencyName.js +5 -5
- package/components/localize/src/number/getFractionDigits.js +4 -4
- package/components/localize/src/number/getSeparatorsFromNumber.js +1 -3
- package/components/localize/src/number/parseNumber.js +0 -3
- package/components/localize/src/number/utils/normalize-format-number-to-parts/forceAddGroupSeparators.js +0 -1
- package/components/localize/src/number/utils/normalize-format-number-to-parts/forceSpaceBetweenCurrencyCodeAndNumber.js +4 -1
- package/components/localize/test/LocalizeManager.test.js +385 -278
- package/components/localize/test/LocalizeMixin.test.js +28 -112
- package/components/localize/test/date/formatDate.test.js +18 -48
- package/components/localize/test/date/getDateFormatBasedOnLocale.test.js +0 -3
- package/components/localize/test/date/getMonthNames.test.js +27 -12
- package/components/localize/test/date/getWeekdayNames.test.js +93 -49
- package/components/localize/test/date/normalizeDateTime.test.js +0 -2
- package/components/localize/test/date/parseDate.test.js +12 -16
- package/components/localize/test/getLocalizeManager.test.js +0 -3
- package/components/localize/test/isLocalizeESModule.test.js +32 -13
- package/components/localize/test/localize.test.js +0 -4
- package/components/localize/test/number/formatNumber.test.js +215 -106
- package/components/localize/test/number/formatNumberToParts.test.js +31 -38
- package/components/localize/test/number/getCurrencyName.test.js +20 -6
- package/components/localize/test/number/getDecimalSeparator.test.js +5 -4
- package/components/localize/test/number/getFractionDigits.test.js +0 -2
- package/components/localize/test/number/getGroupSeparator.test.js +0 -2
- package/components/localize/test/number/getSeparatorsFromNumber.test.js +5 -3
- package/components/localize/test/number/parseNumber.test.js +123 -56
- package/components/localize/test/side-effect-free-entrypoint.test.js +0 -6
- package/components/localize/test-helpers/fake-imports.js +11 -6
- package/components/localize/test-helpers/localizeTearDown.js +0 -1
- package/components/menu/README.md +360 -0
- package/components/menu/src/InteractiveListMixin.js +866 -0
- package/components/menu/src/LionMenu.js +423 -0
- package/components/menu/src/MoreButtonMenuMixin.js +272 -0
- package/components/menu/src/MultiLevelListMixin.js +306 -0
- package/components/menu/src/utils/isInView.js +25 -0
- package/components/menu/src/utils/listItemInteractions.js +124 -0
- package/components/menu/test/InteractiveListMixin.test.js +2 -0
- package/components/menu/test/MoreButtonMenuMixin.test.js +5 -0
- package/components/menu/test/MultiLevelListMixin.test.js +2 -0
- package/components/menu/test/lion-menu-interactions.test.js +2 -0
- package/components/menu/test/lion-menu.test.js +18 -0
- package/components/menu/test-helpers/mimicKeyPress.js +19 -0
- package/components/menu/test-suites/InteractiveListMixin.suite.js +498 -0
- package/components/menu/test-suites/LionMenu.suite.js +107 -0
- package/components/menu/test-suites/LionMenuInteractions.suite.js +561 -0
- package/components/menu/test-suites/MoreButtonMenuMixin.suite.js +365 -0
- package/components/menu/test-suites/MultiLevelListMixin.suite.js +291 -0
- package/components/menu/types/InteractiveListMixinTypes.ts +126 -0
- package/components/menu/types/MoreButtonMenuMixinTypes.ts +51 -0
- package/components/menu/types/MultiLevelListMixinTypes.ts +28 -0
- package/components/menu/types/OverlayWithListInvokerMixinTypes.ts +61 -0
- package/components/overlays/NEXT.md +49 -0
- package/components/overlays/src/ArrowMixin.js +111 -127
- package/components/overlays/src/OverlayController.js +440 -246
- package/components/overlays/src/OverlayMixin.js +130 -68
- package/components/overlays/src/OverlaysManager.js +30 -32
- package/components/overlays/src/configurations/visibility-trigger-partials/withClickInteraction.js +0 -1
- package/components/overlays/src/configurations/visibility-trigger-partials/withHoverInteraction.js +11 -11
- package/components/overlays/src/configurations/withBottomSheetConfig.js +12 -13
- package/components/overlays/src/configurations/withDropdownConfig.js +4 -2
- package/components/overlays/src/configurations/withModalDialogConfig.js +12 -13
- package/components/overlays/src/configurations/withPopoverConfig.js +27 -25
- package/components/overlays/src/configurations/withTooltipConfig.js +15 -13
- package/components/overlays/src/overlayDocumentStyle.js +1 -1
- package/components/overlays/src/overlayShadowDomStyle.js +0 -1
- package/components/overlays/src/singleton.js +0 -2
- package/components/overlays/src/utils/adopt-styles.js +19 -19
- package/components/overlays/src/utils/deep-contains.js +7 -6
- package/components/overlays/src/utils/get-focusable-elements.js +7 -10
- package/components/overlays/src/utils/inert-siblings.js +2 -4
- package/components/overlays/src/utils/is-equal-config.js +14 -6
- package/components/overlays/src/utils/is-visible.js +0 -1
- package/components/overlays/src/utils/simulate-tab.js +1 -4
- package/components/overlays/src/utils/sort-by-tabindex.js +2 -4
- package/components/overlays/test/ArrowMixin.test.js +18 -30
- package/components/overlays/test/OverlayController.test.js +551 -533
- package/components/overlays/test/OverlayMixin.test.js +0 -2
- package/components/overlays/test/OverlaysManager.test.js +30 -35
- package/components/overlays/test/global-positioning.test.js +6 -10
- package/components/overlays/test/local-positioning.test.js +101 -103
- package/components/overlays/test/utils-tests/active-element.test.js +12 -27
- package/components/overlays/test/utils-tests/adopt-styles.test.js +25 -56
- package/components/overlays/test/utils-tests/deep-contains.test.js +73 -74
- package/components/overlays/test/utils-tests/get-focusable-elements.test.js +6 -23
- package/components/overlays/test/utils-tests/is-equal-config.test.js +32 -13
- package/components/overlays/test/utils-tests/visibility.test.js +44 -79
- package/components/overlays/test-helpers/createShadowHost.js +5 -3
- package/components/overlays/test-helpers/normalizeTransformStyle.js +2 -4
- package/components/overlays/test-suites/OverlayMixin.suite.js +159 -188
- package/components/overlays/test-suites/WithHoverInteraction.suite.js +96 -79
- package/components/overlays/translations/bg-BG.js +0 -1
- package/components/overlays/translations/cs-CZ.js +0 -1
- package/components/overlays/translations/de-DE.js +0 -1
- package/components/overlays/translations/en-AU.js +0 -1
- package/components/overlays/translations/en-GB.js +0 -1
- package/components/overlays/translations/en-US.js +0 -1
- package/components/overlays/translations/es-ES.js +0 -1
- package/components/overlays/translations/fr-BE.js +0 -1
- package/components/overlays/translations/fr-FR.js +0 -1
- package/components/overlays/translations/hu-HU.js +0 -1
- package/components/overlays/translations/it-IT.js +0 -1
- package/components/overlays/translations/nl-BE.js +0 -1
- package/components/overlays/translations/nl-NL.js +0 -1
- package/components/overlays/translations/pl-PL.js +0 -1
- package/components/overlays/translations/ro-RO.js +0 -1
- package/components/overlays/translations/ru-RU.js +0 -1
- package/components/overlays/translations/sk-SK.js +0 -1
- package/components/overlays/translations/tr-TR.js +0 -1
- package/components/overlays/translations/uk-UA.js +0 -1
- package/components/overlays/types/ArrowMixinTypes.ts +1 -3
- package/components/overlays/types/OverlayConfig.ts +20 -5
- package/components/overlays/types/OverlayMixinTypes.ts +2 -0
- package/components/pagination/src/LionPagination.js +9 -12
- package/components/pagination/test/lion-pagination.test.js +18 -50
- package/components/progress-indicator/src/LionProgressIndicator.js +10 -12
- package/components/progress-indicator/test/lion-progress-indicator.test.js +1 -22
- package/components/radio-group/src/LionRadioGroup.js +1 -2
- package/components/radio-group/test/lion-radio-group-integrations.test.js +0 -1
- package/components/radio-group/test/lion-radio-group.test.js +27 -27
- package/components/radio-group/test/lion-radio-integrations.test.js +3 -2
- package/components/radio-group/test/lion-radio.test.js +30 -16
- package/components/select/src/LionSelect.js +12 -13
- package/components/select/test/lion-select.test.js +7 -12
- package/components/select-rich/src/LionSelectInvoker.js +18 -11
- package/components/select-rich/src/LionSelectRich.js +32 -43
- package/components/select-rich/test/demos.screenshots-test.js +40 -9
- package/components/select-rich/test/lion-select-invoker.test.js +26 -43
- package/components/select-rich/test/lion-select-listbox-suite-integration.test.js +3 -3
- package/components/select-rich/test/lion-select-rich-dialog-integration.test.js +4 -9
- package/components/select-rich/test/lion-select-rich-interaction.test.js +154 -101
- package/components/select-rich/test/lion-select-rich-upgrade.test.js +26 -0
- package/components/select-rich/test/lion-select-rich.test.js +153 -195
- package/components/select-rich/test-helpers/getSelectRichMembers.js +4 -1
- package/components/steps/src/LionStep.js +21 -12
- package/components/steps/src/LionSteps.js +25 -25
- package/components/steps/test/lion-step.test.js +18 -25
- package/components/steps/test/lion-steps.test.js +45 -78
- package/components/switch/src/LionSwitch.js +2 -7
- package/components/switch/src/LionSwitchButton.js +5 -6
- package/components/switch/test/lion-switch-button.test.js +16 -28
- package/components/switch/test/lion-switch.test.js +17 -31
- package/components/tabs/src/LionTabs.js +25 -28
- package/components/tabs/test/lion-tabs.test.js +156 -154
- package/components/textarea/src/LionTextarea.js +4 -23
- package/components/textarea/test/lion-textarea-integrations.test.js +0 -5
- package/components/textarea/test/lion-textarea.test.js +2 -28
- package/components/tooltip/src/LionTooltip.js +6 -6
- package/components/tooltip/test/lion-tooltip.test.js +75 -102
- package/components/validate-messages/src/getLocalizedMessage.js +8 -7
- package/components/validate-messages/src/loadDefaultFeedbackMessages.js +3 -1
- package/components/validate-messages/src/loadDefaultFeedbackMessagesNoSideEffects.js +9 -5
- package/components/validate-messages/src/per-entrypoint/loadComboboxMessagesNoSideEffects.js +5 -2
- package/components/validate-messages/src/per-entrypoint/loadFormCoreMessagesNoSideEffects.js +99 -35
- package/components/validate-messages/src/per-entrypoint/loadInputTelMessagesNoSideEffects.js +4 -3
- package/components/validate-messages/test/loadDefaultFeedbackMessages.test.js +5 -3
- package/components/validate-messages/test/loadDefaultFeedbackMessagesNoSideEffects.test.js +80 -45
- package/components/validate-messages/translations/bg-BG.js +0 -1
- package/components/validate-messages/translations/cs-CZ.js +0 -1
- package/components/validate-messages/translations/de-DE.js +0 -1
- package/components/validate-messages/translations/en-AU.js +0 -1
- package/components/validate-messages/translations/en-GB.js +0 -1
- package/components/validate-messages/translations/en-PH.js +0 -1
- package/components/validate-messages/translations/en-US.js +0 -1
- package/components/validate-messages/translations/es-ES.js +0 -1
- package/components/validate-messages/translations/fr-BE.js +0 -1
- package/components/validate-messages/translations/fr-FR.js +0 -1
- package/components/validate-messages/translations/hu-HU.js +0 -1
- package/components/validate-messages/translations/it-IT.js +0 -1
- package/components/validate-messages/translations/nl-BE.js +0 -1
- package/components/validate-messages/translations/nl-NL.js +0 -1
- package/components/validate-messages/translations/pl-PL.js +0 -1
- package/components/validate-messages/translations/ro-RO.js +0 -1
- package/components/validate-messages/translations/ru-RU.js +0 -1
- package/components/validate-messages/translations/sk-SK.js +0 -1
- package/components/validate-messages/translations/tr-TR.js +0 -1
- package/components/validate-messages/translations/uk-UA.js +0 -1
- package/custom-elements.json +3312 -206
- package/dist-types/components/combobox/src/LionCombobox.d.ts +1 -1
- package/dist-types/components/combobox/src/LionCombobox.d.ts.map +1 -1
- package/dist-types/components/core/src/SlotMixin.d.ts +6 -1
- package/dist-types/components/core/src/SlotMixin.d.ts.map +1 -1
- package/dist-types/components/core/types/SlotMixinTypes.d.ts +5 -1
- package/dist-types/components/core/types/SlotMixinTypes.d.ts.map +1 -1
- package/dist-types/components/dialog/src/LionDialog.d.ts +6 -2
- package/dist-types/components/dialog/src/LionDialog.d.ts.map +1 -1
- package/dist-types/components/form-core/src/LionField.d.ts +3 -1
- package/dist-types/components/form-core/src/LionField.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/types/choice-group/ChoiceGroupMixinTypes.d.ts +5 -0
- package/dist-types/components/form-core/types/choice-group/ChoiceGroupMixinTypes.d.ts.map +1 -1
- package/dist-types/components/input-amount/src/LionInputAmount.d.ts +3 -1
- package/dist-types/components/input-amount/src/LionInputAmount.d.ts.map +1 -1
- package/dist-types/components/input-amount/src/formatters.d.ts +6 -4
- package/dist-types/components/input-amount/src/formatters.d.ts.map +1 -1
- package/dist-types/components/input-datepicker/src/LionInputDatepicker.d.ts +1 -1
- package/dist-types/components/input-tel/src/LionInputTel.d.ts +6 -6
- package/dist-types/components/input-tel/src/LionInputTel.d.ts.map +1 -1
- package/dist-types/components/input-tel/src/PhoneUtilManager.d.ts +2 -2
- package/dist-types/components/input-tel/src/PhoneUtilManager.d.ts.map +1 -1
- package/dist-types/components/input-tel/src/formatters.d.ts +2 -2
- package/dist-types/components/input-tel/src/formatters.d.ts.map +1 -1
- package/dist-types/components/input-tel/src/preprocessors.d.ts +2 -2
- package/dist-types/components/input-tel/src/preprocessors.d.ts.map +1 -1
- package/dist-types/components/input-tel/test/validators.test.d.ts +1 -1
- package/dist-types/components/input-tel/test/validators.test.d.ts.map +1 -1
- package/dist-types/components/listbox/src/LionOption.d.ts +5 -2
- package/dist-types/components/listbox/src/LionOption.d.ts.map +1 -1
- package/dist-types/components/listbox/src/ListboxMixin.d.ts.map +1 -1
- package/dist-types/components/listbox/types/ListboxMixinTypes.d.ts +7 -1
- package/dist-types/components/listbox/types/ListboxMixinTypes.d.ts.map +1 -1
- package/dist-types/components/menu/src/InteractiveListMixin.d.ts +35 -0
- package/dist-types/components/menu/src/InteractiveListMixin.d.ts.map +1 -0
- package/dist-types/components/menu/src/LionMenu.d.ts +129 -0
- package/dist-types/components/menu/src/LionMenu.d.ts.map +1 -0
- package/dist-types/components/menu/src/MoreButtonMenuMixin.d.ts +8 -0
- package/dist-types/components/menu/src/MoreButtonMenuMixin.d.ts.map +1 -0
- package/dist-types/components/menu/src/MultiLevelListMixin.d.ts +7 -0
- package/dist-types/components/menu/src/MultiLevelListMixin.d.ts.map +1 -0
- package/dist-types/components/menu/src/utils/isInView.d.ts +9 -0
- package/dist-types/components/menu/src/utils/isInView.d.ts.map +1 -0
- package/dist-types/components/menu/src/utils/listItemInteractions.d.ts +48 -0
- package/dist-types/components/menu/src/utils/listItemInteractions.d.ts.map +1 -0
- package/dist-types/components/menu/test/InteractiveListMixin.test.d.ts +2 -0
- package/dist-types/components/menu/test/InteractiveListMixin.test.d.ts.map +1 -0
- package/dist-types/components/menu/test/MoreButtonMenuMixin.test.d.ts +2 -0
- package/dist-types/components/menu/test/MoreButtonMenuMixin.test.d.ts.map +1 -0
- package/dist-types/components/menu/test/MultiLevelListMixin.test.d.ts +2 -0
- package/dist-types/components/menu/test/MultiLevelListMixin.test.d.ts.map +1 -0
- package/dist-types/components/menu/test/lion-menu-interactions.test.d.ts +2 -0
- package/dist-types/components/menu/test/lion-menu-interactions.test.d.ts.map +1 -0
- package/dist-types/components/menu/test/lion-menu.test.d.ts +2 -0
- package/dist-types/components/menu/test/lion-menu.test.d.ts.map +1 -0
- package/dist-types/components/menu/test-helpers/mimicKeyPress.d.ts +7 -0
- package/dist-types/components/menu/test-helpers/mimicKeyPress.d.ts.map +1 -0
- package/dist-types/components/menu/test-suites/InteractiveListMixin.suite.d.ts +11 -0
- package/dist-types/components/menu/test-suites/InteractiveListMixin.suite.d.ts.map +1 -0
- package/dist-types/components/menu/test-suites/LionMenu.suite.d.ts +9 -0
- package/dist-types/components/menu/test-suites/LionMenu.suite.d.ts.map +1 -0
- package/dist-types/components/menu/test-suites/LionMenuInteractions.suite.d.ts +5 -0
- package/dist-types/components/menu/test-suites/LionMenuInteractions.suite.d.ts.map +1 -0
- package/dist-types/components/menu/test-suites/MoreButtonMenuMixin.suite.d.ts +11 -0
- package/dist-types/components/menu/test-suites/MoreButtonMenuMixin.suite.d.ts.map +1 -0
- package/dist-types/components/menu/test-suites/MultiLevelListMixin.suite.d.ts +11 -0
- package/dist-types/components/menu/test-suites/MultiLevelListMixin.suite.d.ts.map +1 -0
- package/dist-types/components/menu/types/InteractiveListMixinTypes.d.ts +72 -0
- package/dist-types/components/menu/types/InteractiveListMixinTypes.d.ts.map +1 -0
- package/dist-types/components/menu/types/MoreButtonMenuMixinTypes.d.ts +30 -0
- package/dist-types/components/menu/types/MoreButtonMenuMixinTypes.d.ts.map +1 -0
- package/dist-types/components/menu/types/MultiLevelListMixinTypes.d.ts +16 -0
- package/dist-types/components/menu/types/MultiLevelListMixinTypes.d.ts.map +1 -0
- package/dist-types/components/menu/types/OverlayWithListInvokerMixinTypes.d.ts +35 -0
- package/dist-types/components/menu/types/OverlayWithListInvokerMixinTypes.d.ts.map +1 -0
- package/dist-types/components/overlays/src/OverlayController.d.ts +22 -5
- package/dist-types/components/overlays/src/OverlayController.d.ts.map +1 -1
- package/dist-types/components/overlays/src/OverlayMixin.d.ts.map +1 -1
- package/dist-types/components/overlays/src/OverlaysManager.d.ts.map +1 -1
- package/dist-types/components/overlays/src/overlayDocumentStyle.d.ts.map +1 -1
- package/dist-types/components/overlays/src/utils/is-equal-config.d.ts.map +1 -1
- package/dist-types/components/overlays/types/ArrowMixinTypes.d.ts.map +1 -1
- package/dist-types/components/overlays/types/OverlayConfig.d.ts +12 -2
- package/dist-types/components/overlays/types/OverlayConfig.d.ts.map +1 -1
- package/dist-types/components/overlays/types/OverlayMixinTypes.d.ts +1 -0
- package/dist-types/components/overlays/types/OverlayMixinTypes.d.ts.map +1 -1
- package/dist-types/components/select-rich/src/LionSelectInvoker.d.ts +3 -1
- package/dist-types/components/select-rich/src/LionSelectInvoker.d.ts.map +1 -1
- package/dist-types/components/select-rich/src/LionSelectRich.d.ts +13 -2
- 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-upgrade.test.d.ts +2 -0
- package/dist-types/components/select-rich/test/lion-select-rich-upgrade.test.d.ts.map +1 -0
- package/dist-types/components/tooltip/src/LionTooltip.d.ts +1 -1
- package/dist-types/exports/define/lion-item.d.ts +2 -0
- package/dist-types/exports/define/lion-item.d.ts.map +1 -0
- package/dist-types/exports/define/lion-menu.d.ts +2 -0
- package/dist-types/exports/define/lion-menu.d.ts.map +1 -0
- package/dist-types/exports/define/lion-menuitem.d.ts +2 -0
- package/dist-types/exports/define/lion-menuitem.d.ts.map +1 -0
- package/dist-types/exports/menu-test-suites.d.ts +4 -0
- package/dist-types/exports/menu-test-suites.d.ts.map +1 -0
- package/dist-types/exports/menu.d.ts +3 -0
- package/dist-types/exports/menu.d.ts.map +1 -0
- package/dist-types/exports/overlays.d.ts +6 -0
- package/dist-types/exports/overlays.d.ts.map +1 -1
- package/dist-types/tsconfig.tsbuildinfo +1 -1
- package/docs/components/accordion/overview.md +2 -2
- package/docs/components/accordion/reference.md +2 -2
- package/docs/components/accordion/use-cases.md +2 -2
- package/docs/components/button/examples.md +2 -2
- package/docs/components/button/extensions.md +2 -2
- package/docs/components/button/overview.md +2 -2
- package/docs/components/button/use-cases.md +2 -2
- package/docs/components/calendar/overview.md +2 -2
- package/docs/components/calendar/use-cases.md +2 -2
- package/docs/components/checkbox-group/overview.md +4 -4
- package/docs/components/checkbox-group/use-cases.md +2 -2
- package/docs/components/collapsible/examples.md +2 -2
- package/docs/components/collapsible/overview.md +3 -3
- package/docs/components/collapsible/use-cases.md +2 -2
- package/docs/components/combobox/api-table.md +53 -39
- package/docs/components/combobox/extensions.md +2 -2
- package/docs/components/combobox/overview.md +3 -3
- package/docs/components/combobox/use-cases.md +3 -3
- package/docs/components/dialog/api-table.md +32 -6
- package/docs/components/dialog/overview.md +3 -3
- package/docs/components/dialog/use-cases.md +2 -2
- package/docs/components/drawer/overview.md +2 -2
- package/docs/components/drawer/use-cases.md +2 -2
- package/docs/components/fieldset/overview.md +7 -7
- package/docs/components/fieldset/use-cases.md +2 -2
- package/docs/components/form/overview.md +5 -5
- package/docs/components/form/use-cases.md +4 -4
- package/docs/components/icon/overview.md +2 -2
- package/docs/components/icon/use-cases.md +3 -3
- package/docs/components/input/overview.md +3 -3
- package/docs/components/input/use-cases.md +2 -2
- package/docs/components/input-amount/api-table.md +9 -7
- package/docs/components/input-amount/overview.md +5 -5
- package/docs/components/input-amount/use-cases.md +17 -6
- package/docs/components/input-amount-dropdown/api-table.md +2 -0
- package/docs/components/input-amount-dropdown/use-cases.md +2 -2
- package/docs/components/input-date/overview.md +5 -5
- package/docs/components/input-date/use-cases.md +2 -2
- package/docs/components/input-datepicker/api-table.md +63 -45
- package/docs/components/input-datepicker/overview.md +7 -7
- package/docs/components/input-datepicker/use-cases.md +2 -2
- package/docs/components/input-email/overview.md +4 -4
- package/docs/components/input-email/use-cases.md +2 -2
- package/docs/components/input-file/overview.md +3 -3
- package/docs/components/input-file/use-cases.md +2 -2
- package/docs/components/input-iban/overview.md +4 -4
- package/docs/components/input-iban/use-cases.md +2 -2
- package/docs/components/input-range/overview.md +4 -4
- package/docs/components/input-range/use-cases.md +2 -2
- package/docs/components/input-stepper/overview.md +3 -3
- package/docs/components/input-stepper/use-cases.md +2 -2
- package/docs/components/input-tel/overview.md +3 -3
- package/docs/components/input-tel/use-cases.md +8 -8
- package/docs/components/input-tel-dropdown/extensions.md +2 -2
- package/docs/components/input-tel-dropdown/overview.md +3 -3
- package/docs/components/input-tel-dropdown/use-cases.md +2 -2
- package/docs/components/listbox/overview.md +2 -2
- package/docs/components/listbox/use-cases.md +3 -3
- package/docs/components/menu/api-table.md +44 -0
- package/docs/components/menu/applyMenuDemoStyles.js +173 -0
- package/docs/components/menu/extensions.md +262 -0
- package/docs/components/menu/index.md +13 -0
- package/docs/components/menu/migration.md +129 -0
- package/docs/components/menu/overview.md +448 -0
- package/docs/components/menu/src/DemoNavigationBar.js +441 -0
- package/docs/components/menu/src/DemoSpinButton.js +215 -0
- package/docs/components/menu/src/DemoToolbar.js +101 -0
- package/docs/components/menu/src/DemoTree.js +55 -0
- package/docs/components/menu/src/navigation-bar-types.js +41 -0
- package/docs/components/menu/use-cases.md +74 -0
- package/docs/components/pagination/overview.md +2 -2
- package/docs/components/pagination/use-cases.md +2 -2
- package/docs/components/progress-indicator/examples.md +2 -2
- package/docs/components/progress-indicator/overview.md +2 -2
- package/docs/components/radio-group/overview.md +5 -5
- package/docs/components/radio-group/use-cases.md +2 -2
- package/docs/components/select/overview.md +2 -2
- package/docs/components/select/use-cases.md +3 -3
- package/docs/components/select-rich/api-table.md +51 -33
- package/docs/components/select-rich/examples.md +2 -2
- package/docs/components/select-rich/overview.md +2 -2
- package/docs/components/select-rich/use-cases.md +4 -4
- package/docs/components/steps/overview.md +2 -2
- package/docs/components/steps/use-cases.md +2 -2
- package/docs/components/switch/overview.md +2 -2
- package/docs/components/switch/reference.md +2 -2
- package/docs/components/switch/use-cases.md +2 -2
- package/docs/components/tabs/examples.md +3 -3
- package/docs/components/tabs/overview.md +2 -2
- package/docs/components/tabs/use-cases.md +2 -2
- package/docs/components/textarea/overview.md +2 -2
- package/docs/components/textarea/use-cases.md +2 -2
- package/docs/components/tooltip/api-table.md +33 -7
- package/docs/components/tooltip/examples.md +2 -2
- package/docs/components/tooltip/overview.md +2 -2
- package/docs/components/tooltip/use-cases.md +2 -2
- package/docs/fundamentals/index.md +4 -4
- package/docs/fundamentals/node-tools/babel-plugin-extend-docs/index.md +2 -2
- package/docs/fundamentals/node-tools/babel-plugin-extend-docs/overview.md +2 -2
- package/docs/fundamentals/node-tools/providence-analytics/index.md +2 -2
- package/docs/fundamentals/node-tools/providence-analytics/overview.md +3 -3
- package/docs/fundamentals/node-tools/publish-docs/index.md +2 -2
- package/docs/fundamentals/node-tools/publish-docs/overview.md +5 -5
- package/docs/fundamentals/node-tools/remark-extend/index.md +2 -2
- package/docs/fundamentals/node-tools/remark-extend/overview.md +2 -2
- package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/index.md +2 -2
- package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +4 -4
- package/docs/fundamentals/rationales/TypeScript.md +62 -2
- package/docs/fundamentals/rationales/accessibility.md +5 -5
- package/docs/fundamentals/rationales/side-effects.md +2 -2
- package/docs/fundamentals/rationales/versioning.md +2 -2
- package/docs/fundamentals/systems/core/SlotMixin.md +3 -3
- package/docs/fundamentals/systems/core/index.md +2 -2
- package/docs/fundamentals/systems/core/overview.md +3 -3
- package/docs/fundamentals/systems/form/formatting-and-parsing.md +6 -6
- package/docs/fundamentals/systems/form/index.md +2 -2
- package/docs/fundamentals/systems/form/interaction-states.md +2 -2
- package/docs/fundamentals/systems/form/model-value.md +3 -3
- package/docs/fundamentals/systems/form/overview.md +30 -30
- package/docs/fundamentals/systems/form/styling.md +2 -2
- package/docs/fundamentals/systems/form/use-cases.md +2 -2
- package/docs/fundamentals/systems/form/validate.md +4 -4
- package/docs/fundamentals/systems/icon/index.md +2 -2
- package/docs/fundamentals/systems/icon/overview.md +2 -2
- package/docs/fundamentals/systems/localize/dates.md +2 -2
- package/docs/fundamentals/systems/localize/index.md +2 -2
- package/docs/fundamentals/systems/localize/numbers.md +2 -2
- package/docs/fundamentals/systems/localize/overview.md +6 -6
- package/docs/fundamentals/systems/localize/rationale.md +2 -2
- package/docs/fundamentals/systems/localize/text.md +2 -2
- package/docs/fundamentals/systems/localize/use-cases.md +2 -2
- package/docs/fundamentals/systems/overlays/_edge-cases.md +2 -2
- package/docs/fundamentals/systems/overlays/api-table.md +46 -43
- package/docs/fundamentals/systems/overlays/configuration.md +4 -4
- package/docs/fundamentals/systems/overlays/index.md +2 -2
- package/docs/fundamentals/systems/overlays/overview.md +7 -7
- package/docs/fundamentals/systems/overlays/rationale.md +2 -2
- package/docs/fundamentals/systems/overlays/use-cases.md +4 -4
- package/docs/fundamentals/tools/ajax/index.md +2 -2
- package/docs/fundamentals/tools/ajax/overview.md +2 -2
- package/docs/fundamentals/tools/ajax/use-cases.md +2 -2
- package/docs/fundamentals/tools/helpers/action-logger.md +2 -2
- package/docs/fundamentals/tools/helpers/index.md +2 -2
- package/docs/fundamentals/tools/helpers/overview.md +3 -3
- package/docs/fundamentals/tools/singleton-manager/example-complex/index.md +2 -2
- package/docs/fundamentals/tools/singleton-manager/example-fail/index.md +2 -2
- package/docs/fundamentals/tools/singleton-manager/example-success/index.md +2 -2
- package/docs/fundamentals/tools/singleton-manager/index.md +2 -2
- package/docs/fundamentals/tools/singleton-manager/overview.md +6 -6
- package/docs/guides/how-to/create-a-custom-field.md +7 -7
- package/docs/guides/how-to/create-a-form.md +6 -6
- package/docs/guides/how-to/extend-a-native-input.md +4 -4
- package/docs/guides/how-to/get-started.md +2 -2
- package/docs/guides/how-to/index.md +1 -1
- package/docs/guides/index.md +8 -8
- package/docs/guides/principles/definitions-and-terms.md +2 -2
- package/docs/guides/principles/index.md +5 -5
- package/docs/guides/principles/scoped-elements.md +2 -2
- package/docs/guides/principles/styling.md +3 -3
- package/docs/guides/principles/subclasser-apis.md +2 -2
- package/exports/define/lion-accordion.js +0 -1
- package/exports/define/lion-button-reset.js +0 -1
- package/exports/define/lion-button-submit.js +0 -1
- package/exports/define/lion-button.js +0 -1
- package/exports/define/lion-calendar.js +0 -1
- package/exports/define/lion-checkbox-group.js +0 -1
- package/exports/define/lion-checkbox-indeterminate.js +0 -1
- package/exports/define/lion-checkbox.js +0 -1
- package/exports/define/lion-collapsible.js +0 -1
- package/exports/define/lion-combobox.js +0 -1
- package/exports/define/lion-dialog.js +0 -1
- package/exports/define/lion-drawer.js +0 -1
- package/exports/define/lion-field.js +0 -1
- package/exports/define/lion-fieldset.js +0 -1
- package/exports/define/lion-form.js +0 -1
- package/exports/define/lion-icon.js +0 -1
- package/exports/define/lion-input-amount-dropdown.js +0 -1
- package/exports/define/lion-input-amount.js +0 -1
- package/exports/define/lion-input-date.js +0 -1
- package/exports/define/lion-input-datepicker.js +0 -1
- package/exports/define/lion-input-email.js +0 -1
- package/exports/define/lion-input-file.js +0 -1
- package/exports/define/lion-input-iban.js +0 -1
- package/exports/define/lion-input-range.js +0 -1
- package/exports/define/lion-input-stepper.js +0 -1
- package/exports/define/lion-input-tel-dropdown.js +0 -1
- package/exports/define/lion-input-tel.js +0 -1
- package/exports/define/lion-input.js +0 -1
- package/exports/define/lion-item.js +2 -0
- package/exports/define/lion-listbox.js +0 -1
- package/exports/define/lion-menu.js +2 -0
- package/exports/define/lion-menuitem.js +2 -0
- package/exports/define/lion-option.js +0 -1
- package/exports/define/lion-options.js +0 -1
- package/exports/define/lion-pagination.js +0 -1
- package/exports/define/lion-progress-indicator.js +0 -1
- package/exports/define/lion-radio-group.js +0 -1
- package/exports/define/lion-radio.js +0 -1
- package/exports/define/lion-select-invoker.js +0 -1
- package/exports/define/lion-select-rich.js +0 -1
- package/exports/define/lion-select.js +0 -1
- package/exports/define/lion-selected-file-list.js +0 -1
- package/exports/define/lion-step.js +0 -1
- package/exports/define/lion-steps.js +0 -1
- package/exports/define/lion-switch-button.js +0 -1
- package/exports/define/lion-switch.js +0 -1
- package/exports/define/lion-tabs.js +0 -1
- package/exports/define/lion-textarea.js +0 -1
- package/exports/define/lion-tooltip.js +0 -1
- package/exports/define/lion-validation-feedback.js +0 -1
- package/exports/define-helpers/sb-action-logger.js +0 -1
- package/exports/define-helpers/sb-locale-switcher.js +0 -1
- package/exports/form-core.js +0 -8
- package/exports/localize-no-side-effects.js +0 -1
- package/exports/localize.js +0 -2
- package/exports/menu-test-suites.js +4 -0
- package/exports/menu.js +3 -0
- package/exports/overlays.js +6 -4
- package/generated/awesome-phonenumber/LICENSE +22 -0
- package/generated/awesome-phonenumber/LICENSE.closure-library +176 -0
- package/generated/awesome-phonenumber/LICENSE.libphonenumber +176 -0
- package/generated/awesome-phonenumber/checksums.json +6 -0
- package/generated/awesome-phonenumber/index-esm.mjs +817 -0
- package/generated/awesome-phonenumber/index.d.ts +227 -0
- package/generated/awesome-phonenumber/index.js +45 -0
- package/generated/awesome-phonenumber/lib/index.js +710 -0
- package/generated/awesome-phonenumber/package.json +9 -0
- package/generated/awesome-phonenumber/provenance.json +13 -0
- package/menu-test-suites.js +4 -0
- package/menu.js +3 -0
- package/overlays.js +6 -0
- package/package.json +35 -6
- package/vscode.html-custom-data.json +76 -8
- package/web-types.json +202 -17
|
@@ -15,7 +15,6 @@ import { defineCE, expect, fixture, html, unsafeStatic, waitUntil } from '@open-
|
|
|
15
15
|
import { sendKeys } from '@web/test-runner-commands';
|
|
16
16
|
import { LitElement, nothing } from 'lit';
|
|
17
17
|
import sinon from 'sinon';
|
|
18
|
-
|
|
19
18
|
import { isActiveElement } from '../../core/test-helpers/isActiveElement.js';
|
|
20
19
|
|
|
21
20
|
/**
|
|
@@ -27,7 +26,8 @@ import { isActiveElement } from '../../core/test-helpers/isActiveElement.js';
|
|
|
27
26
|
* @param {{ autocomplete?:'none'|'list'|'both', matchMode?:'begin'|'all', disabled?: boolean, readonly?: boolean }} config
|
|
28
27
|
*/
|
|
29
28
|
async function fruitFixture({ autocomplete, matchMode, disabled, readonly } = {}) {
|
|
30
|
-
const el =
|
|
29
|
+
const el =
|
|
30
|
+
/** @type {LionCombobox} */
|
|
31
31
|
await fixture(html`
|
|
32
32
|
<lion-combobox label="Search" name="foo">
|
|
33
33
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -35,8 +35,7 @@ async function fruitFixture({ autocomplete, matchMode, disabled, readonly } = {}
|
|
|
35
35
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
36
36
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
37
37
|
</lion-combobox>
|
|
38
|
-
`)
|
|
39
|
-
);
|
|
38
|
+
`);
|
|
40
39
|
if (autocomplete) {
|
|
41
40
|
el.autocomplete = autocomplete;
|
|
42
41
|
}
|
|
@@ -52,7 +51,6 @@ async function fruitFixture({ autocomplete, matchMode, disabled, readonly } = {}
|
|
|
52
51
|
await el.updateComplete;
|
|
53
52
|
return [el, el.formElements];
|
|
54
53
|
}
|
|
55
|
-
|
|
56
54
|
describe('lion-combobox', () => {
|
|
57
55
|
describe('Rendering on API change', () => {
|
|
58
56
|
it('renders when options changed', async () => {
|
|
@@ -78,59 +76,54 @@ describe('lion-combobox', () => {
|
|
|
78
76
|
label: 'Pineapple',
|
|
79
77
|
},
|
|
80
78
|
];
|
|
81
|
-
|
|
82
79
|
class Wrapper extends LitElement {
|
|
83
80
|
static properties = {
|
|
84
81
|
...super.properties,
|
|
85
|
-
entries: {
|
|
82
|
+
entries: {
|
|
83
|
+
type: Array,
|
|
84
|
+
},
|
|
86
85
|
};
|
|
87
|
-
|
|
88
86
|
constructor() {
|
|
89
87
|
super();
|
|
90
88
|
this.entries = entries;
|
|
91
89
|
}
|
|
92
|
-
|
|
93
90
|
render() {
|
|
94
91
|
return html`<lion-combobox name="foo">
|
|
95
92
|
${this.entries.map(
|
|
96
|
-
entry => html`<lion-option .choiceValue="${entry.id}">${entry.label}</lion-option>`,
|
|
93
|
+
(entry) => html`<lion-option .choiceValue="${entry.id}">${entry.label}</lion-option>`,
|
|
97
94
|
)}
|
|
98
95
|
</lion-combobox>`;
|
|
99
96
|
}
|
|
100
97
|
}
|
|
101
|
-
|
|
102
98
|
const tagString = defineCE(Wrapper);
|
|
103
99
|
const tag = unsafeStatic(tagString);
|
|
104
|
-
const wrapperElement = /** @type {Wrapper} */
|
|
100
|
+
const wrapperElement = /** @type {Wrapper} */ await fixture(html`<${tag}></${tag}>`);
|
|
105
101
|
await waitUntil(
|
|
106
102
|
() =>
|
|
107
103
|
wrapperElement?.shadowRoot?.querySelector('lion-options')?.querySelectorAll('lion-option')
|
|
108
104
|
.length === entries.length,
|
|
109
105
|
);
|
|
110
|
-
|
|
111
106
|
wrapperElement.entries = [
|
|
112
107
|
{
|
|
113
108
|
id: '4',
|
|
114
109
|
label: 'Banana',
|
|
115
110
|
},
|
|
116
111
|
];
|
|
117
|
-
|
|
118
112
|
await waitUntil(
|
|
119
113
|
() =>
|
|
120
114
|
wrapperElement?.shadowRoot?.querySelector('lion-options')?.querySelectorAll('lion-option')
|
|
121
115
|
.length === wrapperElement.entries.length,
|
|
122
116
|
);
|
|
123
|
-
|
|
124
117
|
const optionElements = wrapperElement.shadowRoot?.querySelectorAll('lion-option');
|
|
125
118
|
expect(optionElements?.length).to.equal(wrapperElement.entries.length);
|
|
126
119
|
const optionElement = optionElements?.item(0);
|
|
127
120
|
expect(optionElement?.textContent).to.equal('Banana');
|
|
128
121
|
});
|
|
129
122
|
});
|
|
130
|
-
|
|
131
123
|
describe('Options visibility', () => {
|
|
132
124
|
it('hides options when text in input node is cleared after typing something by default', async () => {
|
|
133
|
-
const el =
|
|
125
|
+
const el =
|
|
126
|
+
/** @type {LionCombobox} */
|
|
134
127
|
await fixture(html`
|
|
135
128
|
<lion-combobox name="foo">
|
|
136
129
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -138,12 +131,9 @@ describe('lion-combobox', () => {
|
|
|
138
131
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
139
132
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
140
133
|
</lion-combobox>
|
|
141
|
-
`)
|
|
142
|
-
);
|
|
143
|
-
|
|
134
|
+
`);
|
|
144
135
|
const options = el.formElements;
|
|
145
|
-
const visibleOptions = () => options.filter(o => o.getAttribute('aria-hidden') !== 'true');
|
|
146
|
-
|
|
136
|
+
const visibleOptions = () => options.filter((o) => o.getAttribute('aria-hidden') !== 'true');
|
|
147
137
|
async function performChecks() {
|
|
148
138
|
await mimicUserTyping(el, 'c');
|
|
149
139
|
await el.updateComplete;
|
|
@@ -153,7 +143,6 @@ describe('lion-combobox', () => {
|
|
|
153
143
|
await el.updateComplete;
|
|
154
144
|
expect(visibleOptions().length).to.equal(0, `autocompleteMode is ${el.autocomplete}`);
|
|
155
145
|
}
|
|
156
|
-
|
|
157
146
|
el.autocomplete = 'none';
|
|
158
147
|
await performChecks();
|
|
159
148
|
el.autocomplete = 'list';
|
|
@@ -163,9 +152,9 @@ describe('lion-combobox', () => {
|
|
|
163
152
|
el.autocomplete = 'both';
|
|
164
153
|
await performChecks();
|
|
165
154
|
});
|
|
166
|
-
|
|
167
155
|
it('hides all options on reset()', async () => {
|
|
168
|
-
const el =
|
|
156
|
+
const el =
|
|
157
|
+
/** @type {LionCombobox} */
|
|
169
158
|
await fixture(html`
|
|
170
159
|
<lion-combobox name="foo">
|
|
171
160
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -173,12 +162,9 @@ describe('lion-combobox', () => {
|
|
|
173
162
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
174
163
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
175
164
|
</lion-combobox>
|
|
176
|
-
`)
|
|
177
|
-
);
|
|
178
|
-
|
|
165
|
+
`);
|
|
179
166
|
const options = el.formElements;
|
|
180
|
-
const visibleOptions = () => options.filter(o => o.style.display !== 'none');
|
|
181
|
-
|
|
167
|
+
const visibleOptions = () => options.filter((o) => o.style.display !== 'none');
|
|
182
168
|
await mimicUserTyping(el, 'cha');
|
|
183
169
|
await el.updateComplete;
|
|
184
170
|
expect(visibleOptions().length).to.equal(1);
|
|
@@ -186,9 +172,9 @@ describe('lion-combobox', () => {
|
|
|
186
172
|
await el.updateComplete;
|
|
187
173
|
expect(visibleOptions().length).to.equal(0);
|
|
188
174
|
});
|
|
189
|
-
|
|
190
175
|
it('shows all options on reset() when showAllOnEmpty is set to true and overlay was open', async () => {
|
|
191
|
-
const el =
|
|
176
|
+
const el =
|
|
177
|
+
/** @type {LionCombobox} */
|
|
192
178
|
await fixture(html`
|
|
193
179
|
<lion-combobox name="foo" show-all-on-empty>
|
|
194
180
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -196,24 +182,20 @@ describe('lion-combobox', () => {
|
|
|
196
182
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
197
183
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
198
184
|
</lion-combobox>
|
|
199
|
-
`)
|
|
200
|
-
);
|
|
201
|
-
|
|
185
|
+
`);
|
|
202
186
|
const options = el.formElements;
|
|
203
|
-
const visibleOptions = () => options.filter(o => o.getAttribute('aria-hidden') !== 'true');
|
|
204
|
-
|
|
187
|
+
const visibleOptions = () => options.filter((o) => o.getAttribute('aria-hidden') !== 'true');
|
|
205
188
|
await mimicUserTyping(el, 'cha');
|
|
206
189
|
await el.updateComplete;
|
|
207
190
|
expect(visibleOptions().length).to.equal(1);
|
|
208
191
|
expect(el.opened).to.be.true;
|
|
209
|
-
|
|
210
192
|
el.reset();
|
|
211
193
|
await el.updateComplete;
|
|
212
194
|
expect(visibleOptions().length).to.equal(4);
|
|
213
195
|
});
|
|
214
|
-
|
|
215
196
|
it('hides listbox on click/enter (when multiple-choice is false)', async () => {
|
|
216
|
-
const el =
|
|
197
|
+
const el =
|
|
198
|
+
/** @type {LionCombobox} */
|
|
217
199
|
await fixture(html`
|
|
218
200
|
<lion-combobox name="foo">
|
|
219
201
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -221,19 +203,15 @@ describe('lion-combobox', () => {
|
|
|
221
203
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
222
204
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
223
205
|
</lion-combobox>
|
|
224
|
-
`)
|
|
225
|
-
);
|
|
226
|
-
|
|
206
|
+
`);
|
|
227
207
|
const { _listboxNode } = getComboboxMembers(el);
|
|
228
|
-
|
|
229
208
|
async function open() {
|
|
230
209
|
await mimicUserTyping(el, 'ch');
|
|
231
210
|
return el.updateComplete;
|
|
232
211
|
}
|
|
233
|
-
|
|
234
212
|
await open();
|
|
235
213
|
expect(el.opened).to.be.true;
|
|
236
|
-
const visibleOptions = el.formElements.filter(o => o.style.display !== 'none');
|
|
214
|
+
const visibleOptions = el.formElements.filter((o) => o.style.display !== 'none');
|
|
237
215
|
visibleOptions[0].click();
|
|
238
216
|
expect(el.opened).to.be.false;
|
|
239
217
|
await open();
|
|
@@ -243,10 +221,10 @@ describe('lion-combobox', () => {
|
|
|
243
221
|
await el.updateComplete;
|
|
244
222
|
expect(el.opened).to.be.false;
|
|
245
223
|
});
|
|
246
|
-
|
|
247
224
|
describe('With ".showAllOnEmpty"', () => {
|
|
248
225
|
it('keeps showing options when text in input node is cleared after typing something', async () => {
|
|
249
|
-
const el =
|
|
226
|
+
const el =
|
|
227
|
+
/** @type {LionCombobox} */
|
|
250
228
|
await fixture(html`
|
|
251
229
|
<lion-combobox name="foo" autocomplete="list" show-all-on-empty>
|
|
252
230
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -254,12 +232,10 @@ describe('lion-combobox', () => {
|
|
|
254
232
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
255
233
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
256
234
|
</lion-combobox>
|
|
257
|
-
`)
|
|
258
|
-
);
|
|
259
|
-
|
|
235
|
+
`);
|
|
260
236
|
const options = el.formElements;
|
|
261
|
-
const visibleOptions = () =>
|
|
262
|
-
|
|
237
|
+
const visibleOptions = () =>
|
|
238
|
+
options.filter((o) => o.getAttribute('aria-hidden') !== 'true');
|
|
263
239
|
async function performChecks() {
|
|
264
240
|
await mimicUserTyping(el, 'c');
|
|
265
241
|
await el.updateComplete;
|
|
@@ -268,7 +244,6 @@ describe('lion-combobox', () => {
|
|
|
268
244
|
await el.updateComplete;
|
|
269
245
|
expect(visibleOptions().length).to.equal(options.length);
|
|
270
246
|
}
|
|
271
|
-
|
|
272
247
|
el.autocomplete = 'none';
|
|
273
248
|
await performChecks();
|
|
274
249
|
el.autocomplete = 'list';
|
|
@@ -278,9 +253,9 @@ describe('lion-combobox', () => {
|
|
|
278
253
|
el.autocomplete = 'both';
|
|
279
254
|
await performChecks();
|
|
280
255
|
});
|
|
281
|
-
|
|
282
256
|
it('shows overlay on click', async () => {
|
|
283
|
-
const el =
|
|
257
|
+
const el =
|
|
258
|
+
/** @type {LionCombobox} */
|
|
284
259
|
await fixture(html`
|
|
285
260
|
<lion-combobox name="foo" .showAllOnEmpty="${true}">
|
|
286
261
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -288,18 +263,21 @@ describe('lion-combobox', () => {
|
|
|
288
263
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
289
264
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
290
265
|
</lion-combobox>
|
|
291
|
-
`)
|
|
292
|
-
);
|
|
266
|
+
`);
|
|
293
267
|
const { _inputNode } = getComboboxMembers(el);
|
|
294
|
-
|
|
295
268
|
expect(el.opened).to.be.false;
|
|
296
|
-
_inputNode.dispatchEvent(
|
|
269
|
+
_inputNode.dispatchEvent(
|
|
270
|
+
new Event('click', {
|
|
271
|
+
bubbles: true,
|
|
272
|
+
composed: true,
|
|
273
|
+
}),
|
|
274
|
+
);
|
|
297
275
|
await el.updateComplete;
|
|
298
276
|
expect(el.opened).to.be.true;
|
|
299
277
|
});
|
|
300
|
-
|
|
301
278
|
it('hides overlay on [Escape] after being opened', async () => {
|
|
302
|
-
const el =
|
|
279
|
+
const el =
|
|
280
|
+
/** @type {LionCombobox} */
|
|
303
281
|
await fixture(html`
|
|
304
282
|
<lion-combobox name="foo" .showAllOnEmpty="${true}" opened>
|
|
305
283
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -307,19 +285,20 @@ describe('lion-combobox', () => {
|
|
|
307
285
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
308
286
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
309
287
|
</lion-combobox>
|
|
310
|
-
`)
|
|
311
|
-
);
|
|
288
|
+
`);
|
|
312
289
|
await el.updateComplete;
|
|
313
|
-
|
|
314
290
|
const { _inputNode } = getComboboxMembers(el);
|
|
315
|
-
|
|
316
|
-
|
|
291
|
+
_inputNode.dispatchEvent(
|
|
292
|
+
new KeyboardEvent('keyup', {
|
|
293
|
+
key: 'Escape',
|
|
294
|
+
}),
|
|
295
|
+
);
|
|
317
296
|
await el.updateComplete;
|
|
318
297
|
expect(el.opened).to.be.false;
|
|
319
298
|
});
|
|
320
|
-
|
|
321
299
|
it('hides listbox on click/enter (when multiple-choice is false)', async () => {
|
|
322
|
-
const el =
|
|
300
|
+
const el =
|
|
301
|
+
/** @type {LionCombobox} */
|
|
323
302
|
await fixture(html`
|
|
324
303
|
<lion-combobox name="foo" .showAllOnEmpty="${true}">
|
|
325
304
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -327,11 +306,8 @@ describe('lion-combobox', () => {
|
|
|
327
306
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
328
307
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
329
308
|
</lion-combobox>
|
|
330
|
-
`)
|
|
331
|
-
);
|
|
332
|
-
|
|
309
|
+
`);
|
|
333
310
|
const { _listboxNode, _inputNode } = getComboboxMembers(el);
|
|
334
|
-
|
|
335
311
|
async function open() {
|
|
336
312
|
await mimicUserTyping(el, 'ch');
|
|
337
313
|
return el.updateComplete;
|
|
@@ -345,75 +321,66 @@ describe('lion-combobox', () => {
|
|
|
345
321
|
if (isSafari) {
|
|
346
322
|
return;
|
|
347
323
|
}
|
|
348
|
-
|
|
349
324
|
await open();
|
|
350
325
|
expect(el.opened).to.be.true;
|
|
351
|
-
const visibleOptions = el.formElements.filter(o => o.style.display !== 'none');
|
|
326
|
+
const visibleOptions = el.formElements.filter((o) => o.style.display !== 'none');
|
|
352
327
|
visibleOptions[0].click();
|
|
353
328
|
await el.updateComplete;
|
|
354
329
|
expect(el.opened).to.be.false;
|
|
355
|
-
|
|
356
330
|
_inputNode.value = '';
|
|
357
331
|
_inputNode.blur();
|
|
358
332
|
await open();
|
|
359
333
|
await el.updateComplete;
|
|
360
|
-
|
|
361
334
|
el.activeIndex = el.formElements.indexOf(visibleOptions[0]);
|
|
362
335
|
mimicKeyPress(_listboxNode, 'Enter');
|
|
363
336
|
expect(el.opened).to.be.false;
|
|
364
337
|
});
|
|
365
338
|
});
|
|
366
339
|
});
|
|
367
|
-
|
|
368
340
|
describe('Structure', () => {
|
|
369
341
|
it('has a listbox node', async () => {
|
|
370
|
-
const el =
|
|
342
|
+
const el =
|
|
343
|
+
/** @type {LionCombobox} */
|
|
371
344
|
await fixture(html`
|
|
372
345
|
<lion-combobox name="foo">
|
|
373
346
|
<lion-option .choiceValue="${'10'}" checked>Item 1</lion-option>
|
|
374
347
|
<lion-option .choiceValue="${'20'}">Item 2</lion-option>
|
|
375
348
|
</lion-combobox>
|
|
376
|
-
`)
|
|
377
|
-
);
|
|
349
|
+
`);
|
|
378
350
|
const { _listboxNode } = getComboboxMembers(el);
|
|
379
|
-
|
|
380
351
|
expect(_listboxNode).to.exist;
|
|
381
352
|
// TODO: worked before, find out what has changed in ScopedElements
|
|
382
353
|
// expect(_listboxNode instanceof LionOptions).to.be.true;
|
|
383
354
|
expect(el.querySelector('[role=listbox]')).to.equal(_listboxNode);
|
|
384
355
|
});
|
|
385
|
-
|
|
386
356
|
it('has a textbox element', async () => {
|
|
387
|
-
const el =
|
|
357
|
+
const el =
|
|
358
|
+
/** @type {LionCombobox} */
|
|
388
359
|
await fixture(html`
|
|
389
360
|
<lion-combobox name="foo">
|
|
390
361
|
<lion-option .choiceValue="${'10'}" checked>Item 1</lion-option>
|
|
391
362
|
<lion-option .choiceValue="${'20'}">Item 2</lion-option>
|
|
392
363
|
</lion-combobox>
|
|
393
|
-
`)
|
|
394
|
-
);
|
|
364
|
+
`);
|
|
395
365
|
const { _comboboxNode } = getComboboxMembers(el);
|
|
396
|
-
|
|
397
366
|
expect(_comboboxNode).to.exist;
|
|
398
367
|
expect(el.querySelector('[role=combobox]')).to.equal(_comboboxNode);
|
|
399
368
|
});
|
|
400
|
-
|
|
401
369
|
it('has validator "MatchesOption" applied by default', async () => {
|
|
402
|
-
const el =
|
|
370
|
+
const el =
|
|
371
|
+
/** @type {LionCombobox} */
|
|
403
372
|
await fixture(html`
|
|
404
373
|
<lion-combobox name="foo">
|
|
405
374
|
<lion-option .choiceValue="${'10'}" checked>Item 1</lion-option>
|
|
406
375
|
<lion-option .choiceValue="${'20'}">Item 2</lion-option>
|
|
407
376
|
</lion-combobox>
|
|
408
|
-
`)
|
|
409
|
-
);
|
|
377
|
+
`);
|
|
410
378
|
await mimicUserTyping(el, '30');
|
|
411
379
|
await el.updateComplete;
|
|
412
380
|
expect(el.hasFeedbackFor).to.include('error');
|
|
413
381
|
expect(el.validationStates).to.have.property('error');
|
|
414
382
|
expect(el.validationStates.error).to.have.property('MatchesOption');
|
|
415
383
|
});
|
|
416
|
-
|
|
417
384
|
it('keeps slottable provided in `slots` getter as direct host child', async () => {
|
|
418
385
|
class MyEl extends SlotMixin(LionCombobox) {
|
|
419
386
|
// @ts-ignore
|
|
@@ -428,7 +395,6 @@ describe('lion-combobox', () => {
|
|
|
428
395
|
}),
|
|
429
396
|
};
|
|
430
397
|
}
|
|
431
|
-
|
|
432
398
|
_labelTemplate() {
|
|
433
399
|
return html`
|
|
434
400
|
<div class="form-field__label">
|
|
@@ -438,7 +404,6 @@ describe('lion-combobox', () => {
|
|
|
438
404
|
</div>
|
|
439
405
|
`;
|
|
440
406
|
}
|
|
441
|
-
|
|
442
407
|
constructor() {
|
|
443
408
|
super();
|
|
444
409
|
this.renderSlot = false;
|
|
@@ -446,44 +411,39 @@ describe('lion-combobox', () => {
|
|
|
446
411
|
}
|
|
447
412
|
const tagName = defineCE(MyEl);
|
|
448
413
|
const wrappingTag = unsafeStatic(tagName);
|
|
449
|
-
|
|
450
|
-
|
|
414
|
+
const el =
|
|
415
|
+
/** @type {MyEl} */
|
|
451
416
|
await fixture(html`
|
|
452
417
|
<${wrappingTag} label="my label">
|
|
453
418
|
<lion-option .choiceValue="${'1'}">${'one'}</lion-option>
|
|
454
419
|
</${wrappingTag}>
|
|
455
|
-
`)
|
|
456
|
-
);
|
|
420
|
+
`);
|
|
457
421
|
await el.registrationComplete;
|
|
458
|
-
|
|
459
422
|
el.renderSlot = true;
|
|
460
423
|
await el.updateComplete;
|
|
461
424
|
const lazyRenderedSlot = el.querySelector('#lazyRenderedSlotId');
|
|
462
425
|
expect(lazyRenderedSlot?.parentElement === el).to.be.true;
|
|
463
426
|
});
|
|
464
427
|
});
|
|
465
|
-
|
|
466
428
|
describe('Values', () => {
|
|
467
429
|
it('syncs modelValue with textbox', async () => {
|
|
468
|
-
const el =
|
|
430
|
+
const el =
|
|
431
|
+
/** @type {LionCombobox} */
|
|
469
432
|
await fixture(html`
|
|
470
433
|
<lion-combobox name="foo" .modelValue="${'10'}">
|
|
471
434
|
<lion-option .choiceValue="${'10'}" checked>Item 1</lion-option>
|
|
472
435
|
<lion-option .choiceValue="${'20'}">Item 2</lion-option>
|
|
473
436
|
</lion-combobox>
|
|
474
|
-
`)
|
|
475
|
-
);
|
|
437
|
+
`);
|
|
476
438
|
const { _inputNode } = getComboboxMembers(el);
|
|
477
|
-
|
|
478
439
|
expect(_inputNode.value).to.equal('10');
|
|
479
|
-
|
|
480
440
|
el.modelValue = '20';
|
|
481
441
|
await el.updateComplete;
|
|
482
442
|
expect(_inputNode.value).to.equal('20');
|
|
483
443
|
});
|
|
484
|
-
|
|
485
444
|
it('sets modelValue to Unparseable if no option is selected', async () => {
|
|
486
|
-
const el =
|
|
445
|
+
const el =
|
|
446
|
+
/** @type {LionCombobox} */
|
|
487
447
|
await fixture(html`
|
|
488
448
|
<lion-combobox name="foo" .modelValue="${'Artichoke'}">
|
|
489
449
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -491,10 +451,8 @@ describe('lion-combobox', () => {
|
|
|
491
451
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
492
452
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
493
453
|
</lion-combobox>
|
|
494
|
-
`)
|
|
495
|
-
);
|
|
454
|
+
`);
|
|
496
455
|
const { _inputNode } = getComboboxMembers(el);
|
|
497
|
-
|
|
498
456
|
expect(el.modelValue).to.equal('Artichoke');
|
|
499
457
|
expect(el.formElements[0].checked).to.be.true;
|
|
500
458
|
el.setCheckedIndex(-1);
|
|
@@ -503,7 +461,6 @@ describe('lion-combobox', () => {
|
|
|
503
461
|
expect(el.modelValue instanceof Unparseable).to.be.true;
|
|
504
462
|
expect(el.modelValue.viewValue).to.equal('Artichoke');
|
|
505
463
|
expect(el.formElements[0].checked).to.be.false;
|
|
506
|
-
|
|
507
464
|
el.setCheckedIndex(-1);
|
|
508
465
|
_inputNode.value = 'Foo';
|
|
509
466
|
el.__shouldAutocompleteNextUpdate = true;
|
|
@@ -511,7 +468,6 @@ describe('lion-combobox', () => {
|
|
|
511
468
|
expect(el.modelValue instanceof Unparseable).to.be.true;
|
|
512
469
|
expect(el.modelValue.viewValue).to.equal('Foo');
|
|
513
470
|
expect(el.formElements[0].checked).to.be.false;
|
|
514
|
-
|
|
515
471
|
el.setCheckedIndex(0);
|
|
516
472
|
el.__shouldAutocompleteNextUpdate = true;
|
|
517
473
|
await el.updateComplete;
|
|
@@ -519,9 +475,9 @@ describe('lion-combobox', () => {
|
|
|
519
475
|
expect(el.modelValue).to.equal('Artichoke');
|
|
520
476
|
expect(el.formElements[0].checked).to.be.true;
|
|
521
477
|
});
|
|
522
|
-
|
|
523
478
|
it('sets modelValue to _inputNode.value if no option is selected when requireOptionMatch is false', async () => {
|
|
524
|
-
const el =
|
|
479
|
+
const el =
|
|
480
|
+
/** @type {LionCombobox} */
|
|
525
481
|
await fixture(html`
|
|
526
482
|
<lion-combobox name="foo" .modelValue="${'Artichoke'}" .requireOptionMatch="${false}">
|
|
527
483
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -529,10 +485,8 @@ describe('lion-combobox', () => {
|
|
|
529
485
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
530
486
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
531
487
|
</lion-combobox>
|
|
532
|
-
`)
|
|
533
|
-
);
|
|
488
|
+
`);
|
|
534
489
|
const { _inputNode } = getComboboxMembers(el);
|
|
535
|
-
|
|
536
490
|
expect(el.modelValue).to.equal('Artichoke');
|
|
537
491
|
expect(el.formElements[0].checked).to.be.true;
|
|
538
492
|
el.setCheckedIndex(-1);
|
|
@@ -540,7 +494,6 @@ describe('lion-combobox', () => {
|
|
|
540
494
|
await el.updateComplete;
|
|
541
495
|
expect(el.modelValue).to.equal('Artichoke');
|
|
542
496
|
expect(el.formElements[0].checked).to.be.true;
|
|
543
|
-
|
|
544
497
|
el.setCheckedIndex(-1);
|
|
545
498
|
_inputNode.value = 'Foo';
|
|
546
499
|
el.__shouldAutocompleteNextUpdate = true;
|
|
@@ -548,9 +501,9 @@ describe('lion-combobox', () => {
|
|
|
548
501
|
expect(el.modelValue).to.equal('Foo');
|
|
549
502
|
expect(el.formElements[0].checked).to.be.false;
|
|
550
503
|
});
|
|
551
|
-
|
|
552
504
|
it('sets modelValue to empty array if no option is selected for multiple choice', async () => {
|
|
553
|
-
const el =
|
|
505
|
+
const el =
|
|
506
|
+
/** @type {LionCombobox} */
|
|
554
507
|
await fixture(html`
|
|
555
508
|
<lion-combobox name="foo" multiple-choice .modelValue="${['Artichoke']}">
|
|
556
509
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -558,8 +511,7 @@ describe('lion-combobox', () => {
|
|
|
558
511
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
559
512
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
560
513
|
</lion-combobox>
|
|
561
|
-
`)
|
|
562
|
-
);
|
|
514
|
+
`);
|
|
563
515
|
expect(el.modelValue).to.deep.equal(['Artichoke']);
|
|
564
516
|
expect(el.formElements[0].checked).to.be.true;
|
|
565
517
|
el.setCheckedIndex([]);
|
|
@@ -567,9 +519,9 @@ describe('lion-combobox', () => {
|
|
|
567
519
|
expect(el.modelValue).to.deep.equal([]);
|
|
568
520
|
expect(el.formElements[0].checked).to.be.false;
|
|
569
521
|
});
|
|
570
|
-
|
|
571
522
|
it('clears modelValue and textbox value on clear()', async () => {
|
|
572
|
-
const el =
|
|
523
|
+
const el =
|
|
524
|
+
/** @type {LionCombobox} */
|
|
573
525
|
await fixture(html`
|
|
574
526
|
<lion-combobox name="foo" .modelValue="${'Artichoke'}">
|
|
575
527
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -577,16 +529,13 @@ describe('lion-combobox', () => {
|
|
|
577
529
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
578
530
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
579
531
|
</lion-combobox>
|
|
580
|
-
`)
|
|
581
|
-
);
|
|
582
|
-
|
|
532
|
+
`);
|
|
583
533
|
const { _inputNode } = getComboboxMembers(el);
|
|
584
|
-
|
|
585
534
|
el.clear();
|
|
586
535
|
expect(el.modelValue).to.equal('');
|
|
587
536
|
expect(_inputNode.value).to.equal('');
|
|
588
|
-
|
|
589
|
-
|
|
537
|
+
const el2 =
|
|
538
|
+
/** @type {LionCombobox} */
|
|
590
539
|
await fixture(html`
|
|
591
540
|
<lion-combobox name="foo" multiple-choice .modelValue="${['Artichoke']}">
|
|
592
541
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -594,43 +543,36 @@ describe('lion-combobox', () => {
|
|
|
594
543
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
595
544
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
596
545
|
</lion-combobox>
|
|
597
|
-
`)
|
|
598
|
-
);
|
|
599
|
-
|
|
546
|
+
`);
|
|
600
547
|
el2.clear();
|
|
601
548
|
expect(el2.modelValue).to.eql([]);
|
|
602
549
|
// @ts-ignore [allow-protected] in test
|
|
603
550
|
expect(el2._inputNode.value).to.equal('');
|
|
604
551
|
});
|
|
605
|
-
|
|
606
552
|
it('correctly emits event with an empty value when clear() is called', async () => {
|
|
607
|
-
const el =
|
|
553
|
+
const el =
|
|
554
|
+
/** @type {LionCombobox} */
|
|
608
555
|
await fixture(
|
|
609
556
|
html`<lion-combobox>
|
|
610
557
|
<lion-option .choiceValue=${'red'}>Red</lion-option>
|
|
611
558
|
<lion-option .choiceValue=${'green'}>Green</lion-option>
|
|
612
559
|
<lion-option .choiceValue=${'blue'}>Blue</lion-option>
|
|
613
560
|
</lion-combobox>`,
|
|
614
|
-
)
|
|
615
|
-
);
|
|
616
|
-
|
|
561
|
+
);
|
|
617
562
|
el.modelValue = 'red';
|
|
618
563
|
await el.updateComplete;
|
|
619
|
-
|
|
620
564
|
el.addEventListener('model-value-changed', ({ target }) => {
|
|
621
565
|
expect(target).to.not.be.null;
|
|
622
|
-
|
|
623
|
-
const { modelValue, value } = /** @type {LionCombobox} */ (target);
|
|
566
|
+
const { modelValue, value } = /** @type {LionCombobox} */ target;
|
|
624
567
|
expect(value).to.equal('');
|
|
625
568
|
expect(modelValue).to.equal('');
|
|
626
569
|
});
|
|
627
|
-
|
|
628
570
|
el.clear();
|
|
629
571
|
await el.updateComplete;
|
|
630
572
|
});
|
|
631
|
-
|
|
632
573
|
it('updates option list after clear()', async () => {
|
|
633
|
-
const el =
|
|
574
|
+
const el =
|
|
575
|
+
/** @type {LionCombobox} */
|
|
634
576
|
await fixture(html`
|
|
635
577
|
<lion-combobox name="foo" multiple-choice>
|
|
636
578
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -638,22 +580,19 @@ describe('lion-combobox', () => {
|
|
|
638
580
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
639
581
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
640
582
|
</lion-combobox>
|
|
641
|
-
`)
|
|
642
|
-
);
|
|
583
|
+
`);
|
|
643
584
|
const options = el.formElements;
|
|
644
585
|
await mimicUserTyping(el, 'a');
|
|
645
586
|
await el.updateComplete;
|
|
646
|
-
|
|
647
|
-
const visibleOptions = () => options.filter(o => o.style.display !== 'none');
|
|
587
|
+
const visibleOptions = () => options.filter((o) => o.style.display !== 'none');
|
|
648
588
|
expect(visibleOptions().length).to.equal(3, 'after input');
|
|
649
|
-
|
|
650
589
|
el.clear();
|
|
651
590
|
await el.updateComplete;
|
|
652
591
|
expect(visibleOptions().length).to.equal(0, 'after clear');
|
|
653
592
|
});
|
|
654
|
-
|
|
655
593
|
it('keeps interaction states on clear()', async () => {
|
|
656
|
-
const el =
|
|
594
|
+
const el =
|
|
595
|
+
/** @type {LionCombobox} */
|
|
657
596
|
await fixture(html`
|
|
658
597
|
<lion-combobox name="foo">
|
|
659
598
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -661,19 +600,17 @@ describe('lion-combobox', () => {
|
|
|
661
600
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
662
601
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
663
602
|
</lion-combobox>
|
|
664
|
-
`)
|
|
665
|
-
);
|
|
603
|
+
`);
|
|
666
604
|
await mimicUserTyping(el, 'a');
|
|
667
605
|
await el.updateComplete;
|
|
668
606
|
expect(el.dirty).to.equal(true);
|
|
669
|
-
|
|
670
607
|
el.clear();
|
|
671
608
|
await el.updateComplete;
|
|
672
609
|
expect(el.dirty).to.equal(true);
|
|
673
610
|
});
|
|
674
|
-
|
|
675
611
|
it('resets modelValue and textbox value on reset()', async () => {
|
|
676
|
-
const el =
|
|
612
|
+
const el =
|
|
613
|
+
/** @type {LionCombobox} */
|
|
677
614
|
await fixture(html`
|
|
678
615
|
<lion-combobox name="foo" .modelValue="${'Artichoke'}">
|
|
679
616
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -681,16 +618,14 @@ describe('lion-combobox', () => {
|
|
|
681
618
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
682
619
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
683
620
|
</lion-combobox>
|
|
684
|
-
`)
|
|
685
|
-
);
|
|
686
|
-
|
|
621
|
+
`);
|
|
687
622
|
const { _inputNode } = getComboboxMembers(el);
|
|
688
623
|
el.modelValue = 'Chard';
|
|
689
624
|
el.reset();
|
|
690
625
|
expect(el.modelValue).to.equal('Artichoke');
|
|
691
626
|
expect(_inputNode.value).to.equal('Artichoke');
|
|
692
|
-
|
|
693
|
-
|
|
627
|
+
const el2 =
|
|
628
|
+
/** @type {LionCombobox} */
|
|
694
629
|
await fixture(html`
|
|
695
630
|
<lion-combobox name="foo" multiple-choice .modelValue="${['Artichoke']}">
|
|
696
631
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -698,40 +633,37 @@ describe('lion-combobox', () => {
|
|
|
698
633
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
699
634
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
700
635
|
</lion-combobox>
|
|
701
|
-
`)
|
|
702
|
-
);
|
|
636
|
+
`);
|
|
703
637
|
el2.modelValue = ['Artichoke', 'Chard'];
|
|
704
638
|
el2.reset();
|
|
705
639
|
expect(el2.modelValue).to.deep.equal(['Artichoke']);
|
|
706
640
|
// @ts-ignore [allow-protected] in test
|
|
707
641
|
expect(el2._inputNode.value).to.equal('');
|
|
708
642
|
});
|
|
709
|
-
|
|
710
643
|
it('syncs textbox to modelValue', async () => {
|
|
711
644
|
for (const autocompleteMode of ['none', 'list', 'inline', 'both']) {
|
|
712
|
-
const el =
|
|
645
|
+
const el =
|
|
646
|
+
/** @type {LionCombobox} */
|
|
713
647
|
await fixture(html`
|
|
714
648
|
<lion-combobox name="foo" show-all-on-empty .autocomplete="${autocompleteMode}">
|
|
715
649
|
<lion-option .choiceValue="${'Aa'}" checked>Aa</lion-option>
|
|
716
650
|
<lion-option .choiceValue="${'Bb'}">Bb</lion-option>
|
|
717
651
|
</lion-combobox>
|
|
718
|
-
`)
|
|
719
|
-
);
|
|
652
|
+
`);
|
|
720
653
|
const { _inputNode } = getComboboxMembers(el);
|
|
721
|
-
|
|
722
654
|
expect(_inputNode.value).to.equal('Aa', `autocompleteMode is ${autocompleteMode}`);
|
|
723
|
-
|
|
724
655
|
el.formElements[0].click();
|
|
725
656
|
await el.updateComplete;
|
|
726
|
-
|
|
727
657
|
expect(_inputNode.value).to.equal('Aa', `autocompleteMode is ${autocompleteMode}`);
|
|
728
658
|
expect(el.checkedIndex).to.equal(0, `autocompleteMode is ${autocompleteMode}`);
|
|
729
|
-
|
|
730
659
|
await mimicUserTyping(el, 'B');
|
|
731
660
|
await el.updateComplete;
|
|
732
661
|
if (autocompleteMode === 'none' || autocompleteMode === 'list') {
|
|
733
662
|
expect(el.modelValue).to.deep.equal(
|
|
734
|
-
{
|
|
663
|
+
{
|
|
664
|
+
type: 'unparseable',
|
|
665
|
+
viewValue: 'B',
|
|
666
|
+
},
|
|
735
667
|
`autocompleteMode is ${autocompleteMode}`,
|
|
736
668
|
);
|
|
737
669
|
await el.updateComplete;
|
|
@@ -742,9 +674,9 @@ describe('lion-combobox', () => {
|
|
|
742
674
|
}
|
|
743
675
|
}
|
|
744
676
|
});
|
|
745
|
-
|
|
746
677
|
it('works with Required validator', async () => {
|
|
747
|
-
const el =
|
|
678
|
+
const el =
|
|
679
|
+
/** @type {LionCombobox} */
|
|
748
680
|
await fixture(html`
|
|
749
681
|
<lion-combobox name="foo" .validators=${[new Required()]}>
|
|
750
682
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -752,17 +684,16 @@ describe('lion-combobox', () => {
|
|
|
752
684
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
753
685
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
754
686
|
</lion-combobox>
|
|
755
|
-
`)
|
|
756
|
-
);
|
|
687
|
+
`);
|
|
757
688
|
el.submitted = true;
|
|
758
689
|
await el.feedbackComplete;
|
|
759
690
|
expect(el.hasFeedbackFor).to.include('error', 'hasFeedbackFor');
|
|
760
691
|
await el.feedbackComplete;
|
|
761
692
|
expect(el.showsFeedbackFor).to.include('error', 'showsFeedbackFor');
|
|
762
693
|
});
|
|
763
|
-
|
|
764
694
|
it('ignores empty string modelValue inputs', async () => {
|
|
765
|
-
const el =
|
|
695
|
+
const el =
|
|
696
|
+
/** @type {LionCombobox} */
|
|
766
697
|
await fixture(html`
|
|
767
698
|
<lion-combobox name="foo" multiple-choice autocomplete="none">
|
|
768
699
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -770,26 +701,22 @@ describe('lion-combobox', () => {
|
|
|
770
701
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
771
702
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
772
703
|
</lion-combobox>
|
|
773
|
-
`)
|
|
774
|
-
);
|
|
775
|
-
|
|
704
|
+
`);
|
|
776
705
|
el.requireOptionMatch = false;
|
|
777
706
|
await el.updateComplete;
|
|
778
707
|
const { _inputNode } = getComboboxMembers(el);
|
|
779
|
-
|
|
780
708
|
mimicKeyPress(_inputNode, 'Enter');
|
|
781
709
|
await el.updateComplete;
|
|
782
710
|
expect(el.modelValue).to.eql([]);
|
|
783
|
-
|
|
784
711
|
await mimicUserTyping(el, ' ');
|
|
785
712
|
await el.updateComplete;
|
|
786
713
|
mimicKeyPress(_inputNode, 'Enter');
|
|
787
714
|
await el.updateComplete;
|
|
788
715
|
expect(el.modelValue).to.eql([]);
|
|
789
716
|
});
|
|
790
|
-
|
|
791
717
|
it('allows a value outside of the option list when requireOptionMatch is false', async () => {
|
|
792
|
-
const el =
|
|
718
|
+
const el =
|
|
719
|
+
/** @type {LionCombobox} */
|
|
793
720
|
await fixture(html`
|
|
794
721
|
<lion-combobox name="foo" .validators=${[new Required()]}>
|
|
795
722
|
<lion-option checked .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -797,23 +724,20 @@ describe('lion-combobox', () => {
|
|
|
797
724
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
798
725
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
799
726
|
</lion-combobox>
|
|
800
|
-
`)
|
|
801
|
-
);
|
|
727
|
+
`);
|
|
802
728
|
el.requireOptionMatch = false;
|
|
803
729
|
const { _inputNode } = getComboboxMembers(el);
|
|
804
730
|
expect(el.checkedIndex).to.equal(0);
|
|
805
|
-
|
|
806
731
|
await mimicUserTyping(el, 'Foo');
|
|
807
732
|
_inputNode.dispatchEvent(new Event('input'));
|
|
808
733
|
await el.updateComplete;
|
|
809
|
-
|
|
810
734
|
expect(el.checkedIndex).to.equal(-1);
|
|
811
735
|
expect(el.modelValue).to.equal('Foo');
|
|
812
736
|
expect(_inputNode.value).to.equal('Foo');
|
|
813
737
|
});
|
|
814
|
-
|
|
815
738
|
it('fires "model-value-changed" on every textbox change when requireOptionMatch is false and autocomplete is both', async () => {
|
|
816
|
-
const el =
|
|
739
|
+
const el =
|
|
740
|
+
/** @type {LionCombobox} */
|
|
817
741
|
await fixture(html`
|
|
818
742
|
<lion-combobox name="foo" autocomplete="both" .requireOptionMatch="${false}">
|
|
819
743
|
<lion-option checked .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -821,12 +745,9 @@ describe('lion-combobox', () => {
|
|
|
821
745
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
822
746
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
823
747
|
</lion-combobox>
|
|
824
|
-
`)
|
|
825
|
-
);
|
|
826
|
-
|
|
827
|
-
const fake = sinon.fake(ev => ev.target.modelValue);
|
|
748
|
+
`);
|
|
749
|
+
const fake = sinon.fake((ev) => ev.target.modelValue);
|
|
828
750
|
el.addEventListener('model-value-changed', fake);
|
|
829
|
-
|
|
830
751
|
await mimicUserTyping(el, 'Foo');
|
|
831
752
|
await el.updateComplete;
|
|
832
753
|
expect(fake).to.have.been.calledThrice;
|
|
@@ -835,9 +756,9 @@ describe('lion-combobox', () => {
|
|
|
835
756
|
expect(fake.thirdCall.returnValue).to.equal('Foo');
|
|
836
757
|
expect(el.modelValue).to.equal('Foo');
|
|
837
758
|
});
|
|
838
|
-
|
|
839
759
|
it('fires "model-value-changed" on every textbox change when requireOptionMatch is false and autocomplete is none', async () => {
|
|
840
|
-
const el =
|
|
760
|
+
const el =
|
|
761
|
+
/** @type {LionCombobox} */
|
|
841
762
|
await fixture(html`
|
|
842
763
|
<lion-combobox name="foo" autocomplete="none" .requireOptionMatch="${false}">
|
|
843
764
|
<lion-option checked .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -845,12 +766,9 @@ describe('lion-combobox', () => {
|
|
|
845
766
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
846
767
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
847
768
|
</lion-combobox>
|
|
848
|
-
`)
|
|
849
|
-
);
|
|
850
|
-
|
|
851
|
-
const fake = sinon.fake(ev => ev.target.modelValue);
|
|
769
|
+
`);
|
|
770
|
+
const fake = sinon.fake((ev) => ev.target.modelValue);
|
|
852
771
|
el.addEventListener('model-value-changed', fake);
|
|
853
|
-
|
|
854
772
|
await mimicUserTyping(el, 'Foo');
|
|
855
773
|
await el.updateComplete;
|
|
856
774
|
expect(fake.callCount).to.equal(4);
|
|
@@ -860,9 +778,9 @@ describe('lion-combobox', () => {
|
|
|
860
778
|
expect(fake.getCall(3).returnValue).to.equal('Foo');
|
|
861
779
|
expect(el.modelValue).to.equal('Foo');
|
|
862
780
|
});
|
|
863
|
-
|
|
864
781
|
it('does not fire "model-value-changed" when requireOptionMatch is false but the textbox value did not change', async () => {
|
|
865
|
-
const el =
|
|
782
|
+
const el =
|
|
783
|
+
/** @type {LionCombobox} */
|
|
866
784
|
await fixture(html`
|
|
867
785
|
<lion-combobox name="foo" autocomplete="none" .requireOptionMatch="${false}">
|
|
868
786
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -870,23 +788,20 @@ describe('lion-combobox', () => {
|
|
|
870
788
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
871
789
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
872
790
|
</lion-combobox>
|
|
873
|
-
`)
|
|
874
|
-
);
|
|
791
|
+
`);
|
|
875
792
|
await mimicUserTyping(el, 'Foo');
|
|
876
793
|
await el.updateComplete;
|
|
877
|
-
|
|
878
794
|
const spy = sinon.spy();
|
|
879
795
|
el.addEventListener('model-value-changed', spy);
|
|
880
796
|
|
|
881
797
|
// Re-triggering autocompletion with the exact same textbox value should not dispatch again
|
|
882
798
|
el.__shouldAutocompleteNextUpdate = true;
|
|
883
799
|
await el.updateComplete;
|
|
884
|
-
|
|
885
800
|
expect(spy).to.not.have.been.called;
|
|
886
801
|
});
|
|
887
|
-
|
|
888
802
|
it('fires "model-value-changed" via checked option repropagation (not the manual dispatch) when requireOptionMatch is true', async () => {
|
|
889
|
-
const el =
|
|
803
|
+
const el =
|
|
804
|
+
/** @type {LionCombobox} */
|
|
890
805
|
await fixture(html`
|
|
891
806
|
<lion-combobox name="foo" autocomplete="both">
|
|
892
807
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -894,16 +809,13 @@ describe('lion-combobox', () => {
|
|
|
894
809
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
895
810
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
896
811
|
</lion-combobox>
|
|
897
|
-
`)
|
|
898
|
-
);
|
|
812
|
+
`);
|
|
899
813
|
const spy = sinon.spy();
|
|
900
814
|
el.addEventListener('model-value-changed', spy);
|
|
901
|
-
|
|
902
815
|
await mimicUserTyping(el, 'cha');
|
|
903
816
|
await el.updateComplete;
|
|
904
817
|
expect(el.modelValue).to.equal('Chard');
|
|
905
818
|
expect(spy).to.have.been.calledOnce;
|
|
906
|
-
|
|
907
819
|
spy.resetHistory();
|
|
908
820
|
// No option matches "xyz", so checkedIndex stays -1 and requireOptionMatch is true:
|
|
909
821
|
// no event should be manually dispatched (normal Unparseable flow, no double event)
|
|
@@ -912,9 +824,9 @@ describe('lion-combobox', () => {
|
|
|
912
824
|
expect(el.modelValue instanceof Unparseable).to.be.true;
|
|
913
825
|
expect(spy).to.have.been.calledOnce;
|
|
914
826
|
});
|
|
915
|
-
|
|
916
827
|
it('fires "model-value-changed" via checked option repropagation (not the manual dispatch) when requireOptionMatch is false and no option matches the input', async () => {
|
|
917
|
-
const el =
|
|
828
|
+
const el =
|
|
829
|
+
/** @type {LionCombobox} */
|
|
918
830
|
await fixture(html`
|
|
919
831
|
<lion-combobox name="foo" autocomplete="both">
|
|
920
832
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -922,12 +834,9 @@ describe('lion-combobox', () => {
|
|
|
922
834
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
923
835
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
924
836
|
</lion-combobox>
|
|
925
|
-
`)
|
|
926
|
-
);
|
|
927
|
-
|
|
837
|
+
`);
|
|
928
838
|
el.requireOptionMatch = false;
|
|
929
839
|
await el.updateComplete;
|
|
930
|
-
|
|
931
840
|
const spy = sinon.spy();
|
|
932
841
|
el.addEventListener('model-value-changed', spy);
|
|
933
842
|
|
|
@@ -939,9 +848,9 @@ describe('lion-combobox', () => {
|
|
|
939
848
|
expect(spy.args.length).to.equal(3);
|
|
940
849
|
expect(spy.args[2][0].target.modelValue).to.equal('Chicorys');
|
|
941
850
|
});
|
|
942
|
-
|
|
943
851
|
it("doesn't select any similar options after using delete when requireOptionMatch is false", async () => {
|
|
944
|
-
const el =
|
|
852
|
+
const el =
|
|
853
|
+
/** @type {LionCombobox} */
|
|
945
854
|
await fixture(html`
|
|
946
855
|
<lion-combobox name="foo" .validators=${[new Required()]}>
|
|
947
856
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -949,29 +858,24 @@ describe('lion-combobox', () => {
|
|
|
949
858
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
950
859
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
951
860
|
</lion-combobox>
|
|
952
|
-
`)
|
|
953
|
-
);
|
|
861
|
+
`);
|
|
954
862
|
el.requireOptionMatch = false;
|
|
955
863
|
const { _inputNode } = getComboboxMembers(el);
|
|
956
|
-
|
|
957
864
|
await mimicUserTyping(el, 'Art');
|
|
958
865
|
await el.updateComplete;
|
|
959
|
-
|
|
960
866
|
await mimicUserTypingAdvanced(el, ['Delete']);
|
|
961
867
|
await el.updateComplete;
|
|
962
868
|
await el.updateComplete;
|
|
963
|
-
|
|
964
869
|
mimicKeyPress(_inputNode, 'Enter');
|
|
965
870
|
await el.updateComplete;
|
|
966
|
-
|
|
967
871
|
expect(el.checkedIndex).to.equal(-1);
|
|
968
872
|
expect(el.modelValue).to.equal('Art');
|
|
969
873
|
expect(_inputNode.value).to.equal('Art');
|
|
970
874
|
});
|
|
971
|
-
|
|
972
875
|
it("when removing a letter it won't select the option", async () => {
|
|
973
876
|
// We don't autocomplete when characters are removed
|
|
974
|
-
const el =
|
|
877
|
+
const el =
|
|
878
|
+
/** @type {LionCombobox} */
|
|
975
879
|
await fixture(html`
|
|
976
880
|
<lion-combobox name="foo">
|
|
977
881
|
<lion-option checked .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -979,8 +883,7 @@ describe('lion-combobox', () => {
|
|
|
979
883
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
980
884
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
981
885
|
</lion-combobox>
|
|
982
|
-
`)
|
|
983
|
-
);
|
|
886
|
+
`);
|
|
984
887
|
const { _inputNode } = getComboboxMembers(el);
|
|
985
888
|
expect(el.checkedIndex).to.equal(0);
|
|
986
889
|
|
|
@@ -992,28 +895,25 @@ describe('lion-combobox', () => {
|
|
|
992
895
|
_inputNode.value = arr.join('');
|
|
993
896
|
await el.updateComplete;
|
|
994
897
|
el.dispatchEvent(new Event('blur'));
|
|
995
|
-
|
|
996
898
|
expect(el.checkedIndex).to.equal(-1);
|
|
997
899
|
expect(el.modelValue instanceof Unparseable).to.be.true;
|
|
998
900
|
expect(el.modelValue.viewValue).to.equal('Artichok');
|
|
999
901
|
});
|
|
1000
|
-
|
|
1001
902
|
it('allows the user to override the parser', async () => {
|
|
1002
|
-
const el =
|
|
903
|
+
const el =
|
|
904
|
+
/** @type {LionCombobox} */
|
|
1003
905
|
await fixture(html`
|
|
1004
906
|
<lion-combobox
|
|
1005
907
|
name="foo"
|
|
1006
|
-
.parser="${/** @param {string} value */ value => value.replace(/[0-9]/g, '')}"
|
|
908
|
+
.parser="${/** @param {string} value */ (value) => value.replace(/[0-9]/g, '')}"
|
|
1007
909
|
>
|
|
1008
910
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
1009
911
|
<lion-option .choiceValue="${'Chard'}">Chard</lion-option>
|
|
1010
912
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1011
913
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
1012
914
|
</lion-combobox>
|
|
1013
|
-
`)
|
|
1014
|
-
);
|
|
915
|
+
`);
|
|
1015
916
|
const { _inputNode } = getComboboxMembers(el);
|
|
1016
|
-
|
|
1017
917
|
el.setCheckedIndex(-1);
|
|
1018
918
|
_inputNode.value = 'Foo123';
|
|
1019
919
|
el.__shouldAutocompleteNextUpdate = true;
|
|
@@ -1021,9 +921,9 @@ describe('lion-combobox', () => {
|
|
|
1021
921
|
expect(el.modelValue).to.equal('Foo');
|
|
1022
922
|
expect(el.formElements[0].checked).to.be.false;
|
|
1023
923
|
});
|
|
1024
|
-
|
|
1025
924
|
it('allows custom selections when multi-choice when requireOptionMatch is false', async () => {
|
|
1026
|
-
const el =
|
|
925
|
+
const el =
|
|
926
|
+
/** @type {LionCombobox} */
|
|
1027
927
|
await fixture(html`
|
|
1028
928
|
<lion-combobox
|
|
1029
929
|
name="foo"
|
|
@@ -1036,32 +936,26 @@ describe('lion-combobox', () => {
|
|
|
1036
936
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1037
937
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
1038
938
|
</lion-combobox>
|
|
1039
|
-
`)
|
|
1040
|
-
);
|
|
1041
|
-
|
|
939
|
+
`);
|
|
1042
940
|
el.requireOptionMatch = false;
|
|
1043
941
|
await el.updateComplete;
|
|
1044
|
-
|
|
1045
942
|
const { _inputNode } = getComboboxMembers(el);
|
|
1046
943
|
expect(el.modelValue).to.eql(['Chard']);
|
|
1047
944
|
expect(el.checkedIndex).to.eql([1]);
|
|
1048
|
-
|
|
1049
945
|
await mimicUserTyping(el, 'Foo');
|
|
1050
946
|
await el.updateComplete;
|
|
1051
947
|
mimicKeyPress(_inputNode, 'Enter');
|
|
1052
948
|
await el.updateComplete;
|
|
1053
|
-
|
|
1054
949
|
expect(el.modelValue).to.eql(['Chard', 'Foo']);
|
|
1055
950
|
expect(el.checkedIndex).to.eql([1]);
|
|
1056
|
-
|
|
1057
951
|
await mimicUserTyping(el, 'Bar');
|
|
1058
952
|
await el.updateComplete;
|
|
1059
953
|
mimicKeyPress(_inputNode, 'Enter');
|
|
1060
954
|
await el.updateComplete;
|
|
1061
955
|
});
|
|
1062
|
-
|
|
1063
956
|
it('allows many custom selections when multi-choice when requireOptionMatch is false', async () => {
|
|
1064
|
-
const el =
|
|
957
|
+
const el =
|
|
958
|
+
/** @type {LionCombobox} */
|
|
1065
959
|
await fixture(html`
|
|
1066
960
|
<lion-combobox
|
|
1067
961
|
name="foo"
|
|
@@ -1074,33 +968,26 @@ describe('lion-combobox', () => {
|
|
|
1074
968
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1075
969
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
1076
970
|
</lion-combobox>
|
|
1077
|
-
`)
|
|
1078
|
-
);
|
|
1079
|
-
|
|
971
|
+
`);
|
|
1080
972
|
el.requireOptionMatch = false;
|
|
1081
973
|
await el.updateComplete;
|
|
1082
|
-
|
|
1083
974
|
const { _inputNode } = getComboboxMembers(el);
|
|
1084
|
-
|
|
1085
975
|
await mimicUserTyping(el, 'Foo');
|
|
1086
976
|
await el.updateComplete;
|
|
1087
977
|
mimicKeyPress(_inputNode, 'Enter');
|
|
1088
978
|
await el.updateComplete;
|
|
1089
|
-
|
|
1090
979
|
expect(el.modelValue).to.eql(['Foo']);
|
|
1091
980
|
expect(el.checkedIndex).to.eql([]);
|
|
1092
|
-
|
|
1093
981
|
await mimicUserTyping(el, 'Bar');
|
|
1094
982
|
await el.updateComplete;
|
|
1095
983
|
mimicKeyPress(_inputNode, 'Enter');
|
|
1096
984
|
await el.updateComplete;
|
|
1097
|
-
|
|
1098
985
|
expect(el.modelValue).to.eql(['Foo', 'Bar']);
|
|
1099
986
|
expect(el.checkedIndex).to.eql([]);
|
|
1100
987
|
});
|
|
1101
|
-
|
|
1102
988
|
it('allows new options when multi-choice when requireOptionMatch=false and autocomplete="both", without selecting similar values', async () => {
|
|
1103
|
-
const el =
|
|
989
|
+
const el =
|
|
990
|
+
/** @type {LionCombobox} */
|
|
1104
991
|
await fixture(html`
|
|
1105
992
|
<lion-combobox
|
|
1106
993
|
name="foo"
|
|
@@ -1113,23 +1000,18 @@ describe('lion-combobox', () => {
|
|
|
1113
1000
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1114
1001
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
1115
1002
|
</lion-combobox>
|
|
1116
|
-
`)
|
|
1117
|
-
);
|
|
1118
|
-
|
|
1003
|
+
`);
|
|
1119
1004
|
await el.updateComplete;
|
|
1120
|
-
|
|
1121
1005
|
const { _inputNode } = getComboboxMembers(el);
|
|
1122
|
-
|
|
1123
1006
|
await mimicUserTyping(el, 'Artist');
|
|
1124
1007
|
await el.updateComplete;
|
|
1125
1008
|
mimicKeyPress(_inputNode, 'Enter');
|
|
1126
1009
|
await el.updateComplete;
|
|
1127
|
-
|
|
1128
1010
|
expect(el.modelValue).to.eql(['Artist']);
|
|
1129
1011
|
});
|
|
1130
|
-
|
|
1131
1012
|
it('allows new options when multi-choice when requireOptionMatch=false and autocomplete="both", when deleting autocomplete values using Backspace', async () => {
|
|
1132
|
-
const el =
|
|
1013
|
+
const el =
|
|
1014
|
+
/** @type {LionCombobox} */
|
|
1133
1015
|
await fixture(html`
|
|
1134
1016
|
<lion-combobox
|
|
1135
1017
|
name="foo"
|
|
@@ -1142,11 +1024,8 @@ describe('lion-combobox', () => {
|
|
|
1142
1024
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1143
1025
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
1144
1026
|
</lion-combobox>
|
|
1145
|
-
`)
|
|
1146
|
-
);
|
|
1147
|
-
|
|
1027
|
+
`);
|
|
1148
1028
|
await el.updateComplete;
|
|
1149
|
-
|
|
1150
1029
|
const { _inputNode } = getComboboxMembers(el);
|
|
1151
1030
|
await mimicUserTyping(el, 'Art');
|
|
1152
1031
|
await el.updateComplete;
|
|
@@ -1154,12 +1033,11 @@ describe('lion-combobox', () => {
|
|
|
1154
1033
|
await el.updateComplete;
|
|
1155
1034
|
mimicKeyPress(_inputNode, 'Enter');
|
|
1156
1035
|
await el.updateComplete;
|
|
1157
|
-
|
|
1158
1036
|
expect(el.modelValue).to.eql(['Art']);
|
|
1159
1037
|
});
|
|
1160
|
-
|
|
1161
1038
|
it('allows new custom options when multi-choice when requireOptionMatch=false and autocomplete="both", when deleting autocompleted values using Delete', async () => {
|
|
1162
|
-
const el =
|
|
1039
|
+
const el =
|
|
1040
|
+
/** @type {LionCombobox} */
|
|
1163
1041
|
await fixture(html`
|
|
1164
1042
|
<lion-combobox
|
|
1165
1043
|
name="foo"
|
|
@@ -1172,14 +1050,10 @@ describe('lion-combobox', () => {
|
|
|
1172
1050
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1173
1051
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
1174
1052
|
</lion-combobox>
|
|
1175
|
-
`)
|
|
1176
|
-
);
|
|
1177
|
-
|
|
1053
|
+
`);
|
|
1178
1054
|
await el.updateComplete;
|
|
1179
|
-
|
|
1180
1055
|
const { _inputNode } = getComboboxMembers(el);
|
|
1181
1056
|
el.modelValue = [];
|
|
1182
|
-
|
|
1183
1057
|
await mimicUserTyping(el, 'Art');
|
|
1184
1058
|
await el.updateComplete;
|
|
1185
1059
|
await mimicUserTypingAdvanced(el, ['Delete']);
|
|
@@ -1188,12 +1062,11 @@ describe('lion-combobox', () => {
|
|
|
1188
1062
|
await el.updateComplete;
|
|
1189
1063
|
expect(el.modelValue).to.eql(['Art']);
|
|
1190
1064
|
});
|
|
1191
|
-
|
|
1192
1065
|
it('allows prefilling the combobox', async () => {
|
|
1193
1066
|
const autocompleteValues = ['inline', 'none', 'both', 'list'];
|
|
1194
|
-
|
|
1195
1067
|
for (const autocompleteValue of autocompleteValues) {
|
|
1196
|
-
const el =
|
|
1068
|
+
const el =
|
|
1069
|
+
/** @type {LionCombobox} */
|
|
1197
1070
|
await fixture(html`
|
|
1198
1071
|
<lion-combobox autocomplete="${autocompleteValue}" .modelValue="${'Chard'}" name="foo">
|
|
1199
1072
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -1201,18 +1074,16 @@ describe('lion-combobox', () => {
|
|
|
1201
1074
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1202
1075
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
1203
1076
|
</lion-combobox>
|
|
1204
|
-
`)
|
|
1205
|
-
);
|
|
1206
|
-
|
|
1077
|
+
`);
|
|
1207
1078
|
expect(el.modelValue).to.equal('Chard');
|
|
1208
1079
|
// @ts-expect-error
|
|
1209
1080
|
expect(el._inputNode.value).to.equal('Chard');
|
|
1210
1081
|
}
|
|
1211
1082
|
});
|
|
1212
|
-
|
|
1213
1083
|
it('submits form on [Enter] when listbox is closed', async () => {
|
|
1214
|
-
const submitSpy = sinon.spy(e => e.preventDefault());
|
|
1215
|
-
const el =
|
|
1084
|
+
const submitSpy = sinon.spy((e) => e.preventDefault());
|
|
1085
|
+
const el =
|
|
1086
|
+
/** @type {HTMLFormElement} */
|
|
1216
1087
|
await fixture(html`
|
|
1217
1088
|
<form @submit=${submitSpy}>
|
|
1218
1089
|
<lion-combobox name="foo">
|
|
@@ -1223,9 +1094,8 @@ describe('lion-combobox', () => {
|
|
|
1223
1094
|
</lion-combobox>
|
|
1224
1095
|
<button type="submit">submit</button>
|
|
1225
1096
|
</form>
|
|
1226
|
-
`)
|
|
1227
|
-
);
|
|
1228
|
-
const combobox = /** @type {LionCombobox} */ (el.querySelector('[name="foo"]'));
|
|
1097
|
+
`);
|
|
1098
|
+
const combobox = /** @type {LionCombobox} */ el.querySelector('[name="foo"]');
|
|
1229
1099
|
const { _inputNode } = getComboboxMembers(combobox);
|
|
1230
1100
|
await combobox.updateComplete;
|
|
1231
1101
|
_inputNode.focus();
|
|
@@ -1234,10 +1104,10 @@ describe('lion-combobox', () => {
|
|
|
1234
1104
|
});
|
|
1235
1105
|
expect(submitSpy.callCount).to.equal(1);
|
|
1236
1106
|
});
|
|
1237
|
-
|
|
1238
1107
|
it('does not submit form on [Enter] when listbox is opened', async () => {
|
|
1239
|
-
const submitSpy = sinon.spy(e => e.preventDefault());
|
|
1240
|
-
const el =
|
|
1108
|
+
const submitSpy = sinon.spy((e) => e.preventDefault());
|
|
1109
|
+
const el =
|
|
1110
|
+
/** @type {HTMLFormElement} */
|
|
1241
1111
|
await fixture(html`
|
|
1242
1112
|
<form @submit=${submitSpy}>
|
|
1243
1113
|
<lion-combobox name="foo">
|
|
@@ -1248,9 +1118,8 @@ describe('lion-combobox', () => {
|
|
|
1248
1118
|
</lion-combobox>
|
|
1249
1119
|
<button type="submit">submit</button>
|
|
1250
1120
|
</form>
|
|
1251
|
-
`)
|
|
1252
|
-
);
|
|
1253
|
-
const combobox = /** @type {LionCombobox} */ (el.querySelector('[name="foo"]'));
|
|
1121
|
+
`);
|
|
1122
|
+
const combobox = /** @type {LionCombobox} */ el.querySelector('[name="foo"]');
|
|
1254
1123
|
const { _inputNode } = getComboboxMembers(combobox);
|
|
1255
1124
|
combobox.opened = true;
|
|
1256
1125
|
await combobox.updateComplete;
|
|
@@ -1261,10 +1130,10 @@ describe('lion-combobox', () => {
|
|
|
1261
1130
|
expect(submitSpy.callCount).to.equal(0);
|
|
1262
1131
|
});
|
|
1263
1132
|
});
|
|
1264
|
-
|
|
1265
1133
|
describe('Overlay visibility', () => {
|
|
1266
1134
|
it('does not show overlay on click', async () => {
|
|
1267
|
-
const el =
|
|
1135
|
+
const el =
|
|
1136
|
+
/** @type {LionCombobox} */
|
|
1268
1137
|
await fixture(html`
|
|
1269
1138
|
<lion-combobox name="foo">
|
|
1270
1139
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -1272,27 +1141,28 @@ describe('lion-combobox', () => {
|
|
|
1272
1141
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1273
1142
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
1274
1143
|
</lion-combobox>
|
|
1275
|
-
`)
|
|
1276
|
-
);
|
|
1144
|
+
`);
|
|
1277
1145
|
const { _comboboxNode } = getComboboxMembers(el);
|
|
1278
|
-
|
|
1279
1146
|
expect(el.opened).to.equal(false);
|
|
1280
|
-
_comboboxNode.dispatchEvent(
|
|
1147
|
+
_comboboxNode.dispatchEvent(
|
|
1148
|
+
new Event('click', {
|
|
1149
|
+
bubbles: true,
|
|
1150
|
+
composed: true,
|
|
1151
|
+
}),
|
|
1152
|
+
);
|
|
1281
1153
|
await el.updateComplete;
|
|
1282
1154
|
expect(el.opened).to.equal(false);
|
|
1283
1155
|
});
|
|
1284
|
-
|
|
1285
1156
|
it('does not flash the menu when _showOverlayCondition returns "false"', async () => {
|
|
1286
1157
|
class ComplexCombobox extends LionCombobox {
|
|
1287
1158
|
_showOverlayCondition() {
|
|
1288
1159
|
return false;
|
|
1289
1160
|
}
|
|
1290
1161
|
}
|
|
1291
|
-
|
|
1292
1162
|
const tagName = defineCE(ComplexCombobox);
|
|
1293
1163
|
const tag = unsafeStatic(tagName);
|
|
1294
|
-
|
|
1295
|
-
|
|
1164
|
+
const el =
|
|
1165
|
+
/** @type {LionCombobox} */
|
|
1296
1166
|
await fixture(html`
|
|
1297
1167
|
<${tag} name="combo" label="Display only the label once selected">
|
|
1298
1168
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -1300,15 +1170,13 @@ describe('lion-combobox', () => {
|
|
|
1300
1170
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1301
1171
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
1302
1172
|
</${tag}>
|
|
1303
|
-
`)
|
|
1304
|
-
);
|
|
1305
|
-
|
|
1173
|
+
`);
|
|
1306
1174
|
const dialog = el.shadowRoot?.querySelector('dialog');
|
|
1307
1175
|
/**
|
|
1308
1176
|
* hasDropdownFlashed is `true` if the menu was shown for a short period of time and then got closed
|
|
1309
1177
|
*/
|
|
1310
1178
|
let hasDropdownFlashed = false;
|
|
1311
|
-
const observer = new MutationObserver(mutationList => {
|
|
1179
|
+
const observer = new MutationObserver((mutationList) => {
|
|
1312
1180
|
// eslint-disable-next-line no-unused-vars
|
|
1313
1181
|
for (const mutation of mutationList) {
|
|
1314
1182
|
if (dialog?.style.display === '') {
|
|
@@ -1316,8 +1184,9 @@ describe('lion-combobox', () => {
|
|
|
1316
1184
|
}
|
|
1317
1185
|
}
|
|
1318
1186
|
});
|
|
1319
|
-
observer.observe(/** @type {Node} */
|
|
1320
|
-
|
|
1187
|
+
observer.observe(/** @type {Node} */ dialog, {
|
|
1188
|
+
attributeFilter: ['style'],
|
|
1189
|
+
});
|
|
1321
1190
|
const { _inputNode } = getComboboxMembers(el);
|
|
1322
1191
|
_inputNode.focus();
|
|
1323
1192
|
await sendKeys({
|
|
@@ -1325,9 +1194,9 @@ describe('lion-combobox', () => {
|
|
|
1325
1194
|
});
|
|
1326
1195
|
expect(hasDropdownFlashed).to.be.false;
|
|
1327
1196
|
});
|
|
1328
|
-
|
|
1329
1197
|
it('shows overlay on click when filled', async () => {
|
|
1330
|
-
const el =
|
|
1198
|
+
const el =
|
|
1199
|
+
/** @type {LionCombobox} */
|
|
1331
1200
|
await fixture(html`
|
|
1332
1201
|
<lion-combobox name="foo">
|
|
1333
1202
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -1335,16 +1204,19 @@ describe('lion-combobox', () => {
|
|
|
1335
1204
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1336
1205
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
1337
1206
|
</lion-combobox>
|
|
1338
|
-
`)
|
|
1339
|
-
);
|
|
1207
|
+
`);
|
|
1340
1208
|
const { _comboboxNode } = getComboboxMembers(el);
|
|
1341
1209
|
el.modelValue = 'Art';
|
|
1342
1210
|
expect(el.opened).to.equal(false);
|
|
1343
|
-
_comboboxNode.dispatchEvent(
|
|
1211
|
+
_comboboxNode.dispatchEvent(
|
|
1212
|
+
new Event('click', {
|
|
1213
|
+
bubbles: true,
|
|
1214
|
+
composed: true,
|
|
1215
|
+
}),
|
|
1216
|
+
);
|
|
1344
1217
|
await el.updateComplete;
|
|
1345
1218
|
expect(el.opened).to.equal(false);
|
|
1346
1219
|
});
|
|
1347
|
-
|
|
1348
1220
|
it('shows overlay again after select and char keyup', async () => {
|
|
1349
1221
|
/**
|
|
1350
1222
|
* Scenario:
|
|
@@ -1354,7 +1226,8 @@ describe('lion-combobox', () => {
|
|
|
1354
1226
|
* still has focus
|
|
1355
1227
|
* [4] user changes textbox value to "Artichoke": the overlay should show again
|
|
1356
1228
|
*/
|
|
1357
|
-
const el =
|
|
1229
|
+
const el =
|
|
1230
|
+
/** @type {LionCombobox} */
|
|
1358
1231
|
await fixture(html`
|
|
1359
1232
|
<lion-combobox name="foo">
|
|
1360
1233
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -1362,15 +1235,18 @@ describe('lion-combobox', () => {
|
|
|
1362
1235
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1363
1236
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
1364
1237
|
</lion-combobox>
|
|
1365
|
-
`)
|
|
1366
|
-
);
|
|
1238
|
+
`);
|
|
1367
1239
|
const options = el.formElements;
|
|
1368
1240
|
const { _inputNode } = getComboboxMembers(el);
|
|
1369
|
-
|
|
1370
1241
|
expect(el.opened).to.equal(false);
|
|
1371
1242
|
|
|
1372
1243
|
// step [1]
|
|
1373
|
-
_inputNode.dispatchEvent(
|
|
1244
|
+
_inputNode.dispatchEvent(
|
|
1245
|
+
new Event('click', {
|
|
1246
|
+
bubbles: true,
|
|
1247
|
+
composed: true,
|
|
1248
|
+
}),
|
|
1249
|
+
);
|
|
1374
1250
|
await el.updateComplete;
|
|
1375
1251
|
expect(el.opened).to.equal(false);
|
|
1376
1252
|
|
|
@@ -1391,9 +1267,34 @@ describe('lion-combobox', () => {
|
|
|
1391
1267
|
await el.updateComplete;
|
|
1392
1268
|
expect(el.opened).to.equal(true);
|
|
1393
1269
|
});
|
|
1394
|
-
|
|
1270
|
+
it('syncs a manually checked selection on overlay close while the input remains focused', async () => {
|
|
1271
|
+
const el =
|
|
1272
|
+
/** @type {LionCombobox} */
|
|
1273
|
+
await fixture(html`
|
|
1274
|
+
<lion-combobox name="foo" autocomplete="list">
|
|
1275
|
+
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
1276
|
+
<lion-option .choiceValue="${'Chard'}">Chard</lion-option>
|
|
1277
|
+
</lion-combobox>
|
|
1278
|
+
`);
|
|
1279
|
+
const { _inputNode } = getComboboxMembers(el);
|
|
1280
|
+
_inputNode.focus();
|
|
1281
|
+
el.opened = true;
|
|
1282
|
+
await el.updateComplete;
|
|
1283
|
+
expect(el.opened).to.equal(true);
|
|
1284
|
+
expect(isActiveElement(_inputNode)).to.be.true;
|
|
1285
|
+
el.setCheckedIndex(0);
|
|
1286
|
+
await el.updateComplete;
|
|
1287
|
+
expect(el.modelValue).to.equal('Artichoke');
|
|
1288
|
+
expect(el.checkedIndex).to.equal(0);
|
|
1289
|
+
expect(_inputNode.value).to.equal('');
|
|
1290
|
+
el.opened = false;
|
|
1291
|
+
await el.updateComplete;
|
|
1292
|
+
expect(_inputNode.value).to.equal('Artichoke');
|
|
1293
|
+
expect(isActiveElement(_inputNode)).to.be.true;
|
|
1294
|
+
});
|
|
1395
1295
|
it('hides (and clears) overlay on [Escape]', async () => {
|
|
1396
|
-
const el =
|
|
1296
|
+
const el =
|
|
1297
|
+
/** @type {LionCombobox} */
|
|
1397
1298
|
await fixture(html`
|
|
1398
1299
|
<lion-combobox name="foo">
|
|
1399
1300
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -1401,23 +1302,23 @@ describe('lion-combobox', () => {
|
|
|
1401
1302
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1402
1303
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
1403
1304
|
</lion-combobox>
|
|
1404
|
-
`)
|
|
1405
|
-
);
|
|
1406
|
-
|
|
1305
|
+
`);
|
|
1407
1306
|
const { _inputNode } = getComboboxMembers(el);
|
|
1408
|
-
|
|
1409
1307
|
await mimicUserTyping(el, 'art');
|
|
1410
1308
|
await el.updateComplete;
|
|
1411
1309
|
expect(el.opened).to.equal(true);
|
|
1412
1310
|
expect(_inputNode.value).to.equal('Artichoke');
|
|
1413
|
-
|
|
1414
|
-
|
|
1311
|
+
_inputNode.dispatchEvent(
|
|
1312
|
+
new KeyboardEvent('keydown', {
|
|
1313
|
+
key: 'Escape',
|
|
1314
|
+
}),
|
|
1315
|
+
);
|
|
1415
1316
|
expect(el.opened).to.equal(false);
|
|
1416
1317
|
expect(_inputNode.value).to.equal('');
|
|
1417
1318
|
});
|
|
1418
|
-
|
|
1419
1319
|
it('hides overlay on [Enter]', async () => {
|
|
1420
|
-
const el =
|
|
1320
|
+
const el =
|
|
1321
|
+
/** @type {LionCombobox} */
|
|
1421
1322
|
await fixture(html`
|
|
1422
1323
|
<lion-combobox name="foo">
|
|
1423
1324
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -1425,11 +1326,8 @@ describe('lion-combobox', () => {
|
|
|
1425
1326
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1426
1327
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
1427
1328
|
</lion-combobox>
|
|
1428
|
-
`)
|
|
1429
|
-
);
|
|
1430
|
-
|
|
1329
|
+
`);
|
|
1431
1330
|
const { _inputNode } = getComboboxMembers(el);
|
|
1432
|
-
|
|
1433
1331
|
await mimicUserTyping(el, 'art');
|
|
1434
1332
|
await el.updateComplete;
|
|
1435
1333
|
expect(el.opened).to.equal(true);
|
|
@@ -1437,13 +1335,17 @@ describe('lion-combobox', () => {
|
|
|
1437
1335
|
|
|
1438
1336
|
// N.B. we do only trigger keydown here (and not mimicKeypress (both keyup and down)),
|
|
1439
1337
|
// because this closely mimics what happens in the browser
|
|
1440
|
-
_inputNode.dispatchEvent(
|
|
1338
|
+
_inputNode.dispatchEvent(
|
|
1339
|
+
new KeyboardEvent('keydown', {
|
|
1340
|
+
key: 'Enter',
|
|
1341
|
+
}),
|
|
1342
|
+
);
|
|
1441
1343
|
expect(el.opened).to.equal(false);
|
|
1442
1344
|
expect(_inputNode.value).to.equal('Artichoke');
|
|
1443
1345
|
});
|
|
1444
|
-
|
|
1445
1346
|
it('hides overlay on [Tab]', async () => {
|
|
1446
|
-
const el =
|
|
1347
|
+
const el =
|
|
1348
|
+
/** @type {LionCombobox} */
|
|
1447
1349
|
await fixture(html`
|
|
1448
1350
|
<lion-combobox name="foo">
|
|
1449
1351
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -1451,11 +1353,8 @@ describe('lion-combobox', () => {
|
|
|
1451
1353
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1452
1354
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
1453
1355
|
</lion-combobox>
|
|
1454
|
-
`)
|
|
1455
|
-
);
|
|
1456
|
-
|
|
1356
|
+
`);
|
|
1457
1357
|
const { _inputNode } = getComboboxMembers(el);
|
|
1458
|
-
|
|
1459
1358
|
await mimicUserTyping(el, 'art');
|
|
1460
1359
|
await el.updateComplete;
|
|
1461
1360
|
expect(el.opened).to.equal(true);
|
|
@@ -1463,13 +1362,17 @@ describe('lion-combobox', () => {
|
|
|
1463
1362
|
|
|
1464
1363
|
// N.B. we do only trigger keydown here (and not mimicKeypress (both keyup and down)),
|
|
1465
1364
|
// because this closely mimics what happens in the browser
|
|
1466
|
-
_inputNode.dispatchEvent(
|
|
1365
|
+
_inputNode.dispatchEvent(
|
|
1366
|
+
new KeyboardEvent('keydown', {
|
|
1367
|
+
key: 'Tab',
|
|
1368
|
+
}),
|
|
1369
|
+
);
|
|
1467
1370
|
expect(el.opened).to.equal(false);
|
|
1468
1371
|
expect(_inputNode.value).to.equal('Artichoke');
|
|
1469
1372
|
});
|
|
1470
|
-
|
|
1471
1373
|
it('keeps overlay open on [Shift]', async () => {
|
|
1472
|
-
const el =
|
|
1374
|
+
const el =
|
|
1375
|
+
/** @type {LionCombobox} */
|
|
1473
1376
|
await fixture(html`
|
|
1474
1377
|
<lion-combobox name="foo">
|
|
1475
1378
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -1477,11 +1380,8 @@ describe('lion-combobox', () => {
|
|
|
1477
1380
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1478
1381
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
1479
1382
|
</lion-combobox>
|
|
1480
|
-
`)
|
|
1481
|
-
);
|
|
1482
|
-
|
|
1383
|
+
`);
|
|
1483
1384
|
const { _inputNode } = getComboboxMembers(el);
|
|
1484
|
-
|
|
1485
1385
|
await mimicUserTyping(el, 'art');
|
|
1486
1386
|
await el.updateComplete;
|
|
1487
1387
|
expect(el.opened).to.equal(true);
|
|
@@ -1489,13 +1389,17 @@ describe('lion-combobox', () => {
|
|
|
1489
1389
|
|
|
1490
1390
|
// N.B. we do only trigger keydown here (and not mimicKeypress (both keyup and down)),
|
|
1491
1391
|
// because this closely mimics what happens in the browser
|
|
1492
|
-
_inputNode.dispatchEvent(
|
|
1392
|
+
_inputNode.dispatchEvent(
|
|
1393
|
+
new KeyboardEvent('keydown', {
|
|
1394
|
+
key: 'Shift',
|
|
1395
|
+
}),
|
|
1396
|
+
);
|
|
1493
1397
|
expect(el.opened).to.equal(true);
|
|
1494
1398
|
expect(_inputNode.value).to.equal('Artichoke');
|
|
1495
1399
|
});
|
|
1496
|
-
|
|
1497
1400
|
it('clears checkedIndex on empty text', async () => {
|
|
1498
|
-
const el =
|
|
1401
|
+
const el =
|
|
1402
|
+
/** @type {LionCombobox} */
|
|
1499
1403
|
await fixture(html`
|
|
1500
1404
|
<lion-combobox name="foo">
|
|
1501
1405
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -1503,11 +1407,8 @@ describe('lion-combobox', () => {
|
|
|
1503
1407
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1504
1408
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
1505
1409
|
</lion-combobox>
|
|
1506
|
-
`)
|
|
1507
|
-
);
|
|
1508
|
-
|
|
1410
|
+
`);
|
|
1509
1411
|
const { _inputNode } = getComboboxMembers(el);
|
|
1510
|
-
|
|
1511
1412
|
await mimicUserTyping(el, 'art');
|
|
1512
1413
|
await el.updateComplete;
|
|
1513
1414
|
expect(el.opened).to.equal(true);
|
|
@@ -1515,15 +1416,17 @@ describe('lion-combobox', () => {
|
|
|
1515
1416
|
expect(el.checkedIndex).to.equal(0);
|
|
1516
1417
|
|
|
1517
1418
|
// await mimicUserTyping(el, '');
|
|
1518
|
-
await sendKeys({
|
|
1419
|
+
await sendKeys({
|
|
1420
|
+
press: 'Backspace',
|
|
1421
|
+
});
|
|
1519
1422
|
await el.updateComplete;
|
|
1520
1423
|
el.opened = false;
|
|
1521
1424
|
await el.updateComplete;
|
|
1522
1425
|
expect(el.checkedIndex).to.equal(-1);
|
|
1523
1426
|
});
|
|
1524
|
-
|
|
1525
1427
|
it('has the correct Overlay Config defined', async () => {
|
|
1526
|
-
const el =
|
|
1428
|
+
const el =
|
|
1429
|
+
/** @type {LionCombobox} */
|
|
1527
1430
|
await fixture(html`
|
|
1528
1431
|
<lion-combobox name="foo" .showAllOnEmpty="${true}">
|
|
1529
1432
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -1531,15 +1434,12 @@ describe('lion-combobox', () => {
|
|
|
1531
1434
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1532
1435
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
1533
1436
|
</lion-combobox>
|
|
1534
|
-
`)
|
|
1535
|
-
);
|
|
1437
|
+
`);
|
|
1536
1438
|
// @ts-expect-error [allow-protected] in test
|
|
1537
1439
|
const overlayCfg = el._defineOverlayConfig();
|
|
1538
|
-
|
|
1539
1440
|
const equalsOrContainsInput = (/** @type {HTMLInputElement|HTMLDivElement} */ invokerNode) =>
|
|
1540
1441
|
// @ts-expect-error [allow-protected] in test
|
|
1541
1442
|
invokerNode === el._inputNode || invokerNode.contains(el._inputNode);
|
|
1542
|
-
|
|
1543
1443
|
expect(overlayCfg.elementToFocusAfterHide).to.equal(undefined);
|
|
1544
1444
|
// @ts-expect-error
|
|
1545
1445
|
expect(equalsOrContainsInput(overlayCfg.invokerNode)).to.be.true;
|
|
@@ -1560,8 +1460,8 @@ describe('lion-combobox', () => {
|
|
|
1560
1460
|
}
|
|
1561
1461
|
const tagName = defineCE(ShowOverlayConditionCombobox);
|
|
1562
1462
|
const tag = unsafeStatic(tagName);
|
|
1563
|
-
|
|
1564
|
-
|
|
1463
|
+
const el =
|
|
1464
|
+
/** @type {LionCombobox} */
|
|
1565
1465
|
await fixture(html`
|
|
1566
1466
|
<${tag} name="foo">
|
|
1567
1467
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -1569,13 +1469,10 @@ describe('lion-combobox', () => {
|
|
|
1569
1469
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1570
1470
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
1571
1471
|
</${tag}>
|
|
1572
|
-
`)
|
|
1573
|
-
);
|
|
1574
|
-
|
|
1472
|
+
`);
|
|
1575
1473
|
await mimicUserTyping(el, 'aaa');
|
|
1576
1474
|
expect(el.opened).to.be.false;
|
|
1577
1475
|
});
|
|
1578
|
-
|
|
1579
1476
|
it('allows to control overlay visibility via "_showOverlayCondition": should display overlay if currentValue length condition is fulfilled', async () => {
|
|
1580
1477
|
class ShowOverlayConditionCombobox extends LionCombobox {
|
|
1581
1478
|
/** @param {{ currentValue: string, lastKey:string }} options */
|
|
@@ -1588,8 +1485,8 @@ describe('lion-combobox', () => {
|
|
|
1588
1485
|
}
|
|
1589
1486
|
const tagName = defineCE(ShowOverlayConditionCombobox);
|
|
1590
1487
|
const tag = unsafeStatic(tagName);
|
|
1591
|
-
|
|
1592
|
-
|
|
1488
|
+
const el =
|
|
1489
|
+
/** @type {LionCombobox} */
|
|
1593
1490
|
await fixture(html`
|
|
1594
1491
|
<${tag} name="foo">
|
|
1595
1492
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -1597,13 +1494,10 @@ describe('lion-combobox', () => {
|
|
|
1597
1494
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1598
1495
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
1599
1496
|
</${tag}>
|
|
1600
|
-
`)
|
|
1601
|
-
);
|
|
1602
|
-
|
|
1497
|
+
`);
|
|
1603
1498
|
await mimicUserTyping(el, 'aaaa');
|
|
1604
1499
|
expect(el.opened).to.be.true;
|
|
1605
1500
|
});
|
|
1606
|
-
|
|
1607
1501
|
it('allows to control overlay visibility via "_showOverlayCondition": should not display overlay if currentValue length condition is not fulfilled after once fulfilled', async () => {
|
|
1608
1502
|
class ShowOverlayConditionCombobox extends LionCombobox {
|
|
1609
1503
|
/** @param {{ currentValue: string, lastKey:string }} options */
|
|
@@ -1616,8 +1510,8 @@ describe('lion-combobox', () => {
|
|
|
1616
1510
|
}
|
|
1617
1511
|
const tagName = defineCE(ShowOverlayConditionCombobox);
|
|
1618
1512
|
const tag = unsafeStatic(tagName);
|
|
1619
|
-
|
|
1620
|
-
|
|
1513
|
+
const el =
|
|
1514
|
+
/** @type {LionCombobox} */
|
|
1621
1515
|
await fixture(html`
|
|
1622
1516
|
<${tag} name="foo">
|
|
1623
1517
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -1625,21 +1519,18 @@ describe('lion-combobox', () => {
|
|
|
1625
1519
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1626
1520
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
1627
1521
|
</${tag}>
|
|
1628
|
-
`)
|
|
1629
|
-
);
|
|
1630
|
-
|
|
1522
|
+
`);
|
|
1631
1523
|
await mimicUserTyping(el, 'aaaa');
|
|
1632
1524
|
expect(el.opened).to.be.true;
|
|
1633
|
-
|
|
1634
1525
|
await mimicUserTyping(el, 'aaa');
|
|
1635
1526
|
await el.updateComplete;
|
|
1636
1527
|
expect(el.opened).to.be.false;
|
|
1637
1528
|
});
|
|
1638
1529
|
});
|
|
1639
|
-
|
|
1640
1530
|
describe('Accessibility', () => {
|
|
1641
1531
|
it('sets "aria-posinset" and "aria-setsize" on visible entries', async () => {
|
|
1642
|
-
const el =
|
|
1532
|
+
const el =
|
|
1533
|
+
/** @type {LionCombobox} */
|
|
1643
1534
|
await fixture(html`
|
|
1644
1535
|
<lion-combobox name="foo" multiple-choice>
|
|
1645
1536
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -1647,16 +1538,13 @@ describe('lion-combobox', () => {
|
|
|
1647
1538
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1648
1539
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
1649
1540
|
</lion-combobox>
|
|
1650
|
-
`)
|
|
1651
|
-
);
|
|
1541
|
+
`);
|
|
1652
1542
|
const options = el.formElements;
|
|
1653
1543
|
expect(el.opened).to.equal(false);
|
|
1654
|
-
|
|
1655
1544
|
await mimicUserTyping(el, 'art');
|
|
1656
1545
|
await el.updateComplete;
|
|
1657
1546
|
expect(el.opened).to.equal(true);
|
|
1658
|
-
|
|
1659
|
-
const visibleOptions = options.filter(o => o.style.display !== 'none');
|
|
1547
|
+
const visibleOptions = options.filter((o) => o.style.display !== 'none');
|
|
1660
1548
|
expect(visibleOptions.length).to.not.equal(0);
|
|
1661
1549
|
visibleOptions.forEach((o, i) => {
|
|
1662
1550
|
expect(o.getAttribute('aria-posinset')).to.equal(`${i + 1}`);
|
|
@@ -1665,11 +1553,11 @@ describe('lion-combobox', () => {
|
|
|
1665
1553
|
/**
|
|
1666
1554
|
* @param {{ style: { display: string; }; }} o
|
|
1667
1555
|
*/
|
|
1668
|
-
const hiddenOptions = options.filter(o => o.style.display === 'none');
|
|
1556
|
+
const hiddenOptions = options.filter((o) => o.style.display === 'none');
|
|
1669
1557
|
/**
|
|
1670
1558
|
* @param {{ hasAttribute: (arg0: string) => any; }} o
|
|
1671
1559
|
*/
|
|
1672
|
-
hiddenOptions.forEach(o => {
|
|
1560
|
+
hiddenOptions.forEach((o) => {
|
|
1673
1561
|
expect(o.hasAttribute('aria-posinset')).to.equal(false);
|
|
1674
1562
|
expect(o.hasAttribute('aria-setsize')).to.equal(false);
|
|
1675
1563
|
});
|
|
@@ -1680,7 +1568,8 @@ describe('lion-combobox', () => {
|
|
|
1680
1568
|
* (like fade in/out)
|
|
1681
1569
|
*/
|
|
1682
1570
|
it('sets aria-hidden="true" on hidden entries', async () => {
|
|
1683
|
-
const el =
|
|
1571
|
+
const el =
|
|
1572
|
+
/** @type {LionCombobox} */
|
|
1684
1573
|
await fixture(html`
|
|
1685
1574
|
<lion-combobox name="foo">
|
|
1686
1575
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -1688,27 +1577,24 @@ describe('lion-combobox', () => {
|
|
|
1688
1577
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1689
1578
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
1690
1579
|
</lion-combobox>
|
|
1691
|
-
`)
|
|
1692
|
-
);
|
|
1580
|
+
`);
|
|
1693
1581
|
const options = el.formElements;
|
|
1694
1582
|
expect(el.opened).to.equal(false);
|
|
1695
|
-
|
|
1696
1583
|
await mimicUserTyping(el, 'art');
|
|
1697
1584
|
expect(el.opened).to.equal(true);
|
|
1698
1585
|
await el.updateComplete;
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
visibleOptions.forEach(o => {
|
|
1586
|
+
const visibleOptions = options.filter((o) => o.style.display !== 'none');
|
|
1587
|
+
visibleOptions.forEach((o) => {
|
|
1702
1588
|
expect(o.hasAttribute('aria-hidden')).to.be.false;
|
|
1703
1589
|
});
|
|
1704
|
-
const hiddenOptions = options.filter(o => o.style.display === 'none');
|
|
1705
|
-
hiddenOptions.forEach(o => {
|
|
1590
|
+
const hiddenOptions = options.filter((o) => o.style.display === 'none');
|
|
1591
|
+
hiddenOptions.forEach((o) => {
|
|
1706
1592
|
expect(o.getAttribute('aria-hidden')).to.equal('true');
|
|
1707
1593
|
});
|
|
1708
1594
|
});
|
|
1709
|
-
|
|
1710
1595
|
it('dropdown has a label', async () => {
|
|
1711
|
-
const el =
|
|
1596
|
+
const el =
|
|
1597
|
+
/** @type {LionCombobox} */
|
|
1712
1598
|
await fixture(html`
|
|
1713
1599
|
<lion-combobox name="foo" .validators=${[new Required()]}>
|
|
1714
1600
|
<lion-option checked .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -1716,8 +1602,7 @@ describe('lion-combobox', () => {
|
|
|
1716
1602
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1717
1603
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
1718
1604
|
</lion-combobox>
|
|
1719
|
-
`)
|
|
1720
|
-
);
|
|
1605
|
+
`);
|
|
1721
1606
|
const { _overlayCtrl } = getComboboxMembers(el);
|
|
1722
1607
|
expect(_overlayCtrl.contentWrapperNode.getAttribute('aria-label')).to.equal(
|
|
1723
1608
|
'Combobox options popup',
|
|
@@ -1731,67 +1616,59 @@ describe('lion-combobox', () => {
|
|
|
1731
1616
|
describe('Invoker component integration', () => {
|
|
1732
1617
|
describe('Accessibility', () => {
|
|
1733
1618
|
it('sets role="combobox" on textbox wrapper/listbox sibling', async () => {
|
|
1734
|
-
const el =
|
|
1619
|
+
const el =
|
|
1620
|
+
/** @type {LionCombobox} */
|
|
1735
1621
|
await fixture(html`
|
|
1736
1622
|
<lion-combobox name="foo">
|
|
1737
1623
|
<lion-option .choiceValue="${'10'}" checked>Item 1</lion-option>
|
|
1738
1624
|
<lion-option .choiceValue="${'20'}">Item 2</lion-option>
|
|
1739
1625
|
</lion-combobox>
|
|
1740
|
-
`)
|
|
1741
|
-
);
|
|
1626
|
+
`);
|
|
1742
1627
|
const { _comboboxNode } = getComboboxMembers(el);
|
|
1743
|
-
|
|
1744
1628
|
expect(_comboboxNode.getAttribute('role')).to.equal('combobox');
|
|
1745
1629
|
});
|
|
1746
|
-
|
|
1747
1630
|
it('sets aria-expanded to element with role="combobox" in wai-aria 1.0 and 1.1', async () => {
|
|
1748
|
-
const el =
|
|
1631
|
+
const el =
|
|
1632
|
+
/** @type {LionCombobox} */
|
|
1749
1633
|
await fixture(html`
|
|
1750
1634
|
<lion-combobox name="foo" ._ariaVersion="${'1.0'}">
|
|
1751
1635
|
<lion-option .choiceValue="${'10'}" checked>Item 1</lion-option>
|
|
1752
1636
|
<lion-option .choiceValue="${'20'}">Item 2</lion-option>
|
|
1753
1637
|
</lion-combobox>
|
|
1754
|
-
`)
|
|
1755
|
-
);
|
|
1638
|
+
`);
|
|
1756
1639
|
const { _comboboxNode } = getComboboxMembers(el);
|
|
1757
|
-
|
|
1758
1640
|
expect(_comboboxNode.getAttribute('aria-expanded')).to.equal('false');
|
|
1759
1641
|
el.opened = true;
|
|
1760
1642
|
await el.updateComplete;
|
|
1761
1643
|
expect(_comboboxNode.getAttribute('aria-expanded')).to.equal('true');
|
|
1762
|
-
|
|
1763
|
-
|
|
1644
|
+
const el2 =
|
|
1645
|
+
/** @type {LionCombobox} */
|
|
1764
1646
|
await fixture(html`
|
|
1765
1647
|
<lion-combobox name="foo" ._ariaVersion="${'1.1'}">
|
|
1766
1648
|
<lion-option .choiceValue="${'10'}" checked>Item 1</lion-option>
|
|
1767
1649
|
<lion-option .choiceValue="${'20'}">Item 2</lion-option>
|
|
1768
1650
|
</lion-combobox>
|
|
1769
|
-
`)
|
|
1770
|
-
);
|
|
1651
|
+
`);
|
|
1771
1652
|
const { _comboboxNode: comboboxNode2 } = getComboboxMembers(el2);
|
|
1772
|
-
|
|
1773
1653
|
expect(comboboxNode2.getAttribute('aria-expanded')).to.equal('false');
|
|
1774
1654
|
el2.opened = true;
|
|
1775
1655
|
await el2.updateComplete;
|
|
1776
1656
|
expect(_comboboxNode.getAttribute('aria-expanded')).to.equal('true');
|
|
1777
1657
|
});
|
|
1778
|
-
|
|
1779
1658
|
it('makes sure listbox node is not focusable', async () => {
|
|
1780
|
-
const el =
|
|
1659
|
+
const el =
|
|
1660
|
+
/** @type {LionCombobox} */
|
|
1781
1661
|
await fixture(html`
|
|
1782
1662
|
<lion-combobox name="foo">
|
|
1783
1663
|
<lion-option .choiceValue="${'10'}" checked>Item 1</lion-option>
|
|
1784
1664
|
<lion-option .choiceValue="${'20'}">Item 2</lion-option>
|
|
1785
1665
|
</lion-combobox>
|
|
1786
|
-
`)
|
|
1787
|
-
);
|
|
1666
|
+
`);
|
|
1788
1667
|
const { _listboxNode } = getComboboxMembers(el);
|
|
1789
|
-
|
|
1790
1668
|
expect(_listboxNode.hasAttribute('tabindex')).to.be.false;
|
|
1791
1669
|
});
|
|
1792
1670
|
});
|
|
1793
1671
|
});
|
|
1794
|
-
|
|
1795
1672
|
describe('Selection display', () => {
|
|
1796
1673
|
class MySelectionDisplay extends LitElement {
|
|
1797
1674
|
/**
|
|
@@ -1808,43 +1685,39 @@ describe('lion-combobox', () => {
|
|
|
1808
1685
|
}
|
|
1809
1686
|
}
|
|
1810
1687
|
const selectionDisplayTag = unsafeStatic(defineCE(MySelectionDisplay));
|
|
1811
|
-
|
|
1812
1688
|
it('stores internal reference _selectionDisplayNode in LionCombobox', async () => {
|
|
1813
|
-
const el =
|
|
1689
|
+
const el =
|
|
1690
|
+
/** @type {LionCombobox} */
|
|
1814
1691
|
await fixture(html`
|
|
1815
1692
|
<lion-combobox name="foo">
|
|
1816
1693
|
<${selectionDisplayTag} slot="selection-display"></${selectionDisplayTag}>
|
|
1817
1694
|
<lion-option .choiceValue="${'10'}" checked>Item 1</lion-option>
|
|
1818
1695
|
</lion-combobox>
|
|
1819
|
-
`)
|
|
1820
|
-
);
|
|
1696
|
+
`);
|
|
1821
1697
|
const { _selectionDisplayNode } = getComboboxMembers(el);
|
|
1822
|
-
|
|
1823
1698
|
expect(_selectionDisplayNode).to.equal(el.querySelector('[slot=selection-display]'));
|
|
1824
1699
|
});
|
|
1825
|
-
|
|
1826
1700
|
it('sets a reference to combobox element in _selectionDisplayNode', async () => {
|
|
1827
|
-
const el =
|
|
1701
|
+
const el =
|
|
1702
|
+
/** @type {LionCombobox} */
|
|
1828
1703
|
await fixture(html`
|
|
1829
1704
|
<lion-combobox name="foo">
|
|
1830
1705
|
<${selectionDisplayTag} slot="selection-display"></${selectionDisplayTag}>
|
|
1831
1706
|
<lion-option .choiceValue="${'10'}" checked>Item 1</lion-option>
|
|
1832
1707
|
</lion-combobox>
|
|
1833
|
-
`)
|
|
1834
|
-
);
|
|
1708
|
+
`);
|
|
1835
1709
|
// @ts-ignore allow protected members
|
|
1836
1710
|
expect(el._selectionDisplayNode.comboboxElement).to.equal(el);
|
|
1837
1711
|
});
|
|
1838
|
-
|
|
1839
1712
|
it('calls "onComboboxElementUpdated(changedProperties)" on "updated" in _selectionDisplayNode', async () => {
|
|
1840
|
-
const el =
|
|
1713
|
+
const el =
|
|
1714
|
+
/** @type {LionCombobox} */
|
|
1841
1715
|
await fixture(html`
|
|
1842
1716
|
<lion-combobox name="foo">
|
|
1843
1717
|
<${selectionDisplayTag} slot="selection-display"></${selectionDisplayTag}>
|
|
1844
1718
|
<lion-option .choiceValue="${'10'}" checked>Item 1</lion-option>
|
|
1845
1719
|
</lion-combobox>
|
|
1846
|
-
`)
|
|
1847
|
-
);
|
|
1720
|
+
`);
|
|
1848
1721
|
// @ts-ignore sinon type error
|
|
1849
1722
|
const spy = sinon.spy(el._selectionDisplayNode, 'onComboboxElementUpdated');
|
|
1850
1723
|
el.requestUpdate('modelValue', undefined);
|
|
@@ -1916,21 +1789,20 @@ describe('lion-combobox', () => {
|
|
|
1916
1789
|
// });
|
|
1917
1790
|
});
|
|
1918
1791
|
});
|
|
1919
|
-
|
|
1920
1792
|
describe('Autocompletion', () => {
|
|
1921
1793
|
it('has autocomplete "both" by default', async () => {
|
|
1922
|
-
const el =
|
|
1794
|
+
const el =
|
|
1795
|
+
/** @type {LionCombobox} */
|
|
1923
1796
|
await fixture(html`
|
|
1924
1797
|
<lion-combobox name="foo">
|
|
1925
1798
|
<lion-option .choiceValue="${'10'}" checked>Item 1</lion-option>
|
|
1926
1799
|
</lion-combobox>
|
|
1927
|
-
`)
|
|
1928
|
-
);
|
|
1800
|
+
`);
|
|
1929
1801
|
expect(el.autocomplete).to.equal('both');
|
|
1930
1802
|
});
|
|
1931
|
-
|
|
1932
1803
|
it('filters options when autocomplete is "both"', async () => {
|
|
1933
|
-
const el =
|
|
1804
|
+
const el =
|
|
1805
|
+
/** @type {LionCombobox} */
|
|
1934
1806
|
await fixture(html`
|
|
1935
1807
|
<lion-combobox name="foo" autocomplete="both">
|
|
1936
1808
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -1938,15 +1810,14 @@ describe('lion-combobox', () => {
|
|
|
1938
1810
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1939
1811
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
1940
1812
|
</lion-combobox>
|
|
1941
|
-
`)
|
|
1942
|
-
);
|
|
1813
|
+
`);
|
|
1943
1814
|
await mimicUserTyping(el, 'ch');
|
|
1944
1815
|
await el.updateComplete;
|
|
1945
1816
|
expect(getFilteredOptionValues(el)).to.eql(['Artichoke', 'Chard', 'Chicory']);
|
|
1946
1817
|
});
|
|
1947
|
-
|
|
1948
1818
|
it('completes textbox when autocomplete is "both"', async () => {
|
|
1949
|
-
const el =
|
|
1819
|
+
const el =
|
|
1820
|
+
/** @type {LionCombobox} */
|
|
1950
1821
|
await fixture(html`
|
|
1951
1822
|
<lion-combobox name="foo" autocomplete="both">
|
|
1952
1823
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -1954,12 +1825,10 @@ describe('lion-combobox', () => {
|
|
|
1954
1825
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1955
1826
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
1956
1827
|
</lion-combobox>
|
|
1957
|
-
`)
|
|
1958
|
-
);
|
|
1828
|
+
`);
|
|
1959
1829
|
await mimicUserTyping(el, 'ch');
|
|
1960
1830
|
await el.updateComplete;
|
|
1961
1831
|
const { _inputNode } = getComboboxMembers(el);
|
|
1962
|
-
|
|
1963
1832
|
expect(_inputNode.value).to.equal('Chard');
|
|
1964
1833
|
expect(_inputNode.selectionStart).to.equal(2);
|
|
1965
1834
|
expect(_inputNode.selectionEnd).to.equal(_inputNode.value.length);
|
|
@@ -1969,9 +1838,9 @@ describe('lion-combobox', () => {
|
|
|
1969
1838
|
expect(_inputNode.value).to.equal('c');
|
|
1970
1839
|
expect(_inputNode.selectionStart).to.equal(_inputNode.value.length);
|
|
1971
1840
|
});
|
|
1972
|
-
|
|
1973
1841
|
it('filters options when autocomplete is "list"', async () => {
|
|
1974
|
-
const el =
|
|
1842
|
+
const el =
|
|
1843
|
+
/** @type {LionCombobox} */
|
|
1975
1844
|
await fixture(html`
|
|
1976
1845
|
<lion-combobox name="foo" autocomplete="list">
|
|
1977
1846
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -1979,18 +1848,16 @@ describe('lion-combobox', () => {
|
|
|
1979
1848
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1980
1849
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
1981
1850
|
</lion-combobox>
|
|
1982
|
-
`)
|
|
1983
|
-
);
|
|
1851
|
+
`);
|
|
1984
1852
|
const { _inputNode } = getComboboxMembers(el);
|
|
1985
|
-
|
|
1986
1853
|
await mimicUserTyping(el, 'ch');
|
|
1987
1854
|
await el.updateComplete;
|
|
1988
1855
|
expect(getFilteredOptionValues(el)).to.eql(['Artichoke', 'Chard', 'Chicory']);
|
|
1989
1856
|
expect(_inputNode.value).to.equal('ch');
|
|
1990
1857
|
});
|
|
1991
|
-
|
|
1992
1858
|
it('does not filter options when autocomplete is "none"', async () => {
|
|
1993
|
-
const el =
|
|
1859
|
+
const el =
|
|
1860
|
+
/** @type {LionCombobox} */
|
|
1994
1861
|
await fixture(html`
|
|
1995
1862
|
<lion-combobox name="foo" autocomplete="none">
|
|
1996
1863
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -1998,8 +1865,7 @@ describe('lion-combobox', () => {
|
|
|
1998
1865
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
1999
1866
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
2000
1867
|
</lion-combobox>
|
|
2001
|
-
`)
|
|
2002
|
-
);
|
|
1868
|
+
`);
|
|
2003
1869
|
await mimicUserTyping(el, 'ch');
|
|
2004
1870
|
await el.updateComplete;
|
|
2005
1871
|
expect(getFilteredOptionValues(el)).to.eql([
|
|
@@ -2009,17 +1875,16 @@ describe('lion-combobox', () => {
|
|
|
2009
1875
|
'Victoria Plum',
|
|
2010
1876
|
]);
|
|
2011
1877
|
});
|
|
2012
|
-
|
|
2013
1878
|
it('does not autocomplete on [Enter] when textbox content does not match options', async () => {
|
|
2014
|
-
const el =
|
|
1879
|
+
const el =
|
|
1880
|
+
/** @type {LionCombobox} */
|
|
2015
1881
|
await fixture(html`
|
|
2016
1882
|
<lion-combobox name="foo">
|
|
2017
1883
|
<lion-option .choiceValue="${'Mango'}">Mango</lion-option>
|
|
2018
1884
|
<lion-option .choiceValue="${'Lemon'}">Lemon</lion-option>
|
|
2019
1885
|
<lion-option .choiceValue="${'Apple'}">Apple</lion-option>
|
|
2020
1886
|
</lion-combobox>
|
|
2021
|
-
`)
|
|
2022
|
-
);
|
|
1887
|
+
`);
|
|
2023
1888
|
const { _inputNode } = getComboboxMembers(el);
|
|
2024
1889
|
mimicUserTypingAdvanced(el, ['m', 'a', 'k']);
|
|
2025
1890
|
await el.updateComplete;
|
|
@@ -2028,17 +1893,16 @@ describe('lion-combobox', () => {
|
|
|
2028
1893
|
await el.updateComplete;
|
|
2029
1894
|
expect(_inputNode.value).to.equal('Mak');
|
|
2030
1895
|
});
|
|
2031
|
-
|
|
2032
1896
|
it('does not autocomplete on [Enter] when textbox content does not match options and content was cleared via [Backspace]', async () => {
|
|
2033
|
-
const el =
|
|
1897
|
+
const el =
|
|
1898
|
+
/** @type {LionCombobox} */
|
|
2034
1899
|
await fixture(html`
|
|
2035
1900
|
<lion-combobox name="foo">
|
|
2036
1901
|
<lion-option .choiceValue="${'Mango'}">Mango</lion-option>
|
|
2037
1902
|
<lion-option .choiceValue="${'Lemon'}">Lemon</lion-option>
|
|
2038
1903
|
<lion-option .choiceValue="${'Apple'}">Apple</lion-option>
|
|
2039
1904
|
</lion-combobox>
|
|
2040
|
-
`)
|
|
2041
|
-
);
|
|
1905
|
+
`);
|
|
2042
1906
|
const { _inputNode } = getComboboxMembers(el);
|
|
2043
1907
|
mimicUserTypingAdvanced(el, ['m', 'o', 'Backspace', 'Backspace', 'm', 'o']);
|
|
2044
1908
|
await el.updateComplete;
|
|
@@ -2050,9 +1914,9 @@ describe('lion-combobox', () => {
|
|
|
2050
1914
|
await el.updateComplete;
|
|
2051
1915
|
expect(_inputNode.value).to.equal('Mo');
|
|
2052
1916
|
});
|
|
2053
|
-
|
|
2054
1917
|
it('does not filter options when autocomplete is "inline"', async () => {
|
|
2055
|
-
const el =
|
|
1918
|
+
const el =
|
|
1919
|
+
/** @type {LionCombobox} */
|
|
2056
1920
|
await fixture(html`
|
|
2057
1921
|
<lion-combobox name="foo" autocomplete="inline">
|
|
2058
1922
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -2060,8 +1924,7 @@ describe('lion-combobox', () => {
|
|
|
2060
1924
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
2061
1925
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
2062
1926
|
</lion-combobox>
|
|
2063
|
-
`)
|
|
2064
|
-
);
|
|
1927
|
+
`);
|
|
2065
1928
|
await mimicUserTyping(el, 'ch');
|
|
2066
1929
|
await el.updateComplete;
|
|
2067
1930
|
expect(getFilteredOptionValues(el)).to.eql([
|
|
@@ -2071,9 +1934,9 @@ describe('lion-combobox', () => {
|
|
|
2071
1934
|
'Victoria Plum',
|
|
2072
1935
|
]);
|
|
2073
1936
|
});
|
|
2074
|
-
|
|
2075
1937
|
it('resets "checkedIndex" when going from matched to unmatched textbox value', async () => {
|
|
2076
|
-
const el =
|
|
1938
|
+
const el =
|
|
1939
|
+
/** @type {LionCombobox} */
|
|
2077
1940
|
await fixture(html`
|
|
2078
1941
|
<lion-combobox name="foo" autocomplete="inline">
|
|
2079
1942
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -2081,19 +1944,17 @@ describe('lion-combobox', () => {
|
|
|
2081
1944
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
2082
1945
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
2083
1946
|
</lion-combobox>
|
|
2084
|
-
`)
|
|
2085
|
-
);
|
|
2086
|
-
|
|
1947
|
+
`);
|
|
2087
1948
|
await mimicUserTyping(el, 'ch');
|
|
2088
1949
|
await el.updateComplete;
|
|
2089
1950
|
expect(el.checkedIndex).to.equal(1);
|
|
2090
|
-
|
|
2091
1951
|
await mimicUserTyping(el, 'cho');
|
|
2092
1952
|
await el.updateComplete;
|
|
2093
1953
|
expect(el.checkedIndex).to.equal(-1);
|
|
2094
1954
|
|
|
2095
1955
|
// Works for autocomplete 'both' as well.
|
|
2096
|
-
const el2 =
|
|
1956
|
+
const el2 =
|
|
1957
|
+
/** @type {LionCombobox} */
|
|
2097
1958
|
await fixture(html`
|
|
2098
1959
|
<lion-combobox name="foo" autocomplete="both">
|
|
2099
1960
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -2101,9 +1962,7 @@ describe('lion-combobox', () => {
|
|
|
2101
1962
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
2102
1963
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
2103
1964
|
</lion-combobox>
|
|
2104
|
-
`)
|
|
2105
|
-
);
|
|
2106
|
-
|
|
1965
|
+
`);
|
|
2107
1966
|
await mimicUserTyping(el2, 'ch');
|
|
2108
1967
|
await el2.updateComplete;
|
|
2109
1968
|
expect(el2.checkedIndex).to.equal(1);
|
|
@@ -2113,9 +1972,9 @@ describe('lion-combobox', () => {
|
|
|
2113
1972
|
await el2.updateComplete;
|
|
2114
1973
|
expect(el2.checkedIndex).to.equal(-1);
|
|
2115
1974
|
});
|
|
2116
|
-
|
|
2117
1975
|
it('resets "checkedIndex" when going from matched to another matched textbox value', async () => {
|
|
2118
|
-
const el =
|
|
1976
|
+
const el =
|
|
1977
|
+
/** @type {LionCombobox} */
|
|
2119
1978
|
await fixture(html`
|
|
2120
1979
|
<lion-combobox name="foo" autocomplete="both">
|
|
2121
1980
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -2123,19 +1982,17 @@ describe('lion-combobox', () => {
|
|
|
2123
1982
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
2124
1983
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
2125
1984
|
</lion-combobox>
|
|
2126
|
-
`)
|
|
2127
|
-
);
|
|
1985
|
+
`);
|
|
2128
1986
|
|
|
2129
1987
|
/** Goes from 2nd option Chard to 3rd option Chicory */
|
|
2130
1988
|
await mimicUserTyping(el, 'ch');
|
|
2131
1989
|
await el.updateComplete;
|
|
2132
1990
|
expect(el.checkedIndex).to.equal(1);
|
|
2133
|
-
|
|
2134
1991
|
await mimicUserTyping(el, 'chi');
|
|
2135
1992
|
await el.updateComplete;
|
|
2136
1993
|
expect(el.checkedIndex).to.equal(2);
|
|
2137
|
-
|
|
2138
|
-
|
|
1994
|
+
const el2 =
|
|
1995
|
+
/** @type {LionCombobox} */
|
|
2139
1996
|
await fixture(html`
|
|
2140
1997
|
<lion-combobox name="foo" autocomplete="both">
|
|
2141
1998
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -2143,9 +2000,7 @@ describe('lion-combobox', () => {
|
|
|
2143
2000
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
2144
2001
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
2145
2002
|
</lion-combobox>
|
|
2146
|
-
`)
|
|
2147
|
-
);
|
|
2148
|
-
|
|
2003
|
+
`);
|
|
2149
2004
|
await mimicUserTyping(el2, 'ch');
|
|
2150
2005
|
await el2.updateComplete;
|
|
2151
2006
|
expect(el2.checkedIndex).to.equal(1);
|
|
@@ -2158,9 +2013,9 @@ describe('lion-combobox', () => {
|
|
|
2158
2013
|
expect(el2.checkedIndex).to.equal(-1);
|
|
2159
2014
|
expect(getFilteredOptionValues(el2)).to.eql(['Artichoke']);
|
|
2160
2015
|
});
|
|
2161
|
-
|
|
2162
2016
|
it('sets "checkedIndex" only if the match, matches from the beginning of the word', async () => {
|
|
2163
|
-
const el =
|
|
2017
|
+
const el =
|
|
2018
|
+
/** @type {LionCombobox} */
|
|
2164
2019
|
await fixture(html`
|
|
2165
2020
|
<lion-combobox name="foo" autocomplete="both">
|
|
2166
2021
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -2168,8 +2023,7 @@ describe('lion-combobox', () => {
|
|
|
2168
2023
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
2169
2024
|
<lion-option .choiceValue="${'Daikon'}">Daikon</lion-option>
|
|
2170
2025
|
</lion-combobox>
|
|
2171
|
-
`)
|
|
2172
|
-
);
|
|
2026
|
+
`);
|
|
2173
2027
|
|
|
2174
2028
|
// first match is Char'd', but better match is 'D'aikon
|
|
2175
2029
|
await mimicUserTyping(el, 'd');
|
|
@@ -2177,9 +2031,9 @@ describe('lion-combobox', () => {
|
|
|
2177
2031
|
expect(el.checkedIndex).to.equal(3);
|
|
2178
2032
|
expect(getFilteredOptionValues(el)).to.eql(['Chard', 'Daikon']);
|
|
2179
2033
|
});
|
|
2180
|
-
|
|
2181
2034
|
it('completes chars inside textbox', async () => {
|
|
2182
|
-
const el =
|
|
2035
|
+
const el =
|
|
2036
|
+
/** @type {LionCombobox} */
|
|
2183
2037
|
await fixture(html`
|
|
2184
2038
|
<lion-combobox name="foo" autocomplete="inline">
|
|
2185
2039
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -2187,16 +2041,13 @@ describe('lion-combobox', () => {
|
|
|
2187
2041
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
2188
2042
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
2189
2043
|
</lion-combobox>
|
|
2190
|
-
`)
|
|
2191
|
-
);
|
|
2044
|
+
`);
|
|
2192
2045
|
const { _inputNode } = getComboboxMembers(el);
|
|
2193
|
-
|
|
2194
2046
|
await mimicUserTyping(el, 'ch');
|
|
2195
2047
|
await el.updateComplete;
|
|
2196
2048
|
expect(_inputNode.value).to.equal('Chard');
|
|
2197
2049
|
expect(_inputNode.selectionStart).to.equal('ch'.length);
|
|
2198
2050
|
expect(_inputNode.selectionEnd).to.equal('Chard'.length);
|
|
2199
|
-
|
|
2200
2051
|
await mimicUserTypingAdvanced(el, ['i', 'c']);
|
|
2201
2052
|
await el.updateComplete;
|
|
2202
2053
|
expect(_inputNode.value).to.equal('Chicory');
|
|
@@ -2210,9 +2061,9 @@ describe('lion-combobox', () => {
|
|
|
2210
2061
|
expect(_inputNode.selectionStart).to.equal('ch'.length);
|
|
2211
2062
|
expect(_inputNode.selectionEnd).to.equal('ch'.length);
|
|
2212
2063
|
});
|
|
2213
|
-
|
|
2214
2064
|
it('synchronizes textbox on overlay close', async () => {
|
|
2215
|
-
const el =
|
|
2065
|
+
const el =
|
|
2066
|
+
/** @type {LionCombobox} */
|
|
2216
2067
|
await fixture(html`
|
|
2217
2068
|
<lion-combobox name="foo" autocomplete="none">
|
|
2218
2069
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -2220,8 +2071,7 @@ describe('lion-combobox', () => {
|
|
|
2220
2071
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
2221
2072
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
2222
2073
|
</lion-combobox>
|
|
2223
|
-
`)
|
|
2224
|
-
);
|
|
2074
|
+
`);
|
|
2225
2075
|
const { _inputNode } = getComboboxMembers(el);
|
|
2226
2076
|
await el.updateComplete;
|
|
2227
2077
|
expect(_inputNode.value).to.equal('');
|
|
@@ -2243,21 +2093,19 @@ describe('lion-combobox', () => {
|
|
|
2243
2093
|
await el.updateComplete;
|
|
2244
2094
|
expect(_inputNode.value).to.equal(valueOnClose, autocomplete);
|
|
2245
2095
|
}
|
|
2246
|
-
|
|
2247
2096
|
await performChecks('none', 0, 'Artichoke');
|
|
2248
2097
|
await performChecks('list', 0, 'Artichoke');
|
|
2249
2098
|
await performChecks('inline', 0, 'Artichoke');
|
|
2250
2099
|
await performChecks('both', 0, 'Artichoke');
|
|
2251
|
-
|
|
2252
2100
|
el.multipleChoice = true;
|
|
2253
2101
|
await performChecks('none', [0, 1], '');
|
|
2254
2102
|
await performChecks('list', [0, 1], '');
|
|
2255
2103
|
await performChecks('inline', [0, 1], '');
|
|
2256
2104
|
await performChecks('both', [0, 1], '');
|
|
2257
2105
|
});
|
|
2258
|
-
|
|
2259
2106
|
it('is possible to adjust textbox synchronize condition on overlay close', async () => {
|
|
2260
|
-
const el =
|
|
2107
|
+
const el =
|
|
2108
|
+
/** @type {LionCombobox} */
|
|
2261
2109
|
await fixture(html`
|
|
2262
2110
|
<lion-combobox name="foo" autocomplete="none" ._syncToTextboxCondition="${() => false}">
|
|
2263
2111
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -2265,9 +2113,7 @@ describe('lion-combobox', () => {
|
|
|
2265
2113
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
2266
2114
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
2267
2115
|
</lion-combobox>
|
|
2268
|
-
`)
|
|
2269
|
-
);
|
|
2270
|
-
|
|
2116
|
+
`);
|
|
2271
2117
|
const { _inputNode } = getComboboxMembers(el);
|
|
2272
2118
|
expect(_inputNode.value).to.equal('');
|
|
2273
2119
|
|
|
@@ -2287,21 +2133,19 @@ describe('lion-combobox', () => {
|
|
|
2287
2133
|
await el.updateComplete;
|
|
2288
2134
|
expect(_inputNode.value).to.equal(valueOnClose);
|
|
2289
2135
|
}
|
|
2290
|
-
|
|
2291
2136
|
await performChecks('none', 0, '');
|
|
2292
2137
|
await performChecks('list', 0, '');
|
|
2293
2138
|
await performChecks('inline', 0, '');
|
|
2294
2139
|
await performChecks('both', 0, '');
|
|
2295
|
-
|
|
2296
2140
|
el.multipleChoice = true;
|
|
2297
2141
|
await performChecks('none', [0, 1], '');
|
|
2298
2142
|
await performChecks('list', [0, 1], '');
|
|
2299
2143
|
await performChecks('inline', [0, 1], '');
|
|
2300
2144
|
await performChecks('both', [0, 1], '');
|
|
2301
2145
|
});
|
|
2302
|
-
|
|
2303
2146
|
it('does inline autocompletion when adding chars', async () => {
|
|
2304
|
-
const el =
|
|
2147
|
+
const el =
|
|
2148
|
+
/** @type {LionCombobox} */
|
|
2305
2149
|
await fixture(html`
|
|
2306
2150
|
<lion-combobox name="foo" autocomplete="inline">
|
|
2307
2151
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -2309,27 +2153,23 @@ describe('lion-combobox', () => {
|
|
|
2309
2153
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
2310
2154
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
2311
2155
|
</lion-combobox>
|
|
2312
|
-
`)
|
|
2313
|
-
);
|
|
2314
|
-
|
|
2156
|
+
`);
|
|
2315
2157
|
await mimicUserTyping(el, 'ch'); // ch
|
|
2316
2158
|
await el.updateComplete; // Ch[ard]
|
|
2317
2159
|
expect(el.activeIndex).to.equal(1);
|
|
2318
2160
|
expect(el.checkedIndex).to.equal(1);
|
|
2319
|
-
|
|
2320
2161
|
await mimicUserTypingAdvanced(el, ['i', 'c']); // Chic
|
|
2321
2162
|
await el.updateComplete; // Chic[ory]
|
|
2322
2163
|
expect(el.activeIndex).to.equal(2);
|
|
2323
2164
|
expect(el.checkedIndex).to.equal(2);
|
|
2324
|
-
|
|
2325
2165
|
await mimicUserTypingAdvanced(el, ['Backspace', 'Backspace', 'Backspace', 'Backspace', 'h']); // Ch
|
|
2326
2166
|
await el.updateComplete; // Ch[ard]
|
|
2327
2167
|
expect(el.activeIndex).to.equal(1);
|
|
2328
2168
|
expect(el.checkedIndex).to.equal(1);
|
|
2329
2169
|
});
|
|
2330
|
-
|
|
2331
2170
|
it('does inline autocompletion when changing the word', async () => {
|
|
2332
|
-
const el =
|
|
2171
|
+
const el =
|
|
2172
|
+
/** @type {LionCombobox} */
|
|
2333
2173
|
await fixture(html`
|
|
2334
2174
|
<lion-combobox name="foo" autocomplete="inline">
|
|
2335
2175
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -2337,14 +2177,11 @@ describe('lion-combobox', () => {
|
|
|
2337
2177
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
2338
2178
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
2339
2179
|
</lion-combobox>
|
|
2340
|
-
`)
|
|
2341
|
-
);
|
|
2342
|
-
|
|
2180
|
+
`);
|
|
2343
2181
|
await mimicUserTyping(el, 'ch');
|
|
2344
2182
|
await el.updateComplete;
|
|
2345
2183
|
expect(el.activeIndex).to.equal(1);
|
|
2346
2184
|
expect(el.checkedIndex).to.equal(1);
|
|
2347
|
-
|
|
2348
2185
|
await mimicUserTypingAdvanced(el, ['i']);
|
|
2349
2186
|
await el.updateComplete;
|
|
2350
2187
|
expect(el.activeIndex).to.equal(2);
|
|
@@ -2356,9 +2193,9 @@ describe('lion-combobox', () => {
|
|
|
2356
2193
|
expect(el.activeIndex).to.equal(0);
|
|
2357
2194
|
expect(el.checkedIndex).to.equal(0);
|
|
2358
2195
|
});
|
|
2359
|
-
|
|
2360
2196
|
it('filters options correctly when changing the middle of the word', async () => {
|
|
2361
|
-
const el =
|
|
2197
|
+
const el =
|
|
2198
|
+
/** @type {LionCombobox} */
|
|
2362
2199
|
await fixture(html`
|
|
2363
2200
|
<lion-combobox name="foo" autocomplete="list" match-mode="all">
|
|
2364
2201
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -2366,17 +2203,13 @@ describe('lion-combobox', () => {
|
|
|
2366
2203
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
2367
2204
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
2368
2205
|
</lion-combobox>
|
|
2369
|
-
`)
|
|
2370
|
-
);
|
|
2371
|
-
|
|
2206
|
+
`);
|
|
2372
2207
|
const { _inputNode } = getComboboxMembers(el);
|
|
2373
|
-
|
|
2374
2208
|
await mimicUserTyping(el, 'char');
|
|
2375
2209
|
expect(_inputNode.value).to.equal('char');
|
|
2376
2210
|
await el.updateComplete; // Char
|
|
2377
2211
|
|
|
2378
2212
|
expect(getFilteredOptionValues(el)).to.eql(['Chard']);
|
|
2379
|
-
|
|
2380
2213
|
_inputNode.setSelectionRange(3, 3);
|
|
2381
2214
|
await mimicUserTypingAdvanced(el, ['Backspace', 'i', 'c', 'o']);
|
|
2382
2215
|
await el.updateComplete; // Chicor
|
|
@@ -2384,9 +2217,9 @@ describe('lion-combobox', () => {
|
|
|
2384
2217
|
expect(_inputNode.value).to.equal('chicor');
|
|
2385
2218
|
expect(getFilteredOptionValues(el)).to.eql(['Chicory']);
|
|
2386
2219
|
});
|
|
2387
|
-
|
|
2388
2220
|
it('computation of "user intends autofill" works correctly afer autofill', async () => {
|
|
2389
|
-
const el =
|
|
2221
|
+
const el =
|
|
2222
|
+
/** @type {LionCombobox} */
|
|
2390
2223
|
await fixture(html`
|
|
2391
2224
|
<lion-combobox name="foo" autocomplete="inline">
|
|
2392
2225
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -2394,10 +2227,8 @@ describe('lion-combobox', () => {
|
|
|
2394
2227
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
2395
2228
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
2396
2229
|
</lion-combobox>
|
|
2397
|
-
`)
|
|
2398
|
-
);
|
|
2230
|
+
`);
|
|
2399
2231
|
const { _inputNode } = getComboboxMembers(el);
|
|
2400
|
-
|
|
2401
2232
|
await mimicUserTyping(el, 'ch');
|
|
2402
2233
|
await el.updateComplete;
|
|
2403
2234
|
expect(_inputNode.value).to.equal('Chard');
|
|
@@ -2412,42 +2243,35 @@ describe('lion-combobox', () => {
|
|
|
2412
2243
|
expect(_inputNode.selectionStart).to.equal('Ch'.length);
|
|
2413
2244
|
expect(_inputNode.selectionEnd).to.equal('Ch'.length);
|
|
2414
2245
|
});
|
|
2415
|
-
|
|
2416
2246
|
describe('Server side completion support', () => {
|
|
2417
2247
|
const listboxData = ['lorem', 'ipsum', 'dolor', 'sit', 'amet'];
|
|
2418
|
-
|
|
2419
2248
|
class MyEl extends LitElement {
|
|
2420
2249
|
constructor() {
|
|
2421
2250
|
super();
|
|
2422
2251
|
/** @type {string[]} */
|
|
2423
2252
|
this.options = [...listboxData];
|
|
2424
2253
|
}
|
|
2425
|
-
|
|
2426
2254
|
clearOptions() {
|
|
2427
2255
|
/** @type {string[]} */
|
|
2428
2256
|
this.options = [];
|
|
2429
2257
|
this.requestUpdate();
|
|
2430
2258
|
}
|
|
2431
|
-
|
|
2432
2259
|
addOption() {
|
|
2433
2260
|
this.options.push(`option ${this.options.length + 1}`);
|
|
2434
2261
|
this.requestUpdate();
|
|
2435
2262
|
}
|
|
2436
|
-
|
|
2437
2263
|
fillAllOptions() {
|
|
2438
2264
|
this.options = [...listboxData];
|
|
2439
2265
|
this.requestUpdate();
|
|
2440
2266
|
}
|
|
2441
|
-
|
|
2442
2267
|
get combobox() {
|
|
2443
|
-
return /** @type {LionCombobox} */
|
|
2268
|
+
return /** @type {LionCombobox} */ this.shadowRoot?.querySelector('#combobox');
|
|
2444
2269
|
}
|
|
2445
|
-
|
|
2446
2270
|
render() {
|
|
2447
2271
|
return html`
|
|
2448
2272
|
<lion-combobox id="combobox" label="Server side completion">
|
|
2449
2273
|
${this.options.map(
|
|
2450
|
-
option => html` <lion-option .choiceValue="${option}">${option}</lion-option> `,
|
|
2274
|
+
(option) => html` <lion-option .choiceValue="${option}">${option}</lion-option> `,
|
|
2451
2275
|
)}
|
|
2452
2276
|
</lion-combobox>
|
|
2453
2277
|
`;
|
|
@@ -2455,9 +2279,8 @@ describe('lion-combobox', () => {
|
|
|
2455
2279
|
}
|
|
2456
2280
|
const tagName = defineCE(MyEl);
|
|
2457
2281
|
const wrappingTag = unsafeStatic(tagName);
|
|
2458
|
-
|
|
2459
2282
|
it('calls "_handleAutocompletion" after externally changing options', async () => {
|
|
2460
|
-
const el = /** @type {MyEl} */
|
|
2283
|
+
const el = /** @type {MyEl} */ await fixture(html`<${wrappingTag}></${wrappingTag}>`);
|
|
2461
2284
|
await el.combobox.registrationComplete;
|
|
2462
2285
|
// @ts-ignore [allow-protected] in test
|
|
2463
2286
|
const spy = sinon.spy(el.combobox, '_handleAutocompletion');
|
|
@@ -2470,10 +2293,9 @@ describe('lion-combobox', () => {
|
|
|
2470
2293
|
await el.updateComplete;
|
|
2471
2294
|
expect(spy).to.have.been.calledTwice;
|
|
2472
2295
|
});
|
|
2473
|
-
|
|
2474
2296
|
it('should handle dynamic options', async () => {
|
|
2475
2297
|
// Arrange
|
|
2476
|
-
const el = /** @type {MyEl} */
|
|
2298
|
+
const el = /** @type {MyEl} */ await fixture(html`<${wrappingTag}></${wrappingTag}>`);
|
|
2477
2299
|
await el.combobox.registrationComplete;
|
|
2478
2300
|
const { _inputNode } = getComboboxMembers(el.combobox);
|
|
2479
2301
|
|
|
@@ -2515,7 +2337,6 @@ describe('lion-combobox', () => {
|
|
|
2515
2337
|
expect(_inputNode.selectionStart).to.equal(_inputNode.value.length);
|
|
2516
2338
|
});
|
|
2517
2339
|
});
|
|
2518
|
-
|
|
2519
2340
|
describe('Subclassers', () => {
|
|
2520
2341
|
it('allows to configure autoselect', async () => {
|
|
2521
2342
|
class X extends LionCombobox {
|
|
@@ -2525,8 +2346,8 @@ describe('lion-combobox', () => {
|
|
|
2525
2346
|
}
|
|
2526
2347
|
const tagName = defineCE(X);
|
|
2527
2348
|
const tag = unsafeStatic(tagName);
|
|
2528
|
-
|
|
2529
|
-
|
|
2349
|
+
const el =
|
|
2350
|
+
/** @type {LionCombobox} */
|
|
2530
2351
|
await fixture(html`
|
|
2531
2352
|
<${tag} name="foo" opened>
|
|
2532
2353
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -2534,17 +2355,15 @@ describe('lion-combobox', () => {
|
|
|
2534
2355
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
2535
2356
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
2536
2357
|
</${tag}>
|
|
2537
|
-
`)
|
|
2538
|
-
);
|
|
2539
|
-
|
|
2358
|
+
`);
|
|
2540
2359
|
await mimicUserTypingAdvanced(el, ['v', 'i']); // so we have options ['Victoria Plum']
|
|
2541
2360
|
await el.updateComplete;
|
|
2542
2361
|
expect(el.checkedIndex).to.equal(3);
|
|
2543
2362
|
});
|
|
2544
2363
|
});
|
|
2545
|
-
|
|
2546
2364
|
it('highlights first occurrence of matching option', async () => {
|
|
2547
|
-
const el =
|
|
2365
|
+
const el =
|
|
2366
|
+
/** @type {LionCombobox} */
|
|
2548
2367
|
await fixture(html`
|
|
2549
2368
|
<lion-combobox name="foo" match-mode="all">
|
|
2550
2369
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -2552,12 +2371,9 @@ describe('lion-combobox', () => {
|
|
|
2552
2371
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
2553
2372
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
2554
2373
|
</lion-combobox>
|
|
2555
|
-
`)
|
|
2556
|
-
);
|
|
2374
|
+
`);
|
|
2557
2375
|
const options = el.formElements;
|
|
2558
|
-
|
|
2559
|
-
await mimicUserTyping(/** @type {LionCombobox} */ (el), 'c');
|
|
2560
|
-
|
|
2376
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'c');
|
|
2561
2377
|
await el.updateComplete;
|
|
2562
2378
|
expect(options[0]).lightDom.to.equal(`<span aria-label="Artichoke">Arti<b>c</b>hoke</span>`);
|
|
2563
2379
|
expect(options[1]).lightDom.to.equal(`<span aria-label="Chard"><b>C</b>hard</span>`);
|
|
@@ -2565,26 +2381,22 @@ describe('lion-combobox', () => {
|
|
|
2565
2381
|
expect(options[3]).lightDom.to.equal(
|
|
2566
2382
|
`<span aria-label="Victoria Plum">Vi<b>c</b>toria Plum</span>`,
|
|
2567
2383
|
);
|
|
2568
|
-
|
|
2569
|
-
await mimicUserTyping(/** @type {LionCombobox} */ (el), 'ch');
|
|
2570
|
-
|
|
2384
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'ch');
|
|
2571
2385
|
await el.updateComplete;
|
|
2572
2386
|
expect(options[0]).lightDom.to.equal(`<span aria-label="Artichoke">Arti<b>ch</b>oke</span>`);
|
|
2573
2387
|
expect(options[1]).lightDom.to.equal(`<span aria-label="Chard"><b>Ch</b>ard</span>`);
|
|
2574
2388
|
expect(options[2]).lightDom.to.equal(`<span aria-label="Chicory"><b>Ch</b>icory</span>`);
|
|
2575
2389
|
expect(options[3]).lightDom.to.equal(`Victoria Plum`);
|
|
2576
|
-
|
|
2577
|
-
await mimicUserTyping(/** @type {LionCombobox} */ (el), 'D');
|
|
2578
|
-
|
|
2390
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'D');
|
|
2579
2391
|
await el.updateComplete;
|
|
2580
2392
|
expect(options[0]).lightDom.to.equal(`Artichoke`);
|
|
2581
2393
|
expect(options[1]).lightDom.to.equal(`<span aria-label="Chard">Char<b>d</b></span>`);
|
|
2582
2394
|
expect(options[2]).lightDom.to.equal(`Chicory`);
|
|
2583
2395
|
expect(options[3]).lightDom.to.equal(`Victoria Plum`);
|
|
2584
2396
|
});
|
|
2585
|
-
|
|
2586
2397
|
it('highlights matching complex options', async () => {
|
|
2587
|
-
const el =
|
|
2398
|
+
const el =
|
|
2399
|
+
/** @type {LionCombobox} */
|
|
2588
2400
|
await fixture(html`
|
|
2589
2401
|
<lion-combobox name="foo" match-mode="all">
|
|
2590
2402
|
<lion-option .choiceValue="${'Artichoke'}">
|
|
@@ -2604,12 +2416,9 @@ describe('lion-combobox', () => {
|
|
|
2604
2416
|
<small>Prunus domestica</small>
|
|
2605
2417
|
</lion-option>
|
|
2606
2418
|
</lion-combobox>
|
|
2607
|
-
`)
|
|
2608
|
-
);
|
|
2419
|
+
`);
|
|
2609
2420
|
const options = el.formElements;
|
|
2610
|
-
|
|
2611
|
-
await mimicUserTyping(/** @type {LionCombobox} */ (el), 'ch');
|
|
2612
|
-
|
|
2421
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'ch');
|
|
2613
2422
|
await el.updateComplete;
|
|
2614
2423
|
expect(options[0]).lightDom.to.equal(
|
|
2615
2424
|
`<span aria-label=" Artichoke Cardoon "><div>Arti<b>ch</b>oke</div><small>Cardoon</small>`,
|
|
@@ -2624,9 +2433,9 @@ describe('lion-combobox', () => {
|
|
|
2624
2433
|
`<div>Victoria Plum</div><small>Prunus domestica</small>`,
|
|
2625
2434
|
);
|
|
2626
2435
|
});
|
|
2627
|
-
|
|
2628
2436
|
it('resets removes highlights on reset()', async () => {
|
|
2629
|
-
const el =
|
|
2437
|
+
const el =
|
|
2438
|
+
/** @type {LionCombobox} */
|
|
2630
2439
|
await fixture(html`
|
|
2631
2440
|
<lion-combobox name="foo" match-mode="all">
|
|
2632
2441
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -2634,21 +2443,18 @@ describe('lion-combobox', () => {
|
|
|
2634
2443
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
2635
2444
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
2636
2445
|
</lion-combobox>
|
|
2637
|
-
`)
|
|
2638
|
-
);
|
|
2446
|
+
`);
|
|
2639
2447
|
const options = el.formElements;
|
|
2640
|
-
|
|
2641
|
-
await mimicUserTyping(/** @type {LionCombobox} */ (el), 'c');
|
|
2642
|
-
|
|
2448
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'c');
|
|
2643
2449
|
await el.updateComplete;
|
|
2644
2450
|
expect(options[0]).lightDom.to.equal(`<span aria-label="Artichoke">Arti<b>c</b>hoke</span>`);
|
|
2645
2451
|
el.reset();
|
|
2646
2452
|
await el.updateComplete;
|
|
2647
2453
|
expect(options[0]).lightDom.to.equal(`Artichoke`);
|
|
2648
2454
|
});
|
|
2649
|
-
|
|
2650
2455
|
it('synchronizes textbox when autocomplete is "inline" or "both"', async () => {
|
|
2651
|
-
const el =
|
|
2456
|
+
const el =
|
|
2457
|
+
/** @type {LionCombobox} */
|
|
2652
2458
|
await fixture(html`
|
|
2653
2459
|
<lion-combobox name="foo" autocomplete="none">
|
|
2654
2460
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -2656,38 +2462,32 @@ describe('lion-combobox', () => {
|
|
|
2656
2462
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
2657
2463
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
2658
2464
|
</lion-combobox>
|
|
2659
|
-
`)
|
|
2660
|
-
);
|
|
2465
|
+
`);
|
|
2661
2466
|
const { _inputNode } = getComboboxMembers(el);
|
|
2662
|
-
|
|
2663
2467
|
expect(_inputNode.value).to.equal('');
|
|
2664
|
-
|
|
2665
2468
|
el.setCheckedIndex(-1);
|
|
2666
2469
|
el.autocomplete = 'list';
|
|
2667
2470
|
await mimicUserTypingAdvanced(el, ['a', 'r', 't']);
|
|
2668
2471
|
expect(_inputNode.value).to.equal('art');
|
|
2669
|
-
|
|
2670
2472
|
el.setCheckedIndex(-1);
|
|
2671
2473
|
el.value = '';
|
|
2672
2474
|
el.autocomplete = 'none';
|
|
2673
2475
|
await mimicUserTypingAdvanced(el, ['a', 'r', 't']);
|
|
2674
2476
|
expect(_inputNode.value).to.equal('art');
|
|
2675
|
-
|
|
2676
2477
|
el.setCheckedIndex(-1);
|
|
2677
2478
|
el.value = '';
|
|
2678
2479
|
el.autocomplete = 'inline';
|
|
2679
2480
|
await mimicUserTypingAdvanced(el, ['a', 'r', 't']);
|
|
2680
2481
|
expect(_inputNode.value).to.equal('Artichoke');
|
|
2681
|
-
|
|
2682
2482
|
el.setCheckedIndex(-1);
|
|
2683
2483
|
el.value = '';
|
|
2684
2484
|
el.autocomplete = 'both';
|
|
2685
2485
|
await mimicUserTypingAdvanced(el, ['a', 'r', 't']);
|
|
2686
2486
|
expect(_inputNode.value).to.equal('Artichoke');
|
|
2687
2487
|
});
|
|
2688
|
-
|
|
2689
2488
|
it('synchronizes last index to textbox when autocomplete is "inline" or "both" when multipleChoice', async () => {
|
|
2690
|
-
const el =
|
|
2489
|
+
const el =
|
|
2490
|
+
/** @type {LionCombobox} */
|
|
2691
2491
|
await fixture(html`
|
|
2692
2492
|
<lion-combobox name="foo" autocomplete="none" multiple-choice>
|
|
2693
2493
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -2695,37 +2495,30 @@ describe('lion-combobox', () => {
|
|
|
2695
2495
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
2696
2496
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
2697
2497
|
</lion-combobox>
|
|
2698
|
-
`)
|
|
2699
|
-
);
|
|
2498
|
+
`);
|
|
2700
2499
|
const { _inputNode } = getComboboxMembers(el);
|
|
2701
|
-
|
|
2702
2500
|
expect(_inputNode.value).to.eql('');
|
|
2703
|
-
|
|
2704
2501
|
el.setCheckedIndex(-1);
|
|
2705
2502
|
el.setCheckedIndex(-1);
|
|
2706
2503
|
el.autocomplete = 'list';
|
|
2707
2504
|
await mimicUserTypingAdvanced(el, ['a', 'r', 't']);
|
|
2708
2505
|
expect(_inputNode.value).to.equal('art');
|
|
2709
|
-
|
|
2710
2506
|
el.setCheckedIndex(-1);
|
|
2711
2507
|
el.value = '';
|
|
2712
2508
|
el.autocomplete = 'none';
|
|
2713
2509
|
await mimicUserTypingAdvanced(el, ['a', 'r', 't']);
|
|
2714
2510
|
expect(_inputNode.value).to.equal('art');
|
|
2715
|
-
|
|
2716
2511
|
el.setCheckedIndex(-1);
|
|
2717
2512
|
el.value = '';
|
|
2718
2513
|
el.autocomplete = 'inline';
|
|
2719
2514
|
await mimicUserTypingAdvanced(el, ['a', 'r', 't']);
|
|
2720
2515
|
expect(_inputNode.value).to.equal('Artichoke');
|
|
2721
|
-
|
|
2722
2516
|
el.setCheckedIndex(-1);
|
|
2723
2517
|
el.value = '';
|
|
2724
2518
|
el.autocomplete = 'both';
|
|
2725
2519
|
await mimicUserTypingAdvanced(el, ['a', 'r', 't']);
|
|
2726
2520
|
expect(_inputNode.value).to.equal('Artichoke');
|
|
2727
2521
|
});
|
|
2728
|
-
|
|
2729
2522
|
describe('Subclassers', () => {
|
|
2730
2523
|
it('allows to override "_syncCheckedWithTextboxMultiple"', async () => {
|
|
2731
2524
|
class X extends LionCombobox {
|
|
@@ -2747,8 +2540,8 @@ describe('lion-combobox', () => {
|
|
|
2747
2540
|
}
|
|
2748
2541
|
const tagName = defineCE(X);
|
|
2749
2542
|
const tag = unsafeStatic(tagName);
|
|
2750
|
-
|
|
2751
|
-
|
|
2543
|
+
const el =
|
|
2544
|
+
/** @type {LionCombobox} */
|
|
2752
2545
|
await fixture(html`
|
|
2753
2546
|
<${tag} name="foo" autocomplete="none" multiple-choice>
|
|
2754
2547
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -2756,31 +2549,25 @@ describe('lion-combobox', () => {
|
|
|
2756
2549
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
2757
2550
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
2758
2551
|
</${tag}>
|
|
2759
|
-
`)
|
|
2760
|
-
);
|
|
2552
|
+
`);
|
|
2761
2553
|
const { _inputNode } = getComboboxMembers(el);
|
|
2762
|
-
|
|
2763
2554
|
el.setCheckedIndex(-1);
|
|
2764
2555
|
el.autocomplete = 'none';
|
|
2765
2556
|
el.setCheckedIndex([0]);
|
|
2766
2557
|
expect(_inputNode.value).to.equal('Artichoke--multi');
|
|
2767
|
-
|
|
2768
2558
|
el.setCheckedIndex(-1);
|
|
2769
2559
|
el.autocomplete = 'list';
|
|
2770
2560
|
el.setCheckedIndex([0]);
|
|
2771
2561
|
expect(_inputNode.value).to.equal('Artichoke--multi');
|
|
2772
|
-
|
|
2773
2562
|
el.setCheckedIndex(-1);
|
|
2774
2563
|
el.autocomplete = 'inline';
|
|
2775
2564
|
el.setCheckedIndex([0]);
|
|
2776
2565
|
expect(_inputNode.value).to.equal('Artichoke--multi');
|
|
2777
|
-
|
|
2778
2566
|
el.setCheckedIndex(-1);
|
|
2779
2567
|
el.autocomplete = 'both';
|
|
2780
2568
|
el.setCheckedIndex([0]);
|
|
2781
2569
|
expect(_inputNode.value).to.equal('Artichoke--multi');
|
|
2782
2570
|
});
|
|
2783
|
-
|
|
2784
2571
|
describe('Override _getTextboxValueFromOption', () => {
|
|
2785
2572
|
it('allows to override "_getTextboxValueFromOption" and sync to textbox when multiple', async () => {
|
|
2786
2573
|
class X extends LionCombobox {
|
|
@@ -2797,8 +2584,8 @@ describe('lion-combobox', () => {
|
|
|
2797
2584
|
}
|
|
2798
2585
|
const tagName = defineCE(X);
|
|
2799
2586
|
const tag = unsafeStatic(tagName);
|
|
2800
|
-
|
|
2801
|
-
|
|
2587
|
+
const el =
|
|
2588
|
+
/** @type {LionCombobox} */
|
|
2802
2589
|
await fixture(html`
|
|
2803
2590
|
<${tag} name="foo" autocomplete="both" multiple-choice>
|
|
2804
2591
|
<lion-option .label="${'Artichoke as label'}" .choiceValue="${{
|
|
@@ -2814,8 +2601,7 @@ describe('lion-combobox', () => {
|
|
|
2814
2601
|
value: 'Victoria Plum',
|
|
2815
2602
|
}}">Victoria Plum</lion-option>
|
|
2816
2603
|
</${tag}>
|
|
2817
|
-
`)
|
|
2818
|
-
);
|
|
2604
|
+
`);
|
|
2819
2605
|
const { _inputNode } = getComboboxMembers(el);
|
|
2820
2606
|
el.setCheckedIndex(-1);
|
|
2821
2607
|
|
|
@@ -2831,7 +2617,6 @@ describe('lion-combobox', () => {
|
|
|
2831
2617
|
// Assert
|
|
2832
2618
|
expect(_inputNode.value).to.equal('Victoria Plum as label');
|
|
2833
2619
|
});
|
|
2834
|
-
|
|
2835
2620
|
it('allows to override "_getTextboxValueFromOption" and sync modelValue with textbox', async () => {
|
|
2836
2621
|
class X extends LionCombobox {
|
|
2837
2622
|
/**
|
|
@@ -2850,8 +2635,8 @@ describe('lion-combobox', () => {
|
|
|
2850
2635
|
}
|
|
2851
2636
|
const tagName = defineCE(X);
|
|
2852
2637
|
const tag = unsafeStatic(tagName);
|
|
2853
|
-
|
|
2854
|
-
|
|
2638
|
+
const el =
|
|
2639
|
+
/** @type {LionCombobox} */
|
|
2855
2640
|
await fixture(html`
|
|
2856
2641
|
<${tag} name="foo">
|
|
2857
2642
|
<lion-option .label="${'Artichoke as label'}" .choiceValue="${{
|
|
@@ -2867,21 +2652,21 @@ describe('lion-combobox', () => {
|
|
|
2867
2652
|
value: 'Victoria Plum',
|
|
2868
2653
|
}}">Victoria Plum</lion-option>
|
|
2869
2654
|
</${tag}>
|
|
2870
|
-
`)
|
|
2871
|
-
);
|
|
2655
|
+
`);
|
|
2872
2656
|
const { _inputNode } = getComboboxMembers(el);
|
|
2873
2657
|
|
|
2874
2658
|
// Assume
|
|
2875
2659
|
expect(_inputNode.value).to.equal('Chard as label');
|
|
2876
2660
|
|
|
2877
2661
|
// Act
|
|
2878
|
-
el.modelValue = {
|
|
2662
|
+
el.modelValue = {
|
|
2663
|
+
value: 'Chicory',
|
|
2664
|
+
};
|
|
2879
2665
|
await el.updateComplete;
|
|
2880
2666
|
|
|
2881
2667
|
// Assert
|
|
2882
2668
|
expect(_inputNode.value).to.equal('Chicory as label');
|
|
2883
2669
|
});
|
|
2884
|
-
|
|
2885
2670
|
it('allows to override "_getTextboxValueFromOption" and clears modelValue and textbox value on clear()', async () => {
|
|
2886
2671
|
class X extends LionCombobox {
|
|
2887
2672
|
/**
|
|
@@ -2900,10 +2685,12 @@ describe('lion-combobox', () => {
|
|
|
2900
2685
|
}
|
|
2901
2686
|
const tagName = defineCE(X);
|
|
2902
2687
|
const tag = unsafeStatic(tagName);
|
|
2903
|
-
|
|
2904
|
-
|
|
2688
|
+
const el =
|
|
2689
|
+
/** @type {LionCombobox} */
|
|
2905
2690
|
await fixture(html`
|
|
2906
|
-
<${tag} name="foo" .modelValue="${{
|
|
2691
|
+
<${tag} name="foo" .modelValue="${{
|
|
2692
|
+
value: 'Artichoke',
|
|
2693
|
+
}}">
|
|
2907
2694
|
<lion-option .label="${'Artichoke as label'}" .choiceValue="${{
|
|
2908
2695
|
value: 'Artichoke',
|
|
2909
2696
|
}}">Artichoke</lion-option>
|
|
@@ -2917,8 +2704,7 @@ describe('lion-combobox', () => {
|
|
|
2917
2704
|
value: 'Victoria Plum',
|
|
2918
2705
|
}}">Victoria Plum</lion-option>
|
|
2919
2706
|
</${tag}>
|
|
2920
|
-
`)
|
|
2921
|
-
);
|
|
2707
|
+
`);
|
|
2922
2708
|
const { _inputNode } = getComboboxMembers(el);
|
|
2923
2709
|
|
|
2924
2710
|
// Assume
|
|
@@ -2931,7 +2717,6 @@ describe('lion-combobox', () => {
|
|
|
2931
2717
|
expect(el.modelValue).to.equal('');
|
|
2932
2718
|
expect(_inputNode.value).to.equal('');
|
|
2933
2719
|
});
|
|
2934
|
-
|
|
2935
2720
|
it('allows to override "_getTextboxValueFromOption" and syncs textbox to modelValue', async () => {
|
|
2936
2721
|
class X extends LionCombobox {
|
|
2937
2722
|
/**
|
|
@@ -2947,8 +2732,8 @@ describe('lion-combobox', () => {
|
|
|
2947
2732
|
}
|
|
2948
2733
|
const tagName = defineCE(X);
|
|
2949
2734
|
const tag = unsafeStatic(tagName);
|
|
2950
|
-
|
|
2951
|
-
|
|
2735
|
+
const el =
|
|
2736
|
+
/** @type {LionCombobox} */
|
|
2952
2737
|
await fixture(html`
|
|
2953
2738
|
<${tag} name="foo">
|
|
2954
2739
|
<lion-option .label="${'Artichoke as label'}" .choiceValue="${{
|
|
@@ -2964,31 +2749,25 @@ describe('lion-combobox', () => {
|
|
|
2964
2749
|
value: 'Victoria Plum',
|
|
2965
2750
|
}}">Victoria Plum</lion-option>
|
|
2966
2751
|
</${tag}>
|
|
2967
|
-
`)
|
|
2968
|
-
);
|
|
2752
|
+
`);
|
|
2969
2753
|
const { _inputNode } = getComboboxMembers(el);
|
|
2970
2754
|
|
|
2971
2755
|
/** @param {string} autocompleteMode */
|
|
2972
2756
|
async function performChecks(autocompleteMode) {
|
|
2973
2757
|
await el.updateComplete;
|
|
2974
|
-
|
|
2975
2758
|
await mimicUserTypingAdvanced(el, ['A', 'r', 't', 'i']);
|
|
2976
2759
|
await el.updateComplete;
|
|
2977
2760
|
expect(_inputNode.value).to.equal('Arti', `autocompleteMode is ${autocompleteMode}`);
|
|
2978
|
-
|
|
2979
2761
|
await el.updateComplete;
|
|
2980
2762
|
expect(el.checkedIndex).to.equal(-1, `autocompleteMode is ${autocompleteMode}`);
|
|
2981
2763
|
_inputNode.value = '';
|
|
2982
2764
|
}
|
|
2983
|
-
|
|
2984
2765
|
el.autocomplete = 'none';
|
|
2985
2766
|
await performChecks('none');
|
|
2986
|
-
|
|
2987
2767
|
el.autocomplete = 'list';
|
|
2988
2768
|
await performChecks('list');
|
|
2989
2769
|
});
|
|
2990
2770
|
});
|
|
2991
|
-
|
|
2992
2771
|
it('allows to override "_onFilterMatch" and "_onFilterUmatch"', async () => {
|
|
2993
2772
|
class X extends LionCombobox {
|
|
2994
2773
|
/**
|
|
@@ -2998,7 +2777,7 @@ describe('lion-combobox', () => {
|
|
|
2998
2777
|
* @protected
|
|
2999
2778
|
*/
|
|
3000
2779
|
_onFilterMatch(option, matchingString) {
|
|
3001
|
-
Array.from(option.children).forEach(child => {
|
|
2780
|
+
Array.from(option.children).forEach((child) => {
|
|
3002
2781
|
if (child.hasAttribute('data-key')) {
|
|
3003
2782
|
this._highlightMatchedOption(child, matchingString);
|
|
3004
2783
|
}
|
|
@@ -3016,7 +2795,7 @@ describe('lion-combobox', () => {
|
|
|
3016
2795
|
*/
|
|
3017
2796
|
// eslint-disable-next-line no-unused-vars
|
|
3018
2797
|
_onFilterUnmatch(option, curValue, prevValue) {
|
|
3019
|
-
Array.from(option.children).forEach(child => {
|
|
2798
|
+
Array.from(option.children).forEach((child) => {
|
|
3020
2799
|
if (child.hasAttribute('data-key')) {
|
|
3021
2800
|
this._unhighlightMatchedOption(child);
|
|
3022
2801
|
}
|
|
@@ -3027,8 +2806,8 @@ describe('lion-combobox', () => {
|
|
|
3027
2806
|
}
|
|
3028
2807
|
const tagName = defineCE(X);
|
|
3029
2808
|
const tag = unsafeStatic(tagName);
|
|
3030
|
-
|
|
3031
|
-
|
|
2809
|
+
const el =
|
|
2810
|
+
/** @type {LionCombobox} */
|
|
3032
2811
|
await fixture(html`
|
|
3033
2812
|
<${tag} name="foo" autocomplete="both">
|
|
3034
2813
|
<lion-option .choiceValue="${'Artichoke'}">
|
|
@@ -3048,12 +2827,9 @@ describe('lion-combobox', () => {
|
|
|
3048
2827
|
<small>Prunus domestica</small>
|
|
3049
2828
|
</lion-option>
|
|
3050
2829
|
</${tag}>
|
|
3051
|
-
`)
|
|
3052
|
-
);
|
|
2830
|
+
`);
|
|
3053
2831
|
const options = el.formElements;
|
|
3054
|
-
|
|
3055
|
-
await mimicUserTyping(/** @type {LionCombobox} */ (el), 'ch');
|
|
3056
|
-
|
|
2832
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'ch');
|
|
3057
2833
|
await el.updateComplete;
|
|
3058
2834
|
expect(options[0]).lightDom.to.equal(
|
|
3059
2835
|
`<div data-key><span aria-label="Artichoke">Arti<b>ch</b>oke</span></div><small>Cardoon</small>`,
|
|
@@ -3067,9 +2843,7 @@ describe('lion-combobox', () => {
|
|
|
3067
2843
|
expect(options[3]).lightDom.to.equal(
|
|
3068
2844
|
`<div data-key>Victoria Plum</div><small>Prunus domestica</small>`,
|
|
3069
2845
|
);
|
|
3070
|
-
|
|
3071
|
-
await mimicUserTyping(/** @type {LionCombobox} */ (el), 'D');
|
|
3072
|
-
|
|
2846
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'D');
|
|
3073
2847
|
await el.updateComplete;
|
|
3074
2848
|
expect(options[0]).lightDom.to.equal(`<div data-key>Artichoke</div><small>Cardoon</small>`);
|
|
3075
2849
|
expect(options[1]).lightDom.to.equal(
|
|
@@ -3081,10 +2855,10 @@ describe('lion-combobox', () => {
|
|
|
3081
2855
|
);
|
|
3082
2856
|
});
|
|
3083
2857
|
});
|
|
3084
|
-
|
|
3085
2858
|
describe('Active index behavior', () => {
|
|
3086
2859
|
it('sets the active index to the closest match on open by default', async () => {
|
|
3087
|
-
const el =
|
|
2860
|
+
const el =
|
|
2861
|
+
/** @type {LionCombobox} */
|
|
3088
2862
|
await fixture(html`
|
|
3089
2863
|
<lion-combobox name="foo">
|
|
3090
2864
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -3092,13 +2866,11 @@ describe('lion-combobox', () => {
|
|
|
3092
2866
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
3093
2867
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
3094
2868
|
</lion-combobox>
|
|
3095
|
-
`)
|
|
3096
|
-
);
|
|
3097
|
-
await mimicUserTyping(/** @type {LionCombobox} */ (el), 'cha');
|
|
2869
|
+
`);
|
|
2870
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'cha');
|
|
3098
2871
|
await el.updateComplete;
|
|
3099
2872
|
expect(el.activeIndex).to.equal(1);
|
|
3100
2873
|
});
|
|
3101
|
-
|
|
3102
2874
|
it('changes whether activeIndex is set to the closest match automatically depending on autocomplete', async () => {
|
|
3103
2875
|
/**
|
|
3104
2876
|
* Automatic selection (setting activeIndex to closest matching option) in lion is set for
|
|
@@ -3106,7 +2878,8 @@ describe('lion-combobox', () => {
|
|
|
3106
2878
|
* For 'list' & 'none' autocomplete, it is turned off and manual selection is required.
|
|
3107
2879
|
* TODO: Make this configurable for list & none autocomplete?
|
|
3108
2880
|
*/
|
|
3109
|
-
const el =
|
|
2881
|
+
const el =
|
|
2882
|
+
/** @type {LionCombobox} */
|
|
3110
2883
|
await fixture(html`
|
|
3111
2884
|
<lion-combobox name="foo" autocomplete="none">
|
|
3112
2885
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -3114,8 +2887,7 @@ describe('lion-combobox', () => {
|
|
|
3114
2887
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
3115
2888
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
3116
2889
|
</lion-combobox>
|
|
3117
|
-
`)
|
|
3118
|
-
);
|
|
2890
|
+
`);
|
|
3119
2891
|
const { _inputNode } = getComboboxMembers(el);
|
|
3120
2892
|
|
|
3121
2893
|
/**
|
|
@@ -3138,12 +2910,10 @@ describe('lion-combobox', () => {
|
|
|
3138
2910
|
// Example 1. List Autocomplete with Manual Selection:
|
|
3139
2911
|
// does not set active at all until user selects
|
|
3140
2912
|
await setup(el, 'none');
|
|
3141
|
-
|
|
3142
|
-
await mimicUserTyping(/** @type {LionCombobox} */ (el), 'cha');
|
|
2913
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'cha');
|
|
3143
2914
|
await el.updateComplete;
|
|
3144
2915
|
expect(el.activeIndex).to.equal(-1);
|
|
3145
2916
|
expect(el.opened).to.be.true;
|
|
3146
|
-
|
|
3147
2917
|
mimicKeyPress(_inputNode, 'Enter');
|
|
3148
2918
|
expect(el.opened).to.be.false;
|
|
3149
2919
|
expect(el.activeIndex).to.equal(-1);
|
|
@@ -3152,12 +2922,10 @@ describe('lion-combobox', () => {
|
|
|
3152
2922
|
// Example 2. List Autocomplete with Automatic Selection:
|
|
3153
2923
|
// does not set active at all until user selects
|
|
3154
2924
|
await setup(el, 'list');
|
|
3155
|
-
|
|
3156
|
-
await mimicUserTyping(/** @type {LionCombobox} */ (el), 'cha');
|
|
2925
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'cha');
|
|
3157
2926
|
await el.updateComplete;
|
|
3158
2927
|
expect(el.opened).to.be.true;
|
|
3159
2928
|
expect(el.activeIndex).to.equal(-1);
|
|
3160
|
-
|
|
3161
2929
|
mimicKeyPress(_inputNode, 'Enter');
|
|
3162
2930
|
expect(el.activeIndex).to.equal(-1);
|
|
3163
2931
|
expect(el.opened).to.be.false;
|
|
@@ -3165,37 +2933,33 @@ describe('lion-combobox', () => {
|
|
|
3165
2933
|
// https://www.w3.org/TR/wai-aria-practices/examples/combobox/aria1.1pattern/listbox-combo.html
|
|
3166
2934
|
// Example 3. List with Inline Autocomplete (mostly, but with aria-autocomplete="inline")
|
|
3167
2935
|
await setup(el, 'inline');
|
|
3168
|
-
|
|
3169
|
-
await mimicUserTyping(/** @type {LionCombobox} */ (el), '');
|
|
2936
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, '');
|
|
3170
2937
|
await el.updateComplete;
|
|
3171
|
-
await mimicUserTyping(/** @type {LionCombobox} */
|
|
2938
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'cha');
|
|
3172
2939
|
await el.updateComplete;
|
|
3173
2940
|
await el.updateComplete;
|
|
3174
2941
|
expect(el.opened).to.be.true;
|
|
3175
|
-
|
|
3176
2942
|
expect(el.activeIndex).to.equal(1);
|
|
3177
|
-
|
|
3178
2943
|
mimicKeyPress(_inputNode, 'Enter');
|
|
3179
2944
|
await el.updateComplete;
|
|
3180
2945
|
await el.updateComplete;
|
|
3181
|
-
|
|
3182
2946
|
expect(el.activeIndex).to.equal(-1);
|
|
3183
2947
|
expect(el.opened).to.be.false;
|
|
3184
2948
|
|
|
3185
2949
|
// https://www.w3.org/TR/wai-aria-practices/examples/combobox/aria1.1pattern/listbox-combo.html
|
|
3186
2950
|
// Example 3. List with Inline Autocomplete
|
|
3187
2951
|
await setup(el, 'both');
|
|
3188
|
-
await mimicUserTyping(/** @type {LionCombobox} */
|
|
2952
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, '');
|
|
3189
2953
|
await el.updateComplete;
|
|
3190
|
-
await mimicUserTyping(/** @type {LionCombobox} */
|
|
2954
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'cha');
|
|
3191
2955
|
await el.updateComplete;
|
|
3192
2956
|
mimicKeyPress(_inputNode, 'Enter');
|
|
3193
2957
|
expect(el.activeIndex).to.equal(1);
|
|
3194
2958
|
expect(el.opened).to.be.false;
|
|
3195
2959
|
});
|
|
3196
|
-
|
|
3197
2960
|
it('sets the active index to the closest match on autocomplete', async () => {
|
|
3198
|
-
const el =
|
|
2961
|
+
const el =
|
|
2962
|
+
/** @type {LionCombobox} */
|
|
3199
2963
|
await fixture(html`
|
|
3200
2964
|
<lion-combobox name="foo" autocomplete="both">
|
|
3201
2965
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -3203,37 +2967,32 @@ describe('lion-combobox', () => {
|
|
|
3203
2967
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
3204
2968
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
3205
2969
|
</lion-combobox>
|
|
3206
|
-
`)
|
|
3207
|
-
);
|
|
2970
|
+
`);
|
|
3208
2971
|
const { _inputNode } = getComboboxMembers(el);
|
|
3209
|
-
|
|
3210
|
-
await mimicUserTyping(/** @type {LionCombobox} */ (el), 'cha');
|
|
2972
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'cha');
|
|
3211
2973
|
await el.updateComplete;
|
|
3212
2974
|
expect(el.activeIndex).to.equal(1);
|
|
3213
|
-
|
|
3214
|
-
await mimicUserTyping(/** @type {LionCombobox} */ (el), 'ch');
|
|
2975
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'ch');
|
|
3215
2976
|
await el.updateComplete;
|
|
3216
|
-
await mimicUserTyping(/** @type {LionCombobox} */
|
|
2977
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'chi');
|
|
3217
2978
|
// Chard no longer matches, so should switch active to Chicory
|
|
3218
2979
|
await el.updateComplete;
|
|
3219
|
-
|
|
3220
2980
|
expect(el.activeIndex).to.equal(2);
|
|
3221
2981
|
|
|
3222
2982
|
// select artichoke
|
|
3223
|
-
await mimicUserTyping(/** @type {LionCombobox} */
|
|
2983
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'artichoke');
|
|
3224
2984
|
await el.updateComplete;
|
|
3225
2985
|
mimicKeyPress(_inputNode, 'Enter');
|
|
3226
|
-
|
|
3227
|
-
await mimicUserTyping(/** @type {LionCombobox} */ (el), '');
|
|
2986
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, '');
|
|
3228
2987
|
await el.updateComplete;
|
|
3229
2988
|
// change selection, active index should update to closest match
|
|
3230
|
-
await mimicUserTyping(/** @type {LionCombobox} */
|
|
2989
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'vic');
|
|
3231
2990
|
await el.updateComplete;
|
|
3232
2991
|
expect(el.activeIndex).to.equal(3);
|
|
3233
2992
|
});
|
|
3234
|
-
|
|
3235
2993
|
it('supports clearing by [Escape] key and resets active state on all options', async () => {
|
|
3236
|
-
const el =
|
|
2994
|
+
const el =
|
|
2995
|
+
/** @type {LionCombobox} */
|
|
3237
2996
|
await fixture(html`
|
|
3238
2997
|
<lion-combobox name="foo">
|
|
3239
2998
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -3241,56 +3000,56 @@ describe('lion-combobox', () => {
|
|
|
3241
3000
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
3242
3001
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
3243
3002
|
</lion-combobox>
|
|
3244
|
-
`)
|
|
3245
|
-
);
|
|
3003
|
+
`);
|
|
3246
3004
|
const { _inputNode } = getComboboxMembers(el);
|
|
3247
3005
|
|
|
3248
3006
|
// Select something
|
|
3249
|
-
await mimicUserTyping(/** @type {LionCombobox} */
|
|
3007
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'cha');
|
|
3250
3008
|
await el.updateComplete;
|
|
3251
3009
|
mimicKeyPress(_inputNode, 'Enter');
|
|
3252
3010
|
expect(el.activeIndex).to.equal(1);
|
|
3253
|
-
|
|
3254
3011
|
mimicKeyPress(_inputNode, 'Escape');
|
|
3255
3012
|
await el.updateComplete;
|
|
3256
3013
|
expect(_inputNode.textContent).to.equal('');
|
|
3257
|
-
|
|
3258
|
-
el.formElements.forEach(option => expect(option.active).to.be.false);
|
|
3014
|
+
el.formElements.forEach((option) => expect(option.active).to.be.false);
|
|
3259
3015
|
|
|
3260
3016
|
// change selection, active index should update to closest match
|
|
3261
|
-
await mimicUserTyping(/** @type {LionCombobox} */
|
|
3017
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'vic');
|
|
3262
3018
|
await el.updateComplete;
|
|
3263
3019
|
expect(el.activeIndex).to.equal(3);
|
|
3264
3020
|
});
|
|
3265
3021
|
});
|
|
3266
|
-
|
|
3267
3022
|
describe('Accessibility', () => {
|
|
3268
3023
|
it('synchronizes autocomplete option to textbox', async () => {
|
|
3269
3024
|
let el;
|
|
3270
|
-
[el] = await fruitFixture({
|
|
3025
|
+
[el] = await fruitFixture({
|
|
3026
|
+
autocomplete: 'both',
|
|
3027
|
+
});
|
|
3271
3028
|
expect(
|
|
3272
|
-
getComboboxMembers(/** @type {LionCombobox} */
|
|
3029
|
+
getComboboxMembers(/** @type {LionCombobox} */ el)._inputNode.getAttribute(
|
|
3273
3030
|
'aria-autocomplete',
|
|
3274
3031
|
),
|
|
3275
3032
|
).to.equal('both');
|
|
3276
|
-
|
|
3277
|
-
|
|
3033
|
+
[el] = await fruitFixture({
|
|
3034
|
+
autocomplete: 'list',
|
|
3035
|
+
});
|
|
3278
3036
|
expect(
|
|
3279
|
-
getComboboxMembers(/** @type {LionCombobox} */
|
|
3037
|
+
getComboboxMembers(/** @type {LionCombobox} */ el)._inputNode.getAttribute(
|
|
3280
3038
|
'aria-autocomplete',
|
|
3281
3039
|
),
|
|
3282
3040
|
).to.equal('list');
|
|
3283
|
-
|
|
3284
|
-
|
|
3041
|
+
[el] = await fruitFixture({
|
|
3042
|
+
autocomplete: 'none',
|
|
3043
|
+
});
|
|
3285
3044
|
expect(
|
|
3286
|
-
getComboboxMembers(/** @type {LionCombobox} */
|
|
3045
|
+
getComboboxMembers(/** @type {LionCombobox} */ el)._inputNode.getAttribute(
|
|
3287
3046
|
'aria-autocomplete',
|
|
3288
3047
|
),
|
|
3289
3048
|
).to.equal('none');
|
|
3290
3049
|
});
|
|
3291
|
-
|
|
3292
3050
|
it('updates aria-activedescendant on textbox node', async () => {
|
|
3293
|
-
const el =
|
|
3051
|
+
const el =
|
|
3052
|
+
/** @type {LionCombobox} */
|
|
3294
3053
|
await fixture(html`
|
|
3295
3054
|
<lion-combobox name="foo" autocomplete="none">
|
|
3296
3055
|
<lion-option .choiceValue="${'Artichoke'}" id="artichoke-option"
|
|
@@ -3300,17 +3059,13 @@ describe('lion-combobox', () => {
|
|
|
3300
3059
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
3301
3060
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
3302
3061
|
</lion-combobox>
|
|
3303
|
-
`)
|
|
3304
|
-
);
|
|
3305
|
-
|
|
3062
|
+
`);
|
|
3306
3063
|
const elProts = getComboboxMembers(el);
|
|
3307
|
-
|
|
3308
3064
|
expect(elProts._activeDescendantOwnerNode.getAttribute('aria-activedescendant')).to.equal(
|
|
3309
3065
|
null,
|
|
3310
3066
|
);
|
|
3311
3067
|
expect(el.formElements[1].active).to.equal(false);
|
|
3312
|
-
|
|
3313
|
-
await mimicUserTyping(/** @type {LionCombobox} */ (el), 'ch');
|
|
3068
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'ch');
|
|
3314
3069
|
await el.updateComplete;
|
|
3315
3070
|
expect(elProts._activeDescendantOwnerNode.getAttribute('aria-activedescendant')).to.equal(
|
|
3316
3071
|
null,
|
|
@@ -3321,8 +3076,8 @@ describe('lion-combobox', () => {
|
|
|
3321
3076
|
'artichoke-option',
|
|
3322
3077
|
);
|
|
3323
3078
|
expect(el.formElements[1].active).to.equal(false);
|
|
3324
|
-
|
|
3325
|
-
|
|
3079
|
+
const el2 =
|
|
3080
|
+
/** @type {LionCombobox} */
|
|
3326
3081
|
await fixture(html`
|
|
3327
3082
|
<lion-combobox name="foo" autocomplete="both" match-mode="begin">
|
|
3328
3083
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -3330,39 +3085,37 @@ describe('lion-combobox', () => {
|
|
|
3330
3085
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
3331
3086
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
3332
3087
|
</lion-combobox>
|
|
3333
|
-
`)
|
|
3334
|
-
);
|
|
3335
|
-
|
|
3088
|
+
`);
|
|
3336
3089
|
const el2Prots = getComboboxMembers(el2);
|
|
3337
|
-
|
|
3338
|
-
await mimicUserTyping(/** @type {LionCombobox} */ (el2), 'ch');
|
|
3090
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el2, 'ch');
|
|
3339
3091
|
await el2.updateComplete;
|
|
3340
3092
|
expect(el2Prots._activeDescendantOwnerNode.getAttribute('aria-activedescendant')).to.equal(
|
|
3341
3093
|
el2.formElements[1].id,
|
|
3342
3094
|
);
|
|
3343
3095
|
expect(el2.formElements[1].active).to.equal(true);
|
|
3344
|
-
|
|
3345
3096
|
el2.autocomplete = 'list';
|
|
3346
|
-
await mimicUserTyping(/** @type {LionCombobox} */
|
|
3097
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'ch');
|
|
3347
3098
|
await el2.updateComplete;
|
|
3348
3099
|
expect(el2Prots._activeDescendantOwnerNode.getAttribute('aria-activedescendant')).to.equal(
|
|
3349
3100
|
el2.formElements[1].id,
|
|
3350
3101
|
);
|
|
3351
3102
|
expect(el2.formElements[1].active).to.equal(true);
|
|
3352
3103
|
});
|
|
3353
|
-
|
|
3354
3104
|
it('adds aria-label to highlighted options', async () => {
|
|
3355
|
-
const [el, options] = await fruitFixture({
|
|
3356
|
-
|
|
3105
|
+
const [el, options] = await fruitFixture({
|
|
3106
|
+
autocomplete: 'both',
|
|
3107
|
+
matchMode: 'all',
|
|
3108
|
+
});
|
|
3109
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'choke');
|
|
3357
3110
|
await el.updateComplete;
|
|
3358
3111
|
// @ts-ignore [dynamic-key-access-in-test]
|
|
3359
3112
|
const labelledElement = options[0].querySelector('span[aria-label="Artichoke"]');
|
|
3360
3113
|
expect(labelledElement).to.not.be.null;
|
|
3361
3114
|
expect(labelledElement.innerText).to.equal('Artichoke');
|
|
3362
3115
|
});
|
|
3363
|
-
|
|
3364
3116
|
it('adds aria-label to highlighted complex options', async () => {
|
|
3365
|
-
const el =
|
|
3117
|
+
const el =
|
|
3118
|
+
/** @type {LionCombobox} */
|
|
3366
3119
|
await fixture(html`
|
|
3367
3120
|
<lion-combobox name="foo" match-mode="all">
|
|
3368
3121
|
<lion-option .choiceValue="${'Artichoke'}">
|
|
@@ -3370,11 +3123,9 @@ describe('lion-combobox', () => {
|
|
|
3370
3123
|
<small>Cardoon</small>
|
|
3371
3124
|
</lion-option>
|
|
3372
3125
|
</lion-combobox>
|
|
3373
|
-
`)
|
|
3374
|
-
);
|
|
3126
|
+
`);
|
|
3375
3127
|
const options = el.formElements;
|
|
3376
|
-
|
|
3377
|
-
await mimicUserTyping(/** @type {LionCombobox} */ (el), 'choke');
|
|
3128
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'choke');
|
|
3378
3129
|
await el.updateComplete;
|
|
3379
3130
|
const labelledElement = options[0].querySelector('span[aria-label=" Artichoke Cardoon "]');
|
|
3380
3131
|
expect(labelledElement).to.not.be.null;
|
|
@@ -3382,60 +3133,51 @@ describe('lion-combobox', () => {
|
|
|
3382
3133
|
});
|
|
3383
3134
|
});
|
|
3384
3135
|
});
|
|
3385
|
-
|
|
3386
3136
|
describe('Accessibility', () => {
|
|
3387
3137
|
describe('Aria versions', () => {
|
|
3388
3138
|
it('[role=combobox] wraps input node in v1.1', async () => {
|
|
3389
|
-
const el =
|
|
3139
|
+
const el =
|
|
3140
|
+
/** @type {LionCombobox} */
|
|
3390
3141
|
await fixture(html`
|
|
3391
3142
|
<lion-combobox name="foo" ._ariaVersion="${'1.1'}">
|
|
3392
3143
|
<lion-option .choiceValue="${'10'}" checked>Item 1</lion-option>
|
|
3393
3144
|
</lion-combobox>
|
|
3394
|
-
`)
|
|
3395
|
-
);
|
|
3145
|
+
`);
|
|
3396
3146
|
const { _comboboxNode, _inputNode } = getComboboxMembers(el);
|
|
3397
|
-
|
|
3398
3147
|
expect(_comboboxNode.contains(_inputNode)).to.be.true;
|
|
3399
3148
|
});
|
|
3400
|
-
|
|
3401
3149
|
it('has one input node with [role=combobox] in v1.0', async () => {
|
|
3402
|
-
const el =
|
|
3150
|
+
const el =
|
|
3151
|
+
/** @type {LionCombobox} */
|
|
3403
3152
|
await fixture(html`
|
|
3404
3153
|
<lion-combobox name="foo" ._ariaVersion="${'1.0'}">
|
|
3405
3154
|
<lion-option .choiceValue="${'10'}" checked>Item 1</lion-option>
|
|
3406
3155
|
</lion-combobox>
|
|
3407
|
-
`)
|
|
3408
|
-
);
|
|
3156
|
+
`);
|
|
3409
3157
|
const { _comboboxNode, _inputNode } = getComboboxMembers(el);
|
|
3410
|
-
|
|
3411
3158
|
expect(_comboboxNode).to.equal(_inputNode);
|
|
3412
3159
|
});
|
|
3413
|
-
|
|
3414
3160
|
it('autodetects aria version and sets it to 1.1 on Chromium browsers', async () => {
|
|
3415
3161
|
const browserDetectionIsChromiumOriginal = browserDetection.isChromium;
|
|
3416
|
-
|
|
3417
3162
|
browserDetection.isChromium = true;
|
|
3418
|
-
const el =
|
|
3163
|
+
const el =
|
|
3164
|
+
/** @type {LionCombobox} */
|
|
3419
3165
|
await fixture(html`
|
|
3420
3166
|
<lion-combobox name="foo">
|
|
3421
3167
|
<lion-option .choiceValue="${'10'}" checked>Item 1</lion-option>
|
|
3422
3168
|
</lion-combobox>
|
|
3423
|
-
`)
|
|
3424
|
-
);
|
|
3169
|
+
`);
|
|
3425
3170
|
const elProts = getComboboxMembers(el);
|
|
3426
|
-
|
|
3427
3171
|
expect(elProts._ariaVersion).to.equal('1.1');
|
|
3428
|
-
|
|
3429
3172
|
browserDetection.isChromium = false;
|
|
3430
|
-
const el2 =
|
|
3173
|
+
const el2 =
|
|
3174
|
+
/** @type {LionCombobox} */
|
|
3431
3175
|
await fixture(html`
|
|
3432
3176
|
<lion-combobox name="foo">
|
|
3433
3177
|
<lion-option .choiceValue="${'10'}" checked>Item 1</lion-option>
|
|
3434
3178
|
</lion-combobox>
|
|
3435
|
-
`)
|
|
3436
|
-
);
|
|
3179
|
+
`);
|
|
3437
3180
|
const el2Prots = getComboboxMembers(el2);
|
|
3438
|
-
|
|
3439
3181
|
expect(el2Prots._ariaVersion).to.equal('1.0');
|
|
3440
3182
|
|
|
3441
3183
|
// restore...
|
|
@@ -3443,11 +3185,11 @@ describe('lion-combobox', () => {
|
|
|
3443
3185
|
});
|
|
3444
3186
|
});
|
|
3445
3187
|
});
|
|
3446
|
-
|
|
3447
3188
|
describe('Multiple Choice', () => {
|
|
3448
3189
|
// TODO: possibly later share test with select-rich if it officially supports multipleChoice
|
|
3449
3190
|
it('does not close listbox on click', async () => {
|
|
3450
|
-
const el =
|
|
3191
|
+
const el =
|
|
3192
|
+
/** @type {LionCombobox} */
|
|
3451
3193
|
await fixture(html`
|
|
3452
3194
|
<lion-combobox name="foo" multiple-choice>
|
|
3453
3195
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -3455,21 +3197,19 @@ describe('lion-combobox', () => {
|
|
|
3455
3197
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
3456
3198
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
3457
3199
|
</lion-combobox>
|
|
3458
|
-
`)
|
|
3459
|
-
);
|
|
3200
|
+
`);
|
|
3460
3201
|
|
|
3461
3202
|
// activate opened listbox
|
|
3462
3203
|
await mimicUserTyping(el, 'ch');
|
|
3463
3204
|
await el.updateComplete;
|
|
3464
|
-
|
|
3465
3205
|
expect(el.opened).to.equal(true);
|
|
3466
|
-
const visibleOptions = el.formElements.filter(o => o.style.display !== 'none');
|
|
3206
|
+
const visibleOptions = el.formElements.filter((o) => o.style.display !== 'none');
|
|
3467
3207
|
visibleOptions[0].click();
|
|
3468
3208
|
expect(el.opened).to.equal(true);
|
|
3469
3209
|
});
|
|
3470
|
-
|
|
3471
3210
|
it('does not close listbox on [Enter]', async () => {
|
|
3472
|
-
const el =
|
|
3211
|
+
const el =
|
|
3212
|
+
/** @type {LionCombobox} */
|
|
3473
3213
|
await fixture(html`
|
|
3474
3214
|
<lion-combobox name="foo" multiple-choice>
|
|
3475
3215
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -3477,23 +3217,24 @@ describe('lion-combobox', () => {
|
|
|
3477
3217
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
3478
3218
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
3479
3219
|
</lion-combobox>
|
|
3480
|
-
`)
|
|
3481
|
-
);
|
|
3482
|
-
|
|
3220
|
+
`);
|
|
3483
3221
|
const { _inputNode } = getComboboxMembers(el);
|
|
3484
|
-
|
|
3485
3222
|
await mimicUserTyping(el, 'art');
|
|
3486
3223
|
await el.updateComplete;
|
|
3487
3224
|
expect(el.opened).to.equal(true);
|
|
3488
3225
|
|
|
3489
3226
|
// N.B. we do only trigger keydown here (and not mimicKeypress (both keyup and down)),
|
|
3490
3227
|
// because this closely mimics what happens in the browser
|
|
3491
|
-
_inputNode.dispatchEvent(
|
|
3228
|
+
_inputNode.dispatchEvent(
|
|
3229
|
+
new KeyboardEvent('keydown', {
|
|
3230
|
+
key: 'Enter',
|
|
3231
|
+
}),
|
|
3232
|
+
);
|
|
3492
3233
|
expect(el.opened).to.equal(true);
|
|
3493
3234
|
});
|
|
3494
|
-
|
|
3495
3235
|
it('clears textbox after selection of a new item on [enter]', async () => {
|
|
3496
|
-
const el =
|
|
3236
|
+
const el =
|
|
3237
|
+
/** @type {LionCombobox} */
|
|
3497
3238
|
await fixture(html`
|
|
3498
3239
|
<lion-combobox name="foo" multiple-choice>
|
|
3499
3240
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -3501,29 +3242,29 @@ describe('lion-combobox', () => {
|
|
|
3501
3242
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
3502
3243
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
3503
3244
|
</lion-combobox>
|
|
3504
|
-
`)
|
|
3505
|
-
);
|
|
3506
|
-
|
|
3245
|
+
`);
|
|
3507
3246
|
const { _inputNode } = getComboboxMembers(el);
|
|
3508
3247
|
const options = el.formElements;
|
|
3509
|
-
|
|
3510
3248
|
await mimicUserTyping(el, 'art');
|
|
3511
3249
|
await el.updateComplete;
|
|
3512
|
-
|
|
3513
3250
|
expect(el.opened).to.equal(true);
|
|
3514
|
-
const visibleOptions = () => options.filter(o => o.style.display !== 'none');
|
|
3251
|
+
const visibleOptions = () => options.filter((o) => o.style.display !== 'none');
|
|
3515
3252
|
expect(visibleOptions().length).to.equal(1);
|
|
3516
3253
|
|
|
3517
3254
|
// N.B. we do only trigger keydown here (and not mimicKeypress (both keyup and down)),
|
|
3518
3255
|
// because this closely mimics what happens in the browser
|
|
3519
|
-
_inputNode.dispatchEvent(
|
|
3256
|
+
_inputNode.dispatchEvent(
|
|
3257
|
+
new KeyboardEvent('keydown', {
|
|
3258
|
+
key: 'Enter',
|
|
3259
|
+
}),
|
|
3260
|
+
);
|
|
3520
3261
|
expect(el.opened).to.equal(true);
|
|
3521
3262
|
expect(visibleOptions().length).to.equal(0);
|
|
3522
3263
|
expect(_inputNode.value).to.equal('');
|
|
3523
3264
|
});
|
|
3524
|
-
|
|
3525
3265
|
it('clears textbox after selection of a new item on click', async () => {
|
|
3526
|
-
const el =
|
|
3266
|
+
const el =
|
|
3267
|
+
/** @type {LionCombobox} */
|
|
3527
3268
|
await fixture(html`
|
|
3528
3269
|
<lion-combobox name="foo" multiple-choice>
|
|
3529
3270
|
<lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
|
|
@@ -3531,28 +3272,23 @@ describe('lion-combobox', () => {
|
|
|
3531
3272
|
<lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
|
|
3532
3273
|
<lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
|
|
3533
3274
|
</lion-combobox>
|
|
3534
|
-
`)
|
|
3535
|
-
);
|
|
3536
|
-
|
|
3275
|
+
`);
|
|
3537
3276
|
const { _inputNode } = getComboboxMembers(el);
|
|
3538
3277
|
const options = el.formElements;
|
|
3539
|
-
|
|
3540
3278
|
await mimicUserTyping(el, 'art');
|
|
3541
3279
|
await el.updateComplete;
|
|
3542
|
-
|
|
3543
3280
|
expect(el.opened).to.equal(true);
|
|
3544
|
-
const visibleOptions = () => options.filter(o => o.style.display !== 'none');
|
|
3281
|
+
const visibleOptions = () => options.filter((o) => o.style.display !== 'none');
|
|
3545
3282
|
expect(visibleOptions().length).to.equal(1);
|
|
3546
|
-
|
|
3547
3283
|
visibleOptions()[0].click();
|
|
3548
3284
|
expect(el.opened).to.equal(true);
|
|
3549
3285
|
expect(visibleOptions().length).to.equal(0);
|
|
3550
3286
|
expect(_inputNode.value).to.equal('');
|
|
3551
3287
|
});
|
|
3552
|
-
|
|
3553
3288
|
it('submits form on [Enter] when listbox is closed', async () => {
|
|
3554
|
-
const submitSpy = sinon.spy(e => e.preventDefault());
|
|
3555
|
-
const el =
|
|
3289
|
+
const submitSpy = sinon.spy((e) => e.preventDefault());
|
|
3290
|
+
const el =
|
|
3291
|
+
/** @type {HTMLFormElement} */
|
|
3556
3292
|
await fixture(html`
|
|
3557
3293
|
<form @submit=${submitSpy}>
|
|
3558
3294
|
<lion-combobox name="foo" multiple-choice>
|
|
@@ -3563,9 +3299,8 @@ describe('lion-combobox', () => {
|
|
|
3563
3299
|
</lion-combobox>
|
|
3564
3300
|
<button type="submit">submit</button>
|
|
3565
3301
|
</form>
|
|
3566
|
-
`)
|
|
3567
|
-
);
|
|
3568
|
-
const combobox = /** @type {LionCombobox} */ (el.querySelector('[name="foo"]'));
|
|
3302
|
+
`);
|
|
3303
|
+
const combobox = /** @type {LionCombobox} */ el.querySelector('[name="foo"]');
|
|
3569
3304
|
const { _inputNode } = getComboboxMembers(combobox);
|
|
3570
3305
|
await combobox.updateComplete;
|
|
3571
3306
|
_inputNode.focus();
|
|
@@ -3574,10 +3309,10 @@ describe('lion-combobox', () => {
|
|
|
3574
3309
|
});
|
|
3575
3310
|
expect(submitSpy.callCount).to.equal(1);
|
|
3576
3311
|
});
|
|
3577
|
-
|
|
3578
3312
|
it('does not submit form on [Enter] when listbox is opened', async () => {
|
|
3579
|
-
const submitSpy = sinon.spy(e => e.preventDefault());
|
|
3580
|
-
const el =
|
|
3313
|
+
const submitSpy = sinon.spy((e) => e.preventDefault());
|
|
3314
|
+
const el =
|
|
3315
|
+
/** @type {HTMLFormElement} */
|
|
3581
3316
|
await fixture(html`
|
|
3582
3317
|
<form @submit=${submitSpy}>
|
|
3583
3318
|
<lion-combobox name="foo" multiple-choice>
|
|
@@ -3588,9 +3323,8 @@ describe('lion-combobox', () => {
|
|
|
3588
3323
|
</lion-combobox>
|
|
3589
3324
|
<button type="submit">submit</button>
|
|
3590
3325
|
</form>
|
|
3591
|
-
`)
|
|
3592
|
-
);
|
|
3593
|
-
const combobox = /** @type {LionCombobox} */ (el.querySelector('[name="foo"]'));
|
|
3326
|
+
`);
|
|
3327
|
+
const combobox = /** @type {LionCombobox} */ el.querySelector('[name="foo"]');
|
|
3594
3328
|
const { _inputNode } = getComboboxMembers(combobox);
|
|
3595
3329
|
combobox.opened = true;
|
|
3596
3330
|
await combobox.updateComplete;
|
|
@@ -3601,35 +3335,30 @@ describe('lion-combobox', () => {
|
|
|
3601
3335
|
expect(submitSpy.callCount).to.equal(0);
|
|
3602
3336
|
});
|
|
3603
3337
|
});
|
|
3604
|
-
|
|
3605
3338
|
describe('Match Mode', () => {
|
|
3606
3339
|
it('has a default value of "all"', async () => {
|
|
3607
3340
|
const [el] = await fruitFixture();
|
|
3608
3341
|
expect(el.matchMode).to.equal('all');
|
|
3609
3342
|
});
|
|
3610
|
-
|
|
3611
3343
|
it('will suggest partial matches (in the middle of the word) when set to "all"', async () => {
|
|
3612
3344
|
const [el] = await fruitFixture();
|
|
3613
|
-
await mimicUserTyping(/** @type {LionCombobox} */
|
|
3345
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'c');
|
|
3614
3346
|
await el.updateComplete;
|
|
3615
|
-
expect(getFilteredOptionValues(/** @type {LionCombobox} */
|
|
3347
|
+
expect(getFilteredOptionValues(/** @type {LionCombobox} */ el)).to.eql([
|
|
3616
3348
|
'Artichoke',
|
|
3617
3349
|
'Chard',
|
|
3618
3350
|
'Chicory',
|
|
3619
3351
|
'Victoria Plum',
|
|
3620
3352
|
]);
|
|
3621
3353
|
});
|
|
3622
|
-
|
|
3623
3354
|
it('will only suggest beginning matches when set to "begin"', async () => {
|
|
3624
|
-
const [el] = await fruitFixture({
|
|
3625
|
-
|
|
3355
|
+
const [el] = await fruitFixture({
|
|
3356
|
+
matchMode: 'begin',
|
|
3357
|
+
});
|
|
3358
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'ch');
|
|
3626
3359
|
await el.updateComplete;
|
|
3627
|
-
expect(getFilteredOptionValues(/** @type {LionCombobox} */
|
|
3628
|
-
'Chard',
|
|
3629
|
-
'Chicory',
|
|
3630
|
-
]);
|
|
3360
|
+
expect(getFilteredOptionValues(/** @type {LionCombobox} */ el)).to.eql(['Chard', 'Chicory']);
|
|
3631
3361
|
});
|
|
3632
|
-
|
|
3633
3362
|
describe('Subclassers', () => {
|
|
3634
3363
|
it('allows for custom matching functions', async () => {
|
|
3635
3364
|
const [el] = await fruitFixture();
|
|
@@ -3641,65 +3370,71 @@ describe('lion-combobox', () => {
|
|
|
3641
3370
|
return option.value === curValue;
|
|
3642
3371
|
}
|
|
3643
3372
|
el.matchCondition = onlyExactMatches;
|
|
3644
|
-
await mimicUserTyping(/** @type {LionCombobox} */
|
|
3373
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'Chicory');
|
|
3645
3374
|
await el.updateComplete;
|
|
3646
|
-
expect(getFilteredOptionValues(/** @type {LionCombobox} */
|
|
3647
|
-
await mimicUserTyping(/** @type {LionCombobox} */
|
|
3375
|
+
expect(getFilteredOptionValues(/** @type {LionCombobox} */ el)).to.eql(['Chicory']);
|
|
3376
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'Chicor');
|
|
3648
3377
|
await el.updateComplete;
|
|
3649
|
-
expect(getFilteredOptionValues(/** @type {LionCombobox} */
|
|
3378
|
+
expect(getFilteredOptionValues(/** @type {LionCombobox} */ el)).to.eql([]);
|
|
3650
3379
|
});
|
|
3651
3380
|
});
|
|
3652
3381
|
});
|
|
3653
|
-
|
|
3654
3382
|
describe('Disabled state', () => {
|
|
3655
3383
|
it('does not open overlay or allow input when disabled', async () => {
|
|
3656
|
-
const [el] = await fruitFixture({
|
|
3384
|
+
const [el] = await fruitFixture({
|
|
3385
|
+
disabled: true,
|
|
3386
|
+
});
|
|
3657
3387
|
expect(el.disabled).to.equal(true);
|
|
3658
|
-
|
|
3659
|
-
const { _inputNode } = getComboboxMembers(/** @type {LionCombobox} */ (el));
|
|
3660
|
-
|
|
3388
|
+
const { _inputNode } = getComboboxMembers(/** @type {LionCombobox} */ el);
|
|
3661
3389
|
expect(el.disabled).to.be.true;
|
|
3662
3390
|
expect(_inputNode.disabled).to.be.true;
|
|
3663
3391
|
|
|
3664
3392
|
// Try to open overlay by clicking input
|
|
3665
|
-
_inputNode.dispatchEvent(
|
|
3393
|
+
_inputNode.dispatchEvent(
|
|
3394
|
+
new Event('click', {
|
|
3395
|
+
bubbles: true,
|
|
3396
|
+
composed: true,
|
|
3397
|
+
}),
|
|
3398
|
+
);
|
|
3666
3399
|
await el.updateComplete;
|
|
3667
3400
|
expect(el.opened).to.be.false;
|
|
3668
3401
|
});
|
|
3669
|
-
|
|
3670
3402
|
it('does open overlay or allow input when disabled state is removed after it was previously disabled', async () => {
|
|
3671
|
-
const [el] = await fruitFixture({
|
|
3403
|
+
const [el] = await fruitFixture({
|
|
3404
|
+
disabled: true,
|
|
3405
|
+
});
|
|
3672
3406
|
expect(el.disabled).to.equal(true);
|
|
3673
|
-
|
|
3674
|
-
const { _inputNode } = getComboboxMembers(/** @type {LionCombobox} */ (el));
|
|
3675
|
-
|
|
3407
|
+
const { _inputNode } = getComboboxMembers(/** @type {LionCombobox} */ el);
|
|
3676
3408
|
expect(el.disabled).to.be.true;
|
|
3677
3409
|
expect(_inputNode.disabled).to.be.true;
|
|
3678
3410
|
|
|
3679
3411
|
// Try to open overlay by clicking input
|
|
3680
|
-
_inputNode.dispatchEvent(
|
|
3412
|
+
_inputNode.dispatchEvent(
|
|
3413
|
+
new Event('click', {
|
|
3414
|
+
bubbles: true,
|
|
3415
|
+
composed: true,
|
|
3416
|
+
}),
|
|
3417
|
+
);
|
|
3681
3418
|
await el.updateComplete;
|
|
3682
3419
|
expect(el.opened).to.be.false;
|
|
3683
|
-
|
|
3684
3420
|
el.disabled = false;
|
|
3685
3421
|
await el.updateComplete;
|
|
3686
|
-
|
|
3687
3422
|
expect(el.disabled).to.be.false;
|
|
3688
3423
|
expect(_inputNode.disabled).to.be.false;
|
|
3689
3424
|
|
|
3690
3425
|
// Try to open overlay by clicking input
|
|
3691
3426
|
async function open() {
|
|
3692
|
-
await mimicUserTyping(/** @type {LionCombobox} */
|
|
3427
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'ch');
|
|
3693
3428
|
return el.updateComplete;
|
|
3694
3429
|
}
|
|
3695
|
-
|
|
3696
3430
|
await open();
|
|
3697
3431
|
expect(el.opened).to.be.true;
|
|
3698
3432
|
});
|
|
3699
|
-
|
|
3700
3433
|
it('sets aria-disabled and disables focus when combobox is disabled', async () => {
|
|
3701
|
-
const [el] = await fruitFixture({
|
|
3702
|
-
|
|
3434
|
+
const [el] = await fruitFixture({
|
|
3435
|
+
disabled: true,
|
|
3436
|
+
});
|
|
3437
|
+
const { _comboboxNode, _inputNode } = getComboboxMembers(/** @type {LionCombobox} */ el);
|
|
3703
3438
|
|
|
3704
3439
|
// input should not be focusable
|
|
3705
3440
|
expect(_comboboxNode.tabIndex).to.equal(-1);
|
|
@@ -3710,13 +3445,13 @@ describe('lion-combobox', () => {
|
|
|
3710
3445
|
|
|
3711
3446
|
// aria-disabled should be set
|
|
3712
3447
|
expect(_inputNode.getAttribute('aria-disabled')).to.equal('true');
|
|
3713
|
-
|
|
3714
3448
|
await expect(el).to.be.accessible();
|
|
3715
3449
|
});
|
|
3716
|
-
|
|
3717
3450
|
it('ensure focus when combobox is readonly', async () => {
|
|
3718
|
-
const [el] = await fruitFixture({
|
|
3719
|
-
|
|
3451
|
+
const [el] = await fruitFixture({
|
|
3452
|
+
readonly: true,
|
|
3453
|
+
});
|
|
3454
|
+
const { _comboboxNode, _inputNode } = getComboboxMembers(/** @type {LionCombobox} */ el);
|
|
3720
3455
|
|
|
3721
3456
|
// input should be focusable
|
|
3722
3457
|
expect(_inputNode.tabIndex).to.equal(0);
|
|
@@ -3726,61 +3461,65 @@ describe('lion-combobox', () => {
|
|
|
3726
3461
|
|
|
3727
3462
|
// aria-disabled should be set
|
|
3728
3463
|
expect(_inputNode.getAttribute('aria-readonly')).to.equal('true');
|
|
3729
|
-
|
|
3730
3464
|
await expect(el).to.be.accessible();
|
|
3731
3465
|
});
|
|
3732
3466
|
});
|
|
3733
|
-
|
|
3734
3467
|
describe('Readonly state', () => {
|
|
3735
3468
|
it('does not open overlay or allow input when readonly', async () => {
|
|
3736
|
-
const [el] = await fruitFixture({
|
|
3737
|
-
|
|
3738
|
-
|
|
3469
|
+
const [el] = await fruitFixture({
|
|
3470
|
+
readonly: true,
|
|
3471
|
+
});
|
|
3472
|
+
const { _inputNode } = getComboboxMembers(/** @type {LionCombobox} */ el);
|
|
3739
3473
|
expect(el.readOnly).to.equal(true);
|
|
3740
|
-
|
|
3741
3474
|
expect(el.readOnly).to.be.true;
|
|
3742
3475
|
expect(_inputNode.readOnly).to.be.true;
|
|
3743
3476
|
|
|
3744
3477
|
// Try to open overlay by clicking input
|
|
3745
|
-
_inputNode.dispatchEvent(
|
|
3478
|
+
_inputNode.dispatchEvent(
|
|
3479
|
+
new Event('click', {
|
|
3480
|
+
bubbles: true,
|
|
3481
|
+
composed: true,
|
|
3482
|
+
}),
|
|
3483
|
+
);
|
|
3746
3484
|
await el.updateComplete;
|
|
3747
3485
|
expect(el.opened).to.be.false;
|
|
3748
3486
|
});
|
|
3749
|
-
|
|
3750
3487
|
it('does open overlay or allow input when readonly state is removed after it was previously set', async () => {
|
|
3751
|
-
const [el] = await fruitFixture({
|
|
3488
|
+
const [el] = await fruitFixture({
|
|
3489
|
+
readonly: true,
|
|
3490
|
+
});
|
|
3752
3491
|
expect(el.readOnly).to.equal(true);
|
|
3753
|
-
|
|
3754
|
-
const { _inputNode } = getComboboxMembers(/** @type {LionCombobox} */ (el));
|
|
3755
|
-
|
|
3492
|
+
const { _inputNode } = getComboboxMembers(/** @type {LionCombobox} */ el);
|
|
3756
3493
|
expect(el.readOnly).to.be.true;
|
|
3757
3494
|
expect(_inputNode.readOnly).to.be.true;
|
|
3758
3495
|
|
|
3759
3496
|
// Try to open overlay by clicking input
|
|
3760
|
-
_inputNode.dispatchEvent(
|
|
3497
|
+
_inputNode.dispatchEvent(
|
|
3498
|
+
new Event('click', {
|
|
3499
|
+
bubbles: true,
|
|
3500
|
+
composed: true,
|
|
3501
|
+
}),
|
|
3502
|
+
);
|
|
3761
3503
|
await el.updateComplete;
|
|
3762
3504
|
expect(el.opened).to.be.false;
|
|
3763
|
-
|
|
3764
3505
|
el.readOnly = false;
|
|
3765
3506
|
await el.updateComplete;
|
|
3766
|
-
|
|
3767
3507
|
expect(el.readOnly).to.be.false;
|
|
3768
3508
|
expect(_inputNode.readOnly).to.be.false;
|
|
3769
3509
|
|
|
3770
3510
|
// Try to open overlay by clicking input
|
|
3771
3511
|
async function open() {
|
|
3772
|
-
await mimicUserTyping(/** @type {LionCombobox} */
|
|
3512
|
+
await mimicUserTyping(/** @type {LionCombobox} */ el, 'ch');
|
|
3773
3513
|
return el.updateComplete;
|
|
3774
3514
|
}
|
|
3775
|
-
|
|
3776
3515
|
await open();
|
|
3777
3516
|
expect(el.opened).to.be.true;
|
|
3778
3517
|
});
|
|
3779
3518
|
});
|
|
3780
|
-
|
|
3781
3519
|
describe('Special Characters in Search', () => {
|
|
3782
3520
|
it('correctly escapes all regex special characters in search queries', async () => {
|
|
3783
|
-
const el =
|
|
3521
|
+
const el =
|
|
3522
|
+
/** @type {LionCombobox} */
|
|
3784
3523
|
await fixture(html`
|
|
3785
3524
|
<lion-combobox label="Search" name="foo">
|
|
3786
3525
|
<lion-option .choiceValue="${'test.com'}">test.com</lion-option>
|
|
@@ -3802,8 +3541,7 @@ describe('lion-combobox', () => {
|
|
|
3802
3541
|
<lion-option .choiceValue="${'funcXargX'}">funcXargX</lion-option>
|
|
3803
3542
|
<lion-option .choiceValue="${'arrayX0X'}">arrayX0X</lion-option>
|
|
3804
3543
|
</lion-combobox>
|
|
3805
|
-
`)
|
|
3806
|
-
);
|
|
3544
|
+
`);
|
|
3807
3545
|
|
|
3808
3546
|
// Test dot - should not act as wildcard
|
|
3809
3547
|
await mimicUserTyping(el, 'test.com');
|