@lion/ui 0.23.0 → 0.25.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 +50 -20
- 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 +35 -53
- 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 +576 -869
- 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 -364
- 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-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 +20 -20
- package/components/input-amount/src/formatters.js +0 -3
- package/components/input-amount/src/parsers.js +0 -3
- package/components/input-amount/test/formatters.test.js +24 -16
- package/components/input-amount/test/lion-input-amount-integrations.test.js +0 -4
- package/components/input-amount/test/lion-input-amount.test.js +123 -147
- 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 +127 -11
- package/components/input-tel/test/preprocessors.test.js +24 -13
- package/components/input-tel/test/validators.test.js +7 -14
- package/components/input-tel/test-helpers/mockPhoneUtilManager.js +20 -8
- 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 +5 -2
- package/components/listbox/src/LionOption.js +8 -7
- package/components/listbox/src/LionOptions.js +0 -3
- package/components/listbox/src/ListboxMixin.js +786 -820
- 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/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/src/InteractiveListMixin.js +637 -638
- package/components/menu/src/LionMenu.js +46 -59
- package/components/menu/src/MoreButtonMenuMixin.js +215 -238
- package/components/menu/src/MultiLevelListMixin.js +240 -246
- package/components/menu/src/utils/isInView.js +0 -1
- package/components/menu/src/utils/listItemInteractions.js +4 -4
- package/components/menu/test/InteractiveListMixin.test.js +0 -1
- package/components/menu/test/MoreButtonMenuMixin.test.js +3 -2
- package/components/menu/test/MultiLevelListMixin.test.js +0 -1
- package/components/menu/test/lion-menu-interactions.test.js +0 -1
- package/components/menu/test/lion-menu.test.js +6 -2
- package/components/menu/test-helpers/mimicKeyPress.js +12 -2
- package/components/menu/test-suites/InteractiveListMixin.suite.js +4 -43
- package/components/menu/test-suites/LionMenu.suite.js +1 -8
- package/components/menu/test-suites/LionMenuInteractions.suite.js +22 -44
- package/components/menu/test-suites/MoreButtonMenuMixin.suite.js +34 -41
- package/components/menu/test-suites/MultiLevelListMixin.suite.js +5 -23
- package/components/overlays/src/ArrowMixin.js +111 -127
- package/components/overlays/src/OverlayController.js +172 -152
- package/components/overlays/src/OverlayMixin.js +64 -69
- 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 +18 -18
- 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 +2 -3
- 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 +406 -555
- 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/invoker-compatibility.test.js +37 -0
- 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 +152 -181
- 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/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 +22 -44
- 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 +116 -116
- package/components/select-rich/test/lion-select-rich-upgrade.test.js +3 -7
- 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 +229 -85
- 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/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/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/input-tel/test-helpers/mockPhoneUtilManager.d.ts +5 -0
- package/dist-types/components/input-tel/test-helpers/mockPhoneUtilManager.d.ts.map +1 -1
- package/dist-types/components/listbox/src/LionListbox.d.ts +2 -2
- package/dist-types/components/listbox/src/LionListbox.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/overlays/src/OverlayController.d.ts +3 -1
- 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/test/invoker-compatibility.test.d.ts +3 -0
- package/dist-types/components/overlays/test/invoker-compatibility.test.d.ts.map +1 -0
- 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 +6 -5
- package/dist-types/components/select-rich/src/LionSelectRich.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 +1 -1
- 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/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/overview.md +5 -5
- package/docs/components/input-amount/use-cases.md +2 -2
- 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/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/api-table.md +4 -4
- package/docs/components/listbox/overview.md +2 -2
- package/docs/components/listbox/use-cases.md +3 -3
- package/docs/components/menu/extensions.md +2 -2
- package/docs/components/menu/migration.md +2 -2
- package/docs/components/menu/overview.md +2 -2
- package/docs/components/menu/use-cases.md +1 -1
- 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 +1 -1
- 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/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 +2 -2
- 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 +1 -1
- 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 +0 -1
- package/exports/define/lion-listbox.js +0 -1
- package/exports/define/lion-menu.js +0 -1
- package/exports/define/lion-menuitem.js +0 -1
- 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/overlays.js +0 -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/package.json +38 -15
- package/vscode.html-custom-data.json +5 -5
- package/web-types.json +1 -1
- package/vendor/README.md +0 -61
- package/vendor/awesome-phonenumber-7.9.0-tlouisse.libphonenumber-9.0.41.tgz +0 -0
|
@@ -18,7 +18,6 @@ import {
|
|
|
18
18
|
import { aTimeout, defineCE, expect, fixture, html, unsafeStatic } from '@open-wc/testing';
|
|
19
19
|
import { LitElement } from 'lit';
|
|
20
20
|
import sinon from 'sinon';
|
|
21
|
-
|
|
22
21
|
import '@lion/ui/define/lion-field.js';
|
|
23
22
|
import '@lion/ui/define/lion-validation-feedback.js';
|
|
24
23
|
|
|
@@ -34,9 +33,7 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
34
33
|
tagString: null,
|
|
35
34
|
...customConfig,
|
|
36
35
|
};
|
|
37
|
-
|
|
38
36
|
const lightDom = cfg.lightDom || '';
|
|
39
|
-
|
|
40
37
|
class ValidateElement extends ValidateMixin(LitElement) {
|
|
41
38
|
connectedCallback() {
|
|
42
39
|
super.connectedCallback();
|
|
@@ -45,10 +42,8 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
45
42
|
this.appendChild(inputNode);
|
|
46
43
|
}
|
|
47
44
|
}
|
|
48
|
-
|
|
49
45
|
const tagString = cfg.tagString || defineCE(ValidateElement);
|
|
50
46
|
const tag = unsafeStatic(tagString);
|
|
51
|
-
|
|
52
47
|
describe('ValidateMixin', () => {
|
|
53
48
|
/**
|
|
54
49
|
* Terminology
|
|
@@ -76,7 +71,7 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
76
71
|
it('throws and console.errors if adding non Validator instances to the validators array', async () => {
|
|
77
72
|
// we throw and console error as constructor throw are not visible to the end user
|
|
78
73
|
const stub = sinon.stub(console, 'error');
|
|
79
|
-
const el = /** @type {ValidateElement} */
|
|
74
|
+
const el = /** @type {ValidateElement} */ await fixture(html`<${tag}></${tag}>`);
|
|
80
75
|
const errorMessage =
|
|
81
76
|
'Validators array only accepts class instances of Validator. Type "array" found. This may be caused by having multiple installations of "@lion/ui/form-core.js".';
|
|
82
77
|
expect(() => {
|
|
@@ -84,7 +79,6 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
84
79
|
el.validators = [[new Required()]];
|
|
85
80
|
}).to.throw(errorMessage);
|
|
86
81
|
expect(stub.args[0][0]).to.equal(errorMessage);
|
|
87
|
-
|
|
88
82
|
const errorMessage2 =
|
|
89
83
|
'Validators array only accepts class instances of Validator. Type "string" found. This may be caused by having multiple installations of "@lion/ui/form-core.js".';
|
|
90
84
|
expect(() => {
|
|
@@ -92,10 +86,8 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
92
86
|
el.validators = ['required'];
|
|
93
87
|
}).to.throw(errorMessage2);
|
|
94
88
|
expect(stub.args[1][0]).to.equal(errorMessage2);
|
|
95
|
-
|
|
96
89
|
stub.restore();
|
|
97
90
|
});
|
|
98
|
-
|
|
99
91
|
it('throws a console error if adding a non supported Validator type', async () => {
|
|
100
92
|
// we throw and console error to improve DX
|
|
101
93
|
const stub = sinon.stub(console, 'error');
|
|
@@ -105,28 +97,25 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
105
97
|
super();
|
|
106
98
|
this.type = 'major error';
|
|
107
99
|
}
|
|
108
|
-
|
|
109
100
|
static get validatorName() {
|
|
110
101
|
return 'MajorValidator';
|
|
111
102
|
}
|
|
112
103
|
}
|
|
113
|
-
const el = /** @type {ValidateElement} */
|
|
104
|
+
const el = /** @type {ValidateElement} */ await fixture(html`<${tag}></${tag}>`);
|
|
114
105
|
expect(() => {
|
|
115
106
|
el.validators = [new MajorValidator()];
|
|
116
107
|
}).to.throw(errorMessage);
|
|
117
108
|
expect(stub.args[0][0]).to.equal(errorMessage);
|
|
118
|
-
|
|
119
109
|
stub.restore();
|
|
120
110
|
});
|
|
121
|
-
|
|
122
111
|
it('validates on initialization (once form field has bootstrapped/initialized)', async () => {
|
|
123
|
-
const el =
|
|
112
|
+
const el =
|
|
113
|
+
/** @type {ValidateElement} */
|
|
124
114
|
await fixture(html`
|
|
125
115
|
<${tag}
|
|
126
116
|
.validators=${[new Required()]}
|
|
127
117
|
>${lightDom}</${tag}>
|
|
128
|
-
`)
|
|
129
|
-
);
|
|
118
|
+
`);
|
|
130
119
|
expect(el.hasFeedbackFor).to.deep.equal(['error']);
|
|
131
120
|
});
|
|
132
121
|
|
|
@@ -134,208 +123,169 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
134
123
|
it('determines whether the "Required" validator was already handled by judging the validatorName', async () => {
|
|
135
124
|
class BundledValidator extends EventTarget {
|
|
136
125
|
static ['_$isValidator$'] = true;
|
|
137
|
-
|
|
138
126
|
static validatorName = '';
|
|
139
|
-
|
|
140
127
|
constructor() {
|
|
141
128
|
super();
|
|
142
|
-
|
|
143
129
|
this.type = 'error';
|
|
144
130
|
}
|
|
145
|
-
|
|
146
131
|
get config() {
|
|
147
132
|
// simplified version of the actual config
|
|
148
133
|
return {};
|
|
149
134
|
}
|
|
150
|
-
|
|
151
135
|
execute() {
|
|
152
136
|
// simplified version of the action execution
|
|
153
137
|
return true;
|
|
154
138
|
}
|
|
155
|
-
|
|
156
139
|
onFormControlConnect() {}
|
|
157
|
-
|
|
158
140
|
onFormControlDisconnect() {}
|
|
159
|
-
|
|
160
141
|
async _getMessage() {
|
|
161
142
|
// simplified version of the actual logic
|
|
162
143
|
return 'You need to enter something.';
|
|
163
144
|
}
|
|
164
145
|
}
|
|
165
|
-
|
|
166
146
|
class BundledRequired extends BundledValidator {
|
|
167
147
|
static validatorName = 'Required';
|
|
168
148
|
}
|
|
169
|
-
|
|
170
|
-
|
|
149
|
+
const el =
|
|
150
|
+
/** @type {ValidateElement} */
|
|
171
151
|
await fixture(html`
|
|
172
152
|
<${tag}
|
|
173
153
|
.validators=${[new BundledRequired()]}
|
|
174
154
|
.modelValue=${'myValue'}
|
|
175
155
|
>${lightDom}</${tag}>
|
|
176
|
-
`)
|
|
177
|
-
);
|
|
178
|
-
|
|
156
|
+
`);
|
|
179
157
|
expect(el.hasFeedbackFor).to.deep.equal([]);
|
|
180
158
|
});
|
|
181
|
-
|
|
182
159
|
it('determines whether the "Required" validator was already handled by judging the validatorName', async () => {
|
|
183
160
|
class MyRequired extends Required {
|
|
184
161
|
static validatorName = 'SomethingOtherThanRequired';
|
|
185
162
|
}
|
|
186
|
-
|
|
187
|
-
|
|
163
|
+
const el =
|
|
164
|
+
/** @type {ValidateElement} */
|
|
188
165
|
await fixture(html`
|
|
189
166
|
<${tag}
|
|
190
167
|
.validators=${[new MyRequired()]}
|
|
191
168
|
.modelValue=${'myValue'}
|
|
192
169
|
>${lightDom}</${tag}>
|
|
193
|
-
`)
|
|
194
|
-
);
|
|
195
|
-
|
|
170
|
+
`);
|
|
196
171
|
expect(el.hasFeedbackFor).to.deep.equal([]);
|
|
197
172
|
});
|
|
198
|
-
|
|
199
173
|
it('determines whether the passed Validators are ResultValidators judging by the presence of "executeOnResults"', async () => {
|
|
200
174
|
class ValidateElementWithSuccessType extends ValidateElement {
|
|
201
175
|
static get validationTypes() {
|
|
202
176
|
return ['error', 'success'];
|
|
203
177
|
}
|
|
204
178
|
}
|
|
205
|
-
|
|
206
179
|
const elTagString = defineCE(ValidateElementWithSuccessType);
|
|
207
180
|
const elTag = unsafeStatic(elTagString);
|
|
208
|
-
|
|
209
181
|
class BundledValidator extends EventTarget {
|
|
210
182
|
static ['_$isValidator$'] = true;
|
|
211
|
-
|
|
212
183
|
static validatorName = '';
|
|
213
|
-
|
|
214
184
|
constructor() {
|
|
215
185
|
super();
|
|
216
|
-
|
|
217
186
|
this.type = 'error';
|
|
218
187
|
}
|
|
219
|
-
|
|
220
188
|
get config() {
|
|
221
189
|
// simplified version of the actual config
|
|
222
190
|
return {};
|
|
223
191
|
}
|
|
224
|
-
|
|
225
192
|
execute() {
|
|
226
193
|
// simplified version of the action execution
|
|
227
194
|
return true;
|
|
228
195
|
}
|
|
229
|
-
|
|
230
196
|
onFormControlConnect() {}
|
|
231
|
-
|
|
232
197
|
onFormControlDisconnect() {}
|
|
233
|
-
|
|
234
198
|
async _getMessage() {
|
|
235
199
|
// simplified version of the actual logic
|
|
236
200
|
return 'Success message.';
|
|
237
201
|
}
|
|
238
202
|
}
|
|
239
|
-
|
|
240
203
|
class BundledDefaultSuccess extends BundledValidator {
|
|
241
204
|
constructor() {
|
|
242
205
|
super();
|
|
243
|
-
|
|
244
206
|
this.type = 'success';
|
|
245
207
|
}
|
|
246
|
-
|
|
247
208
|
executeOnResults() {
|
|
248
209
|
return true;
|
|
249
210
|
}
|
|
250
211
|
}
|
|
251
|
-
|
|
252
|
-
|
|
212
|
+
const el =
|
|
213
|
+
/** @type {ValidateElement} */
|
|
253
214
|
await fixture(html`
|
|
254
215
|
<${elTag}
|
|
255
216
|
.validators=${[new Required(), new BundledDefaultSuccess()]}
|
|
256
217
|
.modelValue=${'myValue'}
|
|
257
218
|
>${lightDom}</${elTag}>
|
|
258
|
-
`)
|
|
259
|
-
);
|
|
260
|
-
|
|
219
|
+
`);
|
|
261
220
|
expect(el.hasFeedbackFor).to.deep.equal(['success']);
|
|
262
221
|
});
|
|
263
|
-
|
|
264
222
|
it('revalidates when ".modelValue" changes', async () => {
|
|
265
|
-
const el =
|
|
223
|
+
const el =
|
|
224
|
+
/** @type {ValidateElement} */
|
|
266
225
|
await fixture(html`
|
|
267
226
|
<${tag}
|
|
268
227
|
.validators=${[new AlwaysValid()]}
|
|
269
228
|
.modelValue=${'myValue'}
|
|
270
229
|
>${lightDom}</${tag}>
|
|
271
|
-
`)
|
|
272
|
-
);
|
|
273
|
-
|
|
230
|
+
`);
|
|
274
231
|
const validateSpy = sinon.spy(el, 'validate');
|
|
275
232
|
el.modelValue = 'x';
|
|
276
233
|
expect(validateSpy.callCount).to.equal(1);
|
|
277
234
|
});
|
|
278
|
-
|
|
279
235
|
it('revalidates when child ".modelValue" changes', async () => {
|
|
280
|
-
const el =
|
|
236
|
+
const el =
|
|
237
|
+
/** @type {ValidateElement} */
|
|
281
238
|
await fixture(html`
|
|
282
239
|
<${tag}
|
|
283
240
|
._repropagationRole="${'fieldset'}"
|
|
284
241
|
.validators=${[new AlwaysValid()]}
|
|
285
242
|
.modelValue=${'myValue'}
|
|
286
243
|
><lion-field id="child"><input slot="input"></lion-field></${tag}>
|
|
287
|
-
`)
|
|
288
|
-
);
|
|
244
|
+
`);
|
|
289
245
|
const validateSpy = sinon.spy(el, 'validate');
|
|
290
|
-
/** @type {LionField} */
|
|
246
|
+
/** @type {LionField} */
|
|
247
|
+
el.querySelector('#child').modelValue = 'test';
|
|
291
248
|
await el.updateComplete;
|
|
292
249
|
expect(validateSpy.callCount).to.equal(1);
|
|
293
250
|
});
|
|
294
|
-
|
|
295
251
|
it('revalidates when ".validators" changes', async () => {
|
|
296
|
-
const el =
|
|
252
|
+
const el =
|
|
253
|
+
/** @type {ValidateElement} */
|
|
297
254
|
await fixture(html`
|
|
298
255
|
<${tag}
|
|
299
256
|
.validators=${[new AlwaysValid()]}
|
|
300
257
|
.modelValue=${'myValue'}
|
|
301
258
|
>${lightDom}</${tag}>
|
|
302
|
-
`)
|
|
303
|
-
);
|
|
304
|
-
|
|
259
|
+
`);
|
|
305
260
|
const validateSpy = sinon.spy(el, 'validate');
|
|
306
261
|
el.validators = [new MinLength(3)];
|
|
307
262
|
expect(validateSpy.callCount).to.equal(1);
|
|
308
263
|
});
|
|
309
|
-
|
|
310
264
|
it('revalidates when validator "param-changed"', async () => {
|
|
311
265
|
const validator = new MinLength(3);
|
|
312
|
-
const el =
|
|
266
|
+
const el =
|
|
267
|
+
/** @type {ValidateElement} */
|
|
313
268
|
await fixture(html`
|
|
314
269
|
<${tag}
|
|
315
270
|
.validators=${[validator]}
|
|
316
271
|
.modelValue=${'myValue'}
|
|
317
272
|
>${lightDom}</${tag}>
|
|
318
|
-
`)
|
|
319
|
-
);
|
|
320
|
-
|
|
273
|
+
`);
|
|
321
274
|
const validateSpy = sinon.spy(el, 'validate');
|
|
322
275
|
expect(validateSpy.callCount).to.equal(0);
|
|
323
|
-
|
|
324
276
|
validator.param = 4;
|
|
325
|
-
|
|
326
277
|
expect(validateSpy.callCount).to.equal(1);
|
|
327
278
|
});
|
|
328
|
-
|
|
329
279
|
it('calls "_onValidatorUpdated" when Validator instanced updated', async () => {
|
|
330
280
|
const validator = new MinLength(3);
|
|
331
|
-
const el =
|
|
281
|
+
const el =
|
|
282
|
+
/** @type {ValidateElement} */
|
|
332
283
|
await fixture(html`
|
|
333
284
|
<${tag}
|
|
334
285
|
.validators=${[validator]}
|
|
335
286
|
.modelValue=${'myValue'}
|
|
336
287
|
>${lightDom}</${tag}>
|
|
337
|
-
`)
|
|
338
|
-
);
|
|
288
|
+
`);
|
|
339
289
|
|
|
340
290
|
// @ts-ignore
|
|
341
291
|
const spy = sinon.spy(el, '_onValidatorUpdated');
|
|
@@ -346,7 +296,9 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
346
296
|
const [eventArg1, metaArg1] = spy.args[0];
|
|
347
297
|
expect(eventArg1).to.be.instanceOf(Event);
|
|
348
298
|
expect(eventArg1.type).to.equal('param-changed');
|
|
349
|
-
expect(metaArg1).to.eql({
|
|
299
|
+
expect(metaArg1).to.eql({
|
|
300
|
+
validator,
|
|
301
|
+
});
|
|
350
302
|
|
|
351
303
|
// on config-changed
|
|
352
304
|
validator.config = {};
|
|
@@ -354,18 +306,19 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
354
306
|
const [eventArg2, metaArg2] = spy.args[1];
|
|
355
307
|
expect(eventArg2).to.be.instanceOf(Event);
|
|
356
308
|
expect(eventArg2.type).to.equal('config-changed');
|
|
357
|
-
expect(metaArg2).to.eql({
|
|
309
|
+
expect(metaArg2).to.eql({
|
|
310
|
+
validator,
|
|
311
|
+
});
|
|
358
312
|
});
|
|
359
|
-
|
|
360
313
|
it('clears current results when ".modelValue" changes', async () => {
|
|
361
|
-
const el =
|
|
314
|
+
const el =
|
|
315
|
+
/** @type {ValidateElement} */
|
|
362
316
|
await fixture(html`
|
|
363
317
|
<${tag}
|
|
364
318
|
.validators=${[new AlwaysValid()]}
|
|
365
319
|
.modelValue=${'myValue'}
|
|
366
320
|
>${lightDom}</${tag}>
|
|
367
|
-
`)
|
|
368
|
-
);
|
|
321
|
+
`);
|
|
369
322
|
|
|
370
323
|
// @ts-ignore [allow-private] in test
|
|
371
324
|
const clearSpy = sinon.spy(el, '__clearValidationResults');
|
|
@@ -381,16 +334,15 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
381
334
|
* Inside "Validator integration" we test reinitiation on Validator param change
|
|
382
335
|
*/
|
|
383
336
|
});
|
|
384
|
-
|
|
385
337
|
describe('Validation process: internal flow', () => {
|
|
386
338
|
it('firstly checks for empty values', async () => {
|
|
387
339
|
const alwaysValid = new AlwaysValid();
|
|
388
340
|
const alwaysValidExecuteSpy = sinon.spy(alwaysValid, 'execute');
|
|
389
|
-
const el =
|
|
341
|
+
const el =
|
|
342
|
+
/** @type {ValidateElement} */
|
|
390
343
|
await fixture(html`
|
|
391
344
|
<${tag} .validators=${[alwaysValid]}>${lightDom}</${tag}>
|
|
392
|
-
`)
|
|
393
|
-
);
|
|
345
|
+
`);
|
|
394
346
|
// @ts-ignore [allow-private] in test
|
|
395
347
|
const isEmptySpy = sinon.spy(el, '__isEmpty');
|
|
396
348
|
const validateSpy = sinon.spy(el, 'validate');
|
|
@@ -398,19 +350,17 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
398
350
|
expect(validateSpy.callCount).to.equal(1);
|
|
399
351
|
expect(alwaysValidExecuteSpy.callCount).to.equal(0);
|
|
400
352
|
expect(isEmptySpy.callCount).to.equal(1);
|
|
401
|
-
|
|
402
353
|
el.modelValue = 'nonEmpty';
|
|
403
354
|
expect(validateSpy.callCount).to.equal(2);
|
|
404
355
|
expect(alwaysValidExecuteSpy.callCount).to.equal(1);
|
|
405
356
|
expect(isEmptySpy.callCount).to.equal(2);
|
|
406
357
|
});
|
|
407
|
-
|
|
408
358
|
it('secondly checks for synchronous Validators: creates RegularValidationResult', async () => {
|
|
409
|
-
const el =
|
|
359
|
+
const el =
|
|
360
|
+
/** @type {ValidateElement} */
|
|
410
361
|
await fixture(html`
|
|
411
362
|
<${tag} .validators=${[new AlwaysValid()]}>${lightDom}</${tag}>
|
|
412
|
-
`)
|
|
413
|
-
);
|
|
363
|
+
`);
|
|
414
364
|
// @ts-ignore [allow-private] in test
|
|
415
365
|
const isEmptySpy = sinon.spy(el, '__isEmpty');
|
|
416
366
|
// @ts-ignore [allow-private] in test
|
|
@@ -418,15 +368,14 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
418
368
|
el.modelValue = 'nonEmpty';
|
|
419
369
|
expect(isEmptySpy.calledBefore(syncSpy)).to.be.true;
|
|
420
370
|
});
|
|
421
|
-
|
|
422
371
|
it('thirdly schedules asynchronous Validators: creates RegularValidationResult', async () => {
|
|
423
|
-
const el =
|
|
372
|
+
const el =
|
|
373
|
+
/** @type {ValidateElement} */
|
|
424
374
|
await fixture(html`
|
|
425
375
|
<${tag} .validators=${[new AlwaysValid(), new AsyncAlwaysValid()]}>
|
|
426
376
|
${lightDom}
|
|
427
377
|
</${tag}>
|
|
428
|
-
`)
|
|
429
|
-
);
|
|
378
|
+
`);
|
|
430
379
|
// @ts-ignore [allow-private] in test
|
|
431
380
|
const syncSpy = sinon.spy(el, '__executeSyncValidators');
|
|
432
381
|
// @ts-ignore [allow-private] in test
|
|
@@ -434,31 +383,27 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
434
383
|
el.modelValue = 'nonEmpty';
|
|
435
384
|
expect(syncSpy.calledBefore(asyncSpy)).to.be.true;
|
|
436
385
|
});
|
|
437
|
-
|
|
438
386
|
it('finally checks for ResultValidators: creates TotalValidationResult', async () => {
|
|
439
387
|
class MyResult extends ResultValidator {
|
|
440
388
|
static get validatorName() {
|
|
441
389
|
return 'ResultValidator';
|
|
442
390
|
}
|
|
443
391
|
}
|
|
444
|
-
|
|
445
|
-
|
|
392
|
+
let el =
|
|
393
|
+
/** @type {ValidateElement} */
|
|
446
394
|
await fixture(html`
|
|
447
395
|
<${tag}
|
|
448
396
|
.validators=${[new AlwaysValid(), new MyResult()]}>
|
|
449
397
|
${lightDom}
|
|
450
398
|
</${tag}>
|
|
451
|
-
`)
|
|
452
|
-
);
|
|
399
|
+
`);
|
|
453
400
|
|
|
454
401
|
// @ts-ignore [allow-private] in test
|
|
455
402
|
const syncSpy = sinon.spy(el, '__executeSyncValidators');
|
|
456
403
|
// @ts-ignore [allow-private] in test
|
|
457
404
|
const resultSpy2 = sinon.spy(el, '__executeMetaValidators');
|
|
458
|
-
|
|
459
405
|
el.modelValue = 'nonEmpty';
|
|
460
406
|
expect(syncSpy.calledBefore(resultSpy2)).to.be.true;
|
|
461
|
-
|
|
462
407
|
el = await fixture(html`
|
|
463
408
|
<${tag}
|
|
464
409
|
.validators=${[new AsyncAlwaysValid(), new MyResult()]}>
|
|
@@ -470,37 +415,34 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
470
415
|
const asyncSpy = sinon.spy(el, '__executeAsyncValidators');
|
|
471
416
|
// @ts-ignore [allow-private] in test
|
|
472
417
|
const resultSpy = sinon.spy(el, '__executeMetaValidators');
|
|
473
|
-
|
|
474
418
|
el.modelValue = 'nonEmpty';
|
|
475
419
|
expect(resultSpy.callCount).to.equal(1);
|
|
476
420
|
expect(asyncSpy.callCount).to.equal(1);
|
|
477
421
|
await el.validateComplete;
|
|
478
422
|
expect(resultSpy.callCount).to.equal(2);
|
|
479
423
|
});
|
|
480
|
-
|
|
481
424
|
describe('Finalization', () => {
|
|
482
425
|
it('fires private "validate-performed" event on every cycle', async () => {
|
|
483
|
-
const el =
|
|
426
|
+
const el =
|
|
427
|
+
/** @type {ValidateElement} */
|
|
484
428
|
await fixture(html`
|
|
485
429
|
<${tag} .validators=${[new AlwaysValid(), new AsyncAlwaysInvalid()]}>
|
|
486
430
|
${lightDom}
|
|
487
431
|
</${tag}>
|
|
488
|
-
`)
|
|
489
|
-
);
|
|
432
|
+
`);
|
|
490
433
|
const cbSpy = sinon.spy();
|
|
491
434
|
el.addEventListener('validate-performed', cbSpy);
|
|
492
435
|
el.modelValue = 'nonEmpty';
|
|
493
436
|
expect(cbSpy.callCount).to.equal(1);
|
|
494
437
|
});
|
|
495
|
-
|
|
496
438
|
it('resolves ".validateComplete" Promise', async () => {
|
|
497
|
-
const el =
|
|
439
|
+
const el =
|
|
440
|
+
/** @type {ValidateElement} */
|
|
498
441
|
await fixture(html`
|
|
499
442
|
<${tag} .validators=${[new AsyncAlwaysInvalid()]}>
|
|
500
443
|
${lightDom}
|
|
501
444
|
</${tag}>
|
|
502
|
-
`)
|
|
503
|
-
);
|
|
445
|
+
`);
|
|
504
446
|
el.modelValue = 'nonEmpty';
|
|
505
447
|
// @ts-ignore [allow-private] in test
|
|
506
448
|
const validateResolveSpy = sinon.spy(el, '__validateCompleteResolve');
|
|
@@ -509,7 +451,6 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
509
451
|
});
|
|
510
452
|
});
|
|
511
453
|
});
|
|
512
|
-
|
|
513
454
|
describe('Validator Integration', () => {
|
|
514
455
|
class IsCat extends Validator {
|
|
515
456
|
/**
|
|
@@ -528,12 +469,10 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
528
469
|
return showError;
|
|
529
470
|
};
|
|
530
471
|
}
|
|
531
|
-
|
|
532
472
|
static get validatorName() {
|
|
533
473
|
return 'IsCat';
|
|
534
474
|
}
|
|
535
475
|
}
|
|
536
|
-
|
|
537
476
|
class OtherValidator extends Validator {
|
|
538
477
|
/**
|
|
539
478
|
* @param {...any} args
|
|
@@ -542,12 +481,10 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
542
481
|
super(...args);
|
|
543
482
|
this.execute = () => true;
|
|
544
483
|
}
|
|
545
|
-
|
|
546
484
|
static get validatorName() {
|
|
547
485
|
return 'otherValidator';
|
|
548
486
|
}
|
|
549
487
|
}
|
|
550
|
-
|
|
551
488
|
it('Validators will be called with ".modelValue" as first argument', async () => {
|
|
552
489
|
const otherValidator = new OtherValidator();
|
|
553
490
|
const otherValidatorSpy = sinon.spy(otherValidator, 'execute');
|
|
@@ -560,7 +497,6 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
560
497
|
// @ts-expect-error weird sinon type error..
|
|
561
498
|
expect(otherValidatorSpy.calledWith('model')).to.be.true;
|
|
562
499
|
});
|
|
563
|
-
|
|
564
500
|
it('Validators will be called with viewValue as first argument when modelValue is unparseable', async () => {
|
|
565
501
|
const otherValidator = new OtherValidator();
|
|
566
502
|
const otherValidatorSpy = sinon.spy(otherValidator, 'execute');
|
|
@@ -573,9 +509,10 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
573
509
|
// @ts-expect-error weird sinon type error..
|
|
574
510
|
expect(otherValidatorSpy.calledWith('view')).to.be.true;
|
|
575
511
|
});
|
|
576
|
-
|
|
577
512
|
it('Validators will be called with param as a second argument', async () => {
|
|
578
|
-
const param = {
|
|
513
|
+
const param = {
|
|
514
|
+
number: 5,
|
|
515
|
+
};
|
|
579
516
|
const validator = new IsCat(param);
|
|
580
517
|
const executeSpy = sinon.spy(validator, 'execute');
|
|
581
518
|
await fixture(html`
|
|
@@ -586,7 +523,6 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
586
523
|
`);
|
|
587
524
|
expect(executeSpy.args[0][1]).to.equal(param);
|
|
588
525
|
});
|
|
589
|
-
|
|
590
526
|
it('Validators will be called with a config that has { node } as a third argument', async () => {
|
|
591
527
|
const validator = new IsCat();
|
|
592
528
|
const executeSpy = sinon.spy(validator, 'execute');
|
|
@@ -599,14 +535,12 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
599
535
|
// @ts-expect-error another sinon type problem
|
|
600
536
|
expect(executeSpy.args[0][2].node).to.equal(el);
|
|
601
537
|
});
|
|
602
|
-
|
|
603
538
|
it('Validators will not be called on empty values', async () => {
|
|
604
|
-
const el =
|
|
539
|
+
const el =
|
|
540
|
+
/** @type {ValidateElement} */
|
|
605
541
|
await fixture(html`
|
|
606
542
|
<${tag} .validators=${[new IsCat()]}>${lightDom}</${tag}>
|
|
607
|
-
`)
|
|
608
|
-
);
|
|
609
|
-
|
|
543
|
+
`);
|
|
610
544
|
el.modelValue = 'cat';
|
|
611
545
|
expect(el.validationStates.error.IsCat).to.be.undefined;
|
|
612
546
|
el.modelValue = 'dog';
|
|
@@ -614,54 +548,47 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
614
548
|
el.modelValue = '';
|
|
615
549
|
expect(el.validationStates.error.IsCat).to.be.undefined;
|
|
616
550
|
});
|
|
617
|
-
|
|
618
551
|
it('Validators get retriggered on parameter change', async () => {
|
|
619
552
|
const isCatValidator = new IsCat('Felix');
|
|
620
553
|
const catSpy = sinon.spy(isCatValidator, 'execute');
|
|
621
|
-
const el =
|
|
554
|
+
const el =
|
|
555
|
+
/** @type {ValidateElement} */
|
|
622
556
|
await fixture(html`
|
|
623
557
|
<${tag}
|
|
624
558
|
.validators=${[isCatValidator]}
|
|
625
559
|
.modelValue=${'cat'}
|
|
626
560
|
>${lightDom}</${tag}>
|
|
627
|
-
`)
|
|
628
|
-
);
|
|
561
|
+
`);
|
|
629
562
|
el.modelValue = 'cat';
|
|
630
563
|
expect(catSpy.callCount).to.equal(1);
|
|
631
564
|
isCatValidator.param = 'Garfield';
|
|
632
565
|
expect(catSpy.callCount).to.equal(2);
|
|
633
566
|
});
|
|
634
|
-
|
|
635
567
|
it('Validators will not be called on readOnly fields', async () => {
|
|
636
|
-
const el =
|
|
568
|
+
const el =
|
|
569
|
+
/** @type {ValidateElement} */
|
|
637
570
|
await fixture(html`
|
|
638
571
|
<${tag} .validators=${[new IsCat()]}>${lightDom}</${tag}>
|
|
639
|
-
`)
|
|
640
|
-
);
|
|
641
|
-
|
|
572
|
+
`);
|
|
642
573
|
el.readOnly = true;
|
|
643
574
|
el.modelValue = 'dog';
|
|
644
575
|
expect(el.validationStates.error.IsCat).to.be.undefined;
|
|
645
576
|
});
|
|
646
577
|
});
|
|
647
|
-
|
|
648
578
|
describe('Async Validator Integration', () => {
|
|
649
579
|
/** @type {Promise<any>} */
|
|
650
580
|
let asyncVPromise;
|
|
651
581
|
/** @type {function} */
|
|
652
582
|
let asyncVResolve;
|
|
653
|
-
|
|
654
583
|
beforeEach(() => {
|
|
655
|
-
asyncVPromise = new Promise(resolve => {
|
|
584
|
+
asyncVPromise = new Promise((resolve) => {
|
|
656
585
|
asyncVResolve = resolve;
|
|
657
586
|
});
|
|
658
587
|
});
|
|
659
|
-
|
|
660
588
|
class IsAsyncCat extends Validator {
|
|
661
589
|
static get validatorName() {
|
|
662
590
|
return 'delayed-cat';
|
|
663
591
|
}
|
|
664
|
-
|
|
665
592
|
static get async() {
|
|
666
593
|
return true;
|
|
667
594
|
}
|
|
@@ -681,16 +608,15 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
681
608
|
// default execution trigger is keyup (think of password availability backend)
|
|
682
609
|
// can configure execution trigger (blur, etc?)
|
|
683
610
|
it('handles "execute" functions returning promises', async () => {
|
|
684
|
-
const el =
|
|
611
|
+
const el =
|
|
612
|
+
/** @type {ValidateElement} */
|
|
685
613
|
await fixture(html`
|
|
686
614
|
<${tag}
|
|
687
615
|
.modelValue=${'dog'}
|
|
688
616
|
.validators=${[new IsAsyncCat()]}>
|
|
689
617
|
${lightDom}
|
|
690
618
|
</${tag}>
|
|
691
|
-
`)
|
|
692
|
-
);
|
|
693
|
-
|
|
619
|
+
`);
|
|
694
620
|
const validator = el.validators[0];
|
|
695
621
|
expect(validator instanceof Validator).to.be.true;
|
|
696
622
|
expect(el.hasFeedbackFor).to.deep.equal([]);
|
|
@@ -698,21 +624,18 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
698
624
|
await aTimeout(0);
|
|
699
625
|
expect(el.hasFeedbackFor).to.deep.equal(['error']);
|
|
700
626
|
});
|
|
701
|
-
|
|
702
627
|
it('sets ".isPending/[is-pending]" when validation is in progress', async () => {
|
|
703
|
-
const el =
|
|
628
|
+
const el =
|
|
629
|
+
/** @type {ValidateElement} */
|
|
704
630
|
await fixture(html`
|
|
705
631
|
<${tag} .modelValue=${'dog'}>${lightDom}</${tag}>
|
|
706
|
-
`)
|
|
707
|
-
);
|
|
632
|
+
`);
|
|
708
633
|
expect(el.isPending).to.be.false;
|
|
709
634
|
expect(el.hasAttribute('is-pending')).to.be.false;
|
|
710
|
-
|
|
711
635
|
el.validators = [new IsAsyncCat()];
|
|
712
636
|
expect(el.isPending).to.be.true;
|
|
713
637
|
await aTimeout(0);
|
|
714
638
|
expect(el.hasAttribute('is-pending')).to.be.true;
|
|
715
|
-
|
|
716
639
|
asyncVResolve();
|
|
717
640
|
await aTimeout(0);
|
|
718
641
|
expect(el.isPending).to.be.false;
|
|
@@ -723,14 +646,13 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
723
646
|
it.skip('debounces async validation for performance', async () => {
|
|
724
647
|
const asyncV = new IsAsyncCat();
|
|
725
648
|
const asyncVExecuteSpy = sinon.spy(asyncV, 'execute');
|
|
726
|
-
|
|
727
|
-
|
|
649
|
+
const el =
|
|
650
|
+
/** @type {ValidateElement} */
|
|
728
651
|
await fixture(html`
|
|
729
652
|
<${tag} .modelValue=${'dog'}>
|
|
730
653
|
${lightDom}
|
|
731
654
|
</${tag}>
|
|
732
|
-
`)
|
|
733
|
-
);
|
|
655
|
+
`);
|
|
734
656
|
// debounce started
|
|
735
657
|
el.validators = [asyncV];
|
|
736
658
|
expect(asyncVExecuteSpy.called).to.equal(0);
|
|
@@ -751,18 +673,16 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
751
673
|
|
|
752
674
|
// TODO: nice to have...
|
|
753
675
|
it.skip('developer can configure debounce on FormControl instance', async () => {});
|
|
754
|
-
|
|
755
676
|
it.skip('cancels and reschedules async validation on ".modelValue" change', async () => {
|
|
756
677
|
const asyncV = new IsAsyncCat();
|
|
757
678
|
const asyncVAbortSpy = sinon.spy(asyncV, 'abortExecution');
|
|
758
|
-
|
|
759
|
-
|
|
679
|
+
const el =
|
|
680
|
+
/** @type {ValidateElement} */
|
|
760
681
|
await fixture(html`
|
|
761
682
|
<${tag} .modelValue=${'dog'}>
|
|
762
683
|
${lightDom}
|
|
763
684
|
</${tag}>
|
|
764
|
-
`)
|
|
765
|
-
);
|
|
685
|
+
`);
|
|
766
686
|
// debounce started
|
|
767
687
|
el.validators = [asyncV];
|
|
768
688
|
expect(asyncVAbortSpy.called).to.equal(0);
|
|
@@ -775,8 +695,8 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
775
695
|
it.skip('developer can configure condition for asynchronous validation', async () => {
|
|
776
696
|
const asyncV = new IsAsyncCat();
|
|
777
697
|
const asyncVExecuteSpy = sinon.spy(asyncV, 'execute');
|
|
778
|
-
|
|
779
|
-
|
|
698
|
+
const el =
|
|
699
|
+
/** @type {ValidateElement & { isFocused: boolean }} */
|
|
780
700
|
await fixture(html`
|
|
781
701
|
<${tag}
|
|
782
702
|
.isFocused=${true}
|
|
@@ -789,16 +709,13 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
789
709
|
>
|
|
790
710
|
${lightDom}
|
|
791
711
|
</${tag}>
|
|
792
|
-
`)
|
|
793
|
-
);
|
|
794
|
-
|
|
712
|
+
`);
|
|
795
713
|
expect(asyncVExecuteSpy.called).to.equal(0);
|
|
796
714
|
el.isFocused = false;
|
|
797
715
|
el.validate();
|
|
798
716
|
expect(asyncVExecuteSpy.called).to.equal(1);
|
|
799
717
|
});
|
|
800
718
|
});
|
|
801
|
-
|
|
802
719
|
describe('ResultValidator Integration', () => {
|
|
803
720
|
const MySuccessResultValidator = class extends ResultValidator {
|
|
804
721
|
/**
|
|
@@ -818,14 +735,13 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
818
735
|
*/
|
|
819
736
|
// eslint-disable-next-line class-methods-use-this
|
|
820
737
|
executeOnResults({ regularValidationResult, prevShownValidationResult }) {
|
|
821
|
-
const errorOrWarning = /** @param {Validator} v */ v =>
|
|
738
|
+
const errorOrWarning = /** @param {Validator} v */ (v) =>
|
|
822
739
|
v.type === 'error' || v.type === 'warning';
|
|
823
740
|
const hasErrorOrWarning = !!regularValidationResult.filter(errorOrWarning).length;
|
|
824
741
|
const hasShownErrorOrWarning = !!prevShownValidationResult.filter(errorOrWarning).length;
|
|
825
742
|
return !hasErrorOrWarning && hasShownErrorOrWarning;
|
|
826
743
|
}
|
|
827
744
|
};
|
|
828
|
-
|
|
829
745
|
const withSuccessTagString = defineCE(
|
|
830
746
|
class extends ValidateMixin(LitElement) {
|
|
831
747
|
static get validationTypes() {
|
|
@@ -835,7 +751,6 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
835
751
|
},
|
|
836
752
|
);
|
|
837
753
|
const withSuccessTag = unsafeStatic(withSuccessTagString);
|
|
838
|
-
|
|
839
754
|
it('calls ResultValidators after regular validators', async () => {
|
|
840
755
|
const resultValidator = new MySuccessResultValidator();
|
|
841
756
|
const resultValidateSpy = sinon.spy(resultValidator, 'executeOnResults');
|
|
@@ -862,20 +777,18 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
862
777
|
`);
|
|
863
778
|
expect(validateAsyncSpy.calledBefore(resultValidateSpy)).to.be.true;
|
|
864
779
|
});
|
|
865
|
-
|
|
866
780
|
it(`provides "regular" ValidationResult and previous FinalValidationResult as input to
|
|
867
781
|
"executeOnResults" function`, async () => {
|
|
868
782
|
const resultValidator = new MySuccessResultValidator();
|
|
869
783
|
const resultValidateSpy = sinon.spy(resultValidator, 'executeOnResults');
|
|
870
|
-
|
|
871
|
-
|
|
784
|
+
const el =
|
|
785
|
+
/** @type {ValidateElement} */
|
|
872
786
|
await fixture(html`
|
|
873
787
|
<${withSuccessTag}
|
|
874
788
|
.validators=${[new MinLength(3), resultValidator]}
|
|
875
789
|
.modelValue=${'myValue'}
|
|
876
790
|
>${lightDom}</${withSuccessTag}>
|
|
877
|
-
`)
|
|
878
|
-
);
|
|
791
|
+
`);
|
|
879
792
|
// @ts-ignore [allow-private] in test
|
|
880
793
|
const prevValidationResult = el.__prevValidationResult;
|
|
881
794
|
// @ts-ignore [allow-private] in test
|
|
@@ -886,14 +799,12 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
886
799
|
// @ts-ignore [allow-private] in test
|
|
887
800
|
...el.__asyncValidationResult,
|
|
888
801
|
];
|
|
889
|
-
|
|
890
802
|
expect(resultValidateSpy.args[0][0]).to.eql({
|
|
891
803
|
regularValidationResult,
|
|
892
804
|
prevValidationResult,
|
|
893
805
|
prevShownValidationResult,
|
|
894
806
|
});
|
|
895
807
|
});
|
|
896
|
-
|
|
897
808
|
it('adds ResultValidator outcome as highest prio result to the FinalValidationResult', async () => {
|
|
898
809
|
class AlwaysInvalidResult extends ResultValidator {
|
|
899
810
|
// eslint-disable-next-line class-methods-use-this
|
|
@@ -902,44 +813,49 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
902
813
|
return hasError;
|
|
903
814
|
}
|
|
904
815
|
}
|
|
905
|
-
|
|
906
816
|
const validator = new AlwaysInvalid();
|
|
907
817
|
const resultV = new AlwaysInvalidResult();
|
|
908
|
-
|
|
909
|
-
|
|
818
|
+
const el =
|
|
819
|
+
/** @type {ValidateElement} */
|
|
910
820
|
await fixture(html`
|
|
911
821
|
<${tag}
|
|
912
822
|
.validators=${[validator, resultV]}
|
|
913
823
|
.modelValue=${'myValue'}
|
|
914
824
|
>${lightDom}</${tag}>
|
|
915
|
-
`)
|
|
916
|
-
);
|
|
825
|
+
`);
|
|
917
826
|
|
|
918
827
|
// @ts-ignore [allow-private] in test
|
|
919
828
|
const totalValidationResult = el.__validationResult;
|
|
920
829
|
expect(totalValidationResult).to.eql([
|
|
921
|
-
{
|
|
922
|
-
|
|
830
|
+
{
|
|
831
|
+
validator: resultV,
|
|
832
|
+
outcome: true,
|
|
833
|
+
},
|
|
834
|
+
{
|
|
835
|
+
validator,
|
|
836
|
+
outcome: true,
|
|
837
|
+
},
|
|
923
838
|
]);
|
|
924
839
|
});
|
|
925
840
|
});
|
|
926
|
-
|
|
927
841
|
describe('getMessages with custom HTML', () => {
|
|
928
842
|
it('will render HTML for lion-validation-feedback', async () => {
|
|
929
843
|
const messageHtmlId = 'test123';
|
|
930
844
|
const messageHtml = `<div id="test123">test</div>`;
|
|
931
|
-
const el =
|
|
845
|
+
const el =
|
|
846
|
+
/** @type {ValidateElement} */
|
|
932
847
|
await fixture(html`
|
|
933
848
|
<${tag}
|
|
934
849
|
.validators="${[
|
|
935
850
|
// @ts-expect-error
|
|
936
|
-
new EqualsLength(4, {
|
|
851
|
+
new EqualsLength(4, {
|
|
852
|
+
getMessage: () => html`<div id="test123">test</div>`,
|
|
853
|
+
}),
|
|
937
854
|
]}" })]}"
|
|
938
855
|
.modelValue="${'123'}"
|
|
939
856
|
label="Custom message for validator instance"
|
|
940
857
|
></${tag}>
|
|
941
|
-
`)
|
|
942
|
-
);
|
|
858
|
+
`);
|
|
943
859
|
expect(el.validationStates.error.EqualsLength).to.be.true;
|
|
944
860
|
expect(el.hasFeedbackFor).to.deep.equal(['error']);
|
|
945
861
|
const { _feedbackNode } = getFormControlMembers(el);
|
|
@@ -950,35 +866,32 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
950
866
|
expect(messageHtmlNode?.tagName).to.equal('DIV');
|
|
951
867
|
});
|
|
952
868
|
});
|
|
953
|
-
|
|
954
869
|
describe('Required Validator integration', () => {
|
|
955
870
|
it('will result in erroneous state when form control is empty', async () => {
|
|
956
|
-
const el =
|
|
871
|
+
const el =
|
|
872
|
+
/** @type {ValidateElement} */
|
|
957
873
|
await fixture(html`
|
|
958
874
|
<${tag}
|
|
959
875
|
.validators=${[new Required()]}
|
|
960
876
|
.modelValue=${''}
|
|
961
877
|
>${lightDom}</${tag}>
|
|
962
|
-
`)
|
|
963
|
-
);
|
|
878
|
+
`);
|
|
964
879
|
expect(el.validationStates.error.Required).to.be.true;
|
|
965
880
|
expect(el.hasFeedbackFor).to.deep.equal(['error']);
|
|
966
|
-
|
|
967
881
|
el.modelValue = 'foo';
|
|
968
882
|
expect(el.validationStates.error.Required).to.be.undefined;
|
|
969
883
|
expect(el.hasFeedbackFor).to.deep.equal([]);
|
|
970
884
|
});
|
|
971
|
-
|
|
972
885
|
it('calls private ".__isEmpty" by default', async () => {
|
|
973
|
-
const el =
|
|
886
|
+
const el =
|
|
887
|
+
/** @type {ValidateElement} */
|
|
974
888
|
await fixture(html`
|
|
975
889
|
<${tag}
|
|
976
890
|
.validators=${[new Required()]}
|
|
977
891
|
.modelValue=${''}
|
|
978
892
|
>${lightDom}</${tag}>
|
|
979
|
-
`)
|
|
980
|
-
);
|
|
981
|
-
const validator = /** @type {Validator} */ (el.validators.find(v => v instanceof Required));
|
|
893
|
+
`);
|
|
894
|
+
const validator = /** @type {Validator} */ el.validators.find((v) => v instanceof Required);
|
|
982
895
|
const executeSpy = sinon.spy(validator, 'execute');
|
|
983
896
|
// @ts-ignore [allow-private] in test
|
|
984
897
|
const privateIsEmptySpy = sinon.spy(el, '__isEmpty');
|
|
@@ -986,7 +899,6 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
986
899
|
expect(executeSpy.callCount).to.equal(0);
|
|
987
900
|
expect(privateIsEmptySpy.callCount).to.equal(1);
|
|
988
901
|
});
|
|
989
|
-
|
|
990
902
|
it('calls "._isEmpty" when provided (useful for different modelValues)', async () => {
|
|
991
903
|
class _isEmptyValidate extends ValidateMixin(LitElement) {
|
|
992
904
|
_isEmpty() {
|
|
@@ -995,55 +907,53 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
995
907
|
}
|
|
996
908
|
const customRequiredTagString = defineCE(_isEmptyValidate);
|
|
997
909
|
const customRequiredTag = unsafeStatic(customRequiredTagString);
|
|
998
|
-
|
|
999
|
-
|
|
910
|
+
const el =
|
|
911
|
+
/** @type {_isEmptyValidate} */
|
|
1000
912
|
await fixture(html`
|
|
1001
913
|
<${customRequiredTag}
|
|
1002
914
|
.validators=${[new Required()]}
|
|
1003
|
-
.modelValue=${{
|
|
915
|
+
.modelValue=${{
|
|
916
|
+
model: 'foo',
|
|
917
|
+
}}
|
|
1004
918
|
>${lightDom}</${customRequiredTag}>
|
|
1005
|
-
`)
|
|
1006
|
-
);
|
|
1007
|
-
|
|
919
|
+
`);
|
|
1008
920
|
const providedIsEmptySpy = sinon.spy(el, '_isEmpty');
|
|
1009
|
-
el.modelValue = {
|
|
921
|
+
el.modelValue = {
|
|
922
|
+
model: '',
|
|
923
|
+
};
|
|
1010
924
|
expect(providedIsEmptySpy.callCount).to.equal(1);
|
|
1011
925
|
expect(el.validationStates.error.Required).to.be.true;
|
|
1012
926
|
});
|
|
1013
|
-
|
|
1014
927
|
it('prevents other Validators from being called when input is empty', async () => {
|
|
1015
928
|
const alwaysInvalid = new AlwaysInvalid();
|
|
1016
929
|
const alwaysInvalidSpy = sinon.spy(alwaysInvalid, 'execute');
|
|
1017
|
-
const el =
|
|
930
|
+
const el =
|
|
931
|
+
/** @type {ValidateElement} */
|
|
1018
932
|
await fixture(html`
|
|
1019
933
|
<${tag}
|
|
1020
934
|
.validators=${[new Required(), alwaysInvalid]}
|
|
1021
935
|
.modelValue=${''}
|
|
1022
936
|
>${lightDom}</${tag}>
|
|
1023
|
-
`)
|
|
1024
|
-
);
|
|
937
|
+
`);
|
|
1025
938
|
expect(alwaysInvalidSpy.callCount).to.equal(0); // __isRequired returned false (invalid)
|
|
1026
939
|
el.modelValue = 'foo';
|
|
1027
940
|
expect(alwaysInvalidSpy.callCount).to.equal(1); // __isRequired returned true (valid)
|
|
1028
941
|
});
|
|
1029
|
-
|
|
1030
942
|
it('adds [aria-required="true"] to "._inputNode"', async () => {
|
|
1031
|
-
const el =
|
|
943
|
+
const el =
|
|
944
|
+
/** @type {ValidateElement} */
|
|
1032
945
|
await fixture(html`
|
|
1033
946
|
<${tag}
|
|
1034
947
|
.validators=${[new Required()]}
|
|
1035
948
|
.modelValue=${''}
|
|
1036
949
|
>${lightDom}</${tag}>
|
|
1037
|
-
`)
|
|
1038
|
-
);
|
|
950
|
+
`);
|
|
1039
951
|
const { _inputNode } = getFormControlMembers(el);
|
|
1040
|
-
|
|
1041
952
|
expect(_inputNode?.getAttribute('aria-required')).to.equal('true');
|
|
1042
953
|
el.validators = [];
|
|
1043
954
|
expect(_inputNode?.getAttribute('aria-required')).to.be.null;
|
|
1044
955
|
});
|
|
1045
956
|
});
|
|
1046
|
-
|
|
1047
957
|
describe('Default (preconfigured) Validators', () => {
|
|
1048
958
|
const preconfTagString = defineCE(
|
|
1049
959
|
class extends ValidateMixin(LitElement) {
|
|
@@ -1054,20 +964,17 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
1054
964
|
},
|
|
1055
965
|
);
|
|
1056
966
|
const preconfTag = unsafeStatic(preconfTagString);
|
|
1057
|
-
|
|
1058
967
|
it('can be stored for custom inputs', async () => {
|
|
1059
|
-
const el =
|
|
968
|
+
const el =
|
|
969
|
+
/** @type {ValidateElement} */
|
|
1060
970
|
await fixture(html`
|
|
1061
971
|
<${preconfTag}
|
|
1062
972
|
.validators=${[new MinLength(3)]}
|
|
1063
973
|
.modelValue=${'12'}
|
|
1064
|
-
></${preconfTag}>`)
|
|
1065
|
-
);
|
|
1066
|
-
|
|
974
|
+
></${preconfTag}>`);
|
|
1067
975
|
expect(el.validationStates.error.AlwaysInvalid).to.be.true;
|
|
1068
976
|
expect(el.validationStates.error.MinLength).to.be.true;
|
|
1069
977
|
});
|
|
1070
|
-
|
|
1071
978
|
it('can be altered by App Developers', async () => {
|
|
1072
979
|
const altPreconfTagString = defineCE(
|
|
1073
980
|
class extends ValidateMixin(LitElement) {
|
|
@@ -1078,104 +985,98 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
1078
985
|
},
|
|
1079
986
|
);
|
|
1080
987
|
const altPreconfTag = unsafeStatic(altPreconfTagString);
|
|
1081
|
-
|
|
1082
|
-
|
|
988
|
+
const el =
|
|
989
|
+
/** @type {ValidateElement} */
|
|
1083
990
|
await fixture(html`
|
|
1084
991
|
<${altPreconfTag}
|
|
1085
992
|
.modelValue=${'12'}
|
|
1086
|
-
></${altPreconfTag}>`)
|
|
1087
|
-
);
|
|
1088
|
-
|
|
993
|
+
></${altPreconfTag}>`);
|
|
1089
994
|
expect(el.validationStates.error.MinLength).to.be.true;
|
|
1090
995
|
el.defaultValidators[0].param = 2;
|
|
1091
996
|
expect(el.validationStates.error.MinLength).to.be.undefined;
|
|
1092
997
|
});
|
|
1093
|
-
|
|
1094
998
|
it('can be requested via "._allValidators" getter', async () => {
|
|
1095
|
-
const el =
|
|
999
|
+
const el =
|
|
1000
|
+
/** @type {ValidateElement} */
|
|
1096
1001
|
await fixture(html`
|
|
1097
1002
|
<${preconfTag}
|
|
1098
1003
|
.validators=${[new MinLength(3)]}
|
|
1099
|
-
></${preconfTag}>`)
|
|
1100
|
-
);
|
|
1004
|
+
></${preconfTag}>`);
|
|
1101
1005
|
const { _allValidators } = getFormControlMembers(el);
|
|
1102
|
-
|
|
1103
1006
|
expect(el.validators.length).to.equal(1);
|
|
1104
1007
|
expect(el.defaultValidators.length).to.equal(1);
|
|
1105
1008
|
expect(_allValidators.length).to.equal(2);
|
|
1106
|
-
|
|
1107
1009
|
expect(_allValidators[0] instanceof MinLength).to.be.true;
|
|
1108
1010
|
expect(_allValidators[1] instanceof AlwaysInvalid).to.be.true;
|
|
1109
|
-
|
|
1110
1011
|
el.validators = [new MaxLength(5)];
|
|
1111
1012
|
const { _allValidators: _allValidatorsMl } = getFormControlMembers(el);
|
|
1112
|
-
|
|
1113
1013
|
expect(_allValidatorsMl[0] instanceof MaxLength).to.be.true;
|
|
1114
1014
|
expect(_allValidatorsMl[1] instanceof AlwaysInvalid).to.be.true;
|
|
1115
1015
|
});
|
|
1116
1016
|
});
|
|
1117
|
-
|
|
1118
1017
|
describe('State storage and reflection', () => {
|
|
1119
1018
|
it('stores validity of individual Validators in ".validationStates.error[validator.validatorName]"', async () => {
|
|
1120
|
-
const el =
|
|
1019
|
+
const el =
|
|
1020
|
+
/** @type {ValidateElement} */
|
|
1121
1021
|
await fixture(html`
|
|
1122
1022
|
<${tag}
|
|
1123
1023
|
.modelValue=${'a'}
|
|
1124
1024
|
.validators=${[new MinLength(3), new AlwaysInvalid()]}
|
|
1125
|
-
>${lightDom}</${tag}>`)
|
|
1126
|
-
);
|
|
1127
|
-
|
|
1025
|
+
>${lightDom}</${tag}>`);
|
|
1128
1026
|
expect(el.validationStates.error.MinLength).to.be.true;
|
|
1129
1027
|
expect(el.validationStates.error.AlwaysInvalid).to.be.true;
|
|
1130
|
-
|
|
1131
1028
|
el.modelValue = 'abc';
|
|
1132
1029
|
expect(el.validationStates.error.MinLength).to.equal(undefined);
|
|
1133
1030
|
expect(el.validationStates.error.AlwaysInvalid).to.be.true;
|
|
1134
1031
|
});
|
|
1135
|
-
|
|
1136
1032
|
it('removes "non active" states whenever modelValue becomes undefined', async () => {
|
|
1137
|
-
const el =
|
|
1033
|
+
const el =
|
|
1034
|
+
/** @type {ValidateElement} */
|
|
1138
1035
|
await fixture(html`
|
|
1139
1036
|
<${tag}
|
|
1140
1037
|
.validators=${[new MinLength(3)]}
|
|
1141
1038
|
>${lightDom}</${tag}>
|
|
1142
|
-
`)
|
|
1143
|
-
);
|
|
1039
|
+
`);
|
|
1144
1040
|
el.modelValue = 'a';
|
|
1145
1041
|
expect(el.hasFeedbackFor).to.deep.equal(['error']);
|
|
1146
1042
|
expect(el.validationStates.error).to.not.eql({});
|
|
1147
|
-
|
|
1148
1043
|
el.modelValue = undefined;
|
|
1149
1044
|
expect(el.hasFeedbackFor).to.deep.equal([]);
|
|
1150
1045
|
expect(el.validationStates.error).to.eql({});
|
|
1151
1046
|
});
|
|
1152
|
-
|
|
1153
1047
|
it('clears current validation results when validators array updated', async () => {
|
|
1154
1048
|
const validators = [new Required()];
|
|
1155
|
-
const el =
|
|
1049
|
+
const el =
|
|
1050
|
+
/** @type {ValidateElement} */
|
|
1156
1051
|
await fixture(html`
|
|
1157
1052
|
<${tag}
|
|
1158
1053
|
.validators=${validators}
|
|
1159
1054
|
>${lightDom}</${tag}>
|
|
1160
|
-
`)
|
|
1161
|
-
);
|
|
1055
|
+
`);
|
|
1162
1056
|
expect(el.hasFeedbackFor).to.deep.equal(['error']);
|
|
1163
|
-
expect(el.validationStates.error).to.eql({
|
|
1164
|
-
|
|
1057
|
+
expect(el.validationStates.error).to.eql({
|
|
1058
|
+
Required: true,
|
|
1059
|
+
});
|
|
1165
1060
|
el.validators = [];
|
|
1166
1061
|
expect(el.hasFeedbackFor).to.not.deep.equal(['error']);
|
|
1167
1062
|
expect(el.validationStates.error).to.eql({});
|
|
1168
|
-
|
|
1169
1063
|
el.validators = [new Required()];
|
|
1170
1064
|
expect(el.hasFeedbackFor).to.deep.equal(['error']);
|
|
1171
1065
|
expect(el.validationStates.error).to.not.eql({});
|
|
1172
1066
|
});
|
|
1173
|
-
|
|
1174
1067
|
it('can be configured to change visibility conditions per type', async () => {
|
|
1175
|
-
const el =
|
|
1068
|
+
const el =
|
|
1069
|
+
/** @type {ValidateElement} */
|
|
1176
1070
|
await fixture(html`
|
|
1177
1071
|
<${tag}
|
|
1178
|
-
.validators="${[
|
|
1072
|
+
.validators="${[
|
|
1073
|
+
new Required(
|
|
1074
|
+
{},
|
|
1075
|
+
{
|
|
1076
|
+
type: 'error',
|
|
1077
|
+
},
|
|
1078
|
+
),
|
|
1079
|
+
]}"
|
|
1179
1080
|
.feedbackCondition="${(
|
|
1180
1081
|
/** @type {string} */ type,
|
|
1181
1082
|
/** @type {object} */ meta,
|
|
@@ -1187,101 +1088,91 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
1187
1088
|
return defaultCondition(type);
|
|
1188
1089
|
}}"
|
|
1189
1090
|
>${lightDom}</${tag}>
|
|
1190
|
-
`)
|
|
1191
|
-
);
|
|
1192
|
-
|
|
1091
|
+
`);
|
|
1193
1092
|
expect(el.showsFeedbackFor).to.eql(['error']);
|
|
1194
1093
|
});
|
|
1195
|
-
|
|
1196
1094
|
describe('Events', () => {
|
|
1197
1095
|
it('fires "showsFeedbackForChanged" event async after feedbackData got synced to feedbackElement', async () => {
|
|
1198
1096
|
const spy = sinon.spy();
|
|
1199
|
-
const el =
|
|
1097
|
+
const el =
|
|
1098
|
+
/** @type {ValidateElement} */
|
|
1200
1099
|
await fixture(html`
|
|
1201
1100
|
<${tag}
|
|
1202
1101
|
.submitted=${true}
|
|
1203
1102
|
.validators=${[new MinLength(7)]}
|
|
1204
1103
|
@showsFeedbackForChanged=${spy}
|
|
1205
1104
|
>${lightDom}</${tag}>
|
|
1206
|
-
`)
|
|
1207
|
-
);
|
|
1105
|
+
`);
|
|
1208
1106
|
el.modelValue = 'a';
|
|
1209
1107
|
await el.updateComplete;
|
|
1210
1108
|
expect(spy).to.have.callCount(1);
|
|
1211
|
-
|
|
1212
1109
|
el.modelValue = 'abc';
|
|
1213
1110
|
await el.updateComplete;
|
|
1214
1111
|
expect(spy).to.have.callCount(1);
|
|
1215
|
-
|
|
1216
1112
|
el.modelValue = 'abcdefg';
|
|
1217
1113
|
await el.updateComplete;
|
|
1218
1114
|
expect(spy).to.have.callCount(2);
|
|
1219
1115
|
});
|
|
1220
|
-
|
|
1221
1116
|
it('fires "showsFeedbackFor{type}Changed" event async when type visibility changed', async () => {
|
|
1222
1117
|
const spy = sinon.spy();
|
|
1223
|
-
const el =
|
|
1118
|
+
const el =
|
|
1119
|
+
/** @type {ValidateElement} */
|
|
1224
1120
|
await fixture(html`
|
|
1225
1121
|
<${tag}
|
|
1226
1122
|
.submitted=${true}
|
|
1227
1123
|
.validators=${[new MinLength(7)]}
|
|
1228
1124
|
@showsFeedbackForErrorChanged=${spy}
|
|
1229
1125
|
>${lightDom}</${tag}>
|
|
1230
|
-
`)
|
|
1231
|
-
);
|
|
1126
|
+
`);
|
|
1232
1127
|
el.modelValue = 'a';
|
|
1233
1128
|
await el.updateComplete;
|
|
1234
1129
|
expect(spy).to.have.callCount(1);
|
|
1235
|
-
|
|
1236
1130
|
el.modelValue = 'abc';
|
|
1237
1131
|
await el.updateComplete;
|
|
1238
1132
|
expect(spy).to.have.callCount(1);
|
|
1239
|
-
|
|
1240
1133
|
el.modelValue = 'abcdefg';
|
|
1241
1134
|
await el.updateComplete;
|
|
1242
1135
|
expect(spy).to.have.callCount(2);
|
|
1243
1136
|
});
|
|
1244
|
-
|
|
1245
1137
|
it('fires "{type}StateChanged" event async when type validity changed', async () => {
|
|
1246
1138
|
const spy = sinon.spy();
|
|
1247
|
-
const el =
|
|
1139
|
+
const el =
|
|
1140
|
+
/** @type {ValidateElement} */
|
|
1248
1141
|
await fixture(html`
|
|
1249
1142
|
<${tag}
|
|
1250
1143
|
.submitted=${true}
|
|
1251
1144
|
.validators=${[new MinLength(7)]}
|
|
1252
1145
|
@errorStateChanged=${spy}
|
|
1253
1146
|
>${lightDom}</${tag}>
|
|
1254
|
-
`)
|
|
1255
|
-
);
|
|
1147
|
+
`);
|
|
1256
1148
|
expect(spy).to.have.callCount(0);
|
|
1257
|
-
|
|
1258
1149
|
el.modelValue = 'a';
|
|
1259
1150
|
await el.updateComplete;
|
|
1260
1151
|
expect(spy).to.have.callCount(1);
|
|
1261
|
-
|
|
1262
1152
|
el.modelValue = 'abc';
|
|
1263
1153
|
await el.updateComplete;
|
|
1264
1154
|
expect(spy).to.have.callCount(1);
|
|
1265
|
-
|
|
1266
1155
|
el.modelValue = 'abcdefg';
|
|
1267
1156
|
await el.updateComplete;
|
|
1268
1157
|
expect(spy).to.have.callCount(2);
|
|
1269
1158
|
});
|
|
1270
1159
|
});
|
|
1271
1160
|
});
|
|
1272
|
-
|
|
1273
1161
|
describe('Accessibility', () => {
|
|
1274
1162
|
it.skip('calls "._inputNode.setCustomValidity(errorMessage)"', async () => {
|
|
1275
|
-
const el =
|
|
1163
|
+
const el =
|
|
1164
|
+
/** @type {ValidateElement} */
|
|
1276
1165
|
await fixture(html`
|
|
1277
1166
|
<${tag}
|
|
1278
1167
|
.modelValue=${'123'}
|
|
1279
|
-
.validators=${[
|
|
1168
|
+
.validators=${[
|
|
1169
|
+
new MinLength(3, {
|
|
1170
|
+
getMessage: async () => 'foo',
|
|
1171
|
+
}),
|
|
1172
|
+
]}>
|
|
1280
1173
|
<input slot="input">
|
|
1281
|
-
</${tag}>`)
|
|
1282
|
-
);
|
|
1174
|
+
</${tag}>`);
|
|
1283
1175
|
const { _inputNode } = getFormControlMembers(el);
|
|
1284
|
-
|
|
1285
1176
|
if (_inputNode) {
|
|
1286
1177
|
// @ts-ignore -- we are testing the protected _inputNode here
|
|
1287
1178
|
const spy = sinon.spy(el._inputNode, 'setCustomValidity');
|
|
@@ -1302,7 +1193,6 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
1302
1193
|
it.skip(`removes validity message from DOM instead of toggling "display:none", to trigger Jaws
|
|
1303
1194
|
and VoiceOver [to-be-implemented]`, async () => {});
|
|
1304
1195
|
});
|
|
1305
|
-
|
|
1306
1196
|
describe('Extensibility: Custom Validator types', () => {
|
|
1307
1197
|
const customTypeTagString = defineCE(
|
|
1308
1198
|
class extends ValidateMixin(LitElement) {
|
|
@@ -1313,103 +1203,121 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
1313
1203
|
},
|
|
1314
1204
|
);
|
|
1315
1205
|
const customTypeTag = unsafeStatic(customTypeTagString);
|
|
1316
|
-
|
|
1317
1206
|
it('supports additional validationTypes in .hasFeedbackFor', async () => {
|
|
1318
|
-
const el =
|
|
1207
|
+
const el =
|
|
1208
|
+
/** @type {ValidateElement} */
|
|
1319
1209
|
await fixture(html`
|
|
1320
1210
|
<${customTypeTag}
|
|
1321
1211
|
.validators=${[
|
|
1322
|
-
new MinLength(2, {
|
|
1323
|
-
|
|
1324
|
-
|
|
1212
|
+
new MinLength(2, {
|
|
1213
|
+
type: 'x',
|
|
1214
|
+
}),
|
|
1215
|
+
new MinLength(3, {
|
|
1216
|
+
type: 'error',
|
|
1217
|
+
}),
|
|
1218
|
+
new MinLength(4, {
|
|
1219
|
+
type: 'y',
|
|
1220
|
+
}),
|
|
1325
1221
|
]}
|
|
1326
1222
|
.modelValue=${'1234'}
|
|
1327
1223
|
>${lightDom}</${customTypeTag}>
|
|
1328
|
-
`)
|
|
1329
|
-
);
|
|
1224
|
+
`);
|
|
1330
1225
|
expect(el.hasFeedbackFor).to.deep.equal([]);
|
|
1331
|
-
|
|
1332
1226
|
el.modelValue = '123'; // triggers y
|
|
1333
1227
|
expect(el.hasFeedbackFor).to.deep.equal(['y']);
|
|
1334
|
-
|
|
1335
1228
|
el.modelValue = '12'; // triggers error and y
|
|
1336
1229
|
expect(el.hasFeedbackFor).to.deep.equal(['error', 'y']);
|
|
1337
|
-
|
|
1338
1230
|
el.modelValue = '1'; // triggers x, error and y
|
|
1339
1231
|
expect(el.hasFeedbackFor).to.deep.equal(['x', 'error', 'y']);
|
|
1340
1232
|
});
|
|
1341
|
-
|
|
1342
1233
|
it('supports additional validationTypes in .validationStates', async () => {
|
|
1343
|
-
const el =
|
|
1234
|
+
const el =
|
|
1235
|
+
/** @type {ValidateElement} */
|
|
1344
1236
|
await fixture(html`
|
|
1345
1237
|
<${customTypeTag}
|
|
1346
1238
|
.validators=${[
|
|
1347
|
-
new MinLength(2, {
|
|
1348
|
-
|
|
1349
|
-
|
|
1239
|
+
new MinLength(2, {
|
|
1240
|
+
type: 'x',
|
|
1241
|
+
}),
|
|
1242
|
+
new MinLength(3, {
|
|
1243
|
+
type: 'error',
|
|
1244
|
+
}),
|
|
1245
|
+
new MinLength(4, {
|
|
1246
|
+
type: 'y',
|
|
1247
|
+
}),
|
|
1350
1248
|
]}
|
|
1351
1249
|
.modelValue=${'1234'}
|
|
1352
1250
|
>${lightDom}</${customTypeTag}>
|
|
1353
|
-
`)
|
|
1354
|
-
);
|
|
1251
|
+
`);
|
|
1355
1252
|
expect(el.validationStates).to.eql({
|
|
1356
1253
|
x: {},
|
|
1357
1254
|
error: {},
|
|
1358
1255
|
y: {},
|
|
1359
1256
|
});
|
|
1360
|
-
|
|
1361
1257
|
el.modelValue = '123'; // triggers y
|
|
1362
1258
|
expect(el.validationStates).to.eql({
|
|
1363
1259
|
x: {},
|
|
1364
1260
|
error: {},
|
|
1365
|
-
y: {
|
|
1261
|
+
y: {
|
|
1262
|
+
MinLength: true,
|
|
1263
|
+
},
|
|
1366
1264
|
});
|
|
1367
|
-
|
|
1368
1265
|
el.modelValue = '12'; // triggers error and y
|
|
1369
1266
|
expect(el.validationStates).to.eql({
|
|
1370
1267
|
x: {},
|
|
1371
|
-
error: {
|
|
1372
|
-
|
|
1268
|
+
error: {
|
|
1269
|
+
MinLength: true,
|
|
1270
|
+
},
|
|
1271
|
+
y: {
|
|
1272
|
+
MinLength: true,
|
|
1273
|
+
},
|
|
1373
1274
|
});
|
|
1374
|
-
|
|
1375
1275
|
el.modelValue = '1'; // triggers x, error and y
|
|
1376
1276
|
expect(el.validationStates).to.eql({
|
|
1377
|
-
x: {
|
|
1378
|
-
|
|
1379
|
-
|
|
1277
|
+
x: {
|
|
1278
|
+
MinLength: true,
|
|
1279
|
+
},
|
|
1280
|
+
error: {
|
|
1281
|
+
MinLength: true,
|
|
1282
|
+
},
|
|
1283
|
+
y: {
|
|
1284
|
+
MinLength: true,
|
|
1285
|
+
},
|
|
1380
1286
|
});
|
|
1381
1287
|
});
|
|
1382
|
-
|
|
1383
1288
|
it('orders feedback based on provided "validationTypes"', async () => {
|
|
1384
1289
|
// we set submitted to always show error message in the test
|
|
1385
|
-
const el =
|
|
1290
|
+
const el =
|
|
1291
|
+
/** @type {ValidateElement} */
|
|
1386
1292
|
await fixture(html`
|
|
1387
1293
|
<${customTypeTag}
|
|
1388
1294
|
.submitted=${true}
|
|
1389
1295
|
._visibleMessagesAmount=${Infinity}
|
|
1390
1296
|
.validators=${[
|
|
1391
|
-
new MinLength(2, {
|
|
1392
|
-
|
|
1393
|
-
|
|
1297
|
+
new MinLength(2, {
|
|
1298
|
+
type: 'x',
|
|
1299
|
+
}),
|
|
1300
|
+
new MinLength(3, {
|
|
1301
|
+
type: 'error',
|
|
1302
|
+
}),
|
|
1303
|
+
new MinLength(4, {
|
|
1304
|
+
type: 'y',
|
|
1305
|
+
}),
|
|
1394
1306
|
]}
|
|
1395
1307
|
.modelValue=${'1'}
|
|
1396
1308
|
>${lightDom}</${customTypeTag}>
|
|
1397
|
-
`)
|
|
1398
|
-
);
|
|
1309
|
+
`);
|
|
1399
1310
|
const { _feedbackNode } = getFormControlMembers(el);
|
|
1400
|
-
|
|
1401
1311
|
await el.feedbackComplete;
|
|
1402
|
-
|
|
1403
1312
|
const feedbackNode =
|
|
1404
1313
|
/** @type {import('../src/validate/LionValidationFeedback.js').LionValidationFeedback} */
|
|
1405
|
-
|
|
1406
|
-
const resultOrder = feedbackNode.feedbackData?.map(v => v.type);
|
|
1314
|
+
_feedbackNode;
|
|
1315
|
+
const resultOrder = feedbackNode.feedbackData?.map((v) => v.type);
|
|
1407
1316
|
expect(resultOrder).to.deep.equal(['error', 'x', 'y']);
|
|
1408
|
-
|
|
1409
1317
|
el.modelValue = '12';
|
|
1410
1318
|
await el.updateComplete;
|
|
1411
1319
|
await el.feedbackComplete;
|
|
1412
|
-
const resultOrder2 = feedbackNode.feedbackData?.map(v => v.type);
|
|
1320
|
+
const resultOrder2 = feedbackNode.feedbackData?.map((v) => v.type);
|
|
1413
1321
|
expect(resultOrder2).to.deep.equal(['error', 'y']);
|
|
1414
1322
|
});
|
|
1415
1323
|
|
|
@@ -1419,7 +1327,6 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
1419
1327
|
* 'Subclassers' for an example on how to do this
|
|
1420
1328
|
*/
|
|
1421
1329
|
});
|
|
1422
|
-
|
|
1423
1330
|
describe('Subclassers', () => {
|
|
1424
1331
|
describe('Adding new Validator types', () => {
|
|
1425
1332
|
it('can add helpers for validation types', async () => {
|
|
@@ -1428,11 +1335,9 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
1428
1335
|
// @ts-ignore [ts7-2855] TS7 rejects field access via super (the parent declares this as a field). Dot form kept deliberately: bracket access is exempt from property mangling (terser keep_quoted), which could split this property into two names. Upstream fix: declare an accessor in the parent type
|
|
1429
1336
|
return [...super.validationTypes, 'x'];
|
|
1430
1337
|
}
|
|
1431
|
-
|
|
1432
1338
|
get hasX() {
|
|
1433
1339
|
return this.hasFeedbackFor.includes('x');
|
|
1434
1340
|
}
|
|
1435
|
-
|
|
1436
1341
|
get hasXVisible() {
|
|
1437
1342
|
return this.showsFeedbackFor.includes('x');
|
|
1438
1343
|
}
|
|
@@ -1441,26 +1346,28 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
1441
1346
|
const elTag = unsafeStatic(elTagString);
|
|
1442
1347
|
|
|
1443
1348
|
// we set submitted to always show errors
|
|
1444
|
-
const el =
|
|
1349
|
+
const el =
|
|
1350
|
+
/** @type {ValidateHasX} */
|
|
1445
1351
|
await fixture(html`
|
|
1446
1352
|
<${elTag}
|
|
1447
1353
|
.submitted=${true}
|
|
1448
|
-
.validators=${[
|
|
1354
|
+
.validators=${[
|
|
1355
|
+
new MinLength(2, {
|
|
1356
|
+
type: 'x',
|
|
1357
|
+
}),
|
|
1358
|
+
]}
|
|
1449
1359
|
.modelValue=${'1'}
|
|
1450
1360
|
>${lightDom}</${elTag}>
|
|
1451
|
-
`)
|
|
1452
|
-
);
|
|
1361
|
+
`);
|
|
1453
1362
|
await el.feedbackComplete;
|
|
1454
1363
|
expect(el.hasX).to.be.true;
|
|
1455
1364
|
expect(el.hasXVisible).to.be.true;
|
|
1456
|
-
|
|
1457
1365
|
el.modelValue = '12';
|
|
1458
1366
|
expect(el.hasX).to.be.false;
|
|
1459
1367
|
await el.updateComplete;
|
|
1460
1368
|
await el.feedbackComplete;
|
|
1461
1369
|
expect(el.hasXVisible).to.be.false;
|
|
1462
1370
|
});
|
|
1463
|
-
|
|
1464
1371
|
it('can fire custom events if needed', async () => {
|
|
1465
1372
|
/**
|
|
1466
1373
|
*
|
|
@@ -1469,8 +1376,8 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
1469
1376
|
*/
|
|
1470
1377
|
function arrayDiff(array1 = [], array2 = []) {
|
|
1471
1378
|
return array1
|
|
1472
|
-
.filter(x => !array2.includes(x))
|
|
1473
|
-
.concat(array2.filter(x => !array1.includes(x)));
|
|
1379
|
+
.filter((x) => !array2.includes(x))
|
|
1380
|
+
.concat(array2.filter((x) => !array1.includes(x)));
|
|
1474
1381
|
}
|
|
1475
1382
|
const elTagString = defineCE(
|
|
1476
1383
|
class extends ValidateMixin(LitElement) {
|
|
@@ -1488,26 +1395,33 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
1488
1395
|
if (name === 'hasFeedbackFor') {
|
|
1489
1396
|
const diff = arrayDiff(this.hasFeedbackFor, oldValue);
|
|
1490
1397
|
if (diff.length > 0 && diff.includes('x')) {
|
|
1491
|
-
this.dispatchEvent(
|
|
1398
|
+
this.dispatchEvent(
|
|
1399
|
+
new Event(`hasFeedbackForXChanged`, {
|
|
1400
|
+
bubbles: true,
|
|
1401
|
+
}),
|
|
1402
|
+
);
|
|
1492
1403
|
}
|
|
1493
1404
|
}
|
|
1494
1405
|
}
|
|
1495
1406
|
},
|
|
1496
1407
|
);
|
|
1497
1408
|
const elTag = unsafeStatic(elTagString);
|
|
1498
|
-
|
|
1499
1409
|
const spy = sinon.spy();
|
|
1500
1410
|
// we set prefilled to always show errors
|
|
1501
|
-
const el =
|
|
1411
|
+
const el =
|
|
1412
|
+
/** @type {ValidateElement} */
|
|
1502
1413
|
await fixture(html`
|
|
1503
1414
|
<${elTag}
|
|
1504
1415
|
.prefilled=${true}
|
|
1505
1416
|
@hasFeedbackForXChanged=${spy}
|
|
1506
|
-
.validators=${[
|
|
1417
|
+
.validators=${[
|
|
1418
|
+
new MinLength(2, {
|
|
1419
|
+
type: 'x',
|
|
1420
|
+
}),
|
|
1421
|
+
]}
|
|
1507
1422
|
.modelValue=${'1'}
|
|
1508
1423
|
>${lightDom}</${elTag}>
|
|
1509
|
-
`)
|
|
1510
|
-
);
|
|
1424
|
+
`);
|
|
1511
1425
|
expect(spy).to.have.callCount(1);
|
|
1512
1426
|
el.modelValue = '1';
|
|
1513
1427
|
expect(spy).to.have.callCount(1);
|
|
@@ -1519,7 +1433,6 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
1519
1433
|
expect(spy).to.have.callCount(3);
|
|
1520
1434
|
});
|
|
1521
1435
|
});
|
|
1522
|
-
|
|
1523
1436
|
describe('Changing feedback visibility conditions', () => {
|
|
1524
1437
|
// TODO: add this test on FormControl layer
|
|
1525
1438
|
it('reconsiders feedback visibility when interaction states changed', async () => {
|
|
@@ -1535,21 +1448,20 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
1535
1448
|
submitted: Boolean,
|
|
1536
1449
|
};
|
|
1537
1450
|
}
|
|
1538
|
-
|
|
1539
1451
|
_showFeedbackConditionFor() {
|
|
1540
1452
|
return true;
|
|
1541
1453
|
}
|
|
1542
1454
|
},
|
|
1543
1455
|
);
|
|
1544
1456
|
const elTag = unsafeStatic(elTagString);
|
|
1545
|
-
const el =
|
|
1457
|
+
const el =
|
|
1458
|
+
/** @type {ValidateElement} */
|
|
1546
1459
|
await fixture(html`
|
|
1547
1460
|
<${elTag}
|
|
1548
1461
|
.validators=${[new AlwaysInvalid()]}
|
|
1549
1462
|
.modelValue=${'myValue'}
|
|
1550
1463
|
>${lightDom}</${elTag}>
|
|
1551
|
-
`)
|
|
1552
|
-
);
|
|
1464
|
+
`);
|
|
1553
1465
|
|
|
1554
1466
|
// @ts-ignore [allow-protected] in test
|
|
1555
1467
|
const spy = sinon.spy(el, '_updateShouldShowFeedbackFor');
|
|
@@ -1571,7 +1483,6 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
1571
1483
|
expect(spy.callCount).to.equal(counter);
|
|
1572
1484
|
}
|
|
1573
1485
|
});
|
|
1574
|
-
|
|
1575
1486
|
it('filters feedback visibility according interaction states', async () => {
|
|
1576
1487
|
const elTagString = defineCE(
|
|
1577
1488
|
class extends ValidateMixin(LitElement) {
|
|
@@ -1582,7 +1493,9 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
1582
1493
|
/** @type {any} */
|
|
1583
1494
|
static get properties() {
|
|
1584
1495
|
return {
|
|
1585
|
-
modelValue: {
|
|
1496
|
+
modelValue: {
|
|
1497
|
+
type: String,
|
|
1498
|
+
},
|
|
1586
1499
|
};
|
|
1587
1500
|
}
|
|
1588
1501
|
|
|
@@ -1600,17 +1513,26 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
1600
1513
|
},
|
|
1601
1514
|
);
|
|
1602
1515
|
const elTag = unsafeStatic(elTagString);
|
|
1603
|
-
const el =
|
|
1516
|
+
const el =
|
|
1517
|
+
/** @type {ValidateElement} */
|
|
1604
1518
|
await fixture(html`
|
|
1605
1519
|
<${elTag}
|
|
1606
1520
|
.validators=${[
|
|
1607
|
-
new AlwaysInvalid(
|
|
1608
|
-
|
|
1521
|
+
new AlwaysInvalid(
|
|
1522
|
+
{},
|
|
1523
|
+
{
|
|
1524
|
+
type: 'error',
|
|
1525
|
+
},
|
|
1526
|
+
),
|
|
1527
|
+
new AlwaysInvalid(
|
|
1528
|
+
{},
|
|
1529
|
+
{
|
|
1530
|
+
type: 'info',
|
|
1531
|
+
},
|
|
1532
|
+
),
|
|
1609
1533
|
]}
|
|
1610
1534
|
>${lightDom}</${elTag}>
|
|
1611
|
-
`)
|
|
1612
|
-
);
|
|
1613
|
-
|
|
1535
|
+
`);
|
|
1614
1536
|
for (const [modelValue, expected] of [
|
|
1615
1537
|
['A', ['error']],
|
|
1616
1538
|
['B', ['error']],
|
|
@@ -1622,12 +1544,11 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
1622
1544
|
await el.feedbackComplete;
|
|
1623
1545
|
|
|
1624
1546
|
// @ts-expect-error [allow-protected]
|
|
1625
|
-
const resultOrder = el._feedbackNode.feedbackData.map(v => v.type);
|
|
1547
|
+
const resultOrder = el._feedbackNode.feedbackData.map((v) => v.type);
|
|
1626
1548
|
expect(resultOrder).to.deep.equal(expected);
|
|
1627
1549
|
}
|
|
1628
1550
|
});
|
|
1629
1551
|
});
|
|
1630
|
-
|
|
1631
1552
|
describe('Changing feedback messages globally', () => {
|
|
1632
1553
|
// Please see tests of Validation Feedback
|
|
1633
1554
|
});
|