@lion/ui 0.20.0-menu-system.0 → 0.21.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/calendar-suites.js +1 -0
- package/collapsible.js +0 -1
- package/components/button/src/LionButton.js +0 -4
- package/components/button/test-suites/LionButton.suite.js +0 -1
- package/components/calendar/src/LionCalendar.js +1 -3
- package/components/calendar/test/lion-calendar.test.js +67 -47
- package/components/calendar/test-suites/LionCalendar.suite.js +79 -0
- package/components/combobox/test/lion-combobox.test.js +0 -1
- package/components/form-core/src/FormatMixin.js +17 -7
- package/components/form-core/src/form-group/FormGroupMixin.js +0 -7
- package/components/form-core/src/registration/FormRegistrarMixin.js +0 -11
- package/components/form-core/test/FormControlMixin.test.js +0 -1
- package/components/form-core/test/FormatMixin.test.js +4 -1
- package/components/form-core/test/validate/Validator.test.js +0 -2
- package/components/form-core/test-helpers/mimicUserInput.js +1 -0
- package/components/form-core/test-suites/FormatMixin.suite.js +273 -79
- package/components/form-core/test-suites/ValidateMixin.suite.js +0 -2
- package/components/form-core/test-suites/ValidateMixinFeedbackPart.suite.js +0 -1
- package/components/input/test/input-integrations.test.js +3 -2
- package/components/input/test/lion-input-integrations.test.js +2 -1
- package/components/input-amount/test/lion-input-amount-integrations.test.js +1 -1
- package/components/input-amount-dropdown/src/LionInputAmountDropdown.js +72 -11
- package/components/input-amount-dropdown/test/lion-input-amount-dropdown-integrations.test.js +27 -0
- package/components/input-amount-dropdown/test-suites/LionInputAmountDropdown.suite.js +60 -3
- package/components/input-date/test/lion-input-date-integrations.test.js +1 -1
- package/components/input-datepicker/src/LionInputDatepicker.js +4 -0
- package/components/input-datepicker/src/localizeNamespaceLoader.js +0 -1
- package/components/input-datepicker/test/lion-input-datepicker-integrations.test.js +1 -1
- package/components/input-datepicker/test/lion-input-datepicker.test.js +74 -9
- package/components/input-datepicker/test-suites/LionInputDatepicker.suite.js +35 -0
- package/components/input-email/src/LionInputEmail.js +2 -0
- package/components/input-email/test/lion-input-email-integrations.test.js +1 -1
- package/components/input-email/test/lion-input-email.test.js +6 -0
- package/components/input-file/src/validators.js +31 -1
- package/components/input-file/test/FileValidators.test.js +31 -0
- package/components/input-file/translations/bg.js +1 -0
- package/components/input-file/translations/cs.js +1 -0
- package/components/input-file/translations/de.js +2 -0
- package/components/input-file/translations/en.js +1 -0
- package/components/input-file/translations/es.js +1 -0
- package/components/input-file/translations/fr.js +1 -0
- package/components/input-file/translations/hu.js +1 -0
- package/components/input-file/translations/id.js +1 -0
- package/components/input-file/translations/it.js +1 -0
- package/components/input-file/translations/nl.js +1 -0
- package/components/input-file/translations/pl.js +1 -0
- package/components/input-file/translations/ro.js +1 -0
- package/components/input-file/translations/ru.js +1 -0
- package/components/input-file/translations/sk.js +1 -0
- package/components/input-file/translations/uk.js +1 -0
- package/components/input-file/translations/zh.js +1 -0
- package/components/input-iban/test/lion-input-iban-integrations.test.js +1 -1
- package/components/input-range/src/LionInputRange.js +51 -8
- package/components/input-range/test/lion-input-range.test.js +114 -0
- package/components/input-stepper/test-suites/lion-input-stepper.integration.suite.js +2 -2
- package/components/input-tel/src/LionInputTel.js +1 -1
- package/components/input-tel/test-suites/LionInputTel.suite.js +7 -0
- package/components/localize/test/date/formatDate.test.js +0 -1
- package/components/overlays/src/OverlayController.js +110 -278
- package/components/overlays/src/OverlayMixin.js +11 -58
- package/components/overlays/src/OverlaysManager.js +2 -2
- package/components/overlays/src/configurations/visibility-trigger-partials/withHoverInteraction.js +41 -9
- package/components/overlays/src/utils/adopt-styles.js +2 -3
- package/components/overlays/src/utils/get-focusable-elements.js +0 -4
- package/components/overlays/src/utils/is-equal-config.js +6 -10
- package/components/overlays/test/OverlayController.test.js +14 -127
- package/components/overlays/test/utils-tests/is-equal-config.test.js +1 -1
- package/components/overlays/test-suites/OverlayMixin.suite.js +8 -8
- package/components/overlays/test-suites/WithHoverInteraction.suite.js +212 -0
- package/components/overlays/types/ArrowMixinTypes.ts +1 -3
- package/components/overlays/types/OverlayConfig.ts +5 -20
- package/components/overlays/types/OverlayMixinTypes.ts +0 -2
- package/components/select-rich/test/lion-select-rich.test.js +0 -3
- package/components/textarea/test/lion-textarea-integrations.test.js +2 -1
- package/components/tooltip/test/lion-tooltip.test.js +9 -1
- package/custom-elements.json +20629 -32907
- package/dist-types/components/button/src/LionButton.d.ts +0 -1
- package/dist-types/components/button/src/LionButton.d.ts.map +1 -1
- package/dist-types/components/button/test-suites/LionButton.suite.d.ts.map +1 -1
- package/dist-types/components/calendar/src/LionCalendar.d.ts.map +1 -1
- package/dist-types/components/calendar/test/lion-calendar.test.d.ts.map +1 -1
- package/dist-types/components/calendar/test-suites/LionCalendar.suite.d.ts +5 -0
- package/dist-types/components/calendar/test-suites/LionCalendar.suite.d.ts.map +1 -0
- package/dist-types/components/combobox/src/LionCombobox.d.ts +1 -1
- package/dist-types/components/dialog/src/LionDialog.d.ts +2 -6
- package/dist-types/components/dialog/src/LionDialog.d.ts.map +1 -1
- package/dist-types/components/form-core/src/FormatMixin.d.ts.map +1 -1
- package/dist-types/components/form-core/src/form-group/FormGroupMixin.d.ts.map +1 -1
- package/dist-types/components/form-core/src/registration/FormRegistrarMixin.d.ts.map +1 -1
- package/dist-types/components/form-core/test-helpers/mimicUserInput.d.ts.map +1 -1
- package/dist-types/components/form-core/test-suites/FormatMixin.suite.d.ts +58 -5
- package/dist-types/components/form-core/test-suites/FormatMixin.suite.d.ts.map +1 -1
- package/dist-types/components/form-core/test-suites/ValidateMixin.suite.d.ts.map +1 -1
- package/dist-types/components/form-core/test-suites/ValidateMixinFeedbackPart.suite.d.ts.map +1 -1
- package/dist-types/components/icon/src/LionIcon.d.ts +2 -2
- package/dist-types/components/input-amount-dropdown/src/LionInputAmountDropdown.d.ts +24 -6
- package/dist-types/components/input-amount-dropdown/src/LionInputAmountDropdown.d.ts.map +1 -1
- package/dist-types/components/input-amount-dropdown/test/lion-input-amount-dropdown-integrations.test.d.ts +2 -0
- package/dist-types/components/input-amount-dropdown/test/lion-input-amount-dropdown-integrations.test.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/test-suites/LionInputAmountDropdown.suite.d.ts.map +1 -1
- package/dist-types/components/input-datepicker/src/LionInputDatepicker.d.ts +2 -1
- package/dist-types/components/input-datepicker/src/LionInputDatepicker.d.ts.map +1 -1
- package/dist-types/components/input-datepicker/src/localizeNamespaceLoader.d.ts.map +1 -1
- package/dist-types/components/input-datepicker/test/lion-input-datepicker.test.d.ts.map +1 -1
- package/dist-types/components/input-datepicker/test-suites/LionInputDatepicker.suite.d.ts +7 -0
- package/dist-types/components/input-datepicker/test-suites/LionInputDatepicker.suite.d.ts.map +1 -0
- package/dist-types/components/input-email/src/LionInputEmail.d.ts.map +1 -1
- package/dist-types/components/input-file/src/validators.d.ts +11 -0
- package/dist-types/components/input-file/src/validators.d.ts.map +1 -1
- package/dist-types/components/input-file/translations/bg-BG.d.ts +1 -0
- package/dist-types/components/input-file/translations/bg.d.ts +1 -0
- package/dist-types/components/input-file/translations/cs-CZ.d.ts +1 -0
- package/dist-types/components/input-file/translations/cs.d.ts +1 -0
- package/dist-types/components/input-file/translations/de-DE.d.ts +1 -0
- package/dist-types/components/input-file/translations/de.d.ts +1 -0
- package/dist-types/components/input-file/translations/en-AU.d.ts +1 -0
- package/dist-types/components/input-file/translations/en-GB.d.ts +1 -0
- package/dist-types/components/input-file/translations/en-PH.d.ts +1 -0
- package/dist-types/components/input-file/translations/en-US.d.ts +1 -0
- package/dist-types/components/input-file/translations/en.d.ts +1 -0
- package/dist-types/components/input-file/translations/es-ES.d.ts +1 -0
- package/dist-types/components/input-file/translations/es.d.ts +1 -0
- package/dist-types/components/input-file/translations/fr-BE.d.ts +1 -0
- package/dist-types/components/input-file/translations/fr-FR.d.ts +1 -0
- package/dist-types/components/input-file/translations/fr.d.ts +1 -0
- package/dist-types/components/input-file/translations/hu-HU.d.ts +1 -0
- package/dist-types/components/input-file/translations/hu.d.ts +1 -0
- package/dist-types/components/input-file/translations/id-ID.d.ts +1 -0
- package/dist-types/components/input-file/translations/id.d.ts +1 -0
- package/dist-types/components/input-file/translations/it-IT.d.ts +1 -0
- package/dist-types/components/input-file/translations/it.d.ts +1 -0
- package/dist-types/components/input-file/translations/nl-BE.d.ts +1 -0
- package/dist-types/components/input-file/translations/nl-NL.d.ts +1 -0
- package/dist-types/components/input-file/translations/nl.d.ts +1 -0
- package/dist-types/components/input-file/translations/pl-PL.d.ts +1 -0
- package/dist-types/components/input-file/translations/pl.d.ts +1 -0
- package/dist-types/components/input-file/translations/ro-RO.d.ts +1 -0
- package/dist-types/components/input-file/translations/ro.d.ts +1 -0
- package/dist-types/components/input-file/translations/ru-RU.d.ts +1 -0
- package/dist-types/components/input-file/translations/ru.d.ts +1 -0
- package/dist-types/components/input-file/translations/sk-SK.d.ts +1 -0
- package/dist-types/components/input-file/translations/sk.d.ts +1 -0
- package/dist-types/components/input-file/translations/uk-UA.d.ts +1 -0
- package/dist-types/components/input-file/translations/uk.d.ts +1 -0
- package/dist-types/components/input-file/translations/zh-CN.d.ts +1 -0
- package/dist-types/components/input-file/translations/zh.d.ts +1 -0
- package/dist-types/components/input-range/src/LionInputRange.d.ts +11 -0
- package/dist-types/components/input-range/src/LionInputRange.d.ts.map +1 -1
- package/dist-types/components/input-tel/src/LionInputTel.d.ts.map +1 -1
- package/dist-types/components/input-tel/test-suites/LionInputTel.suite.d.ts.map +1 -1
- package/dist-types/components/overlays/src/OverlayController.d.ts +12 -24
- 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/configurations/visibility-trigger-partials/withHoverInteraction.d.ts.map +1 -1
- package/dist-types/components/overlays/src/utils/get-focusable-elements.d.ts.map +1 -1
- package/dist-types/components/overlays/src/utils/is-equal-config.d.ts.map +1 -1
- package/dist-types/components/overlays/test-suites/WithHoverInteraction.suite.d.ts +17 -0
- package/dist-types/components/overlays/test-suites/WithHoverInteraction.suite.d.ts.map +1 -0
- package/dist-types/components/overlays/types/ArrowMixinTypes.d.ts.map +1 -1
- package/dist-types/components/overlays/types/OverlayConfig.d.ts +2 -12
- package/dist-types/components/overlays/types/OverlayConfig.d.ts.map +1 -1
- package/dist-types/components/overlays/types/OverlayMixinTypes.d.ts +0 -1
- package/dist-types/components/overlays/types/OverlayMixinTypes.d.ts.map +1 -1
- package/dist-types/components/select-rich/src/LionSelectRich.d.ts +3 -11
- package/dist-types/components/select-rich/src/LionSelectRich.d.ts.map +1 -1
- package/dist-types/components/tooltip/src/LionTooltip.d.ts +1 -1
- package/dist-types/components/tooltip/test/lion-tooltip.test.d.ts.map +1 -1
- package/dist-types/exports/calendar-suites.d.ts +2 -0
- package/dist-types/exports/calendar-suites.d.ts.map +1 -0
- package/dist-types/exports/input-datepicker-suites.d.ts +2 -0
- package/dist-types/exports/input-datepicker-suites.d.ts.map +1 -0
- package/dist-types/exports/input-file.d.ts +1 -1
- package/dist-types/exports/overlays-test-suites.d.ts +1 -0
- package/dist-types/exports/overlays.d.ts +0 -3
- package/dist-types/exports/overlays.d.ts.map +1 -1
- package/dist-types/tsconfig.tsbuildinfo +1 -1
- package/docs/components/checkbox-group/api-table.md +4 -2
- package/docs/components/checkbox-group/overview.md +2 -2
- package/docs/components/collapsible/overview.md +1 -1
- package/docs/components/combobox/api-table.md +8 -21
- package/docs/components/combobox/overview.md +1 -1
- package/docs/components/combobox/use-cases.md +1 -1
- package/docs/components/dialog/api-table.md +6 -31
- package/docs/components/dialog/overview.md +1 -1
- package/docs/components/fieldset/overview.md +5 -5
- package/docs/components/form/overview.md +3 -3
- package/docs/components/form/use-cases.md +2 -2
- package/docs/components/icon/use-cases.md +1 -1
- package/docs/components/input/api-table.md +2 -1
- package/docs/components/input/overview.md +1 -1
- package/docs/components/input-amount/api-table.md +2 -1
- package/docs/components/input-amount/overview.md +3 -3
- package/docs/components/input-amount-dropdown/api-table.md +3 -2
- package/docs/components/input-date/api-table.md +2 -1
- package/docs/components/input-date/overview.md +3 -3
- package/docs/components/input-datepicker/api-table.md +6 -22
- package/docs/components/input-datepicker/overview.md +5 -5
- package/docs/components/input-email/api-table.md +3 -2
- package/docs/components/input-email/overview.md +2 -2
- package/docs/components/input-file/api-table.md +2 -1
- package/docs/components/input-file/overview.md +1 -1
- package/docs/components/input-file/use-cases.md +18 -0
- package/docs/components/input-iban/api-table.md +2 -1
- package/docs/components/input-iban/overview.md +2 -2
- package/docs/components/input-range/api-table.md +7 -1
- package/docs/components/input-range/overview.md +2 -2
- package/docs/components/input-range/use-cases.md +14 -0
- package/docs/components/input-stepper/api-table.md +2 -1
- package/docs/components/input-stepper/overview.md +1 -1
- package/docs/components/input-tel/api-table.md +3 -2
- package/docs/components/input-tel/overview.md +1 -1
- package/docs/components/input-tel/use-cases.md +6 -6
- package/docs/components/input-tel-dropdown/api-table.md +3 -2
- package/docs/components/input-tel-dropdown/overview.md +1 -1
- package/docs/components/listbox/api-table.md +2 -1
- package/docs/components/listbox/use-cases.md +1 -1
- package/docs/components/radio-group/api-table.md +2 -1
- package/docs/components/radio-group/overview.md +3 -3
- package/docs/components/select/api-table.md +2 -1
- package/docs/components/select/use-cases.md +1 -1
- package/docs/components/select-rich/api-table.md +5 -21
- package/docs/components/select-rich/use-cases.md +2 -2
- package/docs/components/switch/api-table.md +2 -1
- package/docs/components/tabs/examples.md +1 -1
- package/docs/components/textarea/api-table.md +2 -1
- package/docs/components/tooltip/api-table.md +11 -36
- package/docs/components/tooltip/use-cases.md +34 -1
- package/docs/fundamentals/index.md +4 -4
- package/docs/fundamentals/node-tools/publish-docs/overview.md +3 -3
- package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +2 -2
- package/docs/fundamentals/rationales/accessibility.md +1 -1
- package/docs/fundamentals/systems/core/SlotMixin.md +1 -1
- package/docs/fundamentals/systems/core/overview.md +1 -1
- package/docs/fundamentals/systems/form/api-table.md +2 -1
- package/docs/fundamentals/systems/form/formatting-and-parsing.md +4 -4
- package/docs/fundamentals/systems/form/model-value.md +1 -1
- package/docs/fundamentals/systems/form/overview.md +28 -28
- package/docs/fundamentals/systems/form/validate.md +2 -2
- package/docs/fundamentals/systems/localize/overview.md +4 -4
- package/docs/fundamentals/systems/overlays/api-table.md +34 -36
- package/docs/fundamentals/systems/overlays/configuration.md +2 -2
- package/docs/fundamentals/systems/overlays/overview.md +5 -5
- package/docs/fundamentals/systems/overlays/use-cases.md +2 -2
- package/docs/fundamentals/tools/helpers/overview.md +1 -1
- package/docs/fundamentals/tools/singleton-manager/overview.md +4 -4
- package/docs/guides/how-to/create-a-custom-field.md +5 -5
- package/docs/guides/how-to/create-a-form.md +4 -4
- package/docs/guides/how-to/extend-a-native-input.md +2 -2
- package/docs/guides/how-to/index.md +1 -1
- package/docs/guides/index.md +8 -8
- package/docs/guides/principles/index.md +5 -5
- package/docs/guides/principles/styling.md +1 -1
- package/exports/calendar-suites.js +1 -0
- package/exports/collapsible.js +0 -1
- package/exports/input-datepicker-suites.js +1 -0
- package/exports/input-file.js +5 -1
- package/exports/overlays-test-suites.js +1 -0
- package/exports/overlays.js +0 -6
- package/input-datepicker-suites.js +1 -0
- package/input-file.js +5 -1
- package/overlays-test-suites.js +1 -0
- package/overlays.js +0 -6
- package/package.json +2 -2
- package/components/collapsible/src/DisclosureMixin.js +0 -313
- package/components/collapsible/test-suites/DisclosureMixin.suite.js +0 -30
- package/components/collapsible/types/DisclosureMixinTypes.ts +0 -48
- package/components/menu/CHANGELOG.md +0 -37
- package/components/menu/README.md +0 -335
- package/components/menu/index.js +0 -2
- package/components/menu/lion-menu-overlay.js +0 -3
- package/components/menu/lion-menu.js +0 -3
- package/components/menu/lion-spinbutton.js +0 -3
- package/components/menu/lion-toolbar.js +0 -3
- package/components/menu/lion-tree.js +0 -3
- package/components/menu/package.json +0 -46
- package/components/menu/requirements.temp.md +0 -12
- package/components/menu/src/InteractiveListMixin.js +0 -840
- package/components/menu/src/LionMenu.js +0 -250
- package/components/menu/src/LionMenuHybrid.js +0 -46
- package/components/menu/src/LionMenuOverlay.js +0 -155
- package/components/menu/src/LionSpinbutton.js +0 -213
- package/components/menu/src/LionToolbar.js +0 -94
- package/components/menu/src/LionTree.js +0 -52
- package/components/menu/src/MoreButtonMenuMixin.js +0 -278
- package/components/menu/src/MultiLevelListMixin.js +0 -311
- package/components/menu/src/utils/isInView.js +0 -26
- package/components/menu/src/utils/listItemInteractions.js +0 -124
- package/components/menu/test/InteractiveListMixin.test.js +0 -3
- package/components/menu/test/MoreButtonMenuMixin.test.js +0 -4
- package/components/menu/test/MultiLevelListMixin.test.js +0 -3
- package/components/menu/test/lion-menu-hybrid.test.js +0 -3
- package/components/menu/test/lion-menu.test.js +0 -11
- package/components/menu/test/lion-toolbar.test.js +0 -8
- package/components/menu/test/lion-tree.test.js +0 -7
- package/components/menu/test-helpers/mimicKeyPress.js +0 -9
- package/components/menu/test-suites/InteractiveListMixin.suite.js +0 -454
- package/components/menu/test-suites/LionMenu.suite.js +0 -113
- package/components/menu/test-suites/LionMenuHybrid.suite.js +0 -583
- package/components/menu/test-suites/MoreButtonMenuMixin.suite.js +0 -372
- package/components/menu/test-suites/MultiLevelListMixin.suite.js +0 -303
- package/components/menu/types/InteractiveListMixinTypes.d.ts +0 -84
- package/components/navigation-bar/README.md +0 -1
- package/components/navigation-bar/src/LionNavigationBar.js +0 -439
- package/components/navigation-bar/src/types.js +0 -41
- package/components/overlays/NEXT.md +0 -49
- package/components/overlays/test/withHoverInteraction.test.js +0 -90
- package/dist-types/components/collapsible/src/DisclosureMixin.d.ts +0 -3
- package/dist-types/components/collapsible/src/DisclosureMixin.d.ts.map +0 -1
- package/dist-types/components/collapsible/test-suites/DisclosureMixin.suite.d.ts +0 -2
- package/dist-types/components/collapsible/test-suites/DisclosureMixin.suite.d.ts.map +0 -1
- package/dist-types/components/collapsible/types/DisclosureMixinTypes.d.ts +0 -24
- package/dist-types/components/collapsible/types/DisclosureMixinTypes.d.ts.map +0 -1
- package/dist-types/components/menu/index.d.ts +0 -3
- package/dist-types/components/menu/index.d.ts.map +0 -1
- package/dist-types/components/menu/lion-menu-overlay.d.ts +0 -2
- package/dist-types/components/menu/lion-menu-overlay.d.ts.map +0 -1
- package/dist-types/components/menu/lion-menu.d.ts +0 -2
- package/dist-types/components/menu/lion-menu.d.ts.map +0 -1
- package/dist-types/components/menu/lion-spinbutton.d.ts +0 -2
- package/dist-types/components/menu/lion-spinbutton.d.ts.map +0 -1
- package/dist-types/components/menu/lion-toolbar.d.ts +0 -2
- package/dist-types/components/menu/lion-toolbar.d.ts.map +0 -1
- package/dist-types/components/menu/lion-tree.d.ts +0 -2
- package/dist-types/components/menu/lion-tree.d.ts.map +0 -1
- package/dist-types/components/menu/src/InteractiveListMixin.d.ts +0 -617
- package/dist-types/components/menu/src/InteractiveListMixin.d.ts.map +0 -1
- package/dist-types/components/menu/src/LionMenu.d.ts +0 -635
- package/dist-types/components/menu/src/LionMenu.d.ts.map +0 -1
- package/dist-types/components/menu/src/LionMenuHybrid.d.ts +0 -19
- package/dist-types/components/menu/src/LionMenuHybrid.d.ts.map +0 -1
- package/dist-types/components/menu/src/LionMenuOverlay.d.ts +0 -1015
- package/dist-types/components/menu/src/LionMenuOverlay.d.ts.map +0 -1
- package/dist-types/components/menu/src/LionSpinbutton.d.ts +0 -58
- package/dist-types/components/menu/src/LionSpinbutton.d.ts.map +0 -1
- package/dist-types/components/menu/src/LionToolbar.d.ts +0 -8
- package/dist-types/components/menu/src/LionToolbar.d.ts.map +0 -1
- package/dist-types/components/menu/src/LionTree.d.ts +0 -447
- package/dist-types/components/menu/src/LionTree.d.ts.map +0 -1
- package/dist-types/components/menu/src/MoreButtonMenuMixin.d.ts +0 -39
- package/dist-types/components/menu/src/MoreButtonMenuMixin.d.ts.map +0 -1
- package/dist-types/components/menu/src/MultiLevelListMixin.d.ts +0 -503
- package/dist-types/components/menu/src/MultiLevelListMixin.d.ts.map +0 -1
- package/dist-types/components/menu/src/utils/isInView.d.ts +0 -9
- package/dist-types/components/menu/src/utils/isInView.d.ts.map +0 -1
- package/dist-types/components/menu/src/utils/listItemInteractions.d.ts +0 -48
- package/dist-types/components/menu/src/utils/listItemInteractions.d.ts.map +0 -1
- package/dist-types/components/menu/test/InteractiveListMixin.test.d.ts +0 -2
- package/dist-types/components/menu/test/InteractiveListMixin.test.d.ts.map +0 -1
- package/dist-types/components/menu/test/MoreButtonMenuMixin.test.d.ts +0 -2
- package/dist-types/components/menu/test/MoreButtonMenuMixin.test.d.ts.map +0 -1
- package/dist-types/components/menu/test/MultiLevelListMixin.test.d.ts +0 -2
- package/dist-types/components/menu/test/MultiLevelListMixin.test.d.ts.map +0 -1
- package/dist-types/components/menu/test/lion-menu-hybrid.test.d.ts +0 -2
- package/dist-types/components/menu/test/lion-menu-hybrid.test.d.ts.map +0 -1
- package/dist-types/components/menu/test/lion-menu.test.d.ts +0 -2
- package/dist-types/components/menu/test/lion-menu.test.d.ts.map +0 -1
- package/dist-types/components/menu/test/lion-toolbar.test.d.ts +0 -2
- package/dist-types/components/menu/test/lion-toolbar.test.d.ts.map +0 -1
- package/dist-types/components/menu/test/lion-tree.test.d.ts +0 -2
- package/dist-types/components/menu/test/lion-tree.test.d.ts.map +0 -1
- package/dist-types/components/menu/test-helpers/mimicKeyPress.d.ts +0 -7
- package/dist-types/components/menu/test-helpers/mimicKeyPress.d.ts.map +0 -1
- package/dist-types/components/menu/test-suites/InteractiveListMixin.suite.d.ts +0 -14
- package/dist-types/components/menu/test-suites/InteractiveListMixin.suite.d.ts.map +0 -1
- package/dist-types/components/menu/test-suites/LionMenu.suite.d.ts +0 -9
- package/dist-types/components/menu/test-suites/LionMenu.suite.d.ts.map +0 -1
- package/dist-types/components/menu/test-suites/LionMenuHybrid.suite.d.ts +0 -5
- package/dist-types/components/menu/test-suites/LionMenuHybrid.suite.d.ts.map +0 -1
- package/dist-types/components/menu/test-suites/MoreButtonMenuMixin.suite.d.ts +0 -14
- package/dist-types/components/menu/test-suites/MoreButtonMenuMixin.suite.d.ts.map +0 -1
- package/dist-types/components/menu/test-suites/MultiLevelListMixin.suite.d.ts +0 -11
- package/dist-types/components/menu/test-suites/MultiLevelListMixin.suite.d.ts.map +0 -1
- package/dist-types/components/navigation-bar/src/LionNavigationBar.d.ts +0 -238
- package/dist-types/components/navigation-bar/src/LionNavigationBar.d.ts.map +0 -1
- package/dist-types/components/navigation-bar/src/types.d.ts +0 -85
- package/dist-types/components/navigation-bar/src/types.d.ts.map +0 -1
- package/dist-types/components/overlays/test/withHoverInteraction.test.d.ts +0 -2
- package/dist-types/components/overlays/test/withHoverInteraction.test.d.ts.map +0 -1
- package/dist-types/exports/define/lion-item.d.ts +0 -2
- package/dist-types/exports/define/lion-item.d.ts.map +0 -1
- package/dist-types/exports/define/lion-menu-overlay.d.ts +0 -2
- package/dist-types/exports/define/lion-menu-overlay.d.ts.map +0 -1
- package/dist-types/exports/define/lion-menu.d.ts +0 -2
- package/dist-types/exports/define/lion-menu.d.ts.map +0 -1
- package/dist-types/exports/define/lion-navigation-bar.d.ts +0 -2
- package/dist-types/exports/define/lion-navigation-bar.d.ts.map +0 -1
- package/dist-types/exports/define/lion-toolbar.d.ts +0 -2
- package/dist-types/exports/define/lion-toolbar.d.ts.map +0 -1
- package/dist-types/exports/define/lion-tree.d.ts +0 -2
- package/dist-types/exports/define/lion-tree.d.ts.map +0 -1
- package/dist-types/exports/menu-test-suites.d.ts +0 -4
- package/dist-types/exports/menu-test-suites.d.ts.map +0 -1
- package/dist-types/exports/menu.d.ts +0 -7
- package/dist-types/exports/menu.d.ts.map +0 -1
- package/dist-types/exports/navigation-bar.d.ts +0 -2
- package/dist-types/exports/navigation-bar.d.ts.map +0 -1
- package/docs/components/menu/api-table.md +0 -460
- package/docs/components/menu/applyMenuDemoStyles.js +0 -173
- package/docs/components/menu/extensions.md +0 -262
- package/docs/components/menu/index.md +0 -13
- package/docs/components/menu/overview.md +0 -422
- package/docs/components/menu/use-cases.md +0 -77
- package/exports/define/lion-item.js +0 -3
- package/exports/define/lion-menu-overlay.js +0 -3
- package/exports/define/lion-menu.js +0 -3
- package/exports/define/lion-navigation-bar.js +0 -3
- package/exports/define/lion-toolbar.js +0 -3
- package/exports/define/lion-tree.js +0 -3
- package/exports/menu-test-suites.js +0 -4
- package/exports/menu.js +0 -7
- package/exports/navigation-bar.js +0 -1
- package/menu-test-suites.js +0 -4
- package/menu.js +0 -7
- package/navigation-bar.js +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getFormControlMembers, mimicUserInput } from '@lion/ui/form-core-test-helpers.js';
|
|
2
|
+
import { FormatMixin, Unparseable, Validator } from '@lion/ui/form-core.js';
|
|
2
3
|
import { parseDate } from '@lion/ui/localize-no-side-effects.js';
|
|
3
4
|
import { aTimeout, defineCE, expect, fixture, html, unsafeStatic } from '@open-wc/testing';
|
|
5
|
+
import { LitElement } from 'lit';
|
|
4
6
|
import sinon from 'sinon';
|
|
5
|
-
import { Unparseable, Validator, FormatMixin } from '@lion/ui/form-core.js';
|
|
6
|
-
import { getFormControlMembers, mimicUserInput } from '@lion/ui/form-core-test-helpers.js';
|
|
7
7
|
|
|
8
8
|
const isLionInputStepper = (/** @type {FormatClass} */ el) => 'valueTextMapping' in el;
|
|
9
9
|
|
|
@@ -36,56 +36,225 @@ class FormatClass extends FormatMixin(LitElement) {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
|
-
* @
|
|
39
|
+
* @typedef {object} FormatMixinSuiteConfig
|
|
40
|
+
* @property {string | null} [tagString] - Optional. Element tag name; if omitted, one will be auto-generated via defineCE()
|
|
41
|
+
* @property {string | null} [childTagString] - Optional. Not currently used
|
|
42
|
+
* @property {ArrayConstructor | ObjectConstructor | NumberConstructor | BooleanConstructor | StringConstructor | DateConstructor | 'iban' | 'email'} modelValueType - REQUIRED. The model value type for this component
|
|
43
|
+
* @property {(opts: { toggleValue: boolean, viewValue: boolean }) => any} [valueToggler] - Optional. Provide different test values for toggleValue=false vs toggleValue=true. If not provided, defaults will be generated based on modelValueType.
|
|
44
|
+
* @property {(el: FormatClass) => any} [getExpectedInitialModelValue] - Optional. Expected initial modelValue state when element is created without a value. If not provided, defaults will be generated based on modelValueType.
|
|
45
|
+
* @property {(el: FormatClass) => any} [getExpectedInitialFormattedValue] - Optional. Expected initial formattedValue state when element is created without a value. If not provided, defaults will be generated based on modelValueType.
|
|
46
|
+
* @property {(el: FormatClass) => any} [getExpectedInitialSerializedValue] - Optional. Expected initial serializedValue state when element is created without a value. If not provided, defaults will be generated based on modelValueType.
|
|
47
|
+
* @property {(el: FormatClass) => any} [getExpectedModelValueForEmptyInputNode] - Optional. Expected modelValue after user clears the input node value. Defaults to empty string.
|
|
48
|
+
* @property {(value: string, opts?: any) => any} [parser] - Optional. Parser override used by tests. When provided, it is applied before connectedCallback so fallback init sync uses it.
|
|
49
|
+
* @property {number} [valueChangeCounterOffset] - Optional. Offset for model-value-changed event counter. Use 0 for most types, 1 for Date types where parseDate() creates new objects. If not provided, defaults will be generated based on modelValueType.
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Creates default valueToggler based on modelValueType for backwards compatibility
|
|
54
|
+
* @param {ArrayConstructor | ObjectConstructor | NumberConstructor | BooleanConstructor | StringConstructor | DateConstructor | 'iban' | 'email'} modelValueType
|
|
55
|
+
* @returns {(opts: { toggleValue: boolean, viewValue: boolean }) => any}
|
|
56
|
+
*/
|
|
57
|
+
function createDefaultValueToggler(modelValueType) {
|
|
58
|
+
if (modelValueType === String) {
|
|
59
|
+
return ({ toggleValue }) => (!toggleValue ? 'test-value-1' : 'test-value-2');
|
|
60
|
+
}
|
|
61
|
+
if (modelValueType === 'iban') {
|
|
62
|
+
return ({ toggleValue }) => (!toggleValue ? 'NL20INGB0001234567' : 'NL91ABNA0417164300');
|
|
63
|
+
}
|
|
64
|
+
if (modelValueType === 'email') {
|
|
65
|
+
return ({ toggleValue }) => (!toggleValue ? 'test@example.com' : 'user@test.org');
|
|
66
|
+
}
|
|
67
|
+
if (modelValueType === Number) {
|
|
68
|
+
return ({ toggleValue, viewValue }) => {
|
|
69
|
+
if (viewValue) {
|
|
70
|
+
return !toggleValue ? '100' : '200';
|
|
71
|
+
}
|
|
72
|
+
return !toggleValue ? 100 : 200;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
if (modelValueType === Date) {
|
|
76
|
+
return ({ toggleValue, viewValue }) => {
|
|
77
|
+
if (viewValue) {
|
|
78
|
+
return !toggleValue ? '01/01/2020' : '02/02/2021';
|
|
79
|
+
}
|
|
80
|
+
return !toggleValue ? parseDate('01/01/2020') : parseDate('02/02/2021');
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
if (modelValueType === Object) {
|
|
84
|
+
return ({ toggleValue, viewValue }) => {
|
|
85
|
+
if (viewValue) {
|
|
86
|
+
return !toggleValue ? '{"value": 1}' : '{"value": 2}';
|
|
87
|
+
}
|
|
88
|
+
return !toggleValue ? { value: 1 } : { value: 2 };
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
if (modelValueType === Boolean) {
|
|
92
|
+
return ({ toggleValue }) => !toggleValue;
|
|
93
|
+
}
|
|
94
|
+
if (modelValueType === Array) {
|
|
95
|
+
return ({ toggleValue, viewValue }) => {
|
|
96
|
+
if (viewValue) {
|
|
97
|
+
return !toggleValue ? '[1]' : '[2]';
|
|
98
|
+
}
|
|
99
|
+
return !toggleValue ? [1] : [2];
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
// Fallback for unknown types
|
|
103
|
+
return ({ toggleValue }) => (!toggleValue ? 'test-value-1' : 'test-value-2');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Creates default getExpectedInitialModelValue based on modelValueType
|
|
108
|
+
* @param {ArrayConstructor | ObjectConstructor | NumberConstructor | BooleanConstructor | StringConstructor | DateConstructor | 'iban' | 'email'} modelValueType
|
|
109
|
+
* @returns {() => any}
|
|
110
|
+
*/
|
|
111
|
+
function createDefaultGetExpectedInitialModelValue(modelValueType) {
|
|
112
|
+
if (modelValueType === Boolean) {
|
|
113
|
+
return () => false;
|
|
114
|
+
}
|
|
115
|
+
if (modelValueType === Object) {
|
|
116
|
+
return () => ({});
|
|
117
|
+
}
|
|
118
|
+
if (modelValueType === Array) {
|
|
119
|
+
return () => [];
|
|
120
|
+
}
|
|
121
|
+
// String, Number, Date, 'iban', 'email' all default to empty string
|
|
122
|
+
return () => '';
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Creates default getExpectedInitialFormattedValue based on modelValueType
|
|
127
|
+
* @param {ArrayConstructor | ObjectConstructor | NumberConstructor | BooleanConstructor | StringConstructor | DateConstructor | 'iban' | 'email'} modelValueType
|
|
128
|
+
* @returns {() => any}
|
|
129
|
+
*/
|
|
130
|
+
function createDefaultGetExpectedInitialFormattedValue(modelValueType) {
|
|
131
|
+
// Same as modelValue for default case
|
|
132
|
+
return createDefaultGetExpectedInitialModelValue(modelValueType);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Creates default getExpectedInitialSerializedValue based on modelValueType
|
|
137
|
+
* @param {ArrayConstructor | ObjectConstructor | NumberConstructor | BooleanConstructor | StringConstructor | DateConstructor | 'iban' | 'email'} modelValueType
|
|
138
|
+
* @returns {() => any}
|
|
139
|
+
*/
|
|
140
|
+
function createDefaultGetExpectedInitialSerializedValue(modelValueType) {
|
|
141
|
+
// Same as modelValue for default case
|
|
142
|
+
return createDefaultGetExpectedInitialModelValue(modelValueType);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Creates default valueChangeCounterOffset based on modelValueType
|
|
147
|
+
* @param {ArrayConstructor | ObjectConstructor | NumberConstructor | BooleanConstructor | StringConstructor | DateConstructor | 'iban' | 'email'} modelValueType
|
|
148
|
+
* @returns {number}
|
|
149
|
+
*/
|
|
150
|
+
function createDefaultValueChangeCounterOffset(modelValueType) {
|
|
151
|
+
// Date types need offset of 1 because parseDate creates new objects
|
|
152
|
+
if (modelValueType === Date) {
|
|
153
|
+
return 1;
|
|
154
|
+
}
|
|
155
|
+
return 0;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* @param {FormatMixinSuiteConfig} [customConfig]
|
|
40
160
|
*/
|
|
41
161
|
export function runFormatMixinSuite(customConfig) {
|
|
42
162
|
const cfg = {
|
|
43
|
-
tagString: null,
|
|
44
|
-
childTagString: null,
|
|
45
|
-
modelValueType: String,
|
|
46
163
|
...customConfig,
|
|
47
164
|
};
|
|
48
165
|
|
|
166
|
+
// Validate that modelValueType is provided (required for generating defaults)
|
|
167
|
+
if (!cfg.modelValueType) {
|
|
168
|
+
throw new Error(
|
|
169
|
+
'FormatMixinSuite: modelValueType is REQUIRED in config. ' +
|
|
170
|
+
'Provide the model value type for this component (e.g., String, Number, Date, Object, Boolean, Array, "iban", "email").',
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Use provided values or generate defaults based on modelValueType
|
|
175
|
+
const valueToggler = cfg.valueToggler || createDefaultValueToggler(cfg.modelValueType);
|
|
176
|
+
const getExpectedInitialModelValue =
|
|
177
|
+
cfg.getExpectedInitialModelValue ||
|
|
178
|
+
createDefaultGetExpectedInitialModelValue(cfg.modelValueType);
|
|
179
|
+
const getExpectedInitialFormattedValue =
|
|
180
|
+
cfg.getExpectedInitialFormattedValue ||
|
|
181
|
+
createDefaultGetExpectedInitialFormattedValue(cfg.modelValueType);
|
|
182
|
+
const getExpectedInitialSerializedValue =
|
|
183
|
+
cfg.getExpectedInitialSerializedValue ||
|
|
184
|
+
createDefaultGetExpectedInitialSerializedValue(cfg.modelValueType);
|
|
185
|
+
const getExpectedModelValueForEmptyInputNode =
|
|
186
|
+
cfg.getExpectedModelValueForEmptyInputNode || (() => '');
|
|
187
|
+
const defaultParser = (/** @type {string} */ value) => value.replace('foo: ', '');
|
|
188
|
+
const parser = cfg.parser || defaultParser;
|
|
189
|
+
const valueChangeCounterOffset =
|
|
190
|
+
cfg.valueChangeCounterOffset !== undefined
|
|
191
|
+
? cfg.valueChangeCounterOffset
|
|
192
|
+
: createDefaultValueChangeCounterOffset(cfg.modelValueType);
|
|
193
|
+
|
|
49
194
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
195
|
+
* Generates test values by delegating to the component's valueToggler function.
|
|
196
|
+
* The suite does not make assumptions about value types or structures.
|
|
197
|
+
* All value generation is the responsibility of the consuming component.
|
|
198
|
+
*
|
|
199
|
+
* @param {object} [opts={}]
|
|
200
|
+
* @returns {any}
|
|
53
201
|
*/
|
|
54
202
|
function generateValueBasedOnType(opts = {}) {
|
|
55
|
-
const options = {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
203
|
+
const options = {
|
|
204
|
+
toggleValue: false,
|
|
205
|
+
viewValue: false,
|
|
206
|
+
...opts,
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
// Always delegate to the component's valueToggler (required in config)
|
|
210
|
+
return valueToggler(options);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* @param {FormatClass} el
|
|
215
|
+
*/
|
|
216
|
+
function generateExpectedInitialModelValue(el) {
|
|
217
|
+
return getExpectedInitialModelValue(el);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* @param {FormatClass} el
|
|
222
|
+
*/
|
|
223
|
+
function generateExpectedInitialFormattedValue(el) {
|
|
224
|
+
return getExpectedInitialFormattedValue(el);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* @param {FormatClass} el
|
|
229
|
+
*/
|
|
230
|
+
function generateExpectedInitialSerializedValue(el) {
|
|
231
|
+
return getExpectedInitialSerializedValue(el);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* @param {FormatClass} el
|
|
236
|
+
*/
|
|
237
|
+
function generateExpectedModelValueForEmptyInputNode(el) {
|
|
238
|
+
return getExpectedModelValueForEmptyInputNode(el);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* @param {any} actual
|
|
243
|
+
* @param {any} expected
|
|
244
|
+
* @param {string} message
|
|
245
|
+
*/
|
|
246
|
+
function expectValue(actual, expected, message) {
|
|
247
|
+
if (typeof expected === 'object' && expected !== null) {
|
|
248
|
+
expect(actual).to.deep.equal(expected, message);
|
|
249
|
+
return;
|
|
80
250
|
}
|
|
251
|
+
expect(actual).to.equal(expected, message);
|
|
81
252
|
}
|
|
82
253
|
|
|
83
254
|
describe('FormatMixin', async () => {
|
|
84
255
|
/** @type {{_$litStatic$: any}} */
|
|
85
256
|
let tag;
|
|
86
257
|
/** @type {FormatClass} */
|
|
87
|
-
let nonFormat;
|
|
88
|
-
/** @type {FormatClass} */
|
|
89
258
|
let fooFormat;
|
|
90
259
|
|
|
91
260
|
before(async () => {
|
|
@@ -94,21 +263,10 @@ export function runFormatMixinSuite(customConfig) {
|
|
|
94
263
|
}
|
|
95
264
|
tag = unsafeStatic(cfg.tagString);
|
|
96
265
|
|
|
97
|
-
nonFormat = await fixture(html`
|
|
98
|
-
<${tag}
|
|
99
|
-
.formatter="${/** @param {?} v */ v => v}"
|
|
100
|
-
.parser="${/** @param {string} v */ v => v}"
|
|
101
|
-
.serializer="${/** @param {?} v */ v => v}"
|
|
102
|
-
.deserializer="${/** @param {string} v */ v => v}"
|
|
103
|
-
>
|
|
104
|
-
<input slot="input">
|
|
105
|
-
</${tag}>
|
|
106
|
-
`);
|
|
107
|
-
|
|
108
266
|
fooFormat = await fixture(html`
|
|
109
267
|
<${tag}
|
|
110
268
|
.formatter="${/** @param {string} value */ value => `foo: ${value}`}"
|
|
111
|
-
.parser="${
|
|
269
|
+
.parser="${parser}"
|
|
112
270
|
.serializer="${/** @param {string} value */ value => `[foo] ${value}`}"
|
|
113
271
|
.deserializer="${/** @param {string} value */ value => value.replace('[foo] ', '')}"
|
|
114
272
|
>
|
|
@@ -118,14 +276,41 @@ export function runFormatMixinSuite(customConfig) {
|
|
|
118
276
|
});
|
|
119
277
|
|
|
120
278
|
it('has modelValue, formattedValue and serializedValue which are computed synchronously', async () => {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
279
|
+
const nonFormat = /** @type {FormatClass} */ (
|
|
280
|
+
await fixture(html`
|
|
281
|
+
<${tag}
|
|
282
|
+
.formatter="${/** @param {?} v */ v => v}"
|
|
283
|
+
.parser="${/** @param {string} v */ v => v}"
|
|
284
|
+
.serializer="${/** @param {?} v */ v => v}"
|
|
285
|
+
.deserializer="${/** @param {string} v */ v => v}"
|
|
286
|
+
>
|
|
287
|
+
<input slot="input">
|
|
288
|
+
</${tag}>
|
|
289
|
+
`)
|
|
290
|
+
);
|
|
291
|
+
await nonFormat.updateComplete;
|
|
292
|
+
|
|
293
|
+
expectValue(
|
|
294
|
+
nonFormat.modelValue,
|
|
295
|
+
generateExpectedInitialModelValue(nonFormat),
|
|
296
|
+
'modelValue initially',
|
|
297
|
+
);
|
|
298
|
+
expectValue(
|
|
299
|
+
nonFormat.formattedValue,
|
|
300
|
+
generateExpectedInitialFormattedValue(nonFormat),
|
|
301
|
+
'formattedValue initially',
|
|
302
|
+
);
|
|
303
|
+
expectValue(
|
|
304
|
+
nonFormat.serializedValue,
|
|
305
|
+
generateExpectedInitialSerializedValue(nonFormat),
|
|
306
|
+
'serializedValue initially',
|
|
307
|
+
);
|
|
308
|
+
|
|
124
309
|
const generatedValue = generateValueBasedOnType();
|
|
125
310
|
nonFormat.modelValue = generatedValue;
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
311
|
+
expectValue(nonFormat.modelValue, generatedValue, 'modelValue as provided');
|
|
312
|
+
expectValue(nonFormat.formattedValue, generatedValue, 'formattedValue synchronized');
|
|
313
|
+
expectValue(nonFormat.serializedValue, generatedValue, 'serializedValue synchronized');
|
|
129
314
|
});
|
|
130
315
|
|
|
131
316
|
/**
|
|
@@ -145,15 +330,18 @@ export function runFormatMixinSuite(customConfig) {
|
|
|
145
330
|
isTriggeredByUser = /** @type {CustomEvent} */ (event).detail.isTriggeredByUser;
|
|
146
331
|
});
|
|
147
332
|
|
|
148
|
-
|
|
333
|
+
const valueOne = generateValueBasedOnType();
|
|
334
|
+
const valueTwo = generateValueBasedOnType({ toggleValue: true });
|
|
335
|
+
|
|
336
|
+
el.modelValue = valueOne;
|
|
149
337
|
expect(counter).to.equal(1);
|
|
150
338
|
expect(isTriggeredByUser).to.be.false;
|
|
151
339
|
|
|
152
340
|
// no change means no event
|
|
153
|
-
el.modelValue =
|
|
341
|
+
el.modelValue = valueOne;
|
|
154
342
|
expect(counter).to.equal(1);
|
|
155
343
|
|
|
156
|
-
el.modelValue =
|
|
344
|
+
el.modelValue = valueTwo;
|
|
157
345
|
expect(counter).to.equal(2);
|
|
158
346
|
});
|
|
159
347
|
|
|
@@ -172,18 +360,14 @@ export function runFormatMixinSuite(customConfig) {
|
|
|
172
360
|
},
|
|
173
361
|
);
|
|
174
362
|
|
|
175
|
-
mimicUserInput(formatEl, generateValueBasedOnType());
|
|
363
|
+
mimicUserInput(formatEl, generateValueBasedOnType({ viewValue: true }));
|
|
176
364
|
expect(counter).to.equal(1);
|
|
177
365
|
expect(isTriggeredByUser).to.be.true;
|
|
178
366
|
|
|
179
|
-
//
|
|
180
|
-
|
|
181
|
-
// This will result in a model-value-changed trigger even if the user value was the same
|
|
182
|
-
// TODO: a proper solution would be to add `hasChanged` to input-date, like isSameDate()
|
|
183
|
-
// from calendar utils
|
|
184
|
-
const counterOffset = cfg.modelValueType === Date ? 1 : 0;
|
|
367
|
+
// All value comparison logic is the responsibility of consuming components
|
|
368
|
+
const counterOffset = valueChangeCounterOffset;
|
|
185
369
|
|
|
186
|
-
mimicUserInput(formatEl, generateValueBasedOnType());
|
|
370
|
+
mimicUserInput(formatEl, generateValueBasedOnType({ viewValue: true }));
|
|
187
371
|
expect(counter).to.equal(1 + counterOffset);
|
|
188
372
|
|
|
189
373
|
mimicUserInput(formatEl, generateValueBasedOnType({ toggleValue: true }));
|
|
@@ -197,7 +381,7 @@ export function runFormatMixinSuite(customConfig) {
|
|
|
197
381
|
<${tag}
|
|
198
382
|
value="string"
|
|
199
383
|
.formatter=${/** @param {string} value */ value => `foo: ${value}`}
|
|
200
|
-
.parser=${
|
|
384
|
+
.parser=${parser}
|
|
201
385
|
.serializer=${/** @param {string} value */ value => `[foo] ${value}`}
|
|
202
386
|
.deserializer=${/** @param {string} value */ value => value.replace('[foo] ', '')}
|
|
203
387
|
>
|
|
@@ -207,12 +391,14 @@ export function runFormatMixinSuite(customConfig) {
|
|
|
207
391
|
);
|
|
208
392
|
// Now check if the format/parse/serialize loop has been triggered
|
|
209
393
|
await formatElem.updateComplete;
|
|
210
|
-
|
|
394
|
+
const expectedFormattedValue = `foo: ${formatElem.modelValue}`;
|
|
395
|
+
const expectedSerializedValue = `[foo] ${formatElem.modelValue}`;
|
|
211
396
|
|
|
212
|
-
expect(formatElem.
|
|
397
|
+
expect(formatElem.formattedValue).to.equal(expectedFormattedValue);
|
|
213
398
|
|
|
214
|
-
expect(formatElem.
|
|
215
|
-
|
|
399
|
+
expect(formatElem._inputNode.value).to.equal(expectedFormattedValue);
|
|
400
|
+
|
|
401
|
+
expect(formatElem.serializedValue).to.equal(expectedSerializedValue);
|
|
216
402
|
});
|
|
217
403
|
|
|
218
404
|
describe('Unparseable values', () => {
|
|
@@ -274,9 +460,11 @@ export function runFormatMixinSuite(customConfig) {
|
|
|
274
460
|
);
|
|
275
461
|
// This could happen when the user erases the input value
|
|
276
462
|
mimicUserInput(el, '');
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
463
|
+
expectValue(
|
|
464
|
+
el.modelValue,
|
|
465
|
+
generateExpectedModelValueForEmptyInputNode(el),
|
|
466
|
+
'modelValue after clearing input node value',
|
|
467
|
+
);
|
|
280
468
|
});
|
|
281
469
|
});
|
|
282
470
|
});
|
|
@@ -399,6 +587,10 @@ export function runFormatMixinSuite(customConfig) {
|
|
|
399
587
|
|
|
400
588
|
describe('Formatter', () => {
|
|
401
589
|
it('only calls the formatter for valid values on `user-input-changed` ', async () => {
|
|
590
|
+
if (cfg.modelValueType === Object) {
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
|
|
402
594
|
const formatterSpy = sinon.spy(value => `foo: ${value}`);
|
|
403
595
|
|
|
404
596
|
const generatedModelValue = generateValueBasedOnType();
|
|
@@ -619,13 +811,13 @@ export function runFormatMixinSuite(customConfig) {
|
|
|
619
811
|
`)
|
|
620
812
|
);
|
|
621
813
|
|
|
622
|
-
|
|
814
|
+
const initialParserCallCount = parserSpy.callCount;
|
|
623
815
|
// This could happen for instance in a reset
|
|
624
816
|
el.modelValue = undefined;
|
|
625
|
-
expect(parserSpy.callCount).to.equal(
|
|
817
|
+
expect(parserSpy.callCount).to.equal(initialParserCallCount);
|
|
626
818
|
// This could happen when the user erases the input value
|
|
627
819
|
mimicUserInput(el, '');
|
|
628
|
-
expect(parserSpy.callCount).to.equal(
|
|
820
|
+
expect(parserSpy.callCount).to.equal(initialParserCallCount);
|
|
629
821
|
});
|
|
630
822
|
});
|
|
631
823
|
|
|
@@ -649,17 +841,19 @@ export function runFormatMixinSuite(customConfig) {
|
|
|
649
841
|
|
|
650
842
|
const { _inputNode } = getFormControlMembers(el);
|
|
651
843
|
|
|
652
|
-
|
|
844
|
+
const initialPreprocessorCallCount = preprocessorSpy.callCount;
|
|
653
845
|
|
|
654
846
|
const parserSpy = sinon.spy(el, 'parser');
|
|
655
847
|
mimicUserInput(el, toBeCorrectedVal);
|
|
656
848
|
|
|
657
|
-
expect(preprocessorSpy.callCount).to.equal(
|
|
849
|
+
expect(preprocessorSpy.callCount).to.equal(initialPreprocessorCallCount + 1);
|
|
658
850
|
expect(parserSpy.lastCall.args[0]).to.equal(val);
|
|
659
851
|
expect(_inputNode.value).to.equal(val);
|
|
660
852
|
});
|
|
661
853
|
|
|
662
854
|
it('does only calculate derived values as consequence of user input when preprocessed value is different from previous view value', async () => {
|
|
855
|
+
if (cfg.modelValueType === Object) return;
|
|
856
|
+
|
|
663
857
|
const val = generateValueBasedOnType({ viewValue: true }) || 'init-value';
|
|
664
858
|
if (typeof val !== 'string') return;
|
|
665
859
|
|
|
@@ -1554,13 +1554,11 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
1554
1554
|
// eslint-disable-next-line no-restricted-syntax
|
|
1555
1555
|
for (const state of ['dirty', 'touched', 'prefilled', 'submitted']) {
|
|
1556
1556
|
counter += 1;
|
|
1557
|
-
// @ts-ignore - test property access
|
|
1558
1557
|
el[state] = false;
|
|
1559
1558
|
// eslint-disable-next-line no-await-in-loop
|
|
1560
1559
|
await el.updateComplete;
|
|
1561
1560
|
expect(spy.callCount).to.equal(counter);
|
|
1562
1561
|
counter += 1;
|
|
1563
|
-
// @ts-ignore - test property access
|
|
1564
1562
|
el[state] = true;
|
|
1565
1563
|
// eslint-disable-next-line no-await-in-loop
|
|
1566
1564
|
await el.updateComplete;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { defineCE } from '@open-wc/testing';
|
|
2
1
|
import {
|
|
3
|
-
runInteractionStateMixinSuite,
|
|
4
2
|
runFormatMixinSuite,
|
|
3
|
+
runInteractionStateMixinSuite,
|
|
5
4
|
runNativeTextFieldMixinSuite,
|
|
6
5
|
} from '@lion/ui/form-core-test-suites.js';
|
|
6
|
+
import { defineCE } from '@open-wc/testing';
|
|
7
7
|
|
|
8
8
|
import { LionInput } from '@lion/ui/input.js';
|
|
9
9
|
|
|
@@ -26,6 +26,7 @@ describe('<lion-input> integrations', () => {
|
|
|
26
26
|
|
|
27
27
|
runFormatMixinSuite({
|
|
28
28
|
tagString: fieldTagString,
|
|
29
|
+
modelValueType: String,
|
|
29
30
|
});
|
|
30
31
|
|
|
31
32
|
runNativeTextFieldMixinSuite({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
-
runInteractionStateMixinSuite,
|
|
3
2
|
runFormatMixinSuite,
|
|
3
|
+
runInteractionStateMixinSuite,
|
|
4
4
|
} from '@lion/ui/form-core-test-suites.js';
|
|
5
5
|
|
|
6
6
|
import '@lion/ui/define/lion-input.js';
|
|
@@ -14,5 +14,6 @@ describe('<lion-input> integrations', () => {
|
|
|
14
14
|
|
|
15
15
|
runFormatMixinSuite({
|
|
16
16
|
tagString,
|
|
17
|
+
modelValueType: String,
|
|
17
18
|
});
|
|
18
19
|
});
|
|
@@ -1,14 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ref, createRef } from 'lit/directives/ref.js';
|
|
1
|
+
import { css, html } from 'lit';
|
|
3
2
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
3
|
+
import { createRef, ref } from 'lit/directives/ref.js';
|
|
4
4
|
|
|
5
5
|
import { LionInputAmount } from '@lion/ui/input-amount.js';
|
|
6
6
|
import { currencyUtil } from './currencyUtil.js';
|
|
7
|
-
import { parseAmount } from './parsers.js';
|
|
8
7
|
import { formatAmount } from './formatters.js';
|
|
8
|
+
import { localizeNamespaceLoader } from './localizeNamespaceLoader.js';
|
|
9
|
+
import { parseAmount } from './parsers.js';
|
|
9
10
|
import { deserializer, serializer } from './serializers.js';
|
|
10
11
|
import { CurrencyAndAmount } from './validators.js';
|
|
11
|
-
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @param {import('../types/index.js').AmountDropdownModelValue | undefined} newValue
|
|
15
|
+
* @param {import('../types/index.js').AmountDropdownModelValue | undefined} oldValue
|
|
16
|
+
* @returns {boolean}
|
|
17
|
+
*/
|
|
18
|
+
const hasChangedAmountDropdownModelValue = (newValue, oldValue) => {
|
|
19
|
+
if (newValue === oldValue) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (!newValue || !oldValue || typeof newValue !== 'object' || typeof oldValue !== 'object') {
|
|
24
|
+
return newValue !== oldValue;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return newValue.currency !== oldValue.currency || !Object.is(newValue.amount, oldValue.amount);
|
|
28
|
+
};
|
|
12
29
|
|
|
13
30
|
/**
|
|
14
31
|
* Note: one could consider to implement LionInputAmountDropdown as a
|
|
@@ -56,11 +73,48 @@ export class LionInputAmountDropdown extends LionInputAmount {
|
|
|
56
73
|
* @configure LitElement
|
|
57
74
|
* @type {any}
|
|
58
75
|
*/
|
|
59
|
-
static properties
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
76
|
+
static get properties() {
|
|
77
|
+
return {
|
|
78
|
+
modelValue: {
|
|
79
|
+
type: Object,
|
|
80
|
+
attribute: false,
|
|
81
|
+
hasChanged: hasChangedAmountDropdownModelValue,
|
|
82
|
+
},
|
|
83
|
+
preferredCurrencies: { type: Array },
|
|
84
|
+
allowedCurrencies: { type: Array },
|
|
85
|
+
__dropdownSlot: { type: String },
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* The internal modelValue is a combination of the amount and the currency code. The amount is a number, the currency code is a string.
|
|
91
|
+
* @private
|
|
92
|
+
* @type {import('../types/index.js').AmountDropdownModelValue}
|
|
93
|
+
*/
|
|
94
|
+
__modelValue;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* For a FormControl to function properly, its modelValue, serializedValue and viewValue/formattedValue
|
|
98
|
+
* should always translate in two directions. This is expected by `_callParser` method. It guards for empty
|
|
99
|
+
* viewValues. As the viewValue (`.value`) only concerns the amount part and not the currency part in
|
|
100
|
+
* InputAmountDropdown, this contract is broken.
|
|
101
|
+
* Below, we compensate for this.
|
|
102
|
+
*/
|
|
103
|
+
// @ts-expect-error - modelValue is overridden as an accessor but is defined as a property in parent class
|
|
104
|
+
set modelValue(value) {
|
|
105
|
+
if (value) {
|
|
106
|
+
this.__modelValue = /** @type {import('../types/index.js').AmountDropdownModelValue} */ (
|
|
107
|
+
value
|
|
108
|
+
);
|
|
109
|
+
// Below is needed because A1 and A2 in _callParser (FormatMixin) return values that are the wrong type.
|
|
110
|
+
} else {
|
|
111
|
+
this.__modelValue = { currency: this.currency, amount: '' };
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
get modelValue() {
|
|
116
|
+
return /** @type {import('../types/index.js').AmountDropdownModelValue} */ (this.__modelValue);
|
|
117
|
+
}
|
|
64
118
|
|
|
65
119
|
static localizeNamespaces = [
|
|
66
120
|
{ 'lion-input-amount-dropdown': localizeNamespaceLoader },
|
|
@@ -274,6 +328,9 @@ export class LionInputAmountDropdown extends LionInputAmount {
|
|
|
274
328
|
|
|
275
329
|
this.parser = parseAmount;
|
|
276
330
|
|
|
331
|
+
/** @type {import('../types/index.js').AmountDropdownModelValue} */
|
|
332
|
+
this.__modelValue = { currency: this.currency, amount: '' };
|
|
333
|
+
|
|
277
334
|
/**
|
|
278
335
|
* @param {import("../types/index.js").AmountDropdownModelValue} modelValue
|
|
279
336
|
* @param {import('../../localize/types/LocalizeMixinTypes.js').FormatNumberOptions} [givenOptions] Locale Options
|
|
@@ -388,7 +445,8 @@ export class LionInputAmountDropdown extends LionInputAmount {
|
|
|
388
445
|
* @protected
|
|
389
446
|
*/
|
|
390
447
|
_initModelValueBasedOnDropdown() {
|
|
391
|
-
|
|
448
|
+
const { currency, amount } = this._initialModelValue || {};
|
|
449
|
+
if (!currency && !amount && !this.dirty) {
|
|
392
450
|
this.__initializedCurrencyCode = this.currency;
|
|
393
451
|
this._initialModelValue = { currency: this.currency };
|
|
394
452
|
this.modelValue = this._initialModelValue;
|
|
@@ -515,7 +573,10 @@ export class LionInputAmountDropdown extends LionInputAmount {
|
|
|
515
573
|
}
|
|
516
574
|
|
|
517
575
|
// 2. Try to get the currency from user input
|
|
518
|
-
if (
|
|
576
|
+
if (
|
|
577
|
+
this.modelValue?.currency &&
|
|
578
|
+
this.allowedCurrencies?.includes(/** @type {CurrencyCode} */ (this.modelValue?.currency))
|
|
579
|
+
) {
|
|
519
580
|
this.currency = this.modelValue.currency;
|
|
520
581
|
return;
|
|
521
582
|
}
|