@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
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/* eslint-disable class-methods-use-this */
|
|
2
2
|
|
|
3
3
|
import { dedupeMixin } from '@open-wc/dedupe-mixin';
|
|
4
|
-
|
|
5
4
|
import { FormControlMixin } from './FormControlMixin.js';
|
|
6
5
|
import { Unparseable } from './validate/Unparseable.js';
|
|
7
6
|
import { ValidateMixin } from './validate/ValidateMixin.js';
|
|
@@ -59,594 +58,595 @@ import { ValidateMixin } from './validate/ValidateMixin.js';
|
|
|
59
58
|
* @param {import('@open-wc/dedupe-mixin').Constructor<import('lit').LitElement>} superclass
|
|
60
59
|
*/
|
|
61
60
|
// prettier-ignore
|
|
62
|
-
const FormatMixinImplementation = /** @type {FormatMixin} */ (superclass
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
* During format/parse, we sometimes need to know how the current viewValue the user
|
|
75
|
-
* interacts with "came to be". Was it already formatted before for instance?
|
|
76
|
-
* If so, in case of an amount input, we might want to stick to the current interpretation of separators.
|
|
77
|
-
*/
|
|
78
|
-
#viewValueState = {
|
|
79
|
-
didFormatterOutputSyncToView: false,
|
|
80
|
-
didFormatterRun: false,
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* @param {string} [name]
|
|
85
|
-
* @param {unknown} [oldValue]
|
|
86
|
-
* @param {import('lit').PropertyDeclaration} [options]
|
|
87
|
-
* @returns {void}
|
|
88
|
-
*/
|
|
89
|
-
requestUpdate(name, oldValue, options) {
|
|
90
|
-
super.requestUpdate(name, oldValue, options);
|
|
91
|
-
|
|
92
|
-
const didModelValueChange = () =>
|
|
93
|
-
options?.hasChanged
|
|
94
|
-
? options.hasChanged(this.modelValue, oldValue)
|
|
95
|
-
: this.modelValue !== oldValue;
|
|
96
|
-
|
|
97
|
-
if (name === 'modelValue' && didModelValueChange()) {
|
|
98
|
-
this._onModelValueChanged({ modelValue: this.modelValue }, { modelValue: oldValue });
|
|
99
|
-
}
|
|
100
|
-
if (name === 'serializedValue' && this.serializedValue !== oldValue) {
|
|
101
|
-
this._calculateValues({ source: 'serialized' });
|
|
102
|
-
}
|
|
103
|
-
if (name === 'formattedValue' && this.formattedValue !== oldValue) {
|
|
104
|
-
this._calculateValues({ source: 'formatted' });
|
|
61
|
+
const FormatMixinImplementation = /** @type {FormatMixin} */superclass => class FormatMixin extends ValidateMixin(FormControlMixin(superclass)) {
|
|
62
|
+
/** @type {any} */
|
|
63
|
+
static get properties() {
|
|
64
|
+
return {
|
|
65
|
+
formattedValue: {
|
|
66
|
+
attribute: false
|
|
67
|
+
},
|
|
68
|
+
serializedValue: {
|
|
69
|
+
attribute: false
|
|
70
|
+
},
|
|
71
|
+
formatOptions: {
|
|
72
|
+
attribute: false
|
|
105
73
|
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* During format/parse, we sometimes need to know how the current viewValue the user
|
|
79
|
+
* interacts with "came to be". Was it already formatted before for instance?
|
|
80
|
+
* If so, in case of an amount input, we might want to stick to the current interpretation of separators.
|
|
81
|
+
*/
|
|
82
|
+
#viewValueState = {
|
|
83
|
+
didFormatterOutputSyncToView: false,
|
|
84
|
+
didFormatterRun: false
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @param {string} [name]
|
|
89
|
+
* @param {unknown} [oldValue]
|
|
90
|
+
* @param {import('lit').PropertyDeclaration} [options]
|
|
91
|
+
* @returns {void}
|
|
92
|
+
*/
|
|
93
|
+
requestUpdate(name, oldValue, options) {
|
|
94
|
+
super.requestUpdate(name, oldValue, options);
|
|
95
|
+
const didModelValueChange = () => options?.hasChanged ? options.hasChanged(this.modelValue, oldValue) : this.modelValue !== oldValue;
|
|
96
|
+
if (name === 'modelValue' && didModelValueChange()) {
|
|
97
|
+
this._onModelValueChanged({
|
|
98
|
+
modelValue: this.modelValue
|
|
99
|
+
}, {
|
|
100
|
+
modelValue: oldValue
|
|
101
|
+
});
|
|
106
102
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
get value() {
|
|
112
|
-
return this._inputNode?.value || this.__value || '';
|
|
103
|
+
if (name === 'serializedValue' && this.serializedValue !== oldValue) {
|
|
104
|
+
this._calculateValues({
|
|
105
|
+
source: 'serialized'
|
|
106
|
+
});
|
|
113
107
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
108
|
+
if (name === 'formattedValue' && this.formattedValue !== oldValue) {
|
|
109
|
+
this._calculateValues({
|
|
110
|
+
source: 'formatted'
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* The view value. Will be delegated to `._inputNode.value`
|
|
117
|
+
*/
|
|
118
|
+
get value() {
|
|
119
|
+
return this._inputNode?.value || this.__value || '';
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** @param {string} value */
|
|
123
|
+
set value(value) {
|
|
124
|
+
// if not yet connected to dom can't change the value
|
|
125
|
+
if (this._inputNode) {
|
|
126
|
+
this._inputNode.value = value;
|
|
127
|
+
/** @type {string | undefined} */
|
|
128
|
+
this.__value = undefined;
|
|
129
|
+
} else {
|
|
130
|
+
this.__value = value;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
get _isEditingTextField() {
|
|
134
|
+
// For backward compatibility. Ideally we check whether the input is focused,
|
|
135
|
+
// like we do in "hybrid" (picker + textbox) components like datepicker
|
|
136
|
+
return this._isHandlingUserInput;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Preprocessors could be considered 'live formatters'. Their result is shown to the user
|
|
141
|
+
* on keyup instead of after blurring the field. The biggest difference between preprocessors
|
|
142
|
+
* and formatters is their moment of execution: preprocessors are run before modelValue is
|
|
143
|
+
* computed (and work based on view value), whereas formatters are run after the parser (and
|
|
144
|
+
* are based on modelValue)
|
|
145
|
+
* Automatically formats code while typing. It depends on a preprocessor that smartly
|
|
146
|
+
* updates the viewValue and caret position for best UX.
|
|
147
|
+
* @example
|
|
148
|
+
* ```js
|
|
149
|
+
* preprocessor(viewValue) {
|
|
150
|
+
* // only use digits
|
|
151
|
+
* return viewValue.replace(/\D/g, '');
|
|
152
|
+
* }
|
|
153
|
+
* ```
|
|
154
|
+
* @param {string} v - the raw value from the <input> after keyUp/Down event
|
|
155
|
+
* @param {FormatOptions & { prevViewValue: string; currentCaretIndex: number }} opts - the raw value from the <input> after keyUp/Down event
|
|
156
|
+
* @returns {{ viewValue:string; caretIndex:number; }|string|undefined} preprocessedValue: the result of preprocessing for invalid input
|
|
157
|
+
*/
|
|
158
|
+
preprocessor(v, opts) {
|
|
159
|
+
// eslint-disable-line no-unused-vars
|
|
160
|
+
return undefined;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Converts viewValue to modelValue
|
|
165
|
+
* For instance, a localized date to a Date Object
|
|
166
|
+
* @param {string} v - viewValue: the formatted value inside <input>
|
|
167
|
+
* @param {FormatOptions} opts
|
|
168
|
+
* @returns {*} modelValue
|
|
169
|
+
*/
|
|
170
|
+
// eslint-disable-next-line no-unused-vars
|
|
171
|
+
parser(v, opts) {
|
|
172
|
+
return v;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Converts modelValue to formattedValue (formattedValue will be synced with
|
|
177
|
+
* `._inputNode.value`)
|
|
178
|
+
* For instance, a Date object to a localized date.
|
|
179
|
+
* @param {*} v - modelValue: can be an Object, Number, String depending on the
|
|
180
|
+
* input type(date, number, email etc)
|
|
181
|
+
* @param {FormatOptions} opts
|
|
182
|
+
* @returns {string} formattedValue
|
|
183
|
+
*/
|
|
184
|
+
// eslint-disable-next-line no-unused-vars
|
|
185
|
+
formatter(v, opts) {
|
|
186
|
+
return v;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Converts `.modelValue` to `.serializedValue`
|
|
191
|
+
* For instance, a Date object to an iso formatted date string
|
|
192
|
+
* @param {any} v - modelValue: can be an Object, Number, String depending on the
|
|
193
|
+
* input type(date, number, email etc)
|
|
194
|
+
* @returns {string} serializedValue
|
|
195
|
+
*/
|
|
196
|
+
serializer(v) {
|
|
197
|
+
return v !== undefined ? v : '';
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Converts `.serializedValue` to `.modelValue`
|
|
202
|
+
* For instance, an iso formatted date string to a Date object
|
|
203
|
+
* @param {any} v - modelValue: can be an Object, Number, String depending on the
|
|
204
|
+
* input type(date, number, email etc)
|
|
205
|
+
* @returns {any} modelValue
|
|
206
|
+
*/
|
|
207
|
+
deserializer(v) {
|
|
208
|
+
return v === undefined ? '' : v;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Responsible for storing all representations(modelValue, serializedValue, formattedValue
|
|
213
|
+
* and value) of the input value. Prevents infinite loops, so all value observers can be
|
|
214
|
+
* treated like they will only be called once, without indirectly calling other observers.
|
|
215
|
+
* (in fact, some are called twice, but the __preventRecursiveTrigger lock prevents the
|
|
216
|
+
* second call from having effect).
|
|
217
|
+
*
|
|
218
|
+
* @param {{source:'model'|'serialized'|'formatted'|null}} config - the type of value that triggered this method. It should not be
|
|
219
|
+
* set again, so that its observer won't be triggered. Can be:
|
|
220
|
+
* 'model'|'formatted'|'serialized'.
|
|
221
|
+
* @protected
|
|
222
|
+
*/
|
|
223
|
+
_calculateValues({
|
|
224
|
+
source
|
|
225
|
+
} = {
|
|
226
|
+
source: null
|
|
227
|
+
}) {
|
|
228
|
+
// @ts-ignore [ts7-2565] TS7 checks definite assignment on this inferred field; private field: hoist to a class field with an initializer (the fix proven on LionAccordion)
|
|
229
|
+
if (this.__preventRecursiveTrigger) return; // prevent infinite loops
|
|
230
|
+
|
|
231
|
+
/** @type {boolean} */
|
|
232
|
+
this.__preventRecursiveTrigger = true;
|
|
233
|
+
if (source !== 'model') {
|
|
234
|
+
if (source === 'serialized') {
|
|
235
|
+
/** @type {any} */
|
|
236
|
+
this.modelValue = this.deserializer(this.serializedValue);
|
|
237
|
+
} else if (source === 'formatted') {
|
|
238
|
+
this.modelValue = this._callParser();
|
|
124
239
|
}
|
|
125
240
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
241
|
+
if (source !== 'formatted') {
|
|
242
|
+
this.formattedValue = this._callFormatter();
|
|
243
|
+
}
|
|
244
|
+
if (source !== 'serialized') {
|
|
245
|
+
this.serializedValue = this.serializer(this.modelValue);
|
|
246
|
+
}
|
|
247
|
+
this._reflectBackFormattedValueToUser();
|
|
248
|
+
this.__preventRecursiveTrigger = false;
|
|
249
|
+
this.__prevViewValue = this.value;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* @param {string|undefined} value
|
|
254
|
+
* @return {any}
|
|
255
|
+
* @private
|
|
256
|
+
*/
|
|
257
|
+
_callParser(value = this.formattedValue) {
|
|
258
|
+
// A) check if we need to parse at all
|
|
259
|
+
|
|
260
|
+
// A.1) The end user had no intention to parse
|
|
261
|
+
if (value === '') {
|
|
262
|
+
// Ideally, modelValue should be undefined for empty strings.
|
|
263
|
+
// For backwards compatibility we return an empty string:
|
|
264
|
+
// - it can be expected by 3rd parties (for instance unit tests)
|
|
265
|
+
// TODO(@tlouisse): In a breaking refactor of the Validation System, this behavior can be corrected.
|
|
266
|
+
return '';
|
|
131
267
|
}
|
|
132
268
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
* Automatically formats code while typing. It depends on a preprocessor that smartly
|
|
140
|
-
* updates the viewValue and caret position for best UX.
|
|
141
|
-
* @example
|
|
142
|
-
* ```js
|
|
143
|
-
* preprocessor(viewValue) {
|
|
144
|
-
* // only use digits
|
|
145
|
-
* return viewValue.replace(/\D/g, '');
|
|
146
|
-
* }
|
|
147
|
-
* ```
|
|
148
|
-
* @param {string} v - the raw value from the <input> after keyUp/Down event
|
|
149
|
-
* @param {FormatOptions & { prevViewValue: string; currentCaretIndex: number }} opts - the raw value from the <input> after keyUp/Down event
|
|
150
|
-
* @returns {{ viewValue:string; caretIndex:number; }|string|undefined} preprocessedValue: the result of preprocessing for invalid input
|
|
151
|
-
*/
|
|
152
|
-
preprocessor(v, opts) { // eslint-disable-line no-unused-vars
|
|
269
|
+
// A.2) Handle edge cases. We might have no view value yet, for instance because
|
|
270
|
+
// _inputNode.value was not available yet
|
|
271
|
+
if (typeof value !== 'string') {
|
|
272
|
+
// This means there is nothing to find inside the view that can be of
|
|
273
|
+
// interest to the Application Developer or needed to store for future
|
|
274
|
+
// form state retrieval.
|
|
153
275
|
return undefined;
|
|
154
276
|
}
|
|
155
277
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
//
|
|
164
|
-
parser(
|
|
165
|
-
|
|
278
|
+
// B) parse the view value
|
|
279
|
+
|
|
280
|
+
// - if result:
|
|
281
|
+
// return the successfully parsed viewValue
|
|
282
|
+
// - if no result:
|
|
283
|
+
// Apparently, the parser was not able to produce a satisfactory output for the desired
|
|
284
|
+
// modelValue type, based on the current viewValue. Unparseable allows to restore all
|
|
285
|
+
// states (for instance from a lost user session), since it saves the current viewValue.
|
|
286
|
+
const result = this.parser(value, {
|
|
287
|
+
...this.formatOptions,
|
|
288
|
+
mode: this.#getFormatOptionsMode(),
|
|
289
|
+
viewValueStates: this.#getFormatOptionsViewValueStates()
|
|
290
|
+
});
|
|
291
|
+
return result !== undefined ? result : new Unparseable(value);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* @returns {string|undefined}
|
|
296
|
+
* @private
|
|
297
|
+
*/
|
|
298
|
+
_callFormatter() {
|
|
299
|
+
this.#viewValueState.didFormatterRun = false;
|
|
300
|
+
|
|
301
|
+
// - Why check for this.hasError?
|
|
302
|
+
// We only want to format values that are considered valid. For best UX,
|
|
303
|
+
// we only 'reward' valid inputs.
|
|
304
|
+
// - Why check for _isEditingTextField?
|
|
305
|
+
// Downwards sync is prevented whenever we are in an `@user-input-changed` flow, [2].
|
|
306
|
+
// If we are in a 'imperatively set `.modelValue`' flow, [1], we want to reflect back
|
|
307
|
+
// the value, no matter what.
|
|
308
|
+
// This means, whenever we are in hasError and modelValue is set
|
|
309
|
+
// imperatively, we DO want to format a value (it is the only way to get meaningful
|
|
310
|
+
// input into `._inputNode` with modelValue as input)
|
|
311
|
+
if (this._isEditingTextField && this.hasFeedbackFor?.includes('error') && this._inputNode) {
|
|
312
|
+
return this.value;
|
|
166
313
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
* @param {*} v - modelValue: can be an Object, Number, String depending on the
|
|
173
|
-
* input type(date, number, email etc)
|
|
174
|
-
* @param {FormatOptions} opts
|
|
175
|
-
* @returns {string} formattedValue
|
|
176
|
-
*/
|
|
177
|
-
// eslint-disable-next-line no-unused-vars
|
|
178
|
-
formatter(v, opts) {
|
|
179
|
-
return v;
|
|
314
|
+
if (this.modelValue instanceof Unparseable) {
|
|
315
|
+
// When the modelValue currently is unparseable, we need to sync back the supplied
|
|
316
|
+
// viewValue. In flow [2], this should not be needed.
|
|
317
|
+
// In flow [1] (we restore a previously stored modelValue) we should sync down, however.
|
|
318
|
+
return this.modelValue.viewValue;
|
|
180
319
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
320
|
+
this.#viewValueState.didFormatterRun = true;
|
|
321
|
+
return this.formatter(this.modelValue, {
|
|
322
|
+
...this.formatOptions,
|
|
323
|
+
mode: this.#getFormatOptionsMode(),
|
|
324
|
+
viewValueStates: this.#getFormatOptionsViewValueStates()
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Responds to modelValue changes in the synchronous cycle (most subclassers should listen to
|
|
330
|
+
* the asynchronous cycle ('modelValue' in the .updated lifecycle))
|
|
331
|
+
* @param {{ modelValue: unknown; }[]} args
|
|
332
|
+
* @protected
|
|
333
|
+
*/
|
|
334
|
+
_onModelValueChanged(...args) {
|
|
335
|
+
this._calculateValues({
|
|
336
|
+
source: 'model'
|
|
337
|
+
});
|
|
338
|
+
this._dispatchModelValueChangedEvent(...args);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* This is wrapped in a distinct method, so that parents can control when the changed event
|
|
343
|
+
* is fired. For objects, a deep comparison might be needed.
|
|
344
|
+
* @param {{ modelValue: unknown; }[]} args
|
|
345
|
+
* @protected
|
|
346
|
+
*/
|
|
347
|
+
// eslint-disable-next-line no-unused-vars
|
|
348
|
+
_dispatchModelValueChangedEvent(...args) {
|
|
349
|
+
/** @event model-value-changed */
|
|
350
|
+
this.dispatchEvent(/** @privateEvent model-value-changed: FormControl redispatches it as public event */
|
|
351
|
+
new CustomEvent('model-value-changed', {
|
|
352
|
+
bubbles: true,
|
|
353
|
+
detail: (/** @type { ModelValueEventDetails } */
|
|
354
|
+
/** @type {unknown} */{
|
|
355
|
+
formPath: [this],
|
|
356
|
+
isTriggeredByUser: Boolean(this._isHandlingUserInput)
|
|
357
|
+
})
|
|
358
|
+
}));
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Synchronization from `._inputNode.value` to `LionField` (flow [2])
|
|
363
|
+
* Downwards syncing should only happen for `LionField`.value changes from 'above'.
|
|
364
|
+
* This triggers _onModelValueChanged and connects user input
|
|
365
|
+
* to the parsing/formatting/serializing loop.
|
|
366
|
+
* @protected
|
|
367
|
+
*/
|
|
368
|
+
_syncValueUpwards() {
|
|
369
|
+
if (!this.__isHandlingComposition) {
|
|
370
|
+
this.__handlePreprocessor();
|
|
191
371
|
}
|
|
372
|
+
const prevFormatted = this.formattedValue;
|
|
373
|
+
this.modelValue = this._callParser(this.value);
|
|
192
374
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
* input type(date, number, email etc)
|
|
198
|
-
* @returns {any} modelValue
|
|
199
|
-
*/
|
|
200
|
-
deserializer(v) {
|
|
201
|
-
return v === undefined ? '' : v;
|
|
375
|
+
// Sometimes, the formattedValue didn't change, but the viewValue did...
|
|
376
|
+
// We need this check to support pasting values that need to be formatted right on paste
|
|
377
|
+
if (prevFormatted === this.formattedValue && this.__prevViewValue !== this.value) {
|
|
378
|
+
this._calculateValues();
|
|
202
379
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
* @protected
|
|
215
|
-
*/
|
|
216
|
-
_calculateValues({ source } = { source: null }) {
|
|
217
|
-
// @ts-ignore [ts7-2565] TS7 checks definite assignment on this inferred field; private field: hoist to a class field with an initializer (the fix proven on LionAccordion)
|
|
218
|
-
if (this.__preventRecursiveTrigger) return; // prevent infinite loops
|
|
219
|
-
|
|
220
|
-
/** @type {boolean} */
|
|
221
|
-
this.__preventRecursiveTrigger = true;
|
|
222
|
-
if (source !== 'model') {
|
|
223
|
-
if (source === 'serialized') {
|
|
224
|
-
/** @type {any} */
|
|
225
|
-
this.modelValue = this.deserializer(this.serializedValue);
|
|
226
|
-
} else if (source === 'formatted') {
|
|
227
|
-
this.modelValue = this._callParser();
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
if (source !== 'formatted') {
|
|
231
|
-
this.formattedValue = this._callFormatter();
|
|
232
|
-
}
|
|
233
|
-
if (source !== 'serialized') {
|
|
234
|
-
this.serializedValue = this.serializer(this.modelValue);
|
|
235
|
-
}
|
|
236
|
-
this._reflectBackFormattedValueToUser();
|
|
237
|
-
this.__preventRecursiveTrigger = false;
|
|
238
|
-
this.__prevViewValue = this.value;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Handle view value and caretIndex, depending on return type of .preprocessor.
|
|
384
|
+
* @private
|
|
385
|
+
*/
|
|
386
|
+
__handlePreprocessor() {
|
|
387
|
+
let currentCaretIndex = this.value.length;
|
|
388
|
+
// Be gentle with Safari
|
|
389
|
+
if (this._inputNode && 'selectionStart' in this._inputNode && /** @type {HTMLInputElement} */this._inputNode?.type !== 'range') {
|
|
390
|
+
currentCaretIndex = /** @type {number} */this._inputNode.selectionStart;
|
|
239
391
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
//
|
|
248
|
-
|
|
249
|
-
// A.1) The end user had no intention to parse
|
|
250
|
-
if (value === '') {
|
|
251
|
-
// Ideally, modelValue should be undefined for empty strings.
|
|
252
|
-
// For backwards compatibility we return an empty string:
|
|
253
|
-
// - it can be expected by 3rd parties (for instance unit tests)
|
|
254
|
-
// TODO(@tlouisse): In a breaking refactor of the Validation System, this behavior can be corrected.
|
|
255
|
-
return '';
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// A.2) Handle edge cases. We might have no view value yet, for instance because
|
|
259
|
-
// _inputNode.value was not available yet
|
|
260
|
-
if (typeof value !== 'string') {
|
|
261
|
-
// This means there is nothing to find inside the view that can be of
|
|
262
|
-
// interest to the Application Developer or needed to store for future
|
|
263
|
-
// form state retrieval.
|
|
264
|
-
return undefined;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
// B) parse the view value
|
|
268
|
-
|
|
269
|
-
// - if result:
|
|
270
|
-
// return the successfully parsed viewValue
|
|
271
|
-
// - if no result:
|
|
272
|
-
// Apparently, the parser was not able to produce a satisfactory output for the desired
|
|
273
|
-
// modelValue type, based on the current viewValue. Unparseable allows to restore all
|
|
274
|
-
// states (for instance from a lost user session), since it saves the current viewValue.
|
|
275
|
-
const result = this.parser(value, {
|
|
276
|
-
...this.formatOptions,
|
|
277
|
-
mode: this.#getFormatOptionsMode(),
|
|
278
|
-
viewValueStates: this.#getFormatOptionsViewValueStates(),
|
|
279
|
-
});
|
|
280
|
-
return result !== undefined ? result : new Unparseable(value);
|
|
392
|
+
const preprocessedValue = this.preprocessor(this.value, {
|
|
393
|
+
...this.formatOptions,
|
|
394
|
+
currentCaretIndex,
|
|
395
|
+
prevViewValue: this.__prevViewValue
|
|
396
|
+
});
|
|
397
|
+
if (preprocessedValue === undefined) {
|
|
398
|
+
// Make sure we do no set back original value, so we preserve
|
|
399
|
+
// caret index (== selectionStart/selectionEnd)
|
|
400
|
+
return;
|
|
281
401
|
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
// - Why check for _isEditingTextField?
|
|
294
|
-
// Downwards sync is prevented whenever we are in an `@user-input-changed` flow, [2].
|
|
295
|
-
// If we are in a 'imperatively set `.modelValue`' flow, [1], we want to reflect back
|
|
296
|
-
// the value, no matter what.
|
|
297
|
-
// This means, whenever we are in hasError and modelValue is set
|
|
298
|
-
// imperatively, we DO want to format a value (it is the only way to get meaningful
|
|
299
|
-
// input into `._inputNode` with modelValue as input)
|
|
300
|
-
if (this._isEditingTextField && this.hasFeedbackFor?.includes('error') && this._inputNode) {
|
|
301
|
-
return this.value;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
if (this.modelValue instanceof Unparseable) {
|
|
305
|
-
// When the modelValue currently is unparseable, we need to sync back the supplied
|
|
306
|
-
// viewValue. In flow [2], this should not be needed.
|
|
307
|
-
// In flow [1] (we restore a previously stored modelValue) we should sync down, however.
|
|
308
|
-
return this.modelValue.viewValue;
|
|
402
|
+
if (typeof preprocessedValue === 'string') {
|
|
403
|
+
this.value = preprocessedValue;
|
|
404
|
+
} else if (typeof preprocessedValue === 'object') {
|
|
405
|
+
const {
|
|
406
|
+
viewValue,
|
|
407
|
+
caretIndex
|
|
408
|
+
} = preprocessedValue;
|
|
409
|
+
this.value = viewValue;
|
|
410
|
+
if (caretIndex && this._inputNode && 'selectionStart' in this._inputNode) {
|
|
411
|
+
this._inputNode.selectionStart = caretIndex;
|
|
412
|
+
this._inputNode.selectionEnd = caretIndex;
|
|
309
413
|
}
|
|
310
|
-
|
|
311
|
-
this.#viewValueState.didFormatterRun = true;
|
|
312
|
-
|
|
313
|
-
return this.formatter(this.modelValue, {
|
|
314
|
-
...this.formatOptions,
|
|
315
|
-
mode: this.#getFormatOptionsMode(),
|
|
316
|
-
viewValueStates: this.#getFormatOptionsViewValueStates(),
|
|
317
|
-
});
|
|
318
414
|
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Synchronization from `LionField.value` to `._inputNode.value`
|
|
419
|
+
* - flow [1] will always be reflected back
|
|
420
|
+
* - flow [2] will not be reflected back when this flow was triggered via
|
|
421
|
+
* `@user-input-changed` (this will happen later, when `formatOn` condition is met)
|
|
422
|
+
* @protected
|
|
423
|
+
*/
|
|
424
|
+
_reflectBackFormattedValueToUser() {
|
|
425
|
+
if (this._reflectBackOn()) {
|
|
426
|
+
// Text 'undefined' should not end up in <input>
|
|
427
|
+
this.value = typeof this.formattedValue !== 'undefined' ? this.formattedValue : '';
|
|
428
|
+
this.#viewValueState.didFormatterOutputSyncToView = Boolean(this.formattedValue) && this.#viewValueState.didFormatterRun;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Every time .formattedValue is attempted to sync to the view value (on change/blur and on
|
|
434
|
+
* modelValue change), this condition is checked. When enhancing it, it's recommended to
|
|
435
|
+
* call via `return this._myExtraCondition && super._reflectBackOn()`
|
|
436
|
+
* @overridable
|
|
437
|
+
* @return {boolean}
|
|
438
|
+
* @protected
|
|
439
|
+
*/
|
|
440
|
+
_reflectBackOn() {
|
|
441
|
+
return !this._isHandlingUserInput;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* This can be called whenever the view value should be updated. Dependent on component type
|
|
446
|
+
* ("input" for <input> or "change" for <select>(mainly for IE)) a different event should be
|
|
447
|
+
* used as source for the "user-input-changed" event (which can be seen as an abstraction
|
|
448
|
+
* layer on top of other events (input, change, whatever))
|
|
449
|
+
* @protected
|
|
450
|
+
*/
|
|
451
|
+
_proxyInputEvent() {
|
|
452
|
+
// TODO: [v1] remove composed (and bubbles as well if possible)
|
|
453
|
+
/** @protectedEvent user-input-changed meant for usage by Subclassers only */
|
|
454
|
+
this.dispatchEvent(new Event('user-input-changed', {
|
|
455
|
+
bubbles: true
|
|
456
|
+
}));
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/** @protected */
|
|
460
|
+
_onUserInputChanged() {
|
|
461
|
+
// Upwards syncing. Most properties are delegated right away, value is synced to
|
|
462
|
+
// `LionField`, to be able to act on (imperatively set) value changes
|
|
463
|
+
this._isHandlingUserInput = true;
|
|
464
|
+
this._syncValueUpwards();
|
|
465
|
+
this._isHandlingUserInput = false;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* @param {Event} event
|
|
470
|
+
*/
|
|
471
|
+
__onCompositionEvent({
|
|
472
|
+
type
|
|
473
|
+
}) {
|
|
474
|
+
if (type === 'compositionstart') {
|
|
475
|
+
this.__isHandlingComposition = true;
|
|
476
|
+
} else if (type === 'compositionend') {
|
|
477
|
+
this.__isHandlingComposition = false;
|
|
478
|
+
// in all other cases this would be triggered via user-input-changed
|
|
479
|
+
this._syncValueUpwards();
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
constructor() {
|
|
483
|
+
super();
|
|
319
484
|
|
|
485
|
+
// TODO: [v1] delete; use 'change' event directly within this file
|
|
320
486
|
/**
|
|
321
|
-
*
|
|
322
|
-
*
|
|
323
|
-
*
|
|
487
|
+
* Event that will trigger formatting (more precise, visual update of the view, so the
|
|
488
|
+
* user sees the formatted value)
|
|
489
|
+
* Default: 'change'
|
|
490
|
+
* @deprecated use _reflectBackOn()
|
|
324
491
|
* @protected
|
|
325
492
|
*/
|
|
326
|
-
|
|
327
|
-
this._calculateValues({ source: 'model' });
|
|
328
|
-
this._dispatchModelValueChangedEvent(...args);
|
|
329
|
-
}
|
|
493
|
+
this.formatOn = 'change';
|
|
330
494
|
|
|
331
495
|
/**
|
|
332
|
-
*
|
|
333
|
-
* is fired. For objects, a deep comparison might be needed.
|
|
334
|
-
* @param {{ modelValue: unknown; }[]} args
|
|
335
|
-
* @protected
|
|
496
|
+
* Configuration object that will be available inside the formatter function
|
|
336
497
|
*/
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
this.dispatchEvent(
|
|
341
|
-
/** @privateEvent model-value-changed: FormControl redispatches it as public event */
|
|
342
|
-
new CustomEvent('model-value-changed', {
|
|
343
|
-
bubbles: true,
|
|
344
|
-
detail: /** @type { ModelValueEventDetails } */ (
|
|
345
|
-
/** @type {unknown} */ ({
|
|
346
|
-
formPath: [this],
|
|
347
|
-
isTriggeredByUser: Boolean(this._isHandlingUserInput),
|
|
348
|
-
})
|
|
349
|
-
),
|
|
350
|
-
}),
|
|
351
|
-
);
|
|
352
|
-
}
|
|
498
|
+
this.formatOptions = /** @type {FormatOptions} */{
|
|
499
|
+
mode: 'auto'
|
|
500
|
+
};
|
|
353
501
|
|
|
354
502
|
/**
|
|
355
|
-
*
|
|
356
|
-
*
|
|
357
|
-
*
|
|
358
|
-
*
|
|
359
|
-
*
|
|
503
|
+
* The view value is the result of the formatter function (when available).
|
|
504
|
+
* The result will be stored in the native _inputNode (usually an input[type=text]).
|
|
505
|
+
*
|
|
506
|
+
* Examples:
|
|
507
|
+
* - For a date input, this would be '20/01/1999' (dependent on locale).
|
|
508
|
+
* - For a number input, this could be '1,234.56' (a String representation of modelValue
|
|
509
|
+
* 1234.56)
|
|
510
|
+
* @type {string|undefined}
|
|
511
|
+
* @readOnly
|
|
360
512
|
*/
|
|
361
|
-
|
|
362
|
-
if (!this.__isHandlingComposition) {
|
|
363
|
-
this.__handlePreprocessor();
|
|
364
|
-
}
|
|
365
|
-
const prevFormatted = this.formattedValue;
|
|
366
|
-
this.modelValue = this._callParser(this.value);
|
|
367
|
-
|
|
368
|
-
// Sometimes, the formattedValue didn't change, but the viewValue did...
|
|
369
|
-
// We need this check to support pasting values that need to be formatted right on paste
|
|
370
|
-
if (prevFormatted === this.formattedValue && this.__prevViewValue !== this.value) {
|
|
371
|
-
this._calculateValues();
|
|
372
|
-
}
|
|
373
|
-
}
|
|
513
|
+
this.formattedValue = undefined;
|
|
374
514
|
|
|
375
515
|
/**
|
|
376
|
-
*
|
|
377
|
-
*
|
|
516
|
+
* The serialized version of the model value.
|
|
517
|
+
* This value exists for maximal compatibility with the platform API.
|
|
518
|
+
* The serialized value can be an interface in context where data binding is not
|
|
519
|
+
* supported and a serialized string needs to be set.
|
|
520
|
+
*
|
|
521
|
+
* Examples:
|
|
522
|
+
* - For a date input, this would be the iso format of a date, e.g. '1999-01-20'.
|
|
523
|
+
* - For a number input this would be the String representation of a float ('1234.56'
|
|
524
|
+
* instead of 1234.56)
|
|
525
|
+
*
|
|
526
|
+
* When no parser is available, the value is usually the same as the formattedValue
|
|
527
|
+
* (being _inputNode.value)
|
|
528
|
+
* @type {string|undefined}
|
|
378
529
|
*/
|
|
379
|
-
|
|
380
|
-
let currentCaretIndex = this.value.length;
|
|
381
|
-
// Be gentle with Safari
|
|
382
|
-
if (
|
|
383
|
-
this._inputNode &&
|
|
384
|
-
'selectionStart' in this._inputNode &&
|
|
385
|
-
/** @type {HTMLInputElement} */ (this._inputNode)?.type !== 'range'
|
|
386
|
-
) {
|
|
387
|
-
currentCaretIndex = /** @type {number} */ (this._inputNode.selectionStart);
|
|
388
|
-
}
|
|
389
|
-
const preprocessedValue = this.preprocessor(this.value, {
|
|
390
|
-
...this.formatOptions,
|
|
391
|
-
currentCaretIndex,
|
|
392
|
-
prevViewValue: this.__prevViewValue,
|
|
393
|
-
});
|
|
394
|
-
|
|
395
|
-
if (preprocessedValue === undefined) {
|
|
396
|
-
// Make sure we do no set back original value, so we preserve
|
|
397
|
-
// caret index (== selectionStart/selectionEnd)
|
|
398
|
-
return;
|
|
399
|
-
}
|
|
400
|
-
if (typeof preprocessedValue === 'string') {
|
|
401
|
-
this.value = preprocessedValue;
|
|
402
|
-
} else if (typeof preprocessedValue === 'object') {
|
|
403
|
-
const { viewValue, caretIndex } = preprocessedValue;
|
|
404
|
-
this.value = viewValue;
|
|
405
|
-
if (caretIndex && this._inputNode && 'selectionStart' in this._inputNode) {
|
|
406
|
-
this._inputNode.selectionStart = caretIndex;
|
|
407
|
-
this._inputNode.selectionEnd = caretIndex;
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
}
|
|
530
|
+
this.serializedValue = undefined;
|
|
411
531
|
|
|
412
532
|
/**
|
|
413
|
-
*
|
|
414
|
-
*
|
|
415
|
-
*
|
|
416
|
-
*
|
|
533
|
+
* Whether the user is pasting content. Allows Subclassers to do this in their subclass:
|
|
534
|
+
* @example
|
|
535
|
+
* ```js
|
|
536
|
+
* _reflectBackOn() {
|
|
537
|
+
* return super._reflectBackOn() || this._isPasting;
|
|
538
|
+
* }
|
|
539
|
+
* ```
|
|
417
540
|
* @protected
|
|
541
|
+
* @type {boolean}
|
|
418
542
|
*/
|
|
419
|
-
|
|
420
|
-
if (this._reflectBackOn()) {
|
|
421
|
-
// Text 'undefined' should not end up in <input>
|
|
422
|
-
this.value = typeof this.formattedValue !== 'undefined' ? this.formattedValue : '';
|
|
423
|
-
this.#viewValueState.didFormatterOutputSyncToView =
|
|
424
|
-
Boolean(this.formattedValue) && this.#viewValueState.didFormatterRun;
|
|
425
|
-
}
|
|
426
|
-
}
|
|
543
|
+
this._isPasting = false;
|
|
427
544
|
|
|
428
545
|
/**
|
|
429
|
-
*
|
|
430
|
-
*
|
|
431
|
-
*
|
|
432
|
-
* @overridable
|
|
433
|
-
* @return {boolean}
|
|
546
|
+
* Flag that will be set when user interaction takes place (for instance after an 'input'
|
|
547
|
+
* event). Will be added as meta info to the `model-value-changed` event. Depending on
|
|
548
|
+
* whether a user is interacting, formatting logic will be handled differently.
|
|
434
549
|
* @protected
|
|
550
|
+
* @type {boolean}
|
|
435
551
|
*/
|
|
436
|
-
|
|
437
|
-
return !this._isHandlingUserInput;
|
|
438
|
-
}
|
|
439
|
-
|
|
552
|
+
this._isHandlingUserInput = false;
|
|
440
553
|
/**
|
|
441
|
-
*
|
|
442
|
-
*
|
|
443
|
-
* used as source for the "user-input-changed" event (which can be seen as an abstraction
|
|
444
|
-
* layer on top of other events (input, change, whatever))
|
|
445
|
-
* @protected
|
|
554
|
+
* @private
|
|
555
|
+
* @type {string}
|
|
446
556
|
*/
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
/** @protected */
|
|
454
|
-
_onUserInputChanged() {
|
|
455
|
-
// Upwards syncing. Most properties are delegated right away, value is synced to
|
|
456
|
-
// `LionField`, to be able to act on (imperatively set) value changes
|
|
457
|
-
this._isHandlingUserInput = true;
|
|
458
|
-
this._syncValueUpwards();
|
|
459
|
-
this._isHandlingUserInput = false;
|
|
460
|
-
}
|
|
557
|
+
this.__prevViewValue = '';
|
|
558
|
+
this.__onCompositionEvent = this.__onCompositionEvent.bind(this);
|
|
559
|
+
// This computes formattedValue
|
|
560
|
+
this.addEventListener('user-input-changed', this._onUserInputChanged);
|
|
561
|
+
// This sets the formatted viewValue after paste
|
|
562
|
+
this.addEventListener('paste', this.__onPaste);
|
|
461
563
|
|
|
462
564
|
/**
|
|
463
|
-
* @
|
|
565
|
+
* @protected
|
|
464
566
|
*/
|
|
465
|
-
|
|
466
|
-
if (type === 'compositionstart') {
|
|
467
|
-
this.__isHandlingComposition = true;
|
|
468
|
-
} else if (type === 'compositionend') {
|
|
469
|
-
this.__isHandlingComposition = false;
|
|
470
|
-
// in all other cases this would be triggered via user-input-changed
|
|
471
|
-
this._syncValueUpwards();
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
constructor() {
|
|
476
|
-
super();
|
|
477
|
-
|
|
478
|
-
// TODO: [v1] delete; use 'change' event directly within this file
|
|
479
|
-
/**
|
|
480
|
-
* Event that will trigger formatting (more precise, visual update of the view, so the
|
|
481
|
-
* user sees the formatted value)
|
|
482
|
-
* Default: 'change'
|
|
483
|
-
* @deprecated use _reflectBackOn()
|
|
484
|
-
* @protected
|
|
485
|
-
*/
|
|
486
|
-
this.formatOn = 'change';
|
|
487
|
-
|
|
488
|
-
/**
|
|
489
|
-
* Configuration object that will be available inside the formatter function
|
|
490
|
-
*/
|
|
491
|
-
this.formatOptions = /** @type {FormatOptions} */ ({ mode: 'auto' });
|
|
492
|
-
|
|
493
|
-
/**
|
|
494
|
-
* The view value is the result of the formatter function (when available).
|
|
495
|
-
* The result will be stored in the native _inputNode (usually an input[type=text]).
|
|
496
|
-
*
|
|
497
|
-
* Examples:
|
|
498
|
-
* - For a date input, this would be '20/01/1999' (dependent on locale).
|
|
499
|
-
* - For a number input, this could be '1,234.56' (a String representation of modelValue
|
|
500
|
-
* 1234.56)
|
|
501
|
-
* @type {string|undefined}
|
|
502
|
-
* @readOnly
|
|
503
|
-
*/
|
|
504
|
-
this.formattedValue = undefined;
|
|
505
|
-
|
|
506
|
-
/**
|
|
507
|
-
* The serialized version of the model value.
|
|
508
|
-
* This value exists for maximal compatibility with the platform API.
|
|
509
|
-
* The serialized value can be an interface in context where data binding is not
|
|
510
|
-
* supported and a serialized string needs to be set.
|
|
511
|
-
*
|
|
512
|
-
* Examples:
|
|
513
|
-
* - For a date input, this would be the iso format of a date, e.g. '1999-01-20'.
|
|
514
|
-
* - For a number input this would be the String representation of a float ('1234.56'
|
|
515
|
-
* instead of 1234.56)
|
|
516
|
-
*
|
|
517
|
-
* When no parser is available, the value is usually the same as the formattedValue
|
|
518
|
-
* (being _inputNode.value)
|
|
519
|
-
* @type {string|undefined}
|
|
520
|
-
*/
|
|
521
|
-
this.serializedValue = undefined;
|
|
522
|
-
|
|
523
|
-
/**
|
|
524
|
-
* Whether the user is pasting content. Allows Subclassers to do this in their subclass:
|
|
525
|
-
* @example
|
|
526
|
-
* ```js
|
|
527
|
-
* _reflectBackOn() {
|
|
528
|
-
* return super._reflectBackOn() || this._isPasting;
|
|
529
|
-
* }
|
|
530
|
-
* ```
|
|
531
|
-
* @protected
|
|
532
|
-
* @type {boolean}
|
|
533
|
-
*/
|
|
534
|
-
this._isPasting = false;
|
|
535
|
-
|
|
536
|
-
/**
|
|
537
|
-
* Flag that will be set when user interaction takes place (for instance after an 'input'
|
|
538
|
-
* event). Will be added as meta info to the `model-value-changed` event. Depending on
|
|
539
|
-
* whether a user is interacting, formatting logic will be handled differently.
|
|
540
|
-
* @protected
|
|
541
|
-
* @type {boolean}
|
|
542
|
-
*/
|
|
543
|
-
this._isHandlingUserInput = false;
|
|
544
|
-
/**
|
|
545
|
-
* @private
|
|
546
|
-
* @type {string}
|
|
547
|
-
*/
|
|
548
|
-
this.__prevViewValue = '';
|
|
549
|
-
this.__onCompositionEvent = this.__onCompositionEvent.bind(this);
|
|
550
|
-
// This computes formattedValue
|
|
551
|
-
this.addEventListener('user-input-changed', this._onUserInputChanged);
|
|
552
|
-
// This sets the formatted viewValue after paste
|
|
553
|
-
this.addEventListener('paste', this.__onPaste);
|
|
554
|
-
|
|
555
|
-
/**
|
|
556
|
-
* @protected
|
|
557
|
-
*/
|
|
558
|
-
this._reflectBackFormattedValueToUser = this._reflectBackFormattedValueToUser.bind(this);
|
|
559
|
-
|
|
560
|
-
/**
|
|
561
|
-
* @private
|
|
562
|
-
*/
|
|
563
|
-
this._reflectBackFormattedValueDebounced = () => {
|
|
564
|
-
// Make sure this is fired after the change event of _inputNode, so that formattedValue
|
|
565
|
-
// is guaranteed to be calculated
|
|
566
|
-
setTimeout(this._reflectBackFormattedValueToUser);
|
|
567
|
-
};
|
|
568
|
-
}
|
|
567
|
+
this._reflectBackFormattedValueToUser = this._reflectBackFormattedValueToUser.bind(this);
|
|
569
568
|
|
|
570
569
|
/**
|
|
571
570
|
* @private
|
|
572
571
|
*/
|
|
573
|
-
|
|
574
|
-
this
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
572
|
+
this._reflectBackFormattedValueDebounced = () => {
|
|
573
|
+
// Make sure this is fired after the change event of _inputNode, so that formattedValue
|
|
574
|
+
// is guaranteed to be calculated
|
|
575
|
+
setTimeout(this._reflectBackFormattedValueToUser);
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* @private
|
|
581
|
+
*/
|
|
582
|
+
__onPaste() {
|
|
583
|
+
this._isPasting = true;
|
|
584
|
+
setTimeout(() => {
|
|
585
|
+
this._isPasting = false;
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
connectedCallback() {
|
|
589
|
+
super.connectedCallback();
|
|
590
|
+
|
|
591
|
+
// Connect the value found in <input> to the formatting/parsing/serializing loop as a
|
|
592
|
+
// fallback mechanism. Assume the user uses the value property of the
|
|
593
|
+
// `LionField`(recommended api) as the api (this is a downwards sync).
|
|
594
|
+
// However, when no value is specified on `LionField`, have support for sync of the real
|
|
595
|
+
// input to the `LionField` (upwards sync).
|
|
596
|
+
if (typeof this.modelValue === 'undefined') {
|
|
597
|
+
this._syncValueUpwards();
|
|
578
598
|
}
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
// input to the `LionField` (upwards sync).
|
|
588
|
-
if (typeof this.modelValue === 'undefined') {
|
|
589
|
-
this._syncValueUpwards();
|
|
590
|
-
}
|
|
591
|
-
/** @type {string} */
|
|
592
|
-
this.__prevViewValue = this.value;
|
|
593
|
-
|
|
594
|
-
this._reflectBackFormattedValueToUser();
|
|
595
|
-
|
|
596
|
-
if (this._inputNode) {
|
|
597
|
-
this._inputNode.addEventListener(this.formatOn, this._reflectBackFormattedValueDebounced);
|
|
598
|
-
this._inputNode.addEventListener('input', this._proxyInputEvent);
|
|
599
|
-
this._inputNode.addEventListener('compositionstart', this.__onCompositionEvent);
|
|
600
|
-
this._inputNode.addEventListener('compositionend', this.__onCompositionEvent);
|
|
601
|
-
}
|
|
599
|
+
/** @type {string} */
|
|
600
|
+
this.__prevViewValue = this.value;
|
|
601
|
+
this._reflectBackFormattedValueToUser();
|
|
602
|
+
if (this._inputNode) {
|
|
603
|
+
this._inputNode.addEventListener(this.formatOn, this._reflectBackFormattedValueDebounced);
|
|
604
|
+
this._inputNode.addEventListener('input', this._proxyInputEvent);
|
|
605
|
+
this._inputNode.addEventListener('compositionstart', this.__onCompositionEvent);
|
|
606
|
+
this._inputNode.addEventListener('compositionend', this.__onCompositionEvent);
|
|
602
607
|
}
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
),
|
|
613
|
-
);
|
|
614
|
-
this._inputNode.removeEventListener('compositionstart', this.__onCompositionEvent);
|
|
615
|
-
this._inputNode.removeEventListener('compositionend', this.__onCompositionEvent);
|
|
616
|
-
}
|
|
608
|
+
}
|
|
609
|
+
disconnectedCallback() {
|
|
610
|
+
super.disconnectedCallback();
|
|
611
|
+
if (this._inputNode) {
|
|
612
|
+
this._inputNode.removeEventListener('input', this._proxyInputEvent);
|
|
613
|
+
this._inputNode.removeEventListener(this.formatOn, /** @type {EventListenerOrEventListenerObject} */
|
|
614
|
+
this._reflectBackFormattedValueDebounced);
|
|
615
|
+
this._inputNode.removeEventListener('compositionstart', this.__onCompositionEvent);
|
|
616
|
+
this._inputNode.removeEventListener('compositionend', this.__onCompositionEvent);
|
|
617
617
|
}
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
const isUserEditing = this._isHandlingUserInput && this.__prevViewValue;
|
|
633
|
-
if (isUserEditing) {
|
|
634
|
-
return 'user-edited';
|
|
635
|
-
}
|
|
636
|
-
return 'auto';
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
/**
|
|
621
|
+
* This method will be called right before a parser or formatter gets called and computes
|
|
622
|
+
* the formatOptions.mode. In short, it gives meta info about how the user interacted with
|
|
623
|
+
* the form control, as these user interactions can influence the formatting/parsing behavior.
|
|
624
|
+
*
|
|
625
|
+
* It's important that the behavior of these can be different during a paste or user edit,
|
|
626
|
+
* but not during programmatic setting of values (like setting modelValue).
|
|
627
|
+
* @returns {'auto'|'pasted'|'user-edited'}
|
|
628
|
+
*/
|
|
629
|
+
#getFormatOptionsMode() {
|
|
630
|
+
if (this._isPasting) {
|
|
631
|
+
return 'pasted';
|
|
637
632
|
}
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
*/
|
|
642
|
-
#getFormatOptionsViewValueStates() {
|
|
643
|
-
/** @type {FormatOptions['viewValueStates']}} */
|
|
644
|
-
const states = [];
|
|
645
|
-
if (this.#viewValueState.didFormatterOutputSyncToView) {
|
|
646
|
-
states.push('formatted');
|
|
647
|
-
}
|
|
648
|
-
return states;
|
|
633
|
+
const isUserEditing = this._isHandlingUserInput && this.__prevViewValue;
|
|
634
|
+
if (isUserEditing) {
|
|
635
|
+
return 'user-edited';
|
|
649
636
|
}
|
|
650
|
-
|
|
651
|
-
|
|
637
|
+
return 'auto';
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
/**
|
|
641
|
+
* @returns {FormatOptions['viewValueStates']}
|
|
642
|
+
*/
|
|
643
|
+
#getFormatOptionsViewValueStates() {
|
|
644
|
+
/** @type {FormatOptions['viewValueStates']}} */
|
|
645
|
+
const states = [];
|
|
646
|
+
if (this.#viewValueState.didFormatterOutputSyncToView) {
|
|
647
|
+
states.push('formatted');
|
|
648
|
+
}
|
|
649
|
+
return states;
|
|
650
|
+
}
|
|
651
|
+
};
|
|
652
652
|
export const FormatMixin = dedupeMixin(FormatMixinImplementation);
|