@eunomia/elements 1.0.0-beta.6 → 1.0.0-beta.8
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 +1 -1
- package/dist/cdn/components/chunks/{chunk-KDN4O5W2.js → chunk-32L2QYWQ.js} +5 -5
- package/dist/cdn/components/chunks/{chunk-JYIIWN2P.js → chunk-36KLGY6U.js} +8 -8
- package/dist/cdn/components/chunks/chunk-3BMACIDO.js +1 -0
- package/dist/cdn/components/chunks/{chunk-2Y2EU2CI.js → chunk-3UUZM7X2.js} +1 -1
- package/dist/cdn/components/chunks/chunk-55PUDL7D.js +109 -0
- package/dist/cdn/components/chunks/chunk-5LA5DQMP.js +1 -0
- package/dist/cdn/components/chunks/chunk-5LXGJVJR.js +1 -0
- package/dist/cdn/components/chunks/{chunk-ZKZV2YG5.js → chunk-5XPOGBPL.js} +1 -1
- package/dist/cdn/components/chunks/{chunk-LMVW522V.js → chunk-62RLISRD.js} +1 -1
- package/dist/cdn/components/chunks/{chunk-PMPSJG5V.js → chunk-6FYW5TQU.js} +3 -3
- package/dist/cdn/components/chunks/chunk-6TIEBY34.js +1 -0
- package/dist/cdn/components/chunks/{chunk-MOMYII3P.js → chunk-AH2SKZ7T.js} +14 -1
- package/dist/cdn/components/chunks/chunk-AK2DIJX7.js +1 -0
- package/dist/cdn/components/chunks/chunk-B5XMGWM7.js +10 -0
- package/dist/cdn/components/chunks/chunk-GVS6IUKC.js +1 -0
- package/dist/cdn/components/chunks/chunk-GWLD2I3P.js +8 -0
- package/dist/cdn/components/chunks/{chunk-UDVB4LAE.js → chunk-I4ERDXSM.js} +5 -3
- package/dist/cdn/components/chunks/{chunk-QZ5SHR3I.js → chunk-J3SZBXM6.js} +2 -2
- package/dist/cdn/components/chunks/chunk-JAGZL7JH.js +1 -0
- package/dist/cdn/components/chunks/{chunk-VYFR364B.js → chunk-LD35BFNK.js} +18 -17
- package/dist/cdn/components/chunks/{chunk-XDPRWUKN.js → chunk-MQQJ6DID.js} +1 -1
- package/dist/cdn/components/chunks/chunk-P6LGU3FT.js +1 -0
- package/dist/cdn/components/chunks/chunk-QL5GSW2A.js +1 -0
- package/dist/cdn/components/chunks/{chunk-UYZR4JXZ.js → chunk-QSZO4GIH.js} +45 -9
- package/dist/cdn/components/chunks/{chunk-7KKWYPHY.js → chunk-QXQ25SQS.js} +21 -19
- package/dist/cdn/components/chunks/{chunk-SZYEBMG6.js → chunk-QYB6Z6FG.js} +5 -5
- package/dist/cdn/components/chunks/{chunk-RIFF2D2F.js → chunk-RGC3I6MK.js} +1 -1
- package/dist/cdn/components/chunks/{chunk-L2ADCEN7.js → chunk-SVGWCKWT.js} +1 -1
- package/dist/cdn/components/chunks/{chunk-N6ZW5CDN.js → chunk-TCSB2MLU.js} +1 -1
- package/dist/cdn/components/chunks/{chunk-MQQ4BGVJ.js → chunk-TFTRCIIK.js} +7 -6
- package/dist/cdn/components/chunks/chunk-TLBXTBMM.js +46 -0
- package/dist/cdn/components/chunks/chunk-UVHVQRPT.js +1 -0
- package/dist/cdn/components/chunks/chunk-WIUERJII.js +1 -0
- package/dist/cdn/components/chunks/chunk-WW4BTWMH.js +1 -0
- package/dist/cdn/components/eun-alert.js +13 -6
- package/dist/cdn/components/eun-animate.js +6 -6
- package/dist/cdn/components/eun-badge.js +1 -1
- package/dist/cdn/components/eun-button.js +1 -1
- package/dist/cdn/components/eun-calendar.js +2 -2
- package/dist/cdn/components/eun-card.js +4 -4
- package/dist/cdn/components/eun-carousel.js +26 -22
- package/dist/cdn/components/eun-check-card.js +1 -1
- package/dist/cdn/components/eun-checkbox-list.js +11 -8
- package/dist/cdn/components/eun-checkbox.js +1 -1
- package/dist/cdn/components/eun-chip.js +17 -11
- package/dist/cdn/components/eun-collapse.js +1 -1
- package/dist/cdn/components/eun-color-picker.js +74 -69
- package/dist/cdn/components/eun-counter.js +16 -14
- package/dist/cdn/components/eun-date-picker.js +67 -63
- package/dist/cdn/components/eun-description-list.js +2 -2
- package/dist/cdn/components/eun-divider.js +3 -3
- package/dist/cdn/components/eun-drawer.js +21 -22
- package/dist/cdn/components/eun-dropdown-button.js +1 -1
- package/dist/cdn/components/eun-dropdown-item.js +3 -3
- package/dist/cdn/components/eun-fab.js +2 -2
- package/dist/cdn/components/eun-icon.js +1 -1
- package/dist/cdn/components/eun-image-card.js +1 -1
- package/dist/cdn/components/eun-image-carousel.js +10 -10
- package/dist/cdn/components/eun-infinite-list.js +1 -1
- package/dist/cdn/components/eun-input-file.js +21 -21
- package/dist/cdn/components/eun-input-phone.js +16 -12
- package/dist/cdn/components/eun-input.js +1 -1
- package/dist/cdn/components/eun-link.js +59 -13
- package/dist/cdn/components/eun-loader.js +1 -1
- package/dist/cdn/components/eun-modal.js +33 -23
- package/dist/cdn/components/eun-pagination.js +16 -16
- package/dist/cdn/components/eun-password-strength.js +14 -10
- package/dist/cdn/components/eun-radio-card.js +1 -1
- package/dist/cdn/components/eun-radio-list.js +11 -8
- package/dist/cdn/components/eun-radio.js +1 -1
- package/dist/cdn/components/eun-rating.js +276 -0
- package/dist/cdn/components/eun-scheduler-event-editor.js +11 -11
- package/dist/cdn/components/eun-scheduler-event.js +1 -1
- package/dist/cdn/components/eun-scheduler.js +28 -28
- package/dist/cdn/components/eun-search.js +36 -32
- package/dist/cdn/components/eun-select.js +27 -27
- package/dist/cdn/components/eun-sidebar.js +73 -26
- package/dist/cdn/components/eun-skeleton.js +1 -1
- package/dist/cdn/components/eun-slider.js +3 -3
- package/dist/cdn/components/eun-sliding-card.js +1 -1
- package/dist/cdn/components/eun-step.js +5 -4
- package/dist/cdn/components/eun-stepper.js +30 -30
- package/dist/cdn/components/eun-switch.js +1 -1
- package/dist/cdn/components/eun-tab-group.js +4 -4
- package/dist/cdn/components/eun-tab-panel.js +1 -1
- package/dist/cdn/components/eun-tab.js +1 -1
- package/dist/cdn/components/eun-table-action-bar.js +1 -1
- package/dist/cdn/components/eun-table.js +2 -2
- package/dist/cdn/components/eun-tag.js +3 -3
- package/dist/cdn/components/eun-textarea.js +36 -28
- package/dist/cdn/components/eun-time-picker.js +31 -28
- package/dist/cdn/components/eun-toast.js +24 -15
- package/dist/cdn/components/eun-toggle-group.js +75 -37
- package/dist/cdn/components/eun-toggle-item.js +9 -9
- package/dist/cdn/components/eun-toggle.js +2 -2
- package/dist/cdn/components/eun-toolbar.js +22 -22
- package/dist/cdn/components/eun-tooltip.js +6 -6
- package/dist/cdn/styles/eunomia-themes.css +1 -1
- package/dist/cdn/styles/themes/mixins/eunomia-neutrals.mixin.scss +6 -2
- package/dist/cdn/styles/themes/prebuilt-themes/eunomia/eunomia-dark.mixin.scss +6 -2
- package/dist/cdn/styles/themes/prebuilt-themes/eunomia/eunomia.theme.css +1 -1
- package/dist/cdn/styles/themes/prebuilt-themes/fire/eunomia-fire-dark.mixin.scss +6 -2
- package/dist/cdn/styles/themes/prebuilt-themes/fire/eunomia-fire.theme.css +1 -1
- package/dist/cdn/styles/themes/prebuilt-themes/forest/eunomia-forest-dark.mixin.scss +6 -2
- package/dist/cdn/styles/themes/prebuilt-themes/forest/eunomia-forest.theme.css +1 -1
- package/dist/cdn/styles/themes/prebuilt-themes/gold/eunomia-gold-dark.mixin.scss +6 -2
- package/dist/cdn/styles/themes/prebuilt-themes/gold/eunomia-gold.theme.css +1 -1
- package/dist/cdn/styles/themes/prebuilt-themes/ocean/eunomia-ocean-dark.mixin.scss +6 -2
- package/dist/cdn/styles/themes/prebuilt-themes/ocean/eunomia-ocean.theme.css +1 -1
- package/dist/cdn/styles/themes/prebuilt-themes/salmon/eunomia-salmon-dark.mixin.scss +6 -2
- package/dist/cdn/styles/themes/prebuilt-themes/salmon/eunomia-salmon.theme.css +1 -1
- package/dist/cdn/styles/themes/prebuilt-themes/violet/eunomia-violet-dark.mixin.scss +6 -2
- package/dist/cdn/styles/themes/prebuilt-themes/violet/eunomia-violet.theme.css +1 -1
- package/dist/components/action/button/button.d.ts +4 -3
- package/dist/components/action/button/button.js +6 -9
- package/dist/components/action/button/button.styles.js +13 -8
- package/dist/components/action/dropdown-button/dropdown-button.d.ts +4 -6
- package/dist/components/action/dropdown-button/dropdown-button.js +16 -13
- package/dist/components/action/dropdown-button/dropdown-item.d.ts +10 -2
- package/dist/components/action/dropdown-button/dropdown-item.js +24 -9
- package/dist/components/action/link/link.d.ts +10 -1
- package/dist/components/action/link/link.js +13 -1
- package/dist/components/action/link/link.styles.js +50 -3
- package/dist/components/action/toggle/toggle-group.d.ts +12 -2
- package/dist/components/action/toggle/toggle-group.js +18 -3
- package/dist/components/action/toggle/toggle-group.styles.js +58 -20
- package/dist/components/action/toggle/toggle-item.js +1 -3
- package/dist/components/action/toggle/toggle-item.styles.js +7 -7
- package/dist/components/action/toggle/toggle.js +1 -1
- package/dist/components/alert/alert/alert.d.ts +9 -7
- package/dist/components/alert/alert/alert.js +11 -14
- package/dist/components/alert/alert/alert.styles.js +9 -2
- package/dist/components/alert/drawer/drawer.d.ts +30 -5
- package/dist/components/alert/drawer/drawer.js +48 -13
- package/dist/components/alert/drawer/drawer.styles.js +7 -7
- package/dist/components/alert/modal/modal.d.ts +35 -10
- package/dist/components/alert/modal/modal.js +55 -28
- package/dist/components/alert/modal/modal.styles.js +17 -6
- package/dist/components/alert/toast/toast.d.ts +7 -5
- package/dist/components/alert/toast/toast.js +12 -15
- package/dist/components/alert/toast/toast.styles.js +18 -9
- package/dist/components/content/badge/badge.js +2 -2
- package/dist/components/content/card/card.js +1 -1
- package/dist/components/content/card/card.styles.js +2 -2
- package/dist/components/content/chip/chip.d.ts +4 -4
- package/dist/components/content/chip/chip.js +11 -10
- package/dist/components/content/chip/chip.styles.js +9 -3
- package/dist/components/content/description-list/description-list.js +3 -3
- package/dist/components/content/icon/icon.d.ts +3 -0
- package/dist/components/content/icon/icon.js +3 -0
- package/dist/components/content/icon/icon.style.d.ts +2 -0
- package/dist/components/content/icon/icon.style.js +4 -0
- package/dist/components/content/image-carousel/image-carousel.d.ts +12 -12
- package/dist/components/content/image-carousel/image-carousel.js +29 -28
- package/dist/components/content/password-strength/password-strength.d.ts +21 -6
- package/dist/components/content/password-strength/password-strength.js +37 -16
- package/dist/components/content/password-strength/password-strength.styles.js +4 -0
- package/dist/components/content/tag/tag.js +2 -2
- package/dist/components/content/tooltip/tooltip.d.ts +16 -9
- package/dist/components/content/tooltip/tooltip.js +31 -15
- package/dist/components/content/tooltip/tooltip.styles.js +1 -1
- package/dist/components/form/checkbox/check-card.d.ts +1 -0
- package/dist/components/form/checkbox/check-card.js +1 -0
- package/dist/components/form/checkbox/checkbox-list.d.ts +17 -0
- package/dist/components/form/checkbox/checkbox-list.js +39 -10
- package/dist/components/form/checkbox/checkbox.d.ts +1 -0
- package/dist/components/form/checkbox/checkbox.js +3 -1
- package/dist/components/form/checkbox/checkbox.styles.js +3 -2
- package/dist/components/form/color-picker/color-picker.d.ts +47 -28
- package/dist/components/form/color-picker/color-picker.js +73 -51
- package/dist/components/form/color-picker/color-picker.styles.js +14 -1
- package/dist/components/form/counter/counter.d.ts +24 -18
- package/dist/components/form/counter/counter.js +61 -61
- package/dist/components/form/counter/counter.styles.js +6 -4
- package/dist/components/form/date-picker/date-picker.d.ts +33 -7
- package/dist/components/form/date-picker/date-picker.js +82 -56
- package/dist/components/form/date-picker/date-picker.styles.js +9 -6
- package/dist/components/form/input/input.d.ts +43 -39
- package/dist/components/form/input/input.js +91 -110
- package/dist/components/form/input-file/input-file.d.ts +26 -13
- package/dist/components/form/input-file/input-file.js +35 -35
- package/dist/components/form/input-file/input-file.styles.js +4 -4
- package/dist/components/form/input-phone/input-phone.d.ts +28 -5
- package/dist/components/form/input-phone/input-phone.js +47 -13
- package/dist/components/form/input-phone/input-phone.styles.js +6 -3
- package/dist/components/form/radio/radio-card.d.ts +1 -0
- package/dist/components/form/radio/radio-card.js +1 -0
- package/dist/components/form/radio/radio-list.d.ts +23 -7
- package/dist/components/form/radio/radio-list.js +47 -22
- package/dist/components/form/radio/radio.d.ts +1 -0
- package/dist/components/form/radio/radio.js +1 -0
- package/dist/components/form/rating/rating.d.ts +349 -0
- package/dist/components/form/rating/rating.js +665 -0
- package/dist/components/form/rating/rating.styles.d.ts +1 -0
- package/dist/components/form/rating/rating.styles.js +213 -0
- package/dist/components/form/search/search.d.ts +72 -18
- package/dist/components/form/search/search.js +135 -72
- package/dist/components/form/search/search.styles.js +2 -0
- package/dist/components/form/select/select.d.ts +29 -10
- package/dist/components/form/select/select.js +65 -41
- package/dist/components/form/shared-styles/field.styles.js +45 -8
- package/dist/components/form/shared-styles/listbox.styles.js +15 -1
- package/dist/components/form/slider/slider.d.ts +7 -8
- package/dist/components/form/slider/slider.js +9 -12
- package/dist/components/form/switch/switch.d.ts +1 -0
- package/dist/components/form/switch/switch.js +1 -0
- package/dist/components/form/textarea/textarea.d.ts +90 -23
- package/dist/components/form/textarea/textarea.js +194 -44
- package/dist/components/form/textarea/textarea.styles.js +3 -0
- package/dist/components/form/time-picker/time-picker-columns.d.ts +2 -2
- package/dist/components/form/time-picker/time-picker-columns.js +8 -8
- package/dist/components/form/time-picker/time-picker.d.ts +30 -9
- package/dist/components/form/time-picker/time-picker.js +66 -40
- package/dist/components/form/time-picker/time-picker.styles.js +7 -5
- package/dist/components/layout/animate/animate.js +3 -2
- package/dist/components/layout/animate/animate.styles.js +2 -2
- package/dist/components/layout/divider/divider.js +1 -1
- package/dist/components/layout/divider/divider.styles.js +1 -1
- package/dist/components/loader/loader/loader.js +2 -2
- package/dist/components/loader/loader/loader.styles.js +14 -12
- package/dist/components/loader/skeleton/skeleton.js +1 -1
- package/dist/components/navigation/carousel/carousel.d.ts +32 -9
- package/dist/components/navigation/carousel/carousel.js +88 -41
- package/dist/components/navigation/carousel/carousel.styles.js +10 -6
- package/dist/components/navigation/pagination/pagination.d.ts +23 -21
- package/dist/components/navigation/pagination/pagination.js +30 -53
- package/dist/components/navigation/sidebar/sidebar.d.ts +113 -65
- package/dist/components/navigation/sidebar/sidebar.js +161 -118
- package/dist/components/navigation/sidebar/sidebar.styles.d.ts +1 -1
- package/dist/components/navigation/sidebar/sidebar.styles.js +74 -24
- package/dist/components/navigation/stepper/step.js +9 -8
- package/dist/components/navigation/stepper/stepper.d.ts +1 -3
- package/dist/components/navigation/stepper/stepper.js +15 -26
- package/dist/components/navigation/tabs/tab-group/tab-group.js +2 -2
- package/dist/components/navigation/tabs/tab-group/tab-group.styles.js +2 -2
- package/dist/components/navigation/toolbar/toolbar.d.ts +23 -13
- package/dist/components/navigation/toolbar/toolbar.js +28 -35
- package/dist/components/navigation/toolbar/toolbar.styles.js +18 -17
- package/dist/events/select.event.d.ts +3 -2
- package/dist/events/select.event.js +2 -1
- package/dist/features/scheduler/calendar/calendar.js +1 -1
- package/dist/features/scheduler/scheduler/scheduler.d.ts +7 -7
- package/dist/features/scheduler/scheduler/scheduler.js +15 -24
- package/dist/features/scheduler/scheduler-event/scheduler-event.js +3 -3
- package/dist/features/scheduler/scheduler-event/scheduler-event.styles.js +1 -1
- package/dist/features/scheduler/scheduler-event-editor/scheduler-event-editor.d.ts +6 -4
- package/dist/features/scheduler/scheduler-event-editor/scheduler-event-editor.js +7 -8
- package/dist/features/table/table/table.js +1 -1
- package/dist/features/table/table-action-bar/table-action-bar.js +2 -2
- package/dist/i18n/en.d.ts +68 -0
- package/dist/i18n/en.js +68 -0
- package/dist/i18n/fr.js +68 -2
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -0
- package/dist/mixins/button.mixin.d.ts +1 -1
- package/dist/mixins/button.mixin.js +9 -6
- package/dist/mixins/check.mixin.js +11 -10
- package/dist/mixins/dialog-surface.mixin.d.ts +8 -0
- package/dist/mixins/disabled.mixin.d.ts +5 -0
- package/dist/mixins/disabled.mixin.js +21 -1
- package/dist/mixins/editable.mixin.js +28 -5
- package/dist/mixins/field-appearance.mixin.js +3 -2
- package/dist/mixins/field-size.mixin.d.ts +19 -0
- package/dist/mixins/field-size.mixin.js +33 -0
- package/dist/mixins/form.mixin.d.ts +4 -0
- package/dist/mixins/form.mixin.js +87 -13
- package/dist/mixins/localizable.mixin.d.ts +1 -1
- package/dist/mixins/localizable.mixin.js +1 -1
- package/dist/mixins/radio.mixin.js +11 -10
- package/dist/mixins/readonly.mixin.d.ts +2 -1
- package/dist/mixins/readonly.mixin.js +10 -3
- package/dist/mixins/rounded.mixin.d.ts +18 -0
- package/dist/mixins/rounded.mixin.js +32 -0
- package/dist/ssr/alert-ssr.css +187 -0
- package/dist/ssr/badge-ssr.css +67 -0
- package/dist/ssr/breadcrumb-ssr.css +41 -0
- package/dist/ssr/button-ssr.css +5 -5
- package/dist/ssr/card-ssr.css +27 -15
- package/dist/ssr/carousel-ssr.css +247 -0
- package/dist/ssr/checkbox-ssr.css +67 -0
- package/dist/ssr/chip-ssr.css +250 -0
- package/dist/ssr/collapse-ssr.css +180 -0
- package/dist/ssr/field-ssr.css +202 -0
- package/dist/ssr/icon-ssr.css +266 -0
- package/dist/ssr/image-carousel-ssr.css +34 -0
- package/dist/ssr/links-ssr.css +44 -1
- package/dist/ssr/pagination-ssr.css +4 -0
- package/dist/ssr/rating-ssr.css +254 -0
- package/dist/ssr/sidebar-ssr.css +102 -3
- package/dist/ssr/skeleton-ssr.css +63 -0
- package/dist/ssr/tabs-ssr.css +129 -0
- package/dist/ssr/toggle-group-ssr.css +233 -0
- package/dist/ssr/toolbar-ssr.css +81 -2
- package/dist/types/variant.type.d.ts +4 -1
- package/dist/utils/boolean.utils.d.ts +14 -0
- package/dist/utils/boolean.utils.js +20 -0
- package/dist/utils/dropdown-menu.utils.d.ts +1 -1
- package/dist/utils/focusable-elements.utils.d.ts +12 -0
- package/dist/utils/focusable-elements.utils.js +26 -0
- package/dist/utils/implicit-submission.utils.d.ts +18 -0
- package/dist/utils/implicit-submission.utils.js +79 -0
- package/dist/utils/input-modality.utils.d.ts +13 -0
- package/dist/utils/input-modality.utils.js +34 -0
- package/dist/utils/listbox-options.utils.d.ts +11 -0
- package/dist/utils/listbox-options.utils.js +41 -3
- package/dist/utils/theme-generator.utils.d.ts +8 -2
- package/dist/utils/theme-generator.utils.js +30 -9
- package/package.json +26 -7
- package/styles/themes/mixins/eunomia-neutrals.mixin.scss +6 -2
- package/styles/themes/prebuilt-themes/eunomia/eunomia-dark.mixin.scss +6 -2
- package/styles/themes/prebuilt-themes/fire/eunomia-fire-dark.mixin.scss +6 -2
- package/styles/themes/prebuilt-themes/forest/eunomia-forest-dark.mixin.scss +6 -2
- package/styles/themes/prebuilt-themes/gold/eunomia-gold-dark.mixin.scss +6 -2
- package/styles/themes/prebuilt-themes/ocean/eunomia-ocean-dark.mixin.scss +6 -2
- package/styles/themes/prebuilt-themes/salmon/eunomia-salmon-dark.mixin.scss +6 -2
- package/styles/themes/prebuilt-themes/violet/eunomia-violet-dark.mixin.scss +6 -2
- package/dist/cdn/components/chunks/chunk-4PI6RDUS.js +0 -1
- package/dist/cdn/components/chunks/chunk-6VK6SHCG.js +0 -1
- package/dist/cdn/components/chunks/chunk-A3X4KD2X.js +0 -1
- package/dist/cdn/components/chunks/chunk-BQFJR2UP.js +0 -110
- package/dist/cdn/components/chunks/chunk-G5SBDQQ3.js +0 -1
- package/dist/cdn/components/chunks/chunk-KSZRQRN4.js +0 -1
- package/dist/cdn/components/chunks/chunk-PE4DAXHQ.js +0 -3
- package/dist/cdn/components/chunks/chunk-RS7TWEMQ.js +0 -1
- package/dist/cdn/components/chunks/chunk-UDOZRIJZ.js +0 -1
- package/dist/cdn/components/chunks/chunk-VOTRXBDS.js +0 -38
|
@@ -0,0 +1,665 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { customElement, property, query, state } from "lit/decorators.js";
|
|
8
|
+
import { html, LitElement, nothing } from "lit";
|
|
9
|
+
import { classMap } from "lit/directives/class-map.js";
|
|
10
|
+
import { ifDefined } from "lit/directives/if-defined.js";
|
|
11
|
+
import { live } from "lit/directives/live.js";
|
|
12
|
+
import { styleMap } from "lit/directives/style-map.js";
|
|
13
|
+
import { DisabledMixin, } from "../../../mixins/disabled.mixin.js";
|
|
14
|
+
import { ReadonlyMixin, } from "../../../mixins/readonly.mixin.js";
|
|
15
|
+
import { ValidatorsMixin, } from "../../../mixins/validators.mixin.js";
|
|
16
|
+
import { FormMixin } from "../../../mixins/form.mixin.js";
|
|
17
|
+
import { FormLabelMixin, } from "../../../mixins/form-label.mixin.js";
|
|
18
|
+
import { LocalizableMixin, } from "../../../mixins/localizable.mixin.js";
|
|
19
|
+
import { getDefaultLocale } from "../../../i18n/index.js";
|
|
20
|
+
import { ChangeEvent } from "../../../events/change.event.js";
|
|
21
|
+
import { formLabelsStyles } from "../shared-styles/form-labels.styles.js";
|
|
22
|
+
import { ratingStyles } from "./rating.styles.js";
|
|
23
|
+
/**
|
|
24
|
+
* Tag name of the rating component.
|
|
25
|
+
*/
|
|
26
|
+
export const EunomiaRatingTagName = "eun-rating";
|
|
27
|
+
/**
|
|
28
|
+
* Base class with composed mixins used to handle component extends elements type.
|
|
29
|
+
* @internal
|
|
30
|
+
*/
|
|
31
|
+
const Base = DisabledMixin(ValidatorsMixin(LitElement));
|
|
32
|
+
const EunomiaRatingMixinBase = LocalizableMixin(FormLabelMixin(ReadonlyMixin(FormMixin(Base))));
|
|
33
|
+
/**
|
|
34
|
+
* A rating shown as a row of icons, stars by default, that someone fills to
|
|
35
|
+
* give a score, or that simply displays one, such as a product's average
|
|
36
|
+
* review.
|
|
37
|
+
*
|
|
38
|
+
* Picking a score renders one native radio button per possible value,
|
|
39
|
+
* grouped in a radio group, so assistive technology announces each option
|
|
40
|
+
* as "3 out of 5", and the field takes part in forms like every other one.
|
|
41
|
+
* With displayOnly, the icons are rendered as a single image whose
|
|
42
|
+
* accessible name reads the score, such as "Rating: 4.5 out of 5".
|
|
43
|
+
*
|
|
44
|
+
* @slot [label] - Custom label content, falling back to the label property. Not rendered while displayOnly is set
|
|
45
|
+
* @slot [instructions] - Custom instructions content, falling back to the instructions property. Not rendered while displayOnly is set
|
|
46
|
+
* @prop {string} label - The title label of the field. While displayOnly is set, it isn't shown and starts the accessible name instead
|
|
47
|
+
* @prop {string} instructions - Instructions displayed below the label
|
|
48
|
+
* @prop {string} name - The field name
|
|
49
|
+
* @prop {number} value - The current rating. Empty when nothing is picked yet
|
|
50
|
+
* @prop {number} defaultValue - The rating applied when the field connects, and restored on form reset
|
|
51
|
+
* @attr {number} [default-value] - The rating applied when the field connects, and restored on form reset
|
|
52
|
+
* @prop {number} [max=5] - The number of icons, which is also the highest rating
|
|
53
|
+
* @prop {1 | 0.5} [step=1] - Whether a rating is picked by whole icons or by halves
|
|
54
|
+
* @prop {boolean} [displayOnly=false] - Only displays the rating, which can then be any decimal value, such as an average
|
|
55
|
+
* @attr {boolean} [display-only=false] - Only displays the rating, which can then be any decimal value, such as an average
|
|
56
|
+
* @prop {boolean} [clearable=false] - Shows a button that removes the rating, once one is picked
|
|
57
|
+
* @prop {string} [clearLabel] - The accessible label of the clear button. Defaults to the localized string for the current locale (English: "Clear rating")
|
|
58
|
+
* @attr {string} [clear-label] - The accessible label of the clear button
|
|
59
|
+
* @prop {import('../../content/icon/icon.type.js').EunomiaIconName} [icon='star'] - The icon drawn for the filled part of the rating
|
|
60
|
+
* @prop {import('../../content/icon/icon.type.js').EunomiaIconName} [emptyIcon='star_border'] - The icon drawn for the empty part of the rating. Keep its shape different from icon, so the rating doesn't rely on color alone
|
|
61
|
+
* @attr {import('../../content/icon/icon.type.js').EunomiaIconName} [empty-icon='star_border'] - The icon drawn for the empty part of the rating
|
|
62
|
+
* @prop {string} [locale] - The language of the accessible labels and of the decimal separator. Defaults to the shared default locale
|
|
63
|
+
* @prop {boolean} [disabled=false] - Whether the field is disabled
|
|
64
|
+
* @prop {boolean} [readonly=false] - Whether the field is read only
|
|
65
|
+
* @prop {boolean} [required=false] - Whether a rating must be picked
|
|
66
|
+
* @prop {boolean} [hideError=false] - Whether the errors are hidden. The hint stays visible
|
|
67
|
+
* @attr {boolean} [hide-error=false] - Whether the errors are hidden. The hint stays visible
|
|
68
|
+
* @prop {boolean} [invalid=false] - Shows the field as invalid without any message, for an error displayed elsewhere
|
|
69
|
+
* @prop {string} [error] - An error computed outside the field, by the form or by the server. While set, the field is invalid and shows this message right away
|
|
70
|
+
* @prop {string} hint - A short message displayed under the field
|
|
71
|
+
* @prop {Array<import('../../../types/form-validators.type.js').Validators<number | undefined>>} validators - The list of validation rules applied to the rating
|
|
72
|
+
* @fires {ChangeEvent} eunchange - Fired whenever the rating is picked, changed or cleared
|
|
73
|
+
* @cssprop [--rating-size] - Sets the width and height of each icon
|
|
74
|
+
* @cssprop [--rating-gap] - Sets the space between two icons
|
|
75
|
+
* @cssprop [--rating-color] - Sets the color of the filled icons
|
|
76
|
+
* @cssprop [--rating-empty-color] - Sets the color of the empty icons
|
|
77
|
+
* @cssprop [--rating-error-color] - Sets the color of the error message, and of the empty icons while in error
|
|
78
|
+
* @cssprop [--rating-hint-color] - Sets the color of the hint message
|
|
79
|
+
* @cssprop [--rating-focus-outline-color] - Sets the color of the focus outline drawn around the focused icon and the clear button
|
|
80
|
+
* @cssprop [--field-label-font-size] - Sets the font size of the label
|
|
81
|
+
* @cssprop [--field-message-font-size] - Sets the font size of the hint, error messages and instructions
|
|
82
|
+
* @element eun-rating
|
|
83
|
+
*/
|
|
84
|
+
let EunomiaRating = class EunomiaRating extends EunomiaRatingMixinBase {
|
|
85
|
+
constructor() {
|
|
86
|
+
super(...arguments);
|
|
87
|
+
/**
|
|
88
|
+
* Every change is a complete choice, so its error shows right away.
|
|
89
|
+
* @internal
|
|
90
|
+
*/
|
|
91
|
+
this.errorOnChange = true;
|
|
92
|
+
/**
|
|
93
|
+
* The number of icons, which is also the highest rating.
|
|
94
|
+
* @default 5
|
|
95
|
+
*/
|
|
96
|
+
this.max = 5;
|
|
97
|
+
/**
|
|
98
|
+
* Whether a rating is picked by whole icons or by halves. Any other value
|
|
99
|
+
* falls back to `1`.
|
|
100
|
+
* @default 1
|
|
101
|
+
*/
|
|
102
|
+
this.step = 1;
|
|
103
|
+
/**
|
|
104
|
+
* Only displays the rating, which can then be any decimal value, such as
|
|
105
|
+
* an average. The field is then neither focusable nor editable.
|
|
106
|
+
* @default false
|
|
107
|
+
*/
|
|
108
|
+
this.displayOnly = false;
|
|
109
|
+
/**
|
|
110
|
+
* Shows a button that removes the rating, once one is picked.
|
|
111
|
+
* @default false
|
|
112
|
+
*/
|
|
113
|
+
this.clearable = false;
|
|
114
|
+
/**
|
|
115
|
+
* The icon drawn for the filled part of the rating.
|
|
116
|
+
* @default star
|
|
117
|
+
*/
|
|
118
|
+
this.icon = "star";
|
|
119
|
+
/**
|
|
120
|
+
* The icon drawn for the empty part of the rating. Its shape differs from
|
|
121
|
+
* {@link icon} by default, so the rating never relies on color alone.
|
|
122
|
+
* @default star_border
|
|
123
|
+
*/
|
|
124
|
+
this.emptyIcon = "star_border";
|
|
125
|
+
/**
|
|
126
|
+
* Picks the value under the pointer. The radios themselves ignore the
|
|
127
|
+
* pointer, so a whole icon stays one target even while `step` is `0.5`.
|
|
128
|
+
*
|
|
129
|
+
* @param event the click event.
|
|
130
|
+
* @private
|
|
131
|
+
*/
|
|
132
|
+
this.handleClick = (event) => {
|
|
133
|
+
if (this.locked || event.target instanceof HTMLInputElement) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const value = this.valueAtPointer(event);
|
|
137
|
+
if (value === undefined) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
this.pick(value);
|
|
141
|
+
this.radioFor(value)?.focus({ preventScroll: true });
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Previews the value under a mouse pointer.
|
|
145
|
+
*
|
|
146
|
+
* @param event the pointer event.
|
|
147
|
+
* @private
|
|
148
|
+
*/
|
|
149
|
+
this.handlePointerMove = (event) => {
|
|
150
|
+
if (this.locked || event.pointerType !== "mouse") {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
this.hoverValue = this.valueAtPointer(event);
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* Ends the hover preview.
|
|
157
|
+
* @private
|
|
158
|
+
*/
|
|
159
|
+
this.handlePointerLeave = () => {
|
|
160
|
+
this.hoverValue = undefined;
|
|
161
|
+
};
|
|
162
|
+
/**
|
|
163
|
+
* Applies a radio checked natively, by Space or by assistive technology.
|
|
164
|
+
*
|
|
165
|
+
* @param event the native change event.
|
|
166
|
+
* @private
|
|
167
|
+
*/
|
|
168
|
+
this.handleChange = (event) => {
|
|
169
|
+
if (this.locked) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
this.pick(Number(event.target.value));
|
|
173
|
+
};
|
|
174
|
+
/**
|
|
175
|
+
* Keeps a radio from being checked while readonly, since the HTML
|
|
176
|
+
* `readonly` attribute has no effect on radios.
|
|
177
|
+
*
|
|
178
|
+
* @param event the click event dispatched on a radio.
|
|
179
|
+
* @private
|
|
180
|
+
*/
|
|
181
|
+
this.handleRadioClick = (event) => {
|
|
182
|
+
if (this.readonly) {
|
|
183
|
+
event.preventDefault();
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
187
|
+
* Moves the rating with the arrow keys, Home and End, without wrapping
|
|
188
|
+
* around as native radios do, and blocks every change while readonly.
|
|
189
|
+
*
|
|
190
|
+
* @param event the keyboard event.
|
|
191
|
+
* @private
|
|
192
|
+
*/
|
|
193
|
+
this.handleKeydown = (event) => {
|
|
194
|
+
if (!(event.target instanceof HTMLInputElement)) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
const step = this.resolvedStep;
|
|
198
|
+
const rtl = getComputedStyle(this).direction === "rtl";
|
|
199
|
+
const current = this.value ?? 0;
|
|
200
|
+
let next;
|
|
201
|
+
switch (event.key) {
|
|
202
|
+
case "ArrowRight":
|
|
203
|
+
next = current + (rtl ? -step : step);
|
|
204
|
+
break;
|
|
205
|
+
case "ArrowLeft":
|
|
206
|
+
next = current + (rtl ? step : -step);
|
|
207
|
+
break;
|
|
208
|
+
case "ArrowDown":
|
|
209
|
+
next = current + step;
|
|
210
|
+
break;
|
|
211
|
+
case "ArrowUp":
|
|
212
|
+
next = current - step;
|
|
213
|
+
break;
|
|
214
|
+
case "Home":
|
|
215
|
+
next = step;
|
|
216
|
+
break;
|
|
217
|
+
case "End":
|
|
218
|
+
next = this.count;
|
|
219
|
+
break;
|
|
220
|
+
case " ":
|
|
221
|
+
if (this.readonly) {
|
|
222
|
+
event.preventDefault();
|
|
223
|
+
}
|
|
224
|
+
return;
|
|
225
|
+
default:
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
event.preventDefault();
|
|
229
|
+
if (this.readonly) {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
const value = Math.min(this.count, Math.max(step, next));
|
|
233
|
+
this.pick(value);
|
|
234
|
+
this.radioFor(value)?.focus();
|
|
235
|
+
};
|
|
236
|
+
/**
|
|
237
|
+
* Removes the rating, then moves focus to the group, since the clear
|
|
238
|
+
* button disappears with it.
|
|
239
|
+
* @private
|
|
240
|
+
*/
|
|
241
|
+
this.handleClear = async () => {
|
|
242
|
+
this.pick(undefined);
|
|
243
|
+
await this.updateComplete;
|
|
244
|
+
this.focus();
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* The current rating, `undefined` while nothing is picked. Overrides the
|
|
249
|
+
* accessor inherited from `FormMixin` to give it a `Number` converter, as
|
|
250
|
+
* `eun-slider` does, and to clamp every assignment within `0`/`max` : `0`
|
|
251
|
+
* or less means no rating. Snapping to `step` happens in
|
|
252
|
+
* {@link willUpdate}, once `displayOnly` is known, since a displayed
|
|
253
|
+
* average keeps its exact decimals.
|
|
254
|
+
*/
|
|
255
|
+
get value() {
|
|
256
|
+
return super.value;
|
|
257
|
+
}
|
|
258
|
+
set value(value) {
|
|
259
|
+
super.value = this.clamp(value);
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* The rating applied on connection and form reset. Overrides the accessor
|
|
263
|
+
* inherited from `FormMixin` for the same reason as {@link value}.
|
|
264
|
+
*/
|
|
265
|
+
get defaultValue() {
|
|
266
|
+
return super.defaultValue;
|
|
267
|
+
}
|
|
268
|
+
set defaultValue(value) {
|
|
269
|
+
// @ts-expect-error — FormMixin's real setter exists.
|
|
270
|
+
super.defaultValue = value;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* The number of icons drawn, `max` rounded to a whole number of at least
|
|
274
|
+
* one.
|
|
275
|
+
* @private
|
|
276
|
+
*/
|
|
277
|
+
get count() {
|
|
278
|
+
const count = Math.round(this.max);
|
|
279
|
+
return Number.isFinite(count) && count >= 1 ? count : 5;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* The step actually applied, `step` restricted to `1` or `0.5`.
|
|
283
|
+
* @private
|
|
284
|
+
*/
|
|
285
|
+
get resolvedStep() {
|
|
286
|
+
return Number(this.step) === 0.5 ? 0.5 : 1;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Clamps a value within `0`/`max`, turning anything empty, invalid, or at
|
|
290
|
+
* `0` or below into `undefined`.
|
|
291
|
+
*
|
|
292
|
+
* @param value the value to clamp.
|
|
293
|
+
* @returns the clamped value.
|
|
294
|
+
* @private
|
|
295
|
+
*/
|
|
296
|
+
clamp(value) {
|
|
297
|
+
if (value === undefined || value === null || value === "") {
|
|
298
|
+
return undefined;
|
|
299
|
+
}
|
|
300
|
+
const number = Number(value);
|
|
301
|
+
if (!Number.isFinite(number) || number <= 0) {
|
|
302
|
+
return undefined;
|
|
303
|
+
}
|
|
304
|
+
return Math.min(number, this.count);
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Clamps a value, then snaps it to the nearest `step` unless the rating
|
|
308
|
+
* is only displayed.
|
|
309
|
+
*
|
|
310
|
+
* @param value the value to normalize.
|
|
311
|
+
* @returns the normalized value.
|
|
312
|
+
* @private
|
|
313
|
+
*/
|
|
314
|
+
snap(value) {
|
|
315
|
+
const clamped = this.clamp(value);
|
|
316
|
+
if (clamped === undefined || this.displayOnly) {
|
|
317
|
+
return clamped;
|
|
318
|
+
}
|
|
319
|
+
const step = this.resolvedStep;
|
|
320
|
+
return Math.min(this.count, Math.max(step, Math.round(clamped / step) * step));
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Formats a number in the current locale, such as `4,5` in French.
|
|
324
|
+
*
|
|
325
|
+
* @param value the number to format.
|
|
326
|
+
* @returns the formatted number.
|
|
327
|
+
* @private
|
|
328
|
+
*/
|
|
329
|
+
format(value) {
|
|
330
|
+
const locale = this.locale ?? getDefaultLocale();
|
|
331
|
+
try {
|
|
332
|
+
return new Intl.NumberFormat(locale, {
|
|
333
|
+
maximumFractionDigits: 2,
|
|
334
|
+
}).format(value);
|
|
335
|
+
}
|
|
336
|
+
catch {
|
|
337
|
+
return String(value);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* The accessible text of a value, such as "3 out of 5".
|
|
342
|
+
*
|
|
343
|
+
* @param value the value to describe.
|
|
344
|
+
* @returns the localized text.
|
|
345
|
+
* @private
|
|
346
|
+
*/
|
|
347
|
+
valueText(value) {
|
|
348
|
+
return this.dictionary.rating.valueText(this.format(value), this.format(this.count));
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* The radio input matching a value, if rendered.
|
|
352
|
+
*
|
|
353
|
+
* @param value the value to look for.
|
|
354
|
+
* @returns the matching radio input.
|
|
355
|
+
* @private
|
|
356
|
+
*/
|
|
357
|
+
radioFor(value) {
|
|
358
|
+
const radios = this.itemsEl?.querySelectorAll("input");
|
|
359
|
+
return (Array.from(radios ?? []).find((radio) => Number(radio.value) === value) ??
|
|
360
|
+
null);
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* The value of the group's single tab stop: the current rating, or the
|
|
364
|
+
* lowest one while nothing is picked.
|
|
365
|
+
* @private
|
|
366
|
+
*/
|
|
367
|
+
get tabStopValue() {
|
|
368
|
+
return this.value ?? this.resolvedStep;
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* The host is never a tab stop of its own : sequential navigation goes
|
|
372
|
+
* straight to the radio group inside, in both directions, and
|
|
373
|
+
* {@link focus} covers a direct call on the host.
|
|
374
|
+
*/
|
|
375
|
+
get hostTabStop() {
|
|
376
|
+
return false;
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Returns the radio to focus on validation errors.
|
|
380
|
+
*
|
|
381
|
+
* @returns the group's tab stop, if rendered.
|
|
382
|
+
*/
|
|
383
|
+
getFocusAnchor() {
|
|
384
|
+
return this.radioFor(this.tabStopValue) ?? undefined;
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Focuses the group's tab stop.
|
|
388
|
+
*/
|
|
389
|
+
focus(options) {
|
|
390
|
+
super.focus?.(options);
|
|
391
|
+
this.radioFor(this.tabStopValue)?.focus(options);
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Applies a value picked by the user, and notifies consumers when it
|
|
395
|
+
* actually changed.
|
|
396
|
+
*
|
|
397
|
+
* @param value the picked value, `undefined` to clear the rating.
|
|
398
|
+
* @private
|
|
399
|
+
*/
|
|
400
|
+
pick(value) {
|
|
401
|
+
if (value === this.value) {
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
this.value = value;
|
|
405
|
+
this.dispatchEvent(new ChangeEvent(this.value));
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Whether the user can't change the rating right now.
|
|
409
|
+
* @private
|
|
410
|
+
*/
|
|
411
|
+
get locked() {
|
|
412
|
+
return this.disabled || this.readonly || this.displayOnly;
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* The value under the pointer : the whole icon, or its first half while
|
|
416
|
+
* `step` is `0.5`, mirrored in a right-to-left layout. The gap after an
|
|
417
|
+
* icon counts as that whole icon, so moving across the row never empties
|
|
418
|
+
* the hover preview between two icons.
|
|
419
|
+
*
|
|
420
|
+
* @param event the pointer event.
|
|
421
|
+
* @returns the value under the pointer, if over or past an icon.
|
|
422
|
+
* @private
|
|
423
|
+
*/
|
|
424
|
+
valueAtPointer(event) {
|
|
425
|
+
const rtl = getComputedStyle(this).direction === "rtl";
|
|
426
|
+
const hovered = event.target.closest(".item");
|
|
427
|
+
if (!hovered) {
|
|
428
|
+
let item;
|
|
429
|
+
this.itemsEl?.querySelectorAll(".item").forEach((candidate) => {
|
|
430
|
+
const rect = candidate.getBoundingClientRect();
|
|
431
|
+
if (rtl ? rect.right >= event.clientX : rect.left <= event.clientX) {
|
|
432
|
+
item = candidate;
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
return item ? Number(item.dataset.index) : undefined;
|
|
436
|
+
}
|
|
437
|
+
const index = Number(hovered.dataset.index);
|
|
438
|
+
if (this.resolvedStep === 1) {
|
|
439
|
+
return index;
|
|
440
|
+
}
|
|
441
|
+
const rect = hovered.getBoundingClientRect();
|
|
442
|
+
const ratio = rect.width ? (event.clientX - rect.left) / rect.width : 1;
|
|
443
|
+
const fromStart = rtl ? 1 - ratio : ratio;
|
|
444
|
+
return fromStart <= 0.5 ? index - 0.5 : index;
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Snaps the value to `step` and keeps it within `max` whenever either of
|
|
448
|
+
* them, the value, or `displayOnly` changes. Done before render so the
|
|
449
|
+
* correction lands in the update already in progress, and before
|
|
450
|
+
* `FormMixin` validates the value.
|
|
451
|
+
*
|
|
452
|
+
* @param changed the changed properties.
|
|
453
|
+
*/
|
|
454
|
+
willUpdate(changed) {
|
|
455
|
+
if (["value", "valueState", "max", "step", "displayOnly"].some((name) => changed.has(name))) {
|
|
456
|
+
const normalized = this.snap(this.value);
|
|
457
|
+
if (normalized !== this.value) {
|
|
458
|
+
this.value = normalized;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
if (changed.has("disabled") || changed.has("readonly")) {
|
|
462
|
+
this.hoverValue = undefined;
|
|
463
|
+
}
|
|
464
|
+
super.willUpdate(changed);
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Renders one icon, its empty shape with the filled one clipped on top.
|
|
468
|
+
*
|
|
469
|
+
* @param fill how much of the icon is filled, from `0` to `1`.
|
|
470
|
+
* @returns the rendered icon.
|
|
471
|
+
* @private
|
|
472
|
+
*/
|
|
473
|
+
renderIcon(fill) {
|
|
474
|
+
return html `
|
|
475
|
+
<span class="icon" aria-hidden="true">
|
|
476
|
+
<eun-icon class="empty" name=${this.emptyIcon}></eun-icon>
|
|
477
|
+
<span class="fill" style=${styleMap({ width: `${fill * 100}%` })}>
|
|
478
|
+
<eun-icon name=${this.icon}></eun-icon>
|
|
479
|
+
</span>
|
|
480
|
+
</span>
|
|
481
|
+
`;
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Renders the radio of one value, with the ring drawn around its area
|
|
485
|
+
* while it has keyboard focus.
|
|
486
|
+
*
|
|
487
|
+
* @param value the value of the radio.
|
|
488
|
+
* @returns the rendered radio.
|
|
489
|
+
* @private
|
|
490
|
+
*/
|
|
491
|
+
renderRadio(value) {
|
|
492
|
+
const half = !Number.isInteger(value);
|
|
493
|
+
const area = classMap({
|
|
494
|
+
half,
|
|
495
|
+
end: !half && this.resolvedStep === 0.5,
|
|
496
|
+
});
|
|
497
|
+
return html `
|
|
498
|
+
<input
|
|
499
|
+
type="radio"
|
|
500
|
+
name="rating"
|
|
501
|
+
class=${area}
|
|
502
|
+
.value=${String(value)}
|
|
503
|
+
.checked=${live(this.value === value)}
|
|
504
|
+
?disabled=${this.disabled}
|
|
505
|
+
tabindex=${value === this.tabStopValue ? "0" : "-1"}
|
|
506
|
+
aria-label=${this.valueText(value)}
|
|
507
|
+
@click=${this.handleRadioClick}
|
|
508
|
+
/>
|
|
509
|
+
<span class="focus-ring ${half ? "half" : ""}" aria-hidden="true"></span>
|
|
510
|
+
`;
|
|
511
|
+
}
|
|
512
|
+
/**
|
|
513
|
+
* Renders the rating as a single image, its accessible name reading the
|
|
514
|
+
* score.
|
|
515
|
+
* @private
|
|
516
|
+
*/
|
|
517
|
+
renderDisplay() {
|
|
518
|
+
const { rating } = this.dictionary;
|
|
519
|
+
const value = this.value;
|
|
520
|
+
const text = value === undefined ? rating.noValue : this.valueText(value);
|
|
521
|
+
return html `
|
|
522
|
+
<div
|
|
523
|
+
id="items"
|
|
524
|
+
part="items"
|
|
525
|
+
role="img"
|
|
526
|
+
aria-label=${rating.summary(this.label || rating.label, text)}
|
|
527
|
+
>
|
|
528
|
+
${Array.from({ length: this.count }, (_, index) => html `<span class="item">
|
|
529
|
+
${this.renderIcon(Math.min(1, Math.max(0, (value ?? 0) - index)))}
|
|
530
|
+
</span>`)}
|
|
531
|
+
</div>
|
|
532
|
+
`;
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* Renders the clear button, once a rating is picked and can be changed.
|
|
536
|
+
* @private
|
|
537
|
+
*/
|
|
538
|
+
renderClear() {
|
|
539
|
+
if (!this.clearable || this.value === undefined || this.locked) {
|
|
540
|
+
return nothing;
|
|
541
|
+
}
|
|
542
|
+
return html `
|
|
543
|
+
<button
|
|
544
|
+
type="button"
|
|
545
|
+
id="clear"
|
|
546
|
+
part="clear"
|
|
547
|
+
aria-label=${this.clearLabel ?? this.dictionary.rating.clear}
|
|
548
|
+
@click=${this.handleClear}
|
|
549
|
+
>
|
|
550
|
+
<eun-icon name="close" aria-hidden="true"></eun-icon>
|
|
551
|
+
</button>
|
|
552
|
+
`;
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* Renders the rating template.
|
|
556
|
+
* @returns The rendered HTML template
|
|
557
|
+
*/
|
|
558
|
+
render() {
|
|
559
|
+
if (this.displayOnly) {
|
|
560
|
+
return html `<div id="wrapper">${this.renderDisplay()}</div>`;
|
|
561
|
+
}
|
|
562
|
+
const description = this.renderDescription();
|
|
563
|
+
const describedBy = [
|
|
564
|
+
this.instructions ? "group-instructions" : "",
|
|
565
|
+
description === nothing ? "" : "description",
|
|
566
|
+
]
|
|
567
|
+
.filter(Boolean)
|
|
568
|
+
.join(" ") || undefined;
|
|
569
|
+
const shown = this.hoverValue ?? this.value ?? 0;
|
|
570
|
+
return html `
|
|
571
|
+
<div id="wrapper">
|
|
572
|
+
${this.renderFormLabels()}
|
|
573
|
+
${this.instructions
|
|
574
|
+
? html `<span id="group-instructions" hidden
|
|
575
|
+
>${this.instructions}</span
|
|
576
|
+
>`
|
|
577
|
+
: nothing}
|
|
578
|
+
<div id="control">
|
|
579
|
+
<div
|
|
580
|
+
id="items"
|
|
581
|
+
part="items"
|
|
582
|
+
role="radiogroup"
|
|
583
|
+
class=${classMap({ preview: this.hoverValue !== undefined })}
|
|
584
|
+
aria-label=${this.label || this.dictionary.rating.label}
|
|
585
|
+
aria-describedby=${ifDefined(describedBy)}
|
|
586
|
+
aria-required=${this.required ? "true" : nothing}
|
|
587
|
+
aria-readonly=${this.readonly ? "true" : nothing}
|
|
588
|
+
aria-disabled=${this.disabled ? "true" : nothing}
|
|
589
|
+
aria-invalid=${this.showError ? "true" : "false"}
|
|
590
|
+
@click=${this.handleClick}
|
|
591
|
+
@change=${this.handleChange}
|
|
592
|
+
@keydown=${this.handleKeydown}
|
|
593
|
+
@pointermove=${this.handlePointerMove}
|
|
594
|
+
@pointerleave=${this.handlePointerLeave}
|
|
595
|
+
>
|
|
596
|
+
${Array.from({ length: this.count }, (_, index) => {
|
|
597
|
+
const item = index + 1;
|
|
598
|
+
return html `
|
|
599
|
+
<span class="item" data-index=${item}>
|
|
600
|
+
${this.renderIcon(Math.min(1, Math.max(0, shown - index)))}
|
|
601
|
+
${this.resolvedStep === 0.5
|
|
602
|
+
? this.renderRadio(item - 0.5)
|
|
603
|
+
: nothing}
|
|
604
|
+
${this.renderRadio(item)}
|
|
605
|
+
</span>
|
|
606
|
+
`;
|
|
607
|
+
})}
|
|
608
|
+
</div>
|
|
609
|
+
${this.renderClear()}
|
|
610
|
+
</div>
|
|
611
|
+
${description}
|
|
612
|
+
</div>
|
|
613
|
+
`;
|
|
614
|
+
}
|
|
615
|
+
};
|
|
616
|
+
/**
|
|
617
|
+
* Styles to import to the component.
|
|
618
|
+
*
|
|
619
|
+
* @static
|
|
620
|
+
* @internal
|
|
621
|
+
* @readonly
|
|
622
|
+
*/
|
|
623
|
+
EunomiaRating.styles = [
|
|
624
|
+
ratingStyles,
|
|
625
|
+
formLabelsStyles.base,
|
|
626
|
+
formLabelsStyles.errorMessages,
|
|
627
|
+
formLabelsStyles.hintMessages,
|
|
628
|
+
];
|
|
629
|
+
__decorate([
|
|
630
|
+
property({ type: Number })
|
|
631
|
+
], EunomiaRating.prototype, "max", void 0);
|
|
632
|
+
__decorate([
|
|
633
|
+
property({ type: Number })
|
|
634
|
+
], EunomiaRating.prototype, "step", void 0);
|
|
635
|
+
__decorate([
|
|
636
|
+
property({ type: Boolean, attribute: "display-only", reflect: true })
|
|
637
|
+
], EunomiaRating.prototype, "displayOnly", void 0);
|
|
638
|
+
__decorate([
|
|
639
|
+
property({ type: Boolean, reflect: true })
|
|
640
|
+
], EunomiaRating.prototype, "clearable", void 0);
|
|
641
|
+
__decorate([
|
|
642
|
+
property({ attribute: "clear-label" })
|
|
643
|
+
], EunomiaRating.prototype, "clearLabel", void 0);
|
|
644
|
+
__decorate([
|
|
645
|
+
property()
|
|
646
|
+
], EunomiaRating.prototype, "icon", void 0);
|
|
647
|
+
__decorate([
|
|
648
|
+
property({ attribute: "empty-icon" })
|
|
649
|
+
], EunomiaRating.prototype, "emptyIcon", void 0);
|
|
650
|
+
__decorate([
|
|
651
|
+
state()
|
|
652
|
+
], EunomiaRating.prototype, "hoverValue", void 0);
|
|
653
|
+
__decorate([
|
|
654
|
+
property({ type: Number })
|
|
655
|
+
], EunomiaRating.prototype, "value", null);
|
|
656
|
+
__decorate([
|
|
657
|
+
property({ attribute: "default-value", type: Number })
|
|
658
|
+
], EunomiaRating.prototype, "defaultValue", null);
|
|
659
|
+
__decorate([
|
|
660
|
+
query("#items")
|
|
661
|
+
], EunomiaRating.prototype, "itemsEl", void 0);
|
|
662
|
+
EunomiaRating = __decorate([
|
|
663
|
+
customElement(EunomiaRatingTagName)
|
|
664
|
+
], EunomiaRating);
|
|
665
|
+
export { EunomiaRating };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const ratingStyles: import("lit").CSSResult;
|