le-kit 0.5.2 → 0.5.3
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/LLM_CONTEXT.md +22 -0
- package/dist/cjs/le-bar_16.cjs.entry.js +945 -1257
- package/dist/cjs/le-box.cjs.entry.js +40 -88
- package/dist/cjs/le-breadcrumbs.cjs.entry.js +223 -0
- package/dist/cjs/le-card.cjs.entry.js +11 -11
- package/dist/cjs/le-code-input.cjs.entry.js +76 -110
- package/dist/cjs/le-combobox.cjs.entry.js +126 -153
- package/dist/cjs/le-header-placeholder.cjs.entry.js +1 -1
- package/dist/cjs/le-kit.cjs.js +1 -1
- package/dist/cjs/le-multiselect.cjs.entry.js +149 -171
- package/dist/cjs/le-number-input.cjs.entry.js +89 -129
- package/dist/cjs/le-round-progress.cjs.entry.js +6 -11
- package/dist/cjs/le-segmented-control.cjs.entry.js +77 -87
- package/dist/cjs/le-side-panel-toggle.cjs.entry.js +59 -75
- package/dist/cjs/le-side-panel.cjs.entry.js +130 -137
- package/dist/cjs/le-stack.cjs.entry.js +38 -51
- package/dist/cjs/le-tab-bar.cjs.entry.js +80 -89
- package/dist/cjs/le-tab-panel.cjs.entry.js +21 -39
- package/dist/cjs/le-tab.cjs.entry.js +53 -91
- package/dist/cjs/le-tabs.cjs.entry.js +112 -122
- package/dist/cjs/le-tag.cjs.entry.js +23 -40
- package/dist/cjs/le-text.cjs.entry.js +131 -148
- package/dist/cjs/le-turntable.cjs.entry.js +17 -25
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/collection/collection-manifest.json +1 -0
- package/dist/collection/components/le-bar/le-bar.js +132 -139
- package/dist/collection/components/le-bar/le-bar.js.map +1 -1
- package/dist/collection/components/le-box/le-box.js +41 -88
- package/dist/collection/components/le-box/le-box.js.map +1 -1
- package/dist/collection/components/le-breadcrumbs/le-breadcrumbs.css +72 -0
- package/dist/collection/components/le-breadcrumbs/le-breadcrumbs.js +372 -0
- package/dist/collection/components/le-breadcrumbs/le-breadcrumbs.js.map +1 -0
- package/dist/collection/components/le-button/le-button.js +50 -79
- package/dist/collection/components/le-button/le-button.js.map +1 -1
- package/dist/collection/components/le-card/le-card.js +12 -11
- package/dist/collection/components/le-card/le-card.js.map +1 -1
- package/dist/collection/components/le-checkbox/le-checkbox.js +27 -42
- package/dist/collection/components/le-checkbox/le-checkbox.js.map +1 -1
- package/dist/collection/components/le-code-input/le-code-input.js +77 -110
- package/dist/collection/components/le-code-input/le-code-input.js.map +1 -1
- package/dist/collection/components/le-collapse/le-collapse.js +15 -14
- package/dist/collection/components/le-collapse/le-collapse.js.map +1 -1
- package/dist/collection/components/le-combobox/le-combobox.js +127 -153
- package/dist/collection/components/le-combobox/le-combobox.js.map +1 -1
- package/dist/collection/components/le-component/le-component.js +14 -38
- package/dist/collection/components/le-component/le-component.js.map +1 -1
- package/dist/collection/components/le-current-heading/le-current-heading.js +6 -5
- package/dist/collection/components/le-current-heading/le-current-heading.js.map +1 -1
- package/dist/collection/components/le-dropdown-base/le-dropdown-base.js +139 -165
- package/dist/collection/components/le-dropdown-base/le-dropdown-base.js.map +1 -1
- package/dist/collection/components/le-header/le-header.js +22 -45
- package/dist/collection/components/le-header/le-header.js.map +1 -1
- package/dist/collection/components/le-header-placeholder/le-header-placeholder.js +1 -1
- package/dist/collection/components/le-icon/le-icon.js +14 -14
- package/dist/collection/components/le-icon/le-icon.js.map +1 -1
- package/dist/collection/components/le-multiselect/le-multiselect.js +150 -171
- package/dist/collection/components/le-multiselect/le-multiselect.js.map +1 -1
- package/dist/collection/components/le-navigation/le-navigation.js +118 -128
- package/dist/collection/components/le-navigation/le-navigation.js.map +1 -1
- package/dist/collection/components/le-number-input/le-number-input.js +90 -129
- package/dist/collection/components/le-number-input/le-number-input.js.map +1 -1
- package/dist/collection/components/le-popover/le-popover.css +2 -1
- package/dist/collection/components/le-popover/le-popover.js +101 -126
- package/dist/collection/components/le-popover/le-popover.js.map +1 -1
- package/dist/collection/components/le-popup/le-popup.js +89 -115
- package/dist/collection/components/le-popup/le-popup.js.map +1 -1
- package/dist/collection/components/le-round-progress/le-round-progress.js +7 -12
- package/dist/collection/components/le-round-progress/le-round-progress.js.map +1 -1
- package/dist/collection/components/le-scroll-progress/le-scroll-progress.js +6 -7
- package/dist/collection/components/le-scroll-progress/le-scroll-progress.js.map +1 -1
- package/dist/collection/components/le-segmented-control/le-segmented-control.js +78 -87
- package/dist/collection/components/le-segmented-control/le-segmented-control.js.map +1 -1
- package/dist/collection/components/le-select/le-select.js +88 -110
- package/dist/collection/components/le-select/le-select.js.map +1 -1
- package/dist/collection/components/le-side-panel/le-side-panel.css +10 -1
- package/dist/collection/components/le-side-panel/le-side-panel.js +131 -136
- package/dist/collection/components/le-side-panel/le-side-panel.js.map +1 -1
- package/dist/collection/components/le-side-panel-toggle/le-side-panel-toggle.js +60 -75
- package/dist/collection/components/le-side-panel-toggle/le-side-panel-toggle.js.map +1 -1
- package/dist/collection/components/le-slot/le-slot.js +96 -144
- package/dist/collection/components/le-slot/le-slot.js.map +1 -1
- package/dist/collection/components/le-stack/le-stack.js +39 -51
- package/dist/collection/components/le-stack/le-stack.js.map +1 -1
- package/dist/collection/components/le-string-input/le-string-input.js +41 -84
- package/dist/collection/components/le-string-input/le-string-input.js.map +1 -1
- package/dist/collection/components/le-tab/le-tab.js +54 -91
- package/dist/collection/components/le-tab/le-tab.js.map +1 -1
- package/dist/collection/components/le-tab-bar/le-tab-bar.js +81 -89
- package/dist/collection/components/le-tab-bar/le-tab-bar.js.map +1 -1
- package/dist/collection/components/le-tab-panel/le-tab-panel.js +22 -39
- package/dist/collection/components/le-tab-panel/le-tab-panel.js.map +1 -1
- package/dist/collection/components/le-tabs/le-tabs.js +113 -122
- package/dist/collection/components/le-tabs/le-tabs.js.map +1 -1
- package/dist/collection/components/le-tag/le-tag.js +25 -40
- package/dist/collection/components/le-tag/le-tag.js.map +1 -1
- package/dist/collection/components/le-text/le-text.js +132 -148
- package/dist/collection/components/le-text/le-text.js.map +1 -1
- package/dist/collection/components/le-turntable/le-turntable.js +18 -26
- package/dist/collection/components/le-turntable/le-turntable.js.map +1 -1
- package/dist/collection/dist/components/assets/custom-elements.json +973 -645
- package/dist/collection/dist/components/assets/icons/arrow-left.json +21 -0
- package/dist/collection/dist/components/assets/icons/arrow-right.json +21 -0
- package/dist/collection/dist/components/assets/icons/check.json +12 -0
- package/dist/collection/dist/components/assets/icons/chevron-down.json +1 -2
- package/dist/collection/dist/components/assets/icons/chevron-left.json +12 -0
- package/dist/collection/dist/components/assets/icons/chevron-right.json +12 -0
- package/dist/collection/dist/components/assets/icons/chevron-up.json +12 -0
- package/dist/components/assets/custom-elements.json +973 -645
- package/dist/components/assets/icons/arrow-left.json +21 -0
- package/dist/components/assets/icons/arrow-right.json +21 -0
- package/dist/components/assets/icons/check.json +12 -0
- package/dist/components/assets/icons/chevron-down.json +1 -2
- package/dist/components/assets/icons/chevron-left.json +12 -0
- package/dist/components/assets/icons/chevron-right.json +12 -0
- package/dist/components/assets/icons/chevron-up.json +12 -0
- package/dist/components/le-bar2.js +132 -140
- package/dist/components/le-bar2.js.map +1 -1
- package/dist/components/le-box.js +41 -89
- package/dist/components/le-box.js.map +1 -1
- package/dist/components/le-breadcrumbs.d.ts +11 -0
- package/dist/components/le-breadcrumbs.js +327 -0
- package/dist/components/le-breadcrumbs.js.map +1 -0
- package/dist/components/le-button2.js +405 -619
- package/dist/components/le-button2.js.map +1 -1
- package/dist/components/le-card.js +12 -12
- package/dist/components/le-card.js.map +1 -1
- package/dist/components/le-code-input.js +77 -111
- package/dist/components/le-code-input.js.map +1 -1
- package/dist/components/le-collapse2.js +15 -15
- package/dist/components/le-collapse2.js.map +1 -1
- package/dist/components/le-combobox.js +127 -154
- package/dist/components/le-combobox.js.map +1 -1
- package/dist/components/le-current-heading.js +6 -6
- package/dist/components/le-current-heading.js.map +1 -1
- package/dist/components/le-dropdown-base2.js +139 -166
- package/dist/components/le-dropdown-base2.js.map +1 -1
- package/dist/components/le-header-placeholder.js +1 -1
- package/dist/components/le-header.js +22 -46
- package/dist/components/le-header.js.map +1 -1
- package/dist/components/le-icon2.js +14 -15
- package/dist/components/le-icon2.js.map +1 -1
- package/dist/components/le-multiselect.js +150 -172
- package/dist/components/le-multiselect.js.map +1 -1
- package/dist/components/le-navigation.js +1 -494
- package/dist/components/le-navigation.js.map +1 -1
- package/dist/components/le-navigation2.js +488 -0
- package/dist/components/le-navigation2.js.map +1 -0
- package/dist/components/le-number-input.js +90 -130
- package/dist/components/le-number-input.js.map +1 -1
- package/dist/components/le-popover2.js +103 -128
- package/dist/components/le-popover2.js.map +1 -1
- package/dist/components/le-round-progress.js +7 -12
- package/dist/components/le-round-progress.js.map +1 -1
- package/dist/components/le-scroll-progress.js +6 -8
- package/dist/components/le-scroll-progress.js.map +1 -1
- package/dist/components/le-segmented-control.js +78 -88
- package/dist/components/le-segmented-control.js.map +1 -1
- package/dist/components/le-side-panel-toggle2.js +60 -76
- package/dist/components/le-side-panel-toggle2.js.map +1 -1
- package/dist/components/le-side-panel.js +133 -139
- package/dist/components/le-side-panel.js.map +1 -1
- package/dist/components/le-stack.js +39 -52
- package/dist/components/le-stack.js.map +1 -1
- package/dist/components/le-tab-bar.js +81 -90
- package/dist/components/le-tab-bar.js.map +1 -1
- package/dist/components/le-tab-panel.js +22 -40
- package/dist/components/le-tab-panel.js.map +1 -1
- package/dist/components/le-tab2.js +54 -92
- package/dist/components/le-tab2.js.map +1 -1
- package/dist/components/le-tabs.js +113 -123
- package/dist/components/le-tabs.js.map +1 -1
- package/dist/components/le-tag2.js +24 -41
- package/dist/components/le-tag2.js.map +1 -1
- package/dist/components/le-text.js +132 -149
- package/dist/components/le-text.js.map +1 -1
- package/dist/components/le-turntable.js +18 -26
- package/dist/components/le-turntable.js.map +1 -1
- package/dist/docs.json +294 -2
- package/dist/esm/le-bar_16.entry.js +946 -1258
- package/dist/esm/le-box.entry.js +41 -89
- package/dist/esm/le-box.entry.js.map +1 -1
- package/dist/esm/le-breadcrumbs.entry.js +221 -0
- package/dist/esm/le-breadcrumbs.entry.js.map +1 -0
- package/dist/esm/le-card.entry.js +12 -12
- package/dist/esm/le-card.entry.js.map +1 -1
- package/dist/esm/le-code-input.entry.js +77 -111
- package/dist/esm/le-code-input.entry.js.map +1 -1
- package/dist/esm/le-combobox.entry.js +127 -154
- package/dist/esm/le-combobox.entry.js.map +1 -1
- package/dist/esm/le-header-placeholder.entry.js +1 -1
- package/dist/esm/le-kit.js +1 -1
- package/dist/esm/le-multiselect.entry.js +150 -172
- package/dist/esm/le-multiselect.entry.js.map +1 -1
- package/dist/esm/le-number-input.entry.js +90 -130
- package/dist/esm/le-number-input.entry.js.map +1 -1
- package/dist/esm/le-round-progress.entry.js +7 -12
- package/dist/esm/le-round-progress.entry.js.map +1 -1
- package/dist/esm/le-segmented-control.entry.js +78 -88
- package/dist/esm/le-segmented-control.entry.js.map +1 -1
- package/dist/esm/le-side-panel-toggle.entry.js +60 -76
- package/dist/esm/le-side-panel-toggle.entry.js.map +1 -1
- package/dist/esm/le-side-panel.entry.js +131 -138
- package/dist/esm/le-side-panel.entry.js.map +1 -1
- package/dist/esm/le-stack.entry.js +39 -52
- package/dist/esm/le-stack.entry.js.map +1 -1
- package/dist/esm/le-tab-bar.entry.js +81 -90
- package/dist/esm/le-tab-bar.entry.js.map +1 -1
- package/dist/esm/le-tab-panel.entry.js +22 -40
- package/dist/esm/le-tab-panel.entry.js.map +1 -1
- package/dist/esm/le-tab.entry.js +54 -92
- package/dist/esm/le-tab.entry.js.map +1 -1
- package/dist/esm/le-tabs.entry.js +113 -123
- package/dist/esm/le-tabs.entry.js.map +1 -1
- package/dist/esm/le-tag.entry.js +23 -40
- package/dist/esm/le-tag.entry.js.map +1 -1
- package/dist/esm/le-text.entry.js +132 -149
- package/dist/esm/le-text.entry.js.map +1 -1
- package/dist/esm/le-turntable.entry.js +18 -26
- package/dist/esm/le-turntable.entry.js.map +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/le-kit/dist/components/assets/custom-elements.json +973 -645
- package/dist/le-kit/dist/components/assets/icons/arrow-left.json +21 -0
- package/dist/le-kit/dist/components/assets/icons/arrow-right.json +21 -0
- package/dist/le-kit/dist/components/assets/icons/check.json +12 -0
- package/dist/le-kit/dist/components/assets/icons/chevron-down.json +1 -2
- package/dist/le-kit/dist/components/assets/icons/chevron-left.json +12 -0
- package/dist/le-kit/dist/components/assets/icons/chevron-right.json +12 -0
- package/dist/le-kit/dist/components/assets/icons/chevron-up.json +12 -0
- package/dist/le-kit/le-kit.esm.js +1 -1
- package/dist/le-kit/p-3067b18f.entry.js +2 -0
- package/dist/le-kit/p-3067b18f.entry.js.map +1 -0
- package/dist/le-kit/p-34c4d97d.entry.js +2 -0
- package/dist/le-kit/p-34c4d97d.entry.js.map +1 -0
- package/dist/le-kit/p-45182541.entry.js +2 -0
- package/dist/le-kit/p-45182541.entry.js.map +1 -0
- package/dist/le-kit/p-52a41c96.entry.js +2 -0
- package/dist/le-kit/p-52a41c96.entry.js.map +1 -0
- package/dist/le-kit/p-55fb5dd2.entry.js +2 -0
- package/dist/le-kit/p-55fb5dd2.entry.js.map +1 -0
- package/dist/le-kit/{p-ab6c1def.entry.js → p-649025f4.entry.js} +2 -2
- package/dist/le-kit/p-649025f4.entry.js.map +1 -0
- package/dist/le-kit/p-67930309.entry.js +2 -0
- package/dist/le-kit/p-67930309.entry.js.map +1 -0
- package/dist/le-kit/p-6d222705.entry.js +2 -0
- package/dist/le-kit/p-6d222705.entry.js.map +1 -0
- package/dist/le-kit/p-8049e0c2.entry.js +2 -0
- package/dist/le-kit/p-8049e0c2.entry.js.map +1 -0
- package/dist/le-kit/p-884f57bd.entry.js +2 -0
- package/dist/le-kit/p-88c70f9d.entry.js +2 -0
- package/dist/le-kit/p-88c70f9d.entry.js.map +1 -0
- package/dist/le-kit/p-96610729.entry.js +2 -0
- package/dist/le-kit/p-96610729.entry.js.map +1 -0
- package/dist/le-kit/p-a34054e0.entry.js +2 -0
- package/dist/le-kit/p-a34054e0.entry.js.map +1 -0
- package/dist/le-kit/p-a388e46a.entry.js +2 -0
- package/dist/le-kit/p-a388e46a.entry.js.map +1 -0
- package/dist/le-kit/p-c0c53650.entry.js +2 -0
- package/dist/le-kit/p-c0c53650.entry.js.map +1 -0
- package/dist/le-kit/p-cbf17514.entry.js +2 -0
- package/dist/le-kit/p-cbf17514.entry.js.map +1 -0
- package/dist/le-kit/p-d934de74.entry.js +2 -0
- package/dist/le-kit/p-d934de74.entry.js.map +1 -0
- package/dist/le-kit/p-de72c8b5.entry.js +2 -0
- package/dist/le-kit/p-de72c8b5.entry.js.map +1 -0
- package/dist/le-kit/p-e3dd0f2a.entry.js +2 -0
- package/dist/le-kit/p-e3dd0f2a.entry.js.map +1 -0
- package/dist/le-kit/p-ee170967.entry.js +2 -0
- package/dist/le-kit/p-ee170967.entry.js.map +1 -0
- package/dist/le-kit/p-eedb2f75.entry.js +2 -0
- package/dist/le-kit/p-eedb2f75.entry.js.map +1 -0
- package/dist/types/components/le-breadcrumbs/le-breadcrumbs.d.ts +57 -0
- package/dist/types/components/le-side-panel/le-side-panel.d.ts +2 -0
- package/dist/types/components.d.ts +84 -0
- package/package.json +1 -1
- package/dist/collection/assets/icons/chevron-down.svg +0 -3
- package/dist/collection/dist/components/assets/icons/chevron-down.svg +0 -3
- package/dist/components/assets/icons/chevron-down.svg +0 -3
- package/dist/le-kit/dist/components/assets/icons/chevron-down.svg +0 -3
- package/dist/le-kit/p-221d379a.entry.js +0 -2
- package/dist/le-kit/p-221d379a.entry.js.map +0 -1
- package/dist/le-kit/p-24112ca3.entry.js +0 -2
- package/dist/le-kit/p-24112ca3.entry.js.map +0 -1
- package/dist/le-kit/p-2c6d080d.entry.js +0 -2
- package/dist/le-kit/p-2c6d080d.entry.js.map +0 -1
- package/dist/le-kit/p-46276e77.entry.js +0 -2
- package/dist/le-kit/p-46276e77.entry.js.map +0 -1
- package/dist/le-kit/p-516c8531.entry.js +0 -2
- package/dist/le-kit/p-6ae60ba5.entry.js +0 -2
- package/dist/le-kit/p-6ae60ba5.entry.js.map +0 -1
- package/dist/le-kit/p-6b69f9a2.entry.js +0 -2
- package/dist/le-kit/p-6b69f9a2.entry.js.map +0 -1
- package/dist/le-kit/p-6d14306f.entry.js +0 -2
- package/dist/le-kit/p-6d14306f.entry.js.map +0 -1
- package/dist/le-kit/p-7bcdf2d4.entry.js +0 -2
- package/dist/le-kit/p-7bcdf2d4.entry.js.map +0 -1
- package/dist/le-kit/p-7cf1e23c.entry.js +0 -2
- package/dist/le-kit/p-7cf1e23c.entry.js.map +0 -1
- package/dist/le-kit/p-85f2fd4d.entry.js +0 -2
- package/dist/le-kit/p-85f2fd4d.entry.js.map +0 -1
- package/dist/le-kit/p-98242429.entry.js +0 -2
- package/dist/le-kit/p-98242429.entry.js.map +0 -1
- package/dist/le-kit/p-ab6c1def.entry.js.map +0 -1
- package/dist/le-kit/p-ae4ead64.entry.js +0 -2
- package/dist/le-kit/p-ae4ead64.entry.js.map +0 -1
- package/dist/le-kit/p-b05d4511.entry.js +0 -2
- package/dist/le-kit/p-b05d4511.entry.js.map +0 -1
- package/dist/le-kit/p-b6ac02ff.entry.js +0 -2
- package/dist/le-kit/p-b6ac02ff.entry.js.map +0 -1
- package/dist/le-kit/p-c24769e2.entry.js +0 -2
- package/dist/le-kit/p-c24769e2.entry.js.map +0 -1
- package/dist/le-kit/p-dc0445ad.entry.js +0 -2
- package/dist/le-kit/p-dc0445ad.entry.js.map +0 -1
- package/dist/le-kit/p-eb5286f2.entry.js +0 -2
- package/dist/le-kit/p-eb5286f2.entry.js.map +0 -1
- package/dist/le-kit/p-f78b1ee6.entry.js +0 -2
- package/dist/le-kit/p-f78b1ee6.entry.js.map +0 -1
- /package/dist/le-kit/{p-516c8531.entry.js.map → p-884f57bd.entry.js.map} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as registerInstance, c as createEvent,
|
|
1
|
+
import { r as registerInstance, c as createEvent, h, H as Host, a as getElement, F as Fragment, e as getLeKitConfig, f as getAssetPath, i as getAssetBasePath } from './index-DFTm5BqT.js';
|
|
2
2
|
import { g as generateId, c as classnames, o as observeModeChanges } from './utils-DZYCZLrF.js';
|
|
3
3
|
import { leConfirm } from './index.js';
|
|
4
4
|
|
|
@@ -8,71 +8,137 @@ const LeBar = class {
|
|
|
8
8
|
constructor(hostRef) {
|
|
9
9
|
registerInstance(this, hostRef);
|
|
10
10
|
this.leBarOverflowChange = createEvent(this, "leBarOverflowChange");
|
|
11
|
+
/**
|
|
12
|
+
* Overflow behavior when items don't fit on one row.
|
|
13
|
+
* - `more`: Overflow items appear in a "more" dropdown
|
|
14
|
+
* - `scroll`: Items scroll horizontally with optional arrows
|
|
15
|
+
* - `hamburger`: All items go into a hamburger menu if any overflow
|
|
16
|
+
* - `wrap`: Items wrap to additional rows
|
|
17
|
+
*/
|
|
18
|
+
this.overflow = 'more';
|
|
19
|
+
/**
|
|
20
|
+
* Alignment of items within the bar (maps to justify-content).
|
|
21
|
+
*/
|
|
22
|
+
this.alignItems = 'start';
|
|
23
|
+
/**
|
|
24
|
+
* Show scroll arrows when overflow is "scroll".
|
|
25
|
+
*/
|
|
26
|
+
this.arrows = false;
|
|
27
|
+
/**
|
|
28
|
+
* Disable the internal overflow popover.
|
|
29
|
+
* When true, the bar still detects overflow and hides items,
|
|
30
|
+
* but doesn't render its own popover. Use this when providing
|
|
31
|
+
* custom overflow handling via the leBarOverflowChange event.
|
|
32
|
+
*/
|
|
33
|
+
this.disablePopover = false;
|
|
34
|
+
/**
|
|
35
|
+
* Minimum number of visible items required when using "more" overflow mode.
|
|
36
|
+
* If fewer items would be visible, the bar falls back to hamburger mode.
|
|
37
|
+
* Only applies when overflow is "more".
|
|
38
|
+
*/
|
|
39
|
+
this.minVisibleItems = 0;
|
|
40
|
+
/**
|
|
41
|
+
* Show an "all items" menu button.
|
|
42
|
+
* - `false`: Don't show
|
|
43
|
+
* - `true` or `'end'`: Show at end
|
|
44
|
+
* - `'start'`: Show at start
|
|
45
|
+
*/
|
|
46
|
+
this.showAllMenu = false;
|
|
47
|
+
/** Whether the hamburger/more popover is open */
|
|
48
|
+
this.popoverOpen = false;
|
|
49
|
+
/** Whether hamburger mode is active (for hamburger overflow) */
|
|
50
|
+
this.hamburgerActive = false;
|
|
51
|
+
/** IDs of items that are overflowing */
|
|
52
|
+
this.overflowingIds = new Set();
|
|
53
|
+
/** Whether we can scroll left */
|
|
54
|
+
this.canScrollStart = false;
|
|
55
|
+
/** Whether we can scroll right */
|
|
56
|
+
this.canScrollEnd = false;
|
|
57
|
+
/** Whether the all-menu popover is open */
|
|
58
|
+
this.allMenuOpen = false;
|
|
59
|
+
/** Current height of the items container (for overflow handling) */
|
|
60
|
+
this.containerHeight = null;
|
|
61
|
+
this.instanceId = generateId('le-bar');
|
|
62
|
+
// Map to track item elements and their IDs
|
|
63
|
+
this.itemMap = new Map();
|
|
64
|
+
// Prevent multiple recalculations in the same frame
|
|
65
|
+
this.pendingRecalc = null;
|
|
66
|
+
this.handleScroll = () => {
|
|
67
|
+
this.updateScrollState();
|
|
68
|
+
};
|
|
69
|
+
this.scrollToStart = () => {
|
|
70
|
+
if (!this.itemsContainerEl)
|
|
71
|
+
return;
|
|
72
|
+
const items = this.getSlottedItems();
|
|
73
|
+
const container = this.itemsContainerEl;
|
|
74
|
+
// Find the scroll position of the previous item
|
|
75
|
+
const currentScroll = container.scrollLeft;
|
|
76
|
+
let targetScroll = 0;
|
|
77
|
+
for (let i = items.length - 1; i >= 0; i--) {
|
|
78
|
+
const item = items[i];
|
|
79
|
+
// Calculate item's left edge relative to container's scroll position
|
|
80
|
+
const itemLeft = item.offsetLeft - container.offsetLeft;
|
|
81
|
+
// If this item starts before current scroll position, scroll to it
|
|
82
|
+
if (itemLeft < currentScroll - 1) {
|
|
83
|
+
targetScroll = itemLeft;
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
container.scrollTo({ left: targetScroll, behavior: 'smooth' });
|
|
88
|
+
// Update scroll state after animation
|
|
89
|
+
setTimeout(() => this.updateScrollState(), 300);
|
|
90
|
+
};
|
|
91
|
+
this.scrollToEnd = () => {
|
|
92
|
+
if (!this.itemsContainerEl)
|
|
93
|
+
return;
|
|
94
|
+
const container = this.itemsContainerEl;
|
|
95
|
+
const items = this.getSlottedItems();
|
|
96
|
+
if (items.length === 0)
|
|
97
|
+
return;
|
|
98
|
+
const containerWidth = container.clientWidth;
|
|
99
|
+
const currentScroll = container.scrollLeft;
|
|
100
|
+
let targetScroll = container.scrollWidth - containerWidth;
|
|
101
|
+
for (const item of items) {
|
|
102
|
+
// Calculate item's right edge relative to container
|
|
103
|
+
const itemLeft = item.offsetLeft - container.offsetLeft;
|
|
104
|
+
// If this is the next item to scroll to from left to right then scroll to it
|
|
105
|
+
if (itemLeft > currentScroll + 1) {
|
|
106
|
+
targetScroll = itemLeft;
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
container.scrollTo({ left: Math.max(0, targetScroll), behavior: 'smooth' });
|
|
111
|
+
// Update scroll state after animation
|
|
112
|
+
setTimeout(() => this.updateScrollState(), 300);
|
|
113
|
+
};
|
|
114
|
+
this.togglePopover = () => {
|
|
115
|
+
this.popoverOpen = !this.popoverOpen;
|
|
116
|
+
};
|
|
117
|
+
this.closePopover = () => {
|
|
118
|
+
this.popoverOpen = false;
|
|
119
|
+
};
|
|
120
|
+
this.toggleAllMenu = () => {
|
|
121
|
+
this.allMenuOpen = !this.allMenuOpen;
|
|
122
|
+
};
|
|
123
|
+
this.closeAllMenu = () => {
|
|
124
|
+
this.allMenuOpen = false;
|
|
125
|
+
};
|
|
126
|
+
this.handleItemClick = (_e, id) => {
|
|
127
|
+
// Close popover when an item inside is clicked
|
|
128
|
+
const originalItem = this.itemMap.get(id);
|
|
129
|
+
if (originalItem) {
|
|
130
|
+
// Clone the click to the original item
|
|
131
|
+
const cloneEvent = new MouseEvent('click', {
|
|
132
|
+
bubbles: true,
|
|
133
|
+
cancelable: true,
|
|
134
|
+
view: window,
|
|
135
|
+
});
|
|
136
|
+
originalItem.dispatchEvent(cloneEvent);
|
|
137
|
+
}
|
|
138
|
+
this.closePopover();
|
|
139
|
+
this.closeAllMenu();
|
|
140
|
+
};
|
|
11
141
|
}
|
|
12
|
-
get el() { return getElement(this); }
|
|
13
|
-
/**
|
|
14
|
-
* Overflow behavior when items don't fit on one row.
|
|
15
|
-
* - `more`: Overflow items appear in a "more" dropdown
|
|
16
|
-
* - `scroll`: Items scroll horizontally with optional arrows
|
|
17
|
-
* - `hamburger`: All items go into a hamburger menu if any overflow
|
|
18
|
-
* - `wrap`: Items wrap to additional rows
|
|
19
|
-
*/
|
|
20
|
-
overflow = 'more';
|
|
21
|
-
/**
|
|
22
|
-
* Alignment of items within the bar (maps to justify-content).
|
|
23
|
-
*/
|
|
24
|
-
alignItems = 'start';
|
|
25
|
-
/**
|
|
26
|
-
* Show scroll arrows when overflow is "scroll".
|
|
27
|
-
*/
|
|
28
|
-
arrows = false;
|
|
29
|
-
/**
|
|
30
|
-
* Disable the internal overflow popover.
|
|
31
|
-
* When true, the bar still detects overflow and hides items,
|
|
32
|
-
* but doesn't render its own popover. Use this when providing
|
|
33
|
-
* custom overflow handling via the leBarOverflowChange event.
|
|
34
|
-
*/
|
|
35
|
-
disablePopover = false;
|
|
36
|
-
/**
|
|
37
|
-
* Minimum number of visible items required when using "more" overflow mode.
|
|
38
|
-
* If fewer items would be visible, the bar falls back to hamburger mode.
|
|
39
|
-
* Only applies when overflow is "more".
|
|
40
|
-
*/
|
|
41
|
-
minVisibleItems = 0;
|
|
42
|
-
/**
|
|
43
|
-
* Show an "all items" menu button.
|
|
44
|
-
* - `false`: Don't show
|
|
45
|
-
* - `true` or `'end'`: Show at end
|
|
46
|
-
* - `'start'`: Show at start
|
|
47
|
-
*/
|
|
48
|
-
showAllMenu = false;
|
|
49
|
-
/**
|
|
50
|
-
* Emitted when overflow state changes.
|
|
51
|
-
*/
|
|
52
|
-
leBarOverflowChange;
|
|
53
|
-
/** Whether the hamburger/more popover is open */
|
|
54
|
-
popoverOpen = false;
|
|
55
|
-
/** Whether hamburger mode is active (for hamburger overflow) */
|
|
56
|
-
hamburgerActive = false;
|
|
57
|
-
/** IDs of items that are overflowing */
|
|
58
|
-
overflowingIds = new Set();
|
|
59
|
-
/** Whether we can scroll left */
|
|
60
|
-
canScrollStart = false;
|
|
61
|
-
/** Whether we can scroll right */
|
|
62
|
-
canScrollEnd = false;
|
|
63
|
-
/** Whether the all-menu popover is open */
|
|
64
|
-
allMenuOpen = false;
|
|
65
|
-
/** Current height of the items container (for overflow handling) */
|
|
66
|
-
containerHeight = null;
|
|
67
|
-
itemsContainerEl;
|
|
68
|
-
moreButtonEl;
|
|
69
|
-
resizeObserver;
|
|
70
|
-
mutationObserver;
|
|
71
|
-
instanceId = generateId('le-bar');
|
|
72
|
-
// Map to track item elements and their IDs
|
|
73
|
-
itemMap = new Map();
|
|
74
|
-
// Prevent multiple recalculations in the same frame
|
|
75
|
-
pendingRecalc = null;
|
|
76
142
|
handleOverflowChange() {
|
|
77
143
|
this.resetOverflowState();
|
|
78
144
|
this.scheduleOverflowRecalc();
|
|
@@ -279,81 +345,6 @@ const LeBar = class {
|
|
|
279
345
|
this.canScrollStart = el.scrollLeft > 0;
|
|
280
346
|
this.canScrollEnd = el.scrollLeft < el.scrollWidth - el.clientWidth - 1;
|
|
281
347
|
}
|
|
282
|
-
handleScroll = () => {
|
|
283
|
-
this.updateScrollState();
|
|
284
|
-
};
|
|
285
|
-
scrollToStart = () => {
|
|
286
|
-
if (!this.itemsContainerEl)
|
|
287
|
-
return;
|
|
288
|
-
const items = this.getSlottedItems();
|
|
289
|
-
const container = this.itemsContainerEl;
|
|
290
|
-
// Find the scroll position of the previous item
|
|
291
|
-
const currentScroll = container.scrollLeft;
|
|
292
|
-
let targetScroll = 0;
|
|
293
|
-
for (let i = items.length - 1; i >= 0; i--) {
|
|
294
|
-
const item = items[i];
|
|
295
|
-
// Calculate item's left edge relative to container's scroll position
|
|
296
|
-
const itemLeft = item.offsetLeft - container.offsetLeft;
|
|
297
|
-
// If this item starts before current scroll position, scroll to it
|
|
298
|
-
if (itemLeft < currentScroll - 1) {
|
|
299
|
-
targetScroll = itemLeft;
|
|
300
|
-
break;
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
container.scrollTo({ left: targetScroll, behavior: 'smooth' });
|
|
304
|
-
// Update scroll state after animation
|
|
305
|
-
setTimeout(() => this.updateScrollState(), 300);
|
|
306
|
-
};
|
|
307
|
-
scrollToEnd = () => {
|
|
308
|
-
if (!this.itemsContainerEl)
|
|
309
|
-
return;
|
|
310
|
-
const container = this.itemsContainerEl;
|
|
311
|
-
const items = this.getSlottedItems();
|
|
312
|
-
if (items.length === 0)
|
|
313
|
-
return;
|
|
314
|
-
const containerWidth = container.clientWidth;
|
|
315
|
-
const currentScroll = container.scrollLeft;
|
|
316
|
-
let targetScroll = container.scrollWidth - containerWidth;
|
|
317
|
-
for (const item of items) {
|
|
318
|
-
// Calculate item's right edge relative to container
|
|
319
|
-
const itemLeft = item.offsetLeft - container.offsetLeft;
|
|
320
|
-
// If this is the next item to scroll to from left to right then scroll to it
|
|
321
|
-
if (itemLeft > currentScroll + 1) {
|
|
322
|
-
targetScroll = itemLeft;
|
|
323
|
-
break;
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
container.scrollTo({ left: Math.max(0, targetScroll), behavior: 'smooth' });
|
|
327
|
-
// Update scroll state after animation
|
|
328
|
-
setTimeout(() => this.updateScrollState(), 300);
|
|
329
|
-
};
|
|
330
|
-
togglePopover = () => {
|
|
331
|
-
this.popoverOpen = !this.popoverOpen;
|
|
332
|
-
};
|
|
333
|
-
closePopover = () => {
|
|
334
|
-
this.popoverOpen = false;
|
|
335
|
-
};
|
|
336
|
-
toggleAllMenu = () => {
|
|
337
|
-
this.allMenuOpen = !this.allMenuOpen;
|
|
338
|
-
};
|
|
339
|
-
closeAllMenu = () => {
|
|
340
|
-
this.allMenuOpen = false;
|
|
341
|
-
};
|
|
342
|
-
handleItemClick = (_e, id) => {
|
|
343
|
-
// Close popover when an item inside is clicked
|
|
344
|
-
const originalItem = this.itemMap.get(id);
|
|
345
|
-
if (originalItem) {
|
|
346
|
-
// Clone the click to the original item
|
|
347
|
-
const cloneEvent = new MouseEvent('click', {
|
|
348
|
-
bubbles: true,
|
|
349
|
-
cancelable: true,
|
|
350
|
-
view: window,
|
|
351
|
-
});
|
|
352
|
-
originalItem.dispatchEvent(cloneEvent);
|
|
353
|
-
}
|
|
354
|
-
this.closePopover();
|
|
355
|
-
this.closeAllMenu();
|
|
356
|
-
};
|
|
357
348
|
renderMoreButton() {
|
|
358
349
|
const hasSlottedMore = this.el.querySelector('[slot="more"]');
|
|
359
350
|
return (h("button", { class: "bar-more-button", part: "more-button", ref: el => (this.moreButtonEl = el), onClick: this.togglePopover, "aria-expanded": String(this.popoverOpen), "aria-haspopup": "true" }, hasSlottedMore ? h("slot", { name: "more" }) : h("le-icon", { name: "ellipsis-horizontal" })));
|
|
@@ -449,6 +440,7 @@ const LeBar = class {
|
|
|
449
440
|
this.observeContainer(el);
|
|
450
441
|
}, onScroll: this.overflow === 'scroll' ? this.handleScroll : undefined }, h("slot", { key: '338698e038b9df4c7b163017ceb0675b834160e4' })), showOverflowButton && (h("div", { key: 'd619fcda1b0c28247af60899f73cc076b0517787', class: "bar-controls bar-controls-end" }, this.renderOverflowPopover())), showAllMenuAtEnd && (h("div", { key: 'fd9fef90194aabb8d48e77c8f7615daa5d7297ac', class: "bar-controls bar-controls-end" }, this.renderAllMenuPopover())), this.overflow === 'scroll' && this.arrows && (h("div", { key: 'bcffb914e2788767c3765351a3eeae771f3e115f', class: "bar-controls bar-controls-end" }, this.renderScrollArrows()?.[1])))));
|
|
451
442
|
}
|
|
443
|
+
get el() { return getElement(this); }
|
|
452
444
|
static get watchers() { return {
|
|
453
445
|
"overflow": ["handleOverflowChange"]
|
|
454
446
|
}; }
|
|
@@ -464,85 +456,54 @@ const LeButton = class {
|
|
|
464
456
|
constructor(hostRef) {
|
|
465
457
|
registerInstance(this, hostRef);
|
|
466
458
|
this.leClick = createEvent(this, "click");
|
|
459
|
+
/**
|
|
460
|
+
* Button variant style
|
|
461
|
+
* @allowedValues solid | outlined | clear
|
|
462
|
+
*/
|
|
463
|
+
this.variant = 'solid';
|
|
464
|
+
/**
|
|
465
|
+
* Button color theme (uses theme semantic colors)
|
|
466
|
+
* @allowedValues primary | secondary | success | warning | danger | info
|
|
467
|
+
*/
|
|
468
|
+
this.color = 'primary';
|
|
469
|
+
/**
|
|
470
|
+
* Button size
|
|
471
|
+
* @allowedValues small | medium | large
|
|
472
|
+
*/
|
|
473
|
+
this.size = 'medium';
|
|
474
|
+
/**
|
|
475
|
+
* Whether the button is in a selected/active state
|
|
476
|
+
*/
|
|
477
|
+
this.selected = false;
|
|
478
|
+
/**
|
|
479
|
+
* Whether the button takes full width of its container
|
|
480
|
+
*/
|
|
481
|
+
this.fullWidth = false;
|
|
482
|
+
/**
|
|
483
|
+
* Whether the button is disabled
|
|
484
|
+
*/
|
|
485
|
+
this.disabled = false;
|
|
486
|
+
/**
|
|
487
|
+
* The button type attribute
|
|
488
|
+
* @allowedValues button | submit | reset
|
|
489
|
+
*/
|
|
490
|
+
this.type = 'button';
|
|
491
|
+
/**
|
|
492
|
+
* Alignment of the button label without the end icon
|
|
493
|
+
* @allowedValues start | center | space-between | end
|
|
494
|
+
*/
|
|
495
|
+
this.align = 'center';
|
|
496
|
+
this.handleClick = (event) => {
|
|
497
|
+
// We stop the internal button click from bubbling up
|
|
498
|
+
event.stopPropagation();
|
|
499
|
+
if (this.disabled) {
|
|
500
|
+
event.preventDefault();
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
// And emit our own click event from the host element
|
|
504
|
+
this.leClick.emit(event);
|
|
505
|
+
};
|
|
467
506
|
}
|
|
468
|
-
get el() { return getElement(this); }
|
|
469
|
-
/**
|
|
470
|
-
* Mode of the popover should be 'default' for internal use
|
|
471
|
-
*/
|
|
472
|
-
mode;
|
|
473
|
-
/**
|
|
474
|
-
* Button variant style
|
|
475
|
-
* @allowedValues solid | outlined | clear
|
|
476
|
-
*/
|
|
477
|
-
variant = 'solid';
|
|
478
|
-
/**
|
|
479
|
-
* Button color theme (uses theme semantic colors)
|
|
480
|
-
* @allowedValues primary | secondary | success | warning | danger | info
|
|
481
|
-
*/
|
|
482
|
-
color = 'primary';
|
|
483
|
-
/**
|
|
484
|
-
* Button size
|
|
485
|
-
* @allowedValues small | medium | large
|
|
486
|
-
*/
|
|
487
|
-
size = 'medium';
|
|
488
|
-
/**
|
|
489
|
-
* Whether the button is in a selected/active state
|
|
490
|
-
*/
|
|
491
|
-
selected = false;
|
|
492
|
-
/**
|
|
493
|
-
* Whether the button takes full width of its container
|
|
494
|
-
*/
|
|
495
|
-
fullWidth = false;
|
|
496
|
-
/**
|
|
497
|
-
* Icon only button image or emoji
|
|
498
|
-
* if this prop is set, the button will render only the icon slot
|
|
499
|
-
*/
|
|
500
|
-
iconOnly;
|
|
501
|
-
/**
|
|
502
|
-
* Start icon image or emoji
|
|
503
|
-
*/
|
|
504
|
-
iconStart;
|
|
505
|
-
/**
|
|
506
|
-
* End icon image or emoji
|
|
507
|
-
*/
|
|
508
|
-
iconEnd;
|
|
509
|
-
/**
|
|
510
|
-
* Whether the button is disabled
|
|
511
|
-
*/
|
|
512
|
-
disabled = false;
|
|
513
|
-
/**
|
|
514
|
-
* The button type attribute
|
|
515
|
-
* @allowedValues button | submit | reset
|
|
516
|
-
*/
|
|
517
|
-
type = 'button';
|
|
518
|
-
/**
|
|
519
|
-
* Optional href to make the button act as a link
|
|
520
|
-
*/
|
|
521
|
-
href;
|
|
522
|
-
/**
|
|
523
|
-
* Link target when href is set
|
|
524
|
-
*/
|
|
525
|
-
target;
|
|
526
|
-
/**
|
|
527
|
-
* Alignment of the button label without the end icon
|
|
528
|
-
* @allowedValues start | center | space-between | end
|
|
529
|
-
*/
|
|
530
|
-
align = 'center';
|
|
531
|
-
/**
|
|
532
|
-
* Emitted when the button is clicked.
|
|
533
|
-
* This is a custom event that wraps the native click but ensures the target is the le-button.
|
|
534
|
-
*/
|
|
535
|
-
leClick;
|
|
536
|
-
handleClick = (event) => {
|
|
537
|
-
// We stop the internal button click from bubbling up
|
|
538
|
-
event.stopPropagation();
|
|
539
|
-
if (this.disabled) {
|
|
540
|
-
event.preventDefault();
|
|
541
|
-
return;
|
|
542
|
-
}
|
|
543
|
-
// And emit our own click event from the host element
|
|
544
|
-
this.leClick.emit(event);
|
|
545
|
-
};
|
|
546
507
|
render() {
|
|
547
508
|
const classes = classnames(`variant-${this.variant}`, `color-${this.color}`, `size-${this.size}`, {
|
|
548
509
|
'selected': this.selected,
|
|
@@ -554,8 +515,9 @@ const LeButton = class {
|
|
|
554
515
|
const attrs = this.href
|
|
555
516
|
? { href: this.href, target: this.target, role: 'button' }
|
|
556
517
|
: { type: this.type, disabled: this.disabled };
|
|
557
|
-
return (h(Host, { key: '
|
|
518
|
+
return (h(Host, { key: '4bf9fb21e9bf0ca5a19193d977ad9fab90b519a0', class: classes }, h("le-component", { key: '8e0edefabbe9196eba935a1e8cce788c686c170c', component: "le-button" }, h(TagType, { key: '30f88ea834a9029c0f8ec24819107ba318dc6397', class: classnames('le-button-container', `le-button-align-${this.align}`), part: "button", ...attrs, onClick: this.handleClick }, this.iconOnly !== undefined ? (h("slot", { name: "icon-only" }, typeof this.iconOnly === 'string' ? this.iconOnly : null)) : (h(Fragment, null, h("span", { class: "le-button-label" }, this.iconStart && (h("span", { class: "icon-start", part: "icon-start" }, this.iconStart)), h("le-slot", { name: "", description: "Button text", type: "text", class: "content", part: "content" }, h("slot", null))), this.iconEnd && (h("span", { class: "icon-end", part: "icon-end" }, this.iconEnd))))))));
|
|
558
519
|
}
|
|
520
|
+
get el() { return getElement(this); }
|
|
559
521
|
};
|
|
560
522
|
LeButton.style = leButtonCss();
|
|
561
523
|
|
|
@@ -565,51 +527,35 @@ const LeCheckbox = class {
|
|
|
565
527
|
constructor(hostRef) {
|
|
566
528
|
registerInstance(this, hostRef);
|
|
567
529
|
this.leChange = createEvent(this, "change");
|
|
530
|
+
/**
|
|
531
|
+
* Whether the checkbox is checked
|
|
532
|
+
*/
|
|
533
|
+
this.checked = false;
|
|
534
|
+
/**
|
|
535
|
+
* Whether the checkbox is disabled
|
|
536
|
+
*/
|
|
537
|
+
this.disabled = false;
|
|
538
|
+
this.handleChange = (event) => {
|
|
539
|
+
// We stop the internal button click from bubbling up
|
|
540
|
+
event.stopPropagation();
|
|
541
|
+
if (this.disabled) {
|
|
542
|
+
event.preventDefault();
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
const input = event.target;
|
|
546
|
+
this.checked = input.checked;
|
|
547
|
+
this.leChange.emit({
|
|
548
|
+
checked: this.checked,
|
|
549
|
+
value: this.value,
|
|
550
|
+
name: this.name,
|
|
551
|
+
externalId: this.externalId
|
|
552
|
+
});
|
|
553
|
+
};
|
|
568
554
|
}
|
|
569
|
-
get el() { return getElement(this); }
|
|
570
|
-
/**
|
|
571
|
-
* Whether the checkbox is checked
|
|
572
|
-
*/
|
|
573
|
-
checked = false;
|
|
574
|
-
/**
|
|
575
|
-
* Whether the checkbox is disabled
|
|
576
|
-
*/
|
|
577
|
-
disabled = false;
|
|
578
|
-
/**
|
|
579
|
-
* The name of the checkbox input
|
|
580
|
-
*/
|
|
581
|
-
name;
|
|
582
|
-
/**
|
|
583
|
-
* The value of the checkbox input
|
|
584
|
-
*/
|
|
585
|
-
value;
|
|
586
|
-
/**
|
|
587
|
-
* External ID for linking with external systems (e.g. database ID, PDF form field ID)
|
|
588
|
-
*/
|
|
589
|
-
externalId;
|
|
590
|
-
/**
|
|
591
|
-
* Emitted when the checked state changes
|
|
592
|
-
*/
|
|
593
|
-
leChange;
|
|
594
|
-
handleChange = (event) => {
|
|
595
|
-
// We stop the internal button click from bubbling up
|
|
596
|
-
event.stopPropagation();
|
|
597
|
-
if (this.disabled) {
|
|
598
|
-
event.preventDefault();
|
|
599
|
-
return;
|
|
600
|
-
}
|
|
601
|
-
const input = event.target;
|
|
602
|
-
this.checked = input.checked;
|
|
603
|
-
this.leChange.emit({
|
|
604
|
-
checked: this.checked,
|
|
605
|
-
value: this.value,
|
|
606
|
-
name: this.name,
|
|
607
|
-
externalId: this.externalId
|
|
608
|
-
});
|
|
609
|
-
};
|
|
610
555
|
render() {
|
|
611
|
-
return (h("le-component", { key: '
|
|
556
|
+
return (h("le-component", { key: '8b4541e96816b6e69ee790779971981b9d112484', component: "le-checkbox", hostClass: classnames({ 'disabled': this.disabled }) }, h("div", { key: 'c5e3a8692e59fa59a46bc90302e80f20dc700f04', class: "le-checkbox-wrapper" }, h("label", { key: 'b72abfbd39434a2c8be951a933e57ce70e9c922c', class: "le-checkbox-label" }, h("span", { key: '624ebbd37e6ea6a0800d702cbcea5ab8fe78b59e', class: "le-checkbox-input" }, h("input", { key: '182dc9549cc3494fc61e7779242ff14c304c3d97', type: "checkbox", name: this.name, value: this.value, checked: this.checked, disabled: this.disabled, onChange: this.handleChange })), h("span", { key: 'f14dc486329d8375b47ca75bedd2ac31f04273a7', class: "le-checkbox-text" }, h("le-slot", { key: '3be69ca148e121e8970bd3950fcbdee12613c775', name: "", type: "text", tag: "span" }, h("slot", { key: '2a258f7ce0331b9d08df5ac23a5ec492493974ca' })))), h("div", { key: '2deeab5d1d7c6b4046b5b4f54cd92061fc5f7383', class: "le-checkbox-description" }, h("le-slot", { key: '3ec3ca85d9f472d209084c4d95d46d2c114133e8', name: "description", type: "text", tag: "div", label: "Description" }, h("slot", { key: 'e1043ec4613df078446e7a6a5550646bbbe7d8be', name: "description" }))))));
|
|
612
557
|
}
|
|
558
|
+
get el() { return getElement(this); }
|
|
613
559
|
};
|
|
614
560
|
LeCheckbox.style = leCheckboxCss();
|
|
615
561
|
|
|
@@ -619,19 +565,19 @@ const leCollapseCss = () => `:host{--le-collapse-duration:var(--le-transition-no
|
|
|
619
565
|
const LeCollapse = class {
|
|
620
566
|
constructor(hostRef) {
|
|
621
567
|
registerInstance(this, hostRef);
|
|
568
|
+
/**
|
|
569
|
+
* Since Stencil boolean props default to `false` when the attribute is missing.
|
|
570
|
+
* instead of `open` defaulting to `true`, using a `closed` prop.
|
|
571
|
+
*/
|
|
572
|
+
this.closed = false;
|
|
573
|
+
/** Whether the content should scroll down from the top when open. */
|
|
574
|
+
this.scrollDown = false;
|
|
575
|
+
/** Stop fading the content when collapsing/expanding. */
|
|
576
|
+
this.noFading = false;
|
|
577
|
+
/** If true, collapse/expand based on the nearest header shrink event. */
|
|
578
|
+
this.collapseOnHeaderShrink = false;
|
|
579
|
+
this.headerShrunk = false;
|
|
622
580
|
}
|
|
623
|
-
get el() { return getElement(this); }
|
|
624
|
-
/**
|
|
625
|
-
* Since Stencil boolean props default to `false` when the attribute is missing.
|
|
626
|
-
* instead of `open` defaulting to `true`, using a `closed` prop.
|
|
627
|
-
*/
|
|
628
|
-
closed = false;
|
|
629
|
-
/** Whether the content should scroll down from the top when open. */
|
|
630
|
-
scrollDown = false;
|
|
631
|
-
/** Stop fading the content when collapsing/expanding. */
|
|
632
|
-
noFading = false;
|
|
633
|
-
/** If true, collapse/expand based on the nearest header shrink event. */
|
|
634
|
-
collapseOnHeaderShrink = false;
|
|
635
581
|
/**
|
|
636
582
|
* Handles `leHeaderShrinkChange` events from the `le-header`.
|
|
637
583
|
* In case multiple headers are present, only the nearest one in the DOM tree is used.
|
|
@@ -640,7 +586,6 @@ const LeCollapse = class {
|
|
|
640
586
|
const e = ev;
|
|
641
587
|
this.headerShrunk = !!e.detail?.shrunk;
|
|
642
588
|
}
|
|
643
|
-
headerShrunk = false;
|
|
644
589
|
componentDidLoad() {
|
|
645
590
|
this.applyOpenState();
|
|
646
591
|
}
|
|
@@ -662,8 +607,9 @@ const LeCollapse = class {
|
|
|
662
607
|
this.el.toggleAttribute('data-open', nextOpen);
|
|
663
608
|
}
|
|
664
609
|
render() {
|
|
665
|
-
return (h(Host, { key: '
|
|
610
|
+
return (h(Host, { key: '81a03bdd47d7c6e7d4491f4ee6be2e2f7af66334', "data-open": this.shouldBeOpen() ? 'true' : 'false' }, h("le-component", { key: '14cbe57c5cee1a3a7565175528d32b5d1be47919', component: "le-collapse" }, h("div", { key: 'c669a8d9f20776dba9d5ba162aaa6a58a31ad5b5', class: { 'region': true, 'scroll-down': this.scrollDown }, part: "region" }, h("slot", { key: 'd56fd4c71032da7935800874c13a2ba5b7427c83' })))));
|
|
666
611
|
}
|
|
612
|
+
get el() { return getElement(this); }
|
|
667
613
|
static get watchers() { return {
|
|
668
614
|
"open": ["onOpenChange"],
|
|
669
615
|
"headerShrunk": ["onDrivenStateChange"]
|
|
@@ -676,45 +622,19 @@ const leComponentCss = () => `:host{display:contents}:host(.admin-mode){display:
|
|
|
676
622
|
const LeComponent = class {
|
|
677
623
|
constructor(hostRef) {
|
|
678
624
|
registerInstance(this, hostRef);
|
|
625
|
+
/**
|
|
626
|
+
* Internal state to track admin mode
|
|
627
|
+
*/
|
|
628
|
+
this.adminMode = false;
|
|
629
|
+
/**
|
|
630
|
+
* Component metadata loaded from Custom Elements Manifest
|
|
631
|
+
*/
|
|
632
|
+
this.componentMeta = null;
|
|
633
|
+
/**
|
|
634
|
+
* Current property values of the host component
|
|
635
|
+
*/
|
|
636
|
+
this.propertyValues = {};
|
|
679
637
|
}
|
|
680
|
-
get el() { return getElement(this); }
|
|
681
|
-
/**
|
|
682
|
-
* The tag name of the component (e.g., 'le-card').
|
|
683
|
-
* Used to look up property metadata and display the component name.
|
|
684
|
-
*/
|
|
685
|
-
component;
|
|
686
|
-
/**
|
|
687
|
-
* Optional display name for the component.
|
|
688
|
-
* If not provided, the tag name will be formatted as the display name.
|
|
689
|
-
*/
|
|
690
|
-
displayName;
|
|
691
|
-
/**
|
|
692
|
-
* Classes to apply to the host element.
|
|
693
|
-
* Allows parent components to pass their styling classes.
|
|
694
|
-
*/
|
|
695
|
-
hostClass;
|
|
696
|
-
/**
|
|
697
|
-
* Inline styles to apply to the host element.
|
|
698
|
-
* Allows parent components to pass dynamic styles (e.g., flex properties).
|
|
699
|
-
*/
|
|
700
|
-
hostStyle;
|
|
701
|
-
/**
|
|
702
|
-
* Reference to the host element (found automatically from parent)
|
|
703
|
-
*/
|
|
704
|
-
hostElement;
|
|
705
|
-
/**
|
|
706
|
-
* Internal state to track admin mode
|
|
707
|
-
*/
|
|
708
|
-
adminMode = false;
|
|
709
|
-
/**
|
|
710
|
-
* Component metadata loaded from Custom Elements Manifest
|
|
711
|
-
*/
|
|
712
|
-
componentMeta = null;
|
|
713
|
-
/**
|
|
714
|
-
* Current property values of the host component
|
|
715
|
-
*/
|
|
716
|
-
propertyValues = {};
|
|
717
|
-
disconnectModeObserver;
|
|
718
638
|
connectedCallback() {
|
|
719
639
|
// Find the host element - le-component is rendered inside the component's shadow DOM,
|
|
720
640
|
// so we need to find the shadow root's host element
|
|
@@ -911,6 +831,7 @@ const LeComponent = class {
|
|
|
911
831
|
return (h(Host, { class: classnames(this.component, this.hostClass, 'admin-mode'), style: this.hostStyle }, h("div", { class: "le-component-wrapper" }, h("div", { class: "le-component-header" }, h("span", { class: "le-component-name" }, name), h("le-popover", { popoverTitle: `${name} Settings`, position: "right", align: "start", "min-width": "300px", mode: "default" }, h("le-button", { type: "button", class: "le-component-button", slot: "trigger", variant: "clear", size: "small", "aria-label": "Edit component properties", "icon-only": true }, h("span", { class: "le-component-trigger", slot: "icon-only" }, "\u2699")), this.renderPropertyEditor())), h("div", { class: "le-component-content" }, h("slot", null)))));
|
|
912
832
|
}
|
|
913
833
|
static get assetsDirs() { return ["assets"]; }
|
|
834
|
+
get el() { return getElement(this); }
|
|
914
835
|
};
|
|
915
836
|
LeComponent.style = leComponentCss();
|
|
916
837
|
|
|
@@ -919,11 +840,10 @@ const leCurrentHeadingCss = () => `:host{display:inline-flex;min-width:0}.title{
|
|
|
919
840
|
const LeCurrentHeading = class {
|
|
920
841
|
constructor(hostRef) {
|
|
921
842
|
registerInstance(this, hostRef);
|
|
843
|
+
/** CSS selector for page title/headings to watch (e.g. `.page-title`, `main h2`). */
|
|
844
|
+
this.selector = '';
|
|
845
|
+
this.activeText = null;
|
|
922
846
|
}
|
|
923
|
-
get el() { return getElement(this); }
|
|
924
|
-
/** CSS selector for page title/headings to watch (e.g. `.page-title`, `main h2`). */
|
|
925
|
-
selector = '';
|
|
926
|
-
activeText = null;
|
|
927
847
|
componentWillLoad() {
|
|
928
848
|
this.updateActiveTitle();
|
|
929
849
|
}
|
|
@@ -968,8 +888,9 @@ const LeCurrentHeading = class {
|
|
|
968
888
|
}
|
|
969
889
|
}
|
|
970
890
|
render() {
|
|
971
|
-
return (h(Host, { key: '
|
|
891
|
+
return (h(Host, { key: '72903f20413e002efaef27210a1dedfdc4065404' }, this.activeText ? (h("span", { class: "title", part: "title" }, this.activeText)) : (h("slot", null))));
|
|
972
892
|
}
|
|
893
|
+
get el() { return getElement(this); }
|
|
973
894
|
static get watchers() { return {
|
|
974
895
|
"selector": ["onSelectorChange"]
|
|
975
896
|
}; }
|
|
@@ -984,79 +905,143 @@ const LeDropdownBase = class {
|
|
|
984
905
|
this.leOptionSelect = createEvent(this, "leOptionSelect");
|
|
985
906
|
this.leDropdownOpen = createEvent(this, "leDropdownOpen");
|
|
986
907
|
this.leDropdownClose = createEvent(this, "leDropdownClose");
|
|
908
|
+
/**
|
|
909
|
+
* The options to display in the dropdown.
|
|
910
|
+
*/
|
|
911
|
+
this.options = [];
|
|
912
|
+
/**
|
|
913
|
+
* Whether multiple selection is allowed.
|
|
914
|
+
*/
|
|
915
|
+
this.multiple = false;
|
|
916
|
+
/**
|
|
917
|
+
* Whether the dropdown is open.
|
|
918
|
+
*/
|
|
919
|
+
this.open = false;
|
|
920
|
+
/**
|
|
921
|
+
* Whether the dropdown is disabled.
|
|
922
|
+
*/
|
|
923
|
+
this.disabled = false;
|
|
924
|
+
/**
|
|
925
|
+
* Current filter query string.
|
|
926
|
+
*/
|
|
927
|
+
this.filterQuery = '';
|
|
928
|
+
/**
|
|
929
|
+
* Placeholder text when no options match filter.
|
|
930
|
+
*/
|
|
931
|
+
this.emptyText = 'No options';
|
|
932
|
+
/**
|
|
933
|
+
* Whether to show checkboxes for multiselect mode.
|
|
934
|
+
*/
|
|
935
|
+
this.showCheckboxes = true;
|
|
936
|
+
/**
|
|
937
|
+
* Maximum height of the dropdown list.
|
|
938
|
+
*/
|
|
939
|
+
this.maxHeight = '300px';
|
|
940
|
+
/**
|
|
941
|
+
* Sets the dropdown to full width of the trigger.
|
|
942
|
+
*/
|
|
943
|
+
this.fullWidth = false;
|
|
944
|
+
/**
|
|
945
|
+
* Whether to close the dropdown when clicking outside.
|
|
946
|
+
* (used to support combobox with input focus)
|
|
947
|
+
*/
|
|
948
|
+
this.closeOnClickOutside = true;
|
|
949
|
+
this.focusedIndex = -1;
|
|
950
|
+
this.filteredOptions = [];
|
|
951
|
+
this.triggerWidth = 0;
|
|
952
|
+
this.handleKeyDown = (e) => {
|
|
953
|
+
if (!this.open)
|
|
954
|
+
return;
|
|
955
|
+
const optionCount = this.filteredOptions.length;
|
|
956
|
+
switch (e.key) {
|
|
957
|
+
case 'ArrowDown':
|
|
958
|
+
e.preventDefault();
|
|
959
|
+
// check for the next non-disabled option and focus
|
|
960
|
+
let nextIndex = this.focusedIndex < optionCount - 1 ? this.focusedIndex + 1 : 0;
|
|
961
|
+
while (this.filteredOptions[nextIndex].disabled) {
|
|
962
|
+
nextIndex = ++nextIndex < optionCount ? nextIndex : 0;
|
|
963
|
+
}
|
|
964
|
+
this.focusedIndex = nextIndex;
|
|
965
|
+
this.scrollToFocused();
|
|
966
|
+
break;
|
|
967
|
+
case 'ArrowUp':
|
|
968
|
+
e.preventDefault();
|
|
969
|
+
// check for the previous non-disabled option and focus
|
|
970
|
+
let prevIndex = this.focusedIndex > 0 ? this.focusedIndex - 1 : optionCount - 1;
|
|
971
|
+
while (this.filteredOptions[prevIndex].disabled) {
|
|
972
|
+
prevIndex = --prevIndex >= 0 ? prevIndex : optionCount - 1;
|
|
973
|
+
}
|
|
974
|
+
this.focusedIndex = prevIndex;
|
|
975
|
+
this.scrollToFocused();
|
|
976
|
+
break;
|
|
977
|
+
case 'Home':
|
|
978
|
+
e.preventDefault();
|
|
979
|
+
// check for the first non-disabled option and focus
|
|
980
|
+
let firstIndex = 0;
|
|
981
|
+
while (this.filteredOptions[firstIndex].disabled) {
|
|
982
|
+
firstIndex++;
|
|
983
|
+
if (firstIndex >= optionCount) {
|
|
984
|
+
firstIndex = -1;
|
|
985
|
+
break;
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
this.focusedIndex = firstIndex;
|
|
989
|
+
this.scrollToFocused();
|
|
990
|
+
break;
|
|
991
|
+
case 'End':
|
|
992
|
+
e.preventDefault();
|
|
993
|
+
// check for the last non-disabled option and focus
|
|
994
|
+
let lastIndex = optionCount - 1;
|
|
995
|
+
while (this.filteredOptions[lastIndex].disabled) {
|
|
996
|
+
lastIndex--;
|
|
997
|
+
if (lastIndex < 0) {
|
|
998
|
+
lastIndex = -1;
|
|
999
|
+
break;
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
this.focusedIndex = lastIndex;
|
|
1003
|
+
this.scrollToFocused();
|
|
1004
|
+
break;
|
|
1005
|
+
case 'Enter':
|
|
1006
|
+
case ' ':
|
|
1007
|
+
e.preventDefault();
|
|
1008
|
+
if (this.focusedIndex >= 0 && this.focusedIndex < optionCount) {
|
|
1009
|
+
const option = this.filteredOptions[this.focusedIndex];
|
|
1010
|
+
if (!option || option.disabled)
|
|
1011
|
+
return;
|
|
1012
|
+
this.leOptionSelect.emit({
|
|
1013
|
+
value: option.value ?? option.label,
|
|
1014
|
+
option,
|
|
1015
|
+
});
|
|
1016
|
+
if (!this.multiple) {
|
|
1017
|
+
this.hide();
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
break;
|
|
1021
|
+
case 'Escape':
|
|
1022
|
+
e.preventDefault();
|
|
1023
|
+
this.hide();
|
|
1024
|
+
break;
|
|
1025
|
+
case 'Tab':
|
|
1026
|
+
this.hide();
|
|
1027
|
+
break;
|
|
1028
|
+
}
|
|
1029
|
+
};
|
|
1030
|
+
this.handlePopoverOpen = () => {
|
|
1031
|
+
this.open = true;
|
|
1032
|
+
this.focusedIndex = this.getInitialFocusIndex();
|
|
1033
|
+
this.leDropdownOpen.emit();
|
|
1034
|
+
// Add keyboard listener
|
|
1035
|
+
document.addEventListener('keydown', this.handleKeyDown);
|
|
1036
|
+
};
|
|
1037
|
+
this.handlePopoverClose = () => {
|
|
1038
|
+
this.open = false;
|
|
1039
|
+
this.focusedIndex = -1;
|
|
1040
|
+
this.leDropdownClose.emit();
|
|
1041
|
+
// Remove keyboard listener
|
|
1042
|
+
document.removeEventListener('keydown', this.handleKeyDown);
|
|
1043
|
+
};
|
|
987
1044
|
}
|
|
988
|
-
get el() { return getElement(this); }
|
|
989
|
-
/**
|
|
990
|
-
* The options to display in the dropdown.
|
|
991
|
-
*/
|
|
992
|
-
options = [];
|
|
993
|
-
/**
|
|
994
|
-
* Current value(s) - single value or array for multiselect.
|
|
995
|
-
*/
|
|
996
|
-
value;
|
|
997
|
-
/**
|
|
998
|
-
* Whether multiple selection is allowed.
|
|
999
|
-
*/
|
|
1000
|
-
multiple = false;
|
|
1001
|
-
/**
|
|
1002
|
-
* Whether the dropdown is open.
|
|
1003
|
-
*/
|
|
1004
|
-
open = false;
|
|
1005
|
-
/**
|
|
1006
|
-
* Whether the dropdown is disabled.
|
|
1007
|
-
*/
|
|
1008
|
-
disabled = false;
|
|
1009
|
-
/**
|
|
1010
|
-
* Filter function for options.
|
|
1011
|
-
* Return true to include the option.
|
|
1012
|
-
*/
|
|
1013
|
-
filterFn;
|
|
1014
|
-
/**
|
|
1015
|
-
* Current filter query string.
|
|
1016
|
-
*/
|
|
1017
|
-
filterQuery = '';
|
|
1018
|
-
/**
|
|
1019
|
-
* Placeholder text when no options match filter.
|
|
1020
|
-
*/
|
|
1021
|
-
emptyText = 'No options';
|
|
1022
|
-
/**
|
|
1023
|
-
* Whether to show checkboxes for multiselect mode.
|
|
1024
|
-
*/
|
|
1025
|
-
showCheckboxes = true;
|
|
1026
|
-
/**
|
|
1027
|
-
* Maximum height of the dropdown list.
|
|
1028
|
-
*/
|
|
1029
|
-
maxHeight = '300px';
|
|
1030
|
-
/**
|
|
1031
|
-
* Width of the dropdown. If not set, matches trigger width.
|
|
1032
|
-
*/
|
|
1033
|
-
width;
|
|
1034
|
-
/**
|
|
1035
|
-
* Sets the dropdown to full width of the trigger.
|
|
1036
|
-
*/
|
|
1037
|
-
fullWidth = false;
|
|
1038
|
-
/**
|
|
1039
|
-
* Whether to close the dropdown when clicking outside.
|
|
1040
|
-
* (used to support combobox with input focus)
|
|
1041
|
-
*/
|
|
1042
|
-
closeOnClickOutside = true;
|
|
1043
|
-
/**
|
|
1044
|
-
* Emitted when an option is selected.
|
|
1045
|
-
*/
|
|
1046
|
-
leOptionSelect;
|
|
1047
|
-
/**
|
|
1048
|
-
* Emitted when the dropdown opens.
|
|
1049
|
-
*/
|
|
1050
|
-
leDropdownOpen;
|
|
1051
|
-
/**
|
|
1052
|
-
* Emitted when the dropdown closes.
|
|
1053
|
-
*/
|
|
1054
|
-
leDropdownClose;
|
|
1055
|
-
focusedIndex = -1;
|
|
1056
|
-
filteredOptions = [];
|
|
1057
|
-
popoverEl;
|
|
1058
|
-
listEl;
|
|
1059
|
-
triggerWidth = 0;
|
|
1060
1045
|
handleOptionsChange() {
|
|
1061
1046
|
this.updateFilteredOptions();
|
|
1062
1047
|
}
|
|
@@ -1108,84 +1093,6 @@ const LeDropdownBase = class {
|
|
|
1108
1093
|
this.hide();
|
|
1109
1094
|
}
|
|
1110
1095
|
}
|
|
1111
|
-
handleKeyDown = (e) => {
|
|
1112
|
-
if (!this.open)
|
|
1113
|
-
return;
|
|
1114
|
-
const optionCount = this.filteredOptions.length;
|
|
1115
|
-
switch (e.key) {
|
|
1116
|
-
case 'ArrowDown':
|
|
1117
|
-
e.preventDefault();
|
|
1118
|
-
// check for the next non-disabled option and focus
|
|
1119
|
-
let nextIndex = this.focusedIndex < optionCount - 1 ? this.focusedIndex + 1 : 0;
|
|
1120
|
-
while (this.filteredOptions[nextIndex].disabled) {
|
|
1121
|
-
nextIndex = ++nextIndex < optionCount ? nextIndex : 0;
|
|
1122
|
-
}
|
|
1123
|
-
this.focusedIndex = nextIndex;
|
|
1124
|
-
this.scrollToFocused();
|
|
1125
|
-
break;
|
|
1126
|
-
case 'ArrowUp':
|
|
1127
|
-
e.preventDefault();
|
|
1128
|
-
// check for the previous non-disabled option and focus
|
|
1129
|
-
let prevIndex = this.focusedIndex > 0 ? this.focusedIndex - 1 : optionCount - 1;
|
|
1130
|
-
while (this.filteredOptions[prevIndex].disabled) {
|
|
1131
|
-
prevIndex = --prevIndex >= 0 ? prevIndex : optionCount - 1;
|
|
1132
|
-
}
|
|
1133
|
-
this.focusedIndex = prevIndex;
|
|
1134
|
-
this.scrollToFocused();
|
|
1135
|
-
break;
|
|
1136
|
-
case 'Home':
|
|
1137
|
-
e.preventDefault();
|
|
1138
|
-
// check for the first non-disabled option and focus
|
|
1139
|
-
let firstIndex = 0;
|
|
1140
|
-
while (this.filteredOptions[firstIndex].disabled) {
|
|
1141
|
-
firstIndex++;
|
|
1142
|
-
if (firstIndex >= optionCount) {
|
|
1143
|
-
firstIndex = -1;
|
|
1144
|
-
break;
|
|
1145
|
-
}
|
|
1146
|
-
}
|
|
1147
|
-
this.focusedIndex = firstIndex;
|
|
1148
|
-
this.scrollToFocused();
|
|
1149
|
-
break;
|
|
1150
|
-
case 'End':
|
|
1151
|
-
e.preventDefault();
|
|
1152
|
-
// check for the last non-disabled option and focus
|
|
1153
|
-
let lastIndex = optionCount - 1;
|
|
1154
|
-
while (this.filteredOptions[lastIndex].disabled) {
|
|
1155
|
-
lastIndex--;
|
|
1156
|
-
if (lastIndex < 0) {
|
|
1157
|
-
lastIndex = -1;
|
|
1158
|
-
break;
|
|
1159
|
-
}
|
|
1160
|
-
}
|
|
1161
|
-
this.focusedIndex = lastIndex;
|
|
1162
|
-
this.scrollToFocused();
|
|
1163
|
-
break;
|
|
1164
|
-
case 'Enter':
|
|
1165
|
-
case ' ':
|
|
1166
|
-
e.preventDefault();
|
|
1167
|
-
if (this.focusedIndex >= 0 && this.focusedIndex < optionCount) {
|
|
1168
|
-
const option = this.filteredOptions[this.focusedIndex];
|
|
1169
|
-
if (!option || option.disabled)
|
|
1170
|
-
return;
|
|
1171
|
-
this.leOptionSelect.emit({
|
|
1172
|
-
value: option.value ?? option.label,
|
|
1173
|
-
option,
|
|
1174
|
-
});
|
|
1175
|
-
if (!this.multiple) {
|
|
1176
|
-
this.hide();
|
|
1177
|
-
}
|
|
1178
|
-
}
|
|
1179
|
-
break;
|
|
1180
|
-
case 'Escape':
|
|
1181
|
-
e.preventDefault();
|
|
1182
|
-
this.hide();
|
|
1183
|
-
break;
|
|
1184
|
-
case 'Tab':
|
|
1185
|
-
this.hide();
|
|
1186
|
-
break;
|
|
1187
|
-
}
|
|
1188
|
-
};
|
|
1189
1096
|
scrollToFocused() {
|
|
1190
1097
|
if (!this.listEl || this.focusedIndex < 0)
|
|
1191
1098
|
return;
|
|
@@ -1194,20 +1101,6 @@ const LeDropdownBase = class {
|
|
|
1194
1101
|
focusedEl.scrollIntoView({ block: 'nearest' });
|
|
1195
1102
|
}
|
|
1196
1103
|
}
|
|
1197
|
-
handlePopoverOpen = () => {
|
|
1198
|
-
this.open = true;
|
|
1199
|
-
this.focusedIndex = this.getInitialFocusIndex();
|
|
1200
|
-
this.leDropdownOpen.emit();
|
|
1201
|
-
// Add keyboard listener
|
|
1202
|
-
document.addEventListener('keydown', this.handleKeyDown);
|
|
1203
|
-
};
|
|
1204
|
-
handlePopoverClose = () => {
|
|
1205
|
-
this.open = false;
|
|
1206
|
-
this.focusedIndex = -1;
|
|
1207
|
-
this.leDropdownClose.emit();
|
|
1208
|
-
// Remove keyboard listener
|
|
1209
|
-
document.removeEventListener('keydown', this.handleKeyDown);
|
|
1210
|
-
};
|
|
1211
1104
|
getInitialFocusIndex() {
|
|
1212
1105
|
// Focus on first selected option, or first option
|
|
1213
1106
|
const selectableOptions = this.getSelectableOptions();
|
|
@@ -1308,8 +1201,9 @@ const LeDropdownBase = class {
|
|
|
1308
1201
|
}
|
|
1309
1202
|
render() {
|
|
1310
1203
|
const dropdownWidth = this.width || (this.triggerWidth ? `${this.triggerWidth}px` : undefined);
|
|
1311
|
-
return (h(Host, { key: '
|
|
1204
|
+
return (h(Host, { key: '71c3537d6234aebb8c18fb6c07e5a751568a4b87' }, h("le-popover", { key: 'e02fcd7454cae5a9c197a509d18cd7b91e49fc9e', ref: el => (this.popoverEl = el), position: "bottom", align: "start", showClose: false, closeOnClickOutside: this.closeOnClickOutside, closeOnEscape: true, offset: 4, width: dropdownWidth, minWidth: "150px", "trigger-full-width": this.fullWidth, onLePopoverOpen: this.handlePopoverOpen, onLePopoverClose: this.handlePopoverClose }, h("slot", { key: 'f1a9e3145119f1cfc1b8a535b98b0858758c6265', name: "trigger", slot: "trigger" }), h("slot", { key: '8dd6126a610e167fb2b3c2593677f70c387bd275', name: "header" }), h("div", { key: '708b3916132c36f736f8a88e3408d482a50610fb', class: "dropdown-list", role: "listbox", "aria-multiselectable": this.multiple ? 'true' : undefined, ref: el => (this.listEl = el), style: { maxHeight: this.maxHeight } }, this.renderOptions()))));
|
|
1312
1205
|
}
|
|
1206
|
+
get el() { return getElement(this); }
|
|
1313
1207
|
static get watchers() { return {
|
|
1314
1208
|
"options": ["handleOptionsChange"],
|
|
1315
1209
|
"filterQuery": ["handleOptionsChange"]
|
|
@@ -1327,50 +1221,25 @@ const LeHeader = class {
|
|
|
1327
1221
|
this.leHeaderState = createEvent(this, "leHeaderState");
|
|
1328
1222
|
this.leHeaderShrinkChange = createEvent(this, "leHeaderShrinkChange");
|
|
1329
1223
|
this.leHeaderVisibilityChange = createEvent(this, "leHeaderVisibilityChange");
|
|
1224
|
+
/** Force static positioning (default). Ignored if `sticky` or `fixed` are true. */
|
|
1225
|
+
this.isStatic = false;
|
|
1226
|
+
/** Sticky positioning (in-flow). Ignored if `fixed` is true. */
|
|
1227
|
+
this.sticky = false;
|
|
1228
|
+
/** Fixed positioning (out-of-flow). Takes precedence over `sticky`/`static`. */
|
|
1229
|
+
this.fixed = false;
|
|
1230
|
+
/**
|
|
1231
|
+
* If true, expand the header when hovered
|
|
1232
|
+
*/
|
|
1233
|
+
this.expandOnHover = false;
|
|
1234
|
+
this.revealed = true;
|
|
1235
|
+
this.shrunk = false;
|
|
1236
|
+
this.placeholderHeight = null;
|
|
1237
|
+
this.hoverActive = false;
|
|
1238
|
+
this.rafId = null;
|
|
1239
|
+
this.measureRafId = null;
|
|
1240
|
+
this.lastY = 0;
|
|
1241
|
+
this.lastEmittedDirection = 'down';
|
|
1330
1242
|
}
|
|
1331
|
-
get el() { return getElement(this); }
|
|
1332
|
-
/** Force static positioning (default). Ignored if `sticky` or `fixed` are true. */
|
|
1333
|
-
isStatic = false;
|
|
1334
|
-
/** Sticky positioning (in-flow). Ignored if `fixed` is true. */
|
|
1335
|
-
sticky = false;
|
|
1336
|
-
/** Fixed positioning (out-of-flow). Takes precedence over `sticky`/`static`. */
|
|
1337
|
-
fixed = false;
|
|
1338
|
-
/**
|
|
1339
|
-
* Sticky-only reveal behavior (hide on scroll down, show on scroll up).
|
|
1340
|
-
* - missing/false: disabled
|
|
1341
|
-
* - true/empty attribute: enabled with default threshold (16)
|
|
1342
|
-
* - number (as string): enabled and used as threshold
|
|
1343
|
-
*/
|
|
1344
|
-
revealOnScroll;
|
|
1345
|
-
/**
|
|
1346
|
-
* Shrink trigger.
|
|
1347
|
-
* - missing/0: disabled
|
|
1348
|
-
* - number (px): shrink when scrollY >= that value (but never before header height)
|
|
1349
|
-
* - css var name (e.g. --foo): shrink when scrollY >= resolved var value
|
|
1350
|
-
* - selector (e.g. .page-title): shrink when that element scrolls out of view above the viewport
|
|
1351
|
-
*/
|
|
1352
|
-
shrinkOffset;
|
|
1353
|
-
/**
|
|
1354
|
-
* If true, expand the header when hovered
|
|
1355
|
-
*/
|
|
1356
|
-
expandOnHover = false;
|
|
1357
|
-
/** Emits whenever scroll-driven state changes. */
|
|
1358
|
-
leHeaderState;
|
|
1359
|
-
/** Emits when the header shrinks/expands (only on change). */
|
|
1360
|
-
leHeaderShrinkChange;
|
|
1361
|
-
/** Emits when the header hides/shows (only on change). */
|
|
1362
|
-
leHeaderVisibilityChange;
|
|
1363
|
-
revealed = true;
|
|
1364
|
-
shrunk = false;
|
|
1365
|
-
placeholderHeight = null;
|
|
1366
|
-
hoverActive = false;
|
|
1367
|
-
disconnectModeObserver;
|
|
1368
|
-
rafId = null;
|
|
1369
|
-
measureRafId = null;
|
|
1370
|
-
lastY = 0;
|
|
1371
|
-
lastEmittedDirection = 'down';
|
|
1372
|
-
headerEl;
|
|
1373
|
-
shrinkSelectorEl;
|
|
1374
1243
|
setShrunk(next, y) {
|
|
1375
1244
|
if (next === this.shrunk)
|
|
1376
1245
|
return;
|
|
@@ -1552,7 +1421,7 @@ const LeHeader = class {
|
|
|
1552
1421
|
'is-hidden': !this.revealed,
|
|
1553
1422
|
'is-shrunk': this.shrunk,
|
|
1554
1423
|
});
|
|
1555
|
-
return (h(Host, { key: '
|
|
1424
|
+
return (h(Host, { key: 'ade87accbc122a0eb84422598646da357570d7d0', class: hostClass, onMouseEnter: () => {
|
|
1556
1425
|
if (!this.expandOnHover)
|
|
1557
1426
|
return;
|
|
1558
1427
|
this.hoverActive = true;
|
|
@@ -1562,8 +1431,9 @@ const LeHeader = class {
|
|
|
1562
1431
|
return;
|
|
1563
1432
|
this.hoverActive = false;
|
|
1564
1433
|
this.scheduleUpdate(true);
|
|
1565
|
-
} }, h("le-component", { key: '
|
|
1434
|
+
} }, h("le-component", { key: 'dfe9a341d0f8ec702775ff68f2f7afb42bc878dc', component: "le-header" }, h("header", { key: '3239f73706082a6dfc5f7637f5ee8c793debd28f', class: "header", part: "header", role: "banner", ref: el => (this.headerEl = el) }, h("div", { key: '7e4b99e4b1a8bde81c340086d947598ff7bfd9a6', class: "inner", part: "inner" }, h("div", { key: 'b8fb2a8d42a07b35482de7553cd2f3bb608169d2', class: "row", part: "row" }, h("div", { key: '89cd5b7707ccb0626c0ecdf1c07494b184fdda1b', class: "start", part: "start" }, h("le-slot", { key: 'ee442e5f097bd3dcbc5b8376eb5eed024fe474b4', name: "start", label: "Start", description: "Logo / back button / nav", "allowed-components": "le-button,le-text,le-tag,le-box,le-stack" }, h("slot", { key: 'fbf43302c87d9e15cb6e848c1f2e7a30d37ee8f0', name: "start" }))), h("div", { key: '295165dbf2b29744d0687e426cd91665a320944f', class: "title", part: "title" }, h("le-slot", { key: '96aa340f844a15042a17c98610fd4da7e771f61a', name: "title", label: "Title", description: "Header title", type: "text", tag: "span" }, h("span", { key: 'f12cee8413e02e18d3a30a203f61165c4efce673', class: "title-slot", part: "title" }, h("slot", { key: 'dddb32fcf70ec8f16017626056668f325c701b99', name: "title" })))), h("div", { key: 'bc1c9d0deb4120d335de476211e41d86ea408621', class: "end", part: "end" }, h("le-slot", { key: '804482ee7e47f93147899cab94eedbdedc1ba63f', name: "end", label: "End", description: "Actions", "allowed-components": "le-button,le-text,le-tag,le-box,le-stack" }, h("slot", { key: '11bc31fd9875f1d38393606833328c31ac651ece', name: "end" })))), h("div", { key: '8351339444b373d88d9ac0cc4487b67a8c5267cd', class: "secondary", part: "secondary" }, h("le-slot", { key: 'ee99b61af146d91bfb0a84b1fac64ab8e077b85e', name: "", label: "Secondary", description: "Secondary row content", "allowed-components": "le-tabs,le-tab-bar,le-select,le-combobox,le-text,le-stack,le-box" }, h("slot", { key: '77fabff83384d721715bd0ba6efe129dad285875' }))))))));
|
|
1566
1435
|
}
|
|
1436
|
+
get el() { return getElement(this); }
|
|
1567
1437
|
static get watchers() { return {
|
|
1568
1438
|
"revealOnScroll": ["onBehaviorPropsChange"],
|
|
1569
1439
|
"shrinkOffset": ["onBehaviorPropsChange"],
|
|
@@ -1612,19 +1482,18 @@ async function fetchIcon({ name }) {
|
|
|
1612
1482
|
const LeIcon = class {
|
|
1613
1483
|
constructor(hostRef) {
|
|
1614
1484
|
registerInstance(this, hostRef);
|
|
1485
|
+
/**
|
|
1486
|
+
* Name of the icon to display. Corresponds to a JSON file in the assets folder.
|
|
1487
|
+
* For example, "search" will load the "search.json" file.
|
|
1488
|
+
*/
|
|
1489
|
+
this.name = null;
|
|
1490
|
+
/**
|
|
1491
|
+
* Size of the icon in pixels. Default is 16.
|
|
1492
|
+
*/
|
|
1493
|
+
this.size = 16;
|
|
1494
|
+
this.iconData = null;
|
|
1495
|
+
this.visible = false;
|
|
1615
1496
|
}
|
|
1616
|
-
get el() { return getElement(this); }
|
|
1617
|
-
/**
|
|
1618
|
-
* Name of the icon to display. Corresponds to a JSON file in the assets folder.
|
|
1619
|
-
* For example, "search" will load the "search.json" file.
|
|
1620
|
-
*/
|
|
1621
|
-
name = null;
|
|
1622
|
-
/**
|
|
1623
|
-
* Size of the icon in pixels. Default is 16.
|
|
1624
|
-
*/
|
|
1625
|
-
size = 16;
|
|
1626
|
-
iconData = null;
|
|
1627
|
-
visible = false;
|
|
1628
1497
|
async loadIconData() {
|
|
1629
1498
|
const { name, visible } = this;
|
|
1630
1499
|
if (!name || !visible) {
|
|
@@ -1632,7 +1501,6 @@ const LeIcon = class {
|
|
|
1632
1501
|
}
|
|
1633
1502
|
this.iconData = await fetchIcon({ name });
|
|
1634
1503
|
}
|
|
1635
|
-
intersectionObserver;
|
|
1636
1504
|
connectedCallback() {
|
|
1637
1505
|
this.waitUntilVisible(() => {
|
|
1638
1506
|
this.visible = true;
|
|
@@ -1683,9 +1551,10 @@ const LeIcon = class {
|
|
|
1683
1551
|
return svgElements;
|
|
1684
1552
|
}
|
|
1685
1553
|
render() {
|
|
1686
|
-
return (h("svg", { key: '
|
|
1554
|
+
return (h("svg", { key: '15ae743268ab99a174f669436778c2305f4d65df', xmlns: "http://www.w3.org/2000/svg", fill: "currentColor", height: this.size || 16, width: this.size || 16, viewBox: this.iconData?.viewBox || `0 0 ${this.size || 16} ${this.size || 16}` }, this.renderSVGContent(this.iconData?.children)));
|
|
1687
1555
|
}
|
|
1688
1556
|
static get assetsDirs() { return ["assets/icons"]; }
|
|
1557
|
+
get el() { return getElement(this); }
|
|
1689
1558
|
static get watchers() { return {
|
|
1690
1559
|
"name": ["loadIconData"]
|
|
1691
1560
|
}; }
|
|
@@ -1699,79 +1568,123 @@ const LeNavigation = class {
|
|
|
1699
1568
|
registerInstance(this, hostRef);
|
|
1700
1569
|
this.leNavItemSelect = createEvent(this, "leNavItemSelect");
|
|
1701
1570
|
this.leNavItemToggle = createEvent(this, "leNavItemToggle");
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1571
|
+
/**
|
|
1572
|
+
* Navigation items.
|
|
1573
|
+
* Can be passed as an array or JSON string (same pattern as le-select).
|
|
1574
|
+
*/
|
|
1575
|
+
this.items = [];
|
|
1576
|
+
/**
|
|
1577
|
+
* Layout orientation.
|
|
1578
|
+
*/
|
|
1579
|
+
this.orientation = 'horizontal';
|
|
1580
|
+
/**
|
|
1581
|
+
* Horizontal wrapping behavior.
|
|
1582
|
+
* If false, overflow behavior depends on `overflowMode`.
|
|
1583
|
+
*/
|
|
1584
|
+
this.wrap = false;
|
|
1585
|
+
/**
|
|
1586
|
+
* Overflow behavior for horizontal, non-wrapping menus.
|
|
1587
|
+
* - more: moves overflow items into a "More" popover
|
|
1588
|
+
* - hamburger: turns the whole nav into a hamburger popover
|
|
1589
|
+
*/
|
|
1590
|
+
this.overflowMode = 'more';
|
|
1591
|
+
/**
|
|
1592
|
+
* Minimum number of visible top-level items required to use the "More" overflow.
|
|
1593
|
+
* If fewer would be visible, the navigation falls back to hamburger.
|
|
1594
|
+
*/
|
|
1595
|
+
this.minVisibleItemsForMore = 2;
|
|
1596
|
+
/**
|
|
1597
|
+
* Alignment of the menu items within the navigation bar.
|
|
1598
|
+
*/
|
|
1599
|
+
this.align = 'start';
|
|
1600
|
+
/**
|
|
1601
|
+
* Active url for automatic selection.
|
|
1602
|
+
*/
|
|
1603
|
+
this.activeUrl = '';
|
|
1604
|
+
/**
|
|
1605
|
+
* Enables a search input for the vertical navigation.
|
|
1606
|
+
*/
|
|
1607
|
+
this.searchable = false;
|
|
1608
|
+
/**
|
|
1609
|
+
* Placeholder text for the search input.
|
|
1610
|
+
*/
|
|
1611
|
+
this.searchPlaceholder = 'Search...';
|
|
1612
|
+
/**
|
|
1613
|
+
* Text shown when no items match the filter.
|
|
1614
|
+
*/
|
|
1615
|
+
this.emptyText = 'No results found';
|
|
1616
|
+
/**
|
|
1617
|
+
* Whether submenu popovers should include a filter input.
|
|
1618
|
+
*/
|
|
1619
|
+
this.submenuSearchable = false;
|
|
1620
|
+
this.searchQuery = '';
|
|
1621
|
+
this.openState = {};
|
|
1622
|
+
/** IDs of items currently in overflow (from le-bar) */
|
|
1623
|
+
this.overflowIds = [];
|
|
1624
|
+
/** Whether hamburger mode is active (from le-bar) */
|
|
1625
|
+
this.hamburgerActive = false;
|
|
1626
|
+
this.submenuQueries = {};
|
|
1627
|
+
/** Whether the overflow popover is open */
|
|
1628
|
+
this.overflowPopoverOpen = false;
|
|
1629
|
+
this.popoverRefs = new Map();
|
|
1630
|
+
this.instanceId = generateId('le-nav');
|
|
1631
|
+
this.handleItemSelect = (e, item, id) => {
|
|
1632
|
+
if (item.disabled) {
|
|
1633
|
+
e.preventDefault();
|
|
1634
|
+
e.stopPropagation();
|
|
1635
|
+
return;
|
|
1636
|
+
}
|
|
1637
|
+
const emitted = this.leNavItemSelect.emit({
|
|
1638
|
+
item,
|
|
1639
|
+
id,
|
|
1640
|
+
href: item.href,
|
|
1641
|
+
originalEvent: e,
|
|
1642
|
+
});
|
|
1643
|
+
if (emitted.defaultPrevented) {
|
|
1644
|
+
e.preventDefault();
|
|
1645
|
+
}
|
|
1646
|
+
};
|
|
1647
|
+
this.handleToggle = (e, item, id) => {
|
|
1648
|
+
e.preventDefault();
|
|
1649
|
+
e.stopPropagation();
|
|
1650
|
+
if (item.disabled)
|
|
1651
|
+
return;
|
|
1652
|
+
const next = !this.isOpen(item, id);
|
|
1653
|
+
this.setOpen(id, next);
|
|
1654
|
+
this.leNavItemToggle.emit({
|
|
1655
|
+
item,
|
|
1656
|
+
id,
|
|
1657
|
+
open: next,
|
|
1658
|
+
originalEvent: e,
|
|
1659
|
+
});
|
|
1660
|
+
};
|
|
1661
|
+
this.handleSearchInput = (e) => {
|
|
1662
|
+
const target = e.target;
|
|
1663
|
+
this.searchQuery = target.value;
|
|
1664
|
+
};
|
|
1665
|
+
this.handleSubmenuSearchInput = (submenuId, e) => {
|
|
1666
|
+
const target = e.target;
|
|
1667
|
+
const value = target.value;
|
|
1668
|
+
if (this.submenuQueries[submenuId] === value)
|
|
1669
|
+
return;
|
|
1670
|
+
this.submenuQueries = {
|
|
1671
|
+
...this.submenuQueries,
|
|
1672
|
+
[submenuId]: value,
|
|
1673
|
+
};
|
|
1674
|
+
// Position may change as items filter.
|
|
1675
|
+
requestAnimationFrame(() => this.popoverRefs.get(submenuId)?.updatePosition());
|
|
1676
|
+
};
|
|
1677
|
+
this.handleBarOverflowChange = (e) => {
|
|
1678
|
+
this.overflowIds = e.detail.overflowingIds || [];
|
|
1679
|
+
this.hamburgerActive = e.detail.hamburgerActive || false;
|
|
1680
|
+
};
|
|
1681
|
+
this.openOverflowPopover = () => {
|
|
1682
|
+
this.overflowPopoverOpen = true;
|
|
1683
|
+
};
|
|
1684
|
+
this.closeOverflowPopover = () => {
|
|
1685
|
+
this.overflowPopoverOpen = false;
|
|
1686
|
+
};
|
|
1687
|
+
}
|
|
1775
1688
|
partFromOptionPart(base, part) {
|
|
1776
1689
|
const raw = (part ?? '').trim();
|
|
1777
1690
|
if (!raw)
|
|
@@ -1858,62 +1771,6 @@ const LeNavigation = class {
|
|
|
1858
1771
|
});
|
|
1859
1772
|
return result;
|
|
1860
1773
|
}
|
|
1861
|
-
handleItemSelect = (e, item, id) => {
|
|
1862
|
-
if (item.disabled) {
|
|
1863
|
-
e.preventDefault();
|
|
1864
|
-
e.stopPropagation();
|
|
1865
|
-
return;
|
|
1866
|
-
}
|
|
1867
|
-
const emitted = this.leNavItemSelect.emit({
|
|
1868
|
-
item,
|
|
1869
|
-
id,
|
|
1870
|
-
href: item.href,
|
|
1871
|
-
originalEvent: e,
|
|
1872
|
-
});
|
|
1873
|
-
if (emitted.defaultPrevented) {
|
|
1874
|
-
e.preventDefault();
|
|
1875
|
-
}
|
|
1876
|
-
};
|
|
1877
|
-
handleToggle = (e, item, id) => {
|
|
1878
|
-
e.preventDefault();
|
|
1879
|
-
e.stopPropagation();
|
|
1880
|
-
if (item.disabled)
|
|
1881
|
-
return;
|
|
1882
|
-
const next = !this.isOpen(item, id);
|
|
1883
|
-
this.setOpen(id, next);
|
|
1884
|
-
this.leNavItemToggle.emit({
|
|
1885
|
-
item,
|
|
1886
|
-
id,
|
|
1887
|
-
open: next,
|
|
1888
|
-
originalEvent: e,
|
|
1889
|
-
});
|
|
1890
|
-
};
|
|
1891
|
-
handleSearchInput = (e) => {
|
|
1892
|
-
const target = e.target;
|
|
1893
|
-
this.searchQuery = target.value;
|
|
1894
|
-
};
|
|
1895
|
-
handleSubmenuSearchInput = (submenuId, e) => {
|
|
1896
|
-
const target = e.target;
|
|
1897
|
-
const value = target.value;
|
|
1898
|
-
if (this.submenuQueries[submenuId] === value)
|
|
1899
|
-
return;
|
|
1900
|
-
this.submenuQueries = {
|
|
1901
|
-
...this.submenuQueries,
|
|
1902
|
-
[submenuId]: value,
|
|
1903
|
-
};
|
|
1904
|
-
// Position may change as items filter.
|
|
1905
|
-
requestAnimationFrame(() => this.popoverRefs.get(submenuId)?.updatePosition());
|
|
1906
|
-
};
|
|
1907
|
-
handleBarOverflowChange = (e) => {
|
|
1908
|
-
this.overflowIds = e.detail.overflowingIds || [];
|
|
1909
|
-
this.hamburgerActive = e.detail.hamburgerActive || false;
|
|
1910
|
-
};
|
|
1911
|
-
openOverflowPopover = () => {
|
|
1912
|
-
this.overflowPopoverOpen = true;
|
|
1913
|
-
};
|
|
1914
|
-
closeOverflowPopover = () => {
|
|
1915
|
-
this.overflowPopoverOpen = false;
|
|
1916
|
-
};
|
|
1917
1774
|
renderVerticalList(items, { depth, pathPrefix, autoOpenIds, searchable, searchQuery, searchPlaceholder, emptyText, submenuId, closePopover, }) {
|
|
1918
1775
|
const query = searchQuery ?? '';
|
|
1919
1776
|
const openFromSearch = autoOpenIds ?? new Set();
|
|
@@ -2069,6 +1926,7 @@ const LeNavigation = class {
|
|
|
2069
1926
|
emptyText: this.emptyText,
|
|
2070
1927
|
}))));
|
|
2071
1928
|
}
|
|
1929
|
+
get el() { return getElement(this); }
|
|
2072
1930
|
static get watchers() { return {
|
|
2073
1931
|
"items": ["handleLayoutInputsChange"],
|
|
2074
1932
|
"orientation": ["handleLayoutInputsChange"],
|
|
@@ -2086,6 +1944,7 @@ const lePopoverCss = () => `/* ============================================
|
|
|
2086
1944
|
:host {
|
|
2087
1945
|
display: inline-block;
|
|
2088
1946
|
position: relative;
|
|
1947
|
+
--le-popover-padding: var(--le-space-md, 12px);
|
|
2089
1948
|
}
|
|
2090
1949
|
|
|
2091
1950
|
:host([trigger-full-width]) {
|
|
@@ -2231,7 +2090,7 @@ const lePopoverCss = () => `/* ============================================
|
|
|
2231
2090
|
============================================ */
|
|
2232
2091
|
|
|
2233
2092
|
.le-popover-body {
|
|
2234
|
-
padding: var(--le-
|
|
2093
|
+
padding: var(--le-popover-padding);
|
|
2235
2094
|
}
|
|
2236
2095
|
|
|
2237
2096
|
/* ============================================
|
|
@@ -2251,80 +2110,109 @@ const LePopover = class {
|
|
|
2251
2110
|
registerInstance(this, hostRef);
|
|
2252
2111
|
this.lePopoverOpen = createEvent(this, "lePopoverOpen");
|
|
2253
2112
|
this.lePopoverClose = createEvent(this, "lePopoverClose");
|
|
2113
|
+
/**
|
|
2114
|
+
* Whether the popover is currently open
|
|
2115
|
+
*/
|
|
2116
|
+
this.open = false;
|
|
2117
|
+
/**
|
|
2118
|
+
* Position of the popover relative to its trigger
|
|
2119
|
+
*/
|
|
2120
|
+
this.position = 'bottom';
|
|
2121
|
+
/**
|
|
2122
|
+
* Alignment of the popover
|
|
2123
|
+
*/
|
|
2124
|
+
this.align = 'start';
|
|
2125
|
+
/**
|
|
2126
|
+
* Whether to show a close button in the header
|
|
2127
|
+
*/
|
|
2128
|
+
this.showClose = true;
|
|
2129
|
+
/**
|
|
2130
|
+
* Whether clicking outside closes the popover
|
|
2131
|
+
*/
|
|
2132
|
+
this.closeOnClickOutside = true;
|
|
2133
|
+
/**
|
|
2134
|
+
* Whether pressing Escape closes the popover
|
|
2135
|
+
*/
|
|
2136
|
+
this.closeOnEscape = true;
|
|
2137
|
+
/**
|
|
2138
|
+
* Offset from the trigger element (in pixels)
|
|
2139
|
+
*/
|
|
2140
|
+
this.offset = 8;
|
|
2141
|
+
/**
|
|
2142
|
+
* Minimum width for the popover (e.g., '200px', '15rem')
|
|
2143
|
+
*/
|
|
2144
|
+
this.minWidth = '200px';
|
|
2145
|
+
/**
|
|
2146
|
+
* Should the popover's trigger take full width of its container
|
|
2147
|
+
*/
|
|
2148
|
+
this.triggerFullWidth = false;
|
|
2149
|
+
this.isPositioned = false;
|
|
2150
|
+
this.uniqueId = `le-popover-${Math.random().toString(36).substr(2, 9)}`;
|
|
2151
|
+
this.scrollParents = [];
|
|
2152
|
+
this.isListeningForDismiss = false;
|
|
2153
|
+
this.handleDocumentPointerDown = (event) => {
|
|
2154
|
+
if (!this.open || !this.closeOnClickOutside)
|
|
2155
|
+
return;
|
|
2156
|
+
// If the click happens inside this popover component (trigger OR content), don't close.
|
|
2157
|
+
const path = (event.composedPath?.() ?? []);
|
|
2158
|
+
if (path.includes(this.el))
|
|
2159
|
+
return;
|
|
2160
|
+
this.hide();
|
|
2161
|
+
};
|
|
2162
|
+
this.handleDocumentKeyDown = (event) => {
|
|
2163
|
+
if (!this.open || !this.closeOnEscape)
|
|
2164
|
+
return;
|
|
2165
|
+
if (event.key !== 'Escape')
|
|
2166
|
+
return;
|
|
2167
|
+
// Only the top-most opened popover handles Escape.
|
|
2168
|
+
const top = openPopoverStack[openPopoverStack.length - 1];
|
|
2169
|
+
if (top !== this.el)
|
|
2170
|
+
return;
|
|
2171
|
+
event.preventDefault();
|
|
2172
|
+
event.stopPropagation();
|
|
2173
|
+
this.hide();
|
|
2174
|
+
};
|
|
2175
|
+
this.handleScroll = () => {
|
|
2176
|
+
if (this.open) {
|
|
2177
|
+
this._updatePosition();
|
|
2178
|
+
}
|
|
2179
|
+
};
|
|
2180
|
+
this.handlePopoverToggle = (event) => {
|
|
2181
|
+
if (event.newState === 'open') {
|
|
2182
|
+
this.handleOpened();
|
|
2183
|
+
}
|
|
2184
|
+
else {
|
|
2185
|
+
this.handleClosed();
|
|
2186
|
+
}
|
|
2187
|
+
};
|
|
2188
|
+
this.handleOtherPopoverOpen = (event) => {
|
|
2189
|
+
const customEvent = event;
|
|
2190
|
+
const openingPopover = customEvent.detail?.popover;
|
|
2191
|
+
if (!openingPopover)
|
|
2192
|
+
return;
|
|
2193
|
+
if (openingPopover === this.el)
|
|
2194
|
+
return;
|
|
2195
|
+
// Allow nested popovers (e.g., le-select inside another popover).
|
|
2196
|
+
// Use a shadow-DOM-aware containment check.
|
|
2197
|
+
if (this.shadowContains(this.el, openingPopover) ||
|
|
2198
|
+
this.shadowContains(openingPopover, this.el)) {
|
|
2199
|
+
return;
|
|
2200
|
+
}
|
|
2201
|
+
if (this.open) {
|
|
2202
|
+
this.hide();
|
|
2203
|
+
}
|
|
2204
|
+
};
|
|
2205
|
+
this.handleTriggerClick = (event) => {
|
|
2206
|
+
event.stopPropagation();
|
|
2207
|
+
this.toggle();
|
|
2208
|
+
};
|
|
2254
2209
|
}
|
|
2255
|
-
get el() { return getElement(this); }
|
|
2256
|
-
/**
|
|
2257
|
-
* Mode of the popover should be 'default' for internal use
|
|
2258
|
-
*/
|
|
2259
|
-
mode;
|
|
2260
|
-
/**
|
|
2261
|
-
* Whether the popover is currently open
|
|
2262
|
-
*/
|
|
2263
|
-
open = false;
|
|
2264
|
-
/**
|
|
2265
|
-
* Position of the popover relative to its trigger
|
|
2266
|
-
*/
|
|
2267
|
-
position = 'bottom';
|
|
2268
|
-
/**
|
|
2269
|
-
* Alignment of the popover
|
|
2270
|
-
*/
|
|
2271
|
-
align = 'start';
|
|
2272
|
-
/**
|
|
2273
|
-
* Optional title for the popover header
|
|
2274
|
-
*/
|
|
2275
|
-
popoverTitle;
|
|
2276
|
-
/**
|
|
2277
|
-
* Whether to show a close button in the header
|
|
2278
|
-
*/
|
|
2279
|
-
showClose = true;
|
|
2280
|
-
/**
|
|
2281
|
-
* Whether clicking outside closes the popover
|
|
2282
|
-
*/
|
|
2283
|
-
closeOnClickOutside = true;
|
|
2284
|
-
/**
|
|
2285
|
-
* Whether pressing Escape closes the popover
|
|
2286
|
-
*/
|
|
2287
|
-
closeOnEscape = true;
|
|
2288
|
-
/**
|
|
2289
|
-
* Offset from the trigger element (in pixels)
|
|
2290
|
-
*/
|
|
2291
|
-
offset = 8;
|
|
2292
|
-
/**
|
|
2293
|
-
* Fixed width for the popover (e.g., '300px', '20rem')
|
|
2294
|
-
*/
|
|
2295
|
-
width;
|
|
2296
|
-
/**
|
|
2297
|
-
* Minimum width for the popover (e.g., '200px', '15rem')
|
|
2298
|
-
*/
|
|
2299
|
-
minWidth = '200px';
|
|
2300
|
-
/**
|
|
2301
|
-
* Maximum width for the popover (e.g., '400px', '25rem')
|
|
2302
|
-
*/
|
|
2303
|
-
maxWidth;
|
|
2304
|
-
/**
|
|
2305
|
-
* Should the popover's trigger take full width of its container
|
|
2306
|
-
*/
|
|
2307
|
-
triggerFullWidth = false;
|
|
2308
|
-
/**
|
|
2309
|
-
* Emitted when the popover opens
|
|
2310
|
-
*/
|
|
2311
|
-
lePopoverOpen;
|
|
2312
|
-
/**
|
|
2313
|
-
* Emitted when the popover closes
|
|
2314
|
-
*/
|
|
2315
|
-
lePopoverClose;
|
|
2316
2210
|
/**
|
|
2317
2211
|
* Method to update the popover position from a parent component
|
|
2318
2212
|
*/
|
|
2319
2213
|
async updatePosition() {
|
|
2320
2214
|
this._updatePosition();
|
|
2321
2215
|
}
|
|
2322
|
-
isPositioned = false;
|
|
2323
|
-
triggerEl;
|
|
2324
|
-
popoverEl;
|
|
2325
|
-
uniqueId = `le-popover-${Math.random().toString(36).substr(2, 9)}`;
|
|
2326
|
-
scrollParents = [];
|
|
2327
|
-
isListeningForDismiss = false;
|
|
2328
2216
|
get supportsPopoverApi() {
|
|
2329
2217
|
return typeof HTMLElement.prototype.showPopover === 'function';
|
|
2330
2218
|
}
|
|
@@ -2381,28 +2269,6 @@ const LePopover = class {
|
|
|
2381
2269
|
document.removeEventListener('keydown', this.handleDocumentKeyDown, true);
|
|
2382
2270
|
this.isListeningForDismiss = false;
|
|
2383
2271
|
}
|
|
2384
|
-
handleDocumentPointerDown = (event) => {
|
|
2385
|
-
if (!this.open || !this.closeOnClickOutside)
|
|
2386
|
-
return;
|
|
2387
|
-
// If the click happens inside this popover component (trigger OR content), don't close.
|
|
2388
|
-
const path = (event.composedPath?.() ?? []);
|
|
2389
|
-
if (path.includes(this.el))
|
|
2390
|
-
return;
|
|
2391
|
-
this.hide();
|
|
2392
|
-
};
|
|
2393
|
-
handleDocumentKeyDown = (event) => {
|
|
2394
|
-
if (!this.open || !this.closeOnEscape)
|
|
2395
|
-
return;
|
|
2396
|
-
if (event.key !== 'Escape')
|
|
2397
|
-
return;
|
|
2398
|
-
// Only the top-most opened popover handles Escape.
|
|
2399
|
-
const top = openPopoverStack[openPopoverStack.length - 1];
|
|
2400
|
-
if (top !== this.el)
|
|
2401
|
-
return;
|
|
2402
|
-
event.preventDefault();
|
|
2403
|
-
event.stopPropagation();
|
|
2404
|
-
this.hide();
|
|
2405
|
-
};
|
|
2406
2272
|
/**
|
|
2407
2273
|
* Find all scrollable parent elements
|
|
2408
2274
|
*/
|
|
@@ -2446,11 +2312,6 @@ const LePopover = class {
|
|
|
2446
2312
|
window.removeEventListener('resize', this.handleScroll);
|
|
2447
2313
|
this.scrollParents = [];
|
|
2448
2314
|
}
|
|
2449
|
-
handleScroll = () => {
|
|
2450
|
-
if (this.open) {
|
|
2451
|
-
this._updatePosition();
|
|
2452
|
-
}
|
|
2453
|
-
};
|
|
2454
2315
|
handleOpened() {
|
|
2455
2316
|
this.open = true;
|
|
2456
2317
|
// Track stack order for Escape handling.
|
|
@@ -2473,31 +2334,6 @@ const LePopover = class {
|
|
|
2473
2334
|
openPopoverStack.splice(index, 1);
|
|
2474
2335
|
this.lePopoverClose.emit();
|
|
2475
2336
|
}
|
|
2476
|
-
handlePopoverToggle = (event) => {
|
|
2477
|
-
if (event.newState === 'open') {
|
|
2478
|
-
this.handleOpened();
|
|
2479
|
-
}
|
|
2480
|
-
else {
|
|
2481
|
-
this.handleClosed();
|
|
2482
|
-
}
|
|
2483
|
-
};
|
|
2484
|
-
handleOtherPopoverOpen = (event) => {
|
|
2485
|
-
const customEvent = event;
|
|
2486
|
-
const openingPopover = customEvent.detail?.popover;
|
|
2487
|
-
if (!openingPopover)
|
|
2488
|
-
return;
|
|
2489
|
-
if (openingPopover === this.el)
|
|
2490
|
-
return;
|
|
2491
|
-
// Allow nested popovers (e.g., le-select inside another popover).
|
|
2492
|
-
// Use a shadow-DOM-aware containment check.
|
|
2493
|
-
if (this.shadowContains(this.el, openingPopover) ||
|
|
2494
|
-
this.shadowContains(openingPopover, this.el)) {
|
|
2495
|
-
return;
|
|
2496
|
-
}
|
|
2497
|
-
if (this.open) {
|
|
2498
|
-
this.hide();
|
|
2499
|
-
}
|
|
2500
|
-
};
|
|
2501
2337
|
/**
|
|
2502
2338
|
* Opens the popover
|
|
2503
2339
|
*/
|
|
@@ -2534,10 +2370,6 @@ const LePopover = class {
|
|
|
2534
2370
|
await this.show();
|
|
2535
2371
|
}
|
|
2536
2372
|
}
|
|
2537
|
-
handleTriggerClick = (event) => {
|
|
2538
|
-
event.stopPropagation();
|
|
2539
|
-
this.toggle();
|
|
2540
|
-
};
|
|
2541
2373
|
_updatePosition() {
|
|
2542
2374
|
if (!this.triggerEl || !this.popoverEl)
|
|
2543
2375
|
return;
|
|
@@ -2692,13 +2524,14 @@ const LePopover = class {
|
|
|
2692
2524
|
popoverStyles.minWidth = this.minWidth;
|
|
2693
2525
|
if (this.maxWidth)
|
|
2694
2526
|
popoverStyles.maxWidth = this.maxWidth;
|
|
2695
|
-
return (h(Host, { key: '
|
|
2527
|
+
return (h(Host, { key: 'c9adf9fa285b33fca47bd2caa54c3ad62f2784e1', "trigger-full-width": this.triggerFullWidth }, h("div", { key: 'e3f6c1441ec018325400e2673e012ba2939d359b', class: classnames('le-popover-trigger', {
|
|
2696
2528
|
'le-popover-trigger-full-width': this.triggerFullWidth,
|
|
2697
|
-
}), ref: el => (this.triggerEl = el), onClick: this.handleTriggerClick, part: "trigger" }, h("slot", { key: '
|
|
2529
|
+
}), ref: el => (this.triggerEl = el), onClick: this.handleTriggerClick, part: "trigger" }, h("slot", { key: '9ece065f14fedc62905406359f0b6ae25747403b', name: "trigger" }, h("button", { key: '816e450c49c441f315bd619c24a4c96ef3bbc164', type: "button", class: "le-popover-default-trigger" }, h("span", { key: '4408bf0edee9ccf6e3fa9147110793c94eed8a39' }, "\u2295")))), h("div", { key: '9061223ed8051dda88802b1fb54b455aafcd20a6', id: this.uniqueId, class: "le-popover-content",
|
|
2698
2530
|
// Always use manual mode so nested popovers can be open together.
|
|
2699
2531
|
// We implement click-outside and Escape handling ourselves.
|
|
2700
|
-
popover: "manual", ref: el => (this.popoverEl = el), style: popoverStyles, "data-fallback-open": this.supportsPopoverApi ? undefined : String(this.open) }, (this.popoverTitle || this.showClose) && (h("div", { key: '
|
|
2532
|
+
popover: "manual", ref: el => (this.popoverEl = el), style: popoverStyles, "data-fallback-open": this.supportsPopoverApi ? undefined : String(this.open) }, (this.popoverTitle || this.showClose) && (h("div", { key: '92f61d207bfd18693d5e610cdfca708afecadf9d', class: "le-popover-header" }, this.popoverTitle && h("span", { key: 'caeb2cfc8b500061bad1e8dc9cf36eff298ba7ed', class: "le-popover-title" }, this.popoverTitle), this.showClose && (h("button", { key: '3fc53cc7c0ae0bce3330613ecc90003db5028d69', type: "button", class: "le-popover-close", onClick: () => this.hide(), "aria-label": "Close" }, "\u00D7")))), h("div", { key: '829a9d5d78cb8b5d19dfb7c2afeda55faafaa8ac', class: "le-popover-body", part: "content" }, h("slot", { key: '684b41952086d22e7d3d79f6db02f7cbfd32bbf5' })))));
|
|
2701
2533
|
}
|
|
2534
|
+
get el() { return getElement(this); }
|
|
2702
2535
|
};
|
|
2703
2536
|
LePopover.style = lePopoverCss();
|
|
2704
2537
|
|
|
@@ -2712,79 +2545,93 @@ const LePopup = class {
|
|
|
2712
2545
|
this.leCancel = createEvent(this, "leCancel");
|
|
2713
2546
|
this.leOpen = createEvent(this, "leOpen");
|
|
2714
2547
|
this.leClose = createEvent(this, "leClose");
|
|
2548
|
+
/**
|
|
2549
|
+
* The mode of the Le Kit (e.g., 'default' or 'admin')
|
|
2550
|
+
*/
|
|
2551
|
+
this.mode = 'default';
|
|
2552
|
+
/**
|
|
2553
|
+
* Whether the popup is currently visible
|
|
2554
|
+
*/
|
|
2555
|
+
this.open = false;
|
|
2556
|
+
/**
|
|
2557
|
+
* Type of popup: alert (OK only), confirm (OK/Cancel), prompt (input + OK/Cancel), custom
|
|
2558
|
+
*/
|
|
2559
|
+
this.type = 'alert';
|
|
2560
|
+
/**
|
|
2561
|
+
* Whether the popup is modal (blocks interaction with page behind)
|
|
2562
|
+
*/
|
|
2563
|
+
this.modal = true;
|
|
2564
|
+
/**
|
|
2565
|
+
* Position of the popup on screen
|
|
2566
|
+
*/
|
|
2567
|
+
this.position = 'center';
|
|
2568
|
+
/**
|
|
2569
|
+
* Text for the confirm/OK button
|
|
2570
|
+
*/
|
|
2571
|
+
this.confirmText = 'OK';
|
|
2572
|
+
/**
|
|
2573
|
+
* Text for the cancel button
|
|
2574
|
+
*/
|
|
2575
|
+
this.cancelText = 'Cancel';
|
|
2576
|
+
/**
|
|
2577
|
+
* Placeholder text for prompt input
|
|
2578
|
+
*/
|
|
2579
|
+
this.placeholder = '';
|
|
2580
|
+
/**
|
|
2581
|
+
* Default value for prompt input
|
|
2582
|
+
*/
|
|
2583
|
+
this.defaultValue = '';
|
|
2584
|
+
/**
|
|
2585
|
+
* Whether clicking the backdrop closes the popup (modal only)
|
|
2586
|
+
*/
|
|
2587
|
+
this.closeOnBackdrop = true;
|
|
2588
|
+
/**
|
|
2589
|
+
* Internal state for prompt input value
|
|
2590
|
+
*/
|
|
2591
|
+
this.inputValue = '';
|
|
2592
|
+
this.handleDialogCancel = (e) => {
|
|
2593
|
+
e.preventDefault(); // Prevent default close to handle it ourselves
|
|
2594
|
+
this.handleCancel();
|
|
2595
|
+
};
|
|
2596
|
+
this.handleConfirm = () => {
|
|
2597
|
+
const result = {
|
|
2598
|
+
confirmed: true,
|
|
2599
|
+
value: this.type === 'prompt' ? this.inputValue : undefined,
|
|
2600
|
+
};
|
|
2601
|
+
this.leConfirm.emit(result);
|
|
2602
|
+
this.hide(true);
|
|
2603
|
+
};
|
|
2604
|
+
this.handleCancel = () => {
|
|
2605
|
+
const result = {
|
|
2606
|
+
confirmed: false,
|
|
2607
|
+
value: undefined,
|
|
2608
|
+
};
|
|
2609
|
+
this.leCancel.emit(result);
|
|
2610
|
+
this.hide(false);
|
|
2611
|
+
};
|
|
2612
|
+
this.handleBackdropClick = (e) => {
|
|
2613
|
+
// Check if click was on the dialog backdrop (outside the dialog box)
|
|
2614
|
+
if (this.closeOnBackdrop && e.target === this.dialogEl) {
|
|
2615
|
+
const rect = this.dialogEl.getBoundingClientRect();
|
|
2616
|
+
const clickedInDialog = e.clientX >= rect.left &&
|
|
2617
|
+
e.clientX <= rect.right &&
|
|
2618
|
+
e.clientY >= rect.top &&
|
|
2619
|
+
e.clientY <= rect.bottom;
|
|
2620
|
+
if (!clickedInDialog) {
|
|
2621
|
+
this.handleCancel();
|
|
2622
|
+
}
|
|
2623
|
+
}
|
|
2624
|
+
};
|
|
2625
|
+
this.handleInputChange = (e) => {
|
|
2626
|
+
this.inputValue = e.target.value;
|
|
2627
|
+
};
|
|
2628
|
+
this.handleKeyDown = (e) => {
|
|
2629
|
+
if (e.key === 'Enter' && this.type !== 'custom') {
|
|
2630
|
+
e.preventDefault();
|
|
2631
|
+
this.handleConfirm();
|
|
2632
|
+
}
|
|
2633
|
+
};
|
|
2715
2634
|
}
|
|
2716
|
-
get el() { return getElement(this); }
|
|
2717
|
-
/**
|
|
2718
|
-
* The mode of the Le Kit (e.g., 'default' or 'admin')
|
|
2719
|
-
*/
|
|
2720
|
-
mode = 'default';
|
|
2721
|
-
/**
|
|
2722
|
-
* Whether the popup is currently visible
|
|
2723
|
-
*/
|
|
2724
|
-
open = false;
|
|
2725
|
-
/**
|
|
2726
|
-
* Type of popup: alert (OK only), confirm (OK/Cancel), prompt (input + OK/Cancel), custom
|
|
2727
|
-
*/
|
|
2728
|
-
type = 'alert';
|
|
2729
|
-
/**
|
|
2730
|
-
* Optional title for the popup header
|
|
2731
|
-
*/
|
|
2732
|
-
popupTitle;
|
|
2733
|
-
/**
|
|
2734
|
-
* Message text to display (for alert/confirm/prompt types)
|
|
2735
|
-
*/
|
|
2736
|
-
message;
|
|
2737
|
-
/**
|
|
2738
|
-
* Whether the popup is modal (blocks interaction with page behind)
|
|
2739
|
-
*/
|
|
2740
|
-
modal = true;
|
|
2741
|
-
/**
|
|
2742
|
-
* Position of the popup on screen
|
|
2743
|
-
*/
|
|
2744
|
-
position = 'center';
|
|
2745
|
-
/**
|
|
2746
|
-
* Text for the confirm/OK button
|
|
2747
|
-
*/
|
|
2748
|
-
confirmText = 'OK';
|
|
2749
|
-
/**
|
|
2750
|
-
* Text for the cancel button
|
|
2751
|
-
*/
|
|
2752
|
-
cancelText = 'Cancel';
|
|
2753
|
-
/**
|
|
2754
|
-
* Placeholder text for prompt input
|
|
2755
|
-
*/
|
|
2756
|
-
placeholder = '';
|
|
2757
|
-
/**
|
|
2758
|
-
* Default value for prompt input
|
|
2759
|
-
*/
|
|
2760
|
-
defaultValue = '';
|
|
2761
|
-
/**
|
|
2762
|
-
* Whether clicking the backdrop closes the popup (modal only)
|
|
2763
|
-
*/
|
|
2764
|
-
closeOnBackdrop = true;
|
|
2765
|
-
/**
|
|
2766
|
-
* Internal state for prompt input value
|
|
2767
|
-
*/
|
|
2768
|
-
inputValue = '';
|
|
2769
|
-
/**
|
|
2770
|
-
* Emitted when the popup is confirmed (OK clicked)
|
|
2771
|
-
*/
|
|
2772
|
-
leConfirm;
|
|
2773
|
-
/**
|
|
2774
|
-
* Emitted when the popup is cancelled (Cancel clicked or dismissed)
|
|
2775
|
-
*/
|
|
2776
|
-
leCancel;
|
|
2777
|
-
/**
|
|
2778
|
-
* Emitted when the popup opens
|
|
2779
|
-
*/
|
|
2780
|
-
leOpen;
|
|
2781
|
-
/**
|
|
2782
|
-
* Emitted when the popup closes
|
|
2783
|
-
*/
|
|
2784
|
-
leClose;
|
|
2785
|
-
dialogEl;
|
|
2786
|
-
inputEl;
|
|
2787
|
-
resolvePromise;
|
|
2788
2635
|
componentWillLoad() {
|
|
2789
2636
|
this.inputValue = this.defaultValue;
|
|
2790
2637
|
}
|
|
@@ -2796,10 +2643,6 @@ const LePopup = class {
|
|
|
2796
2643
|
disconnectedCallback() {
|
|
2797
2644
|
this.dialogEl?.removeEventListener('cancel', this.handleDialogCancel);
|
|
2798
2645
|
}
|
|
2799
|
-
handleDialogCancel = (e) => {
|
|
2800
|
-
e.preventDefault(); // Prevent default close to handle it ourselves
|
|
2801
|
-
this.handleCancel();
|
|
2802
|
-
};
|
|
2803
2646
|
/**
|
|
2804
2647
|
* Opens the popup and returns a promise that resolves when closed
|
|
2805
2648
|
*/
|
|
@@ -2843,44 +2686,6 @@ const LePopup = class {
|
|
|
2843
2686
|
this.resolvePromise = undefined;
|
|
2844
2687
|
}
|
|
2845
2688
|
}
|
|
2846
|
-
handleConfirm = () => {
|
|
2847
|
-
const result = {
|
|
2848
|
-
confirmed: true,
|
|
2849
|
-
value: this.type === 'prompt' ? this.inputValue : undefined,
|
|
2850
|
-
};
|
|
2851
|
-
this.leConfirm.emit(result);
|
|
2852
|
-
this.hide(true);
|
|
2853
|
-
};
|
|
2854
|
-
handleCancel = () => {
|
|
2855
|
-
const result = {
|
|
2856
|
-
confirmed: false,
|
|
2857
|
-
value: undefined,
|
|
2858
|
-
};
|
|
2859
|
-
this.leCancel.emit(result);
|
|
2860
|
-
this.hide(false);
|
|
2861
|
-
};
|
|
2862
|
-
handleBackdropClick = (e) => {
|
|
2863
|
-
// Check if click was on the dialog backdrop (outside the dialog box)
|
|
2864
|
-
if (this.closeOnBackdrop && e.target === this.dialogEl) {
|
|
2865
|
-
const rect = this.dialogEl.getBoundingClientRect();
|
|
2866
|
-
const clickedInDialog = e.clientX >= rect.left &&
|
|
2867
|
-
e.clientX <= rect.right &&
|
|
2868
|
-
e.clientY >= rect.top &&
|
|
2869
|
-
e.clientY <= rect.bottom;
|
|
2870
|
-
if (!clickedInDialog) {
|
|
2871
|
-
this.handleCancel();
|
|
2872
|
-
}
|
|
2873
|
-
}
|
|
2874
|
-
};
|
|
2875
|
-
handleInputChange = (e) => {
|
|
2876
|
-
this.inputValue = e.target.value;
|
|
2877
|
-
};
|
|
2878
|
-
handleKeyDown = (e) => {
|
|
2879
|
-
if (e.key === 'Enter' && this.type !== 'custom') {
|
|
2880
|
-
e.preventDefault();
|
|
2881
|
-
this.handleConfirm();
|
|
2882
|
-
}
|
|
2883
|
-
};
|
|
2884
2689
|
hasSlot(name) {
|
|
2885
2690
|
return !!this.el.querySelector(`[slot="${name}"]`);
|
|
2886
2691
|
}
|
|
@@ -2908,8 +2713,9 @@ const LePopup = class {
|
|
|
2908
2713
|
}
|
|
2909
2714
|
render() {
|
|
2910
2715
|
const positionClass = `le-popup-position-${this.position}`;
|
|
2911
|
-
return (h("dialog", { key: '
|
|
2716
|
+
return (h("dialog", { key: '9a42c63b24b521264654847ff45ea026000a642d', class: `le-popup-dialog ${positionClass}`, part: "dialog", ref: el => (this.dialogEl = el), onClick: this.handleBackdropClick }, h("le-component", { key: 'a3f086d20a9e611f3907f039bbcf9f7054927fa5', component: "le-popup" }, h("div", { key: 'b2ee2bc7d9eb42f457541c8ffb20af52b7cde8e9', class: "le-popup-container", part: "container" }, this.renderHeader(), this.renderBody(), this.renderFooter()))));
|
|
2912
2717
|
}
|
|
2718
|
+
get el() { return getElement(this); }
|
|
2913
2719
|
};
|
|
2914
2720
|
LePopup.style = lePopupCss();
|
|
2915
2721
|
|
|
@@ -2918,13 +2724,10 @@ const leScrollProgressCss = () => `:host{display:block}:host([sticky]){position:
|
|
|
2918
2724
|
const LeScrollProgress = class {
|
|
2919
2725
|
constructor(hostRef) {
|
|
2920
2726
|
registerInstance(this, hostRef);
|
|
2727
|
+
this.progress = 0;
|
|
2728
|
+
this.rafId = null;
|
|
2729
|
+
this.targetEl = null;
|
|
2921
2730
|
}
|
|
2922
|
-
get el() { return getElement(this); }
|
|
2923
|
-
/** Boolean or selector string. */
|
|
2924
|
-
trackScrollProgress;
|
|
2925
|
-
progress = 0;
|
|
2926
|
-
rafId = null;
|
|
2927
|
-
targetEl = null;
|
|
2928
2731
|
componentWillLoad() {
|
|
2929
2732
|
this.updateProgress();
|
|
2930
2733
|
}
|
|
@@ -3016,8 +2819,9 @@ const LeScrollProgress = class {
|
|
|
3016
2819
|
}
|
|
3017
2820
|
render() {
|
|
3018
2821
|
const width = `${this.progress * 100}%`;
|
|
3019
|
-
return (h(Host, { key: '
|
|
2822
|
+
return (h(Host, { key: '4521900e44e8226280a6fc1d7431e24832057be3' }, h("div", { key: 'a0daeec6b1c39fd4b5cc3ae90f27e615fa9828ef', class: "track", part: "track", "aria-hidden": "true" }, h("div", { key: 'd2c683765627c5eea27483ce00c3eff734e8c87a', class: "fill", part: "fill", style: { width } }))));
|
|
3020
2823
|
}
|
|
2824
|
+
get el() { return getElement(this); }
|
|
3021
2825
|
static get watchers() { return {
|
|
3022
2826
|
"trackScrollProgress": ["onTrackChange"]
|
|
3023
2827
|
}; }
|
|
@@ -3032,72 +2836,91 @@ const LeSelect = class {
|
|
|
3032
2836
|
this.leChange = createEvent(this, "change");
|
|
3033
2837
|
this.leOpen = createEvent(this, "leOpen");
|
|
3034
2838
|
this.leClose = createEvent(this, "leClose");
|
|
2839
|
+
/**
|
|
2840
|
+
* The options to display in the dropdown.
|
|
2841
|
+
*/
|
|
2842
|
+
this.options = [];
|
|
2843
|
+
/**
|
|
2844
|
+
* Placeholder text when no option is selected.
|
|
2845
|
+
*/
|
|
2846
|
+
this.placeholder = 'Select an option';
|
|
2847
|
+
/**
|
|
2848
|
+
* Whether the select is disabled.
|
|
2849
|
+
*/
|
|
2850
|
+
this.disabled = false;
|
|
2851
|
+
/**
|
|
2852
|
+
* Whether selection is required.
|
|
2853
|
+
*/
|
|
2854
|
+
this.required = false;
|
|
2855
|
+
/**
|
|
2856
|
+
* Whether the select should take full width of its container.
|
|
2857
|
+
*/
|
|
2858
|
+
this.fullWidth = false;
|
|
2859
|
+
/**
|
|
2860
|
+
* Size variant of the select.
|
|
2861
|
+
*/
|
|
2862
|
+
this.size = 'medium';
|
|
2863
|
+
/**
|
|
2864
|
+
* Visual variant of the select.
|
|
2865
|
+
*/
|
|
2866
|
+
this.variant = 'default';
|
|
2867
|
+
/**
|
|
2868
|
+
* Whether the input is searchable.
|
|
2869
|
+
*/
|
|
2870
|
+
this.searchable = false;
|
|
2871
|
+
/**
|
|
2872
|
+
* Text to show when no options match the search.
|
|
2873
|
+
*/
|
|
2874
|
+
this.emptyText = 'No results found';
|
|
2875
|
+
/**
|
|
2876
|
+
* Whether the dropdown is currently open.
|
|
2877
|
+
*/
|
|
2878
|
+
this.open = false;
|
|
2879
|
+
this.searchQuery = '';
|
|
2880
|
+
this.filterOption = (option, query) => {
|
|
2881
|
+
if (!query)
|
|
2882
|
+
return true;
|
|
2883
|
+
const searchLower = query.toLowerCase();
|
|
2884
|
+
return (option.label.toLowerCase().includes(searchLower) ||
|
|
2885
|
+
(option.description?.toLowerCase().includes(searchLower) ?? false));
|
|
2886
|
+
};
|
|
2887
|
+
this.handleOptionSelect = (e) => {
|
|
2888
|
+
this.value = e.detail.value;
|
|
2889
|
+
this.selectedOption = e.detail.option;
|
|
2890
|
+
this.leChange.emit(e.detail);
|
|
2891
|
+
};
|
|
2892
|
+
this.handleDropdownOpen = () => {
|
|
2893
|
+
this.open = true;
|
|
2894
|
+
this.leOpen.emit();
|
|
2895
|
+
// Focus search input if searchable
|
|
2896
|
+
if (this.searchable) {
|
|
2897
|
+
setTimeout(() => {
|
|
2898
|
+
this.inputEl?.focus();
|
|
2899
|
+
}, 50);
|
|
2900
|
+
}
|
|
2901
|
+
};
|
|
2902
|
+
this.handleDropdownClose = () => {
|
|
2903
|
+
this.open = false;
|
|
2904
|
+
this.leClose.emit();
|
|
2905
|
+
};
|
|
2906
|
+
this.handleTriggerClick = () => {
|
|
2907
|
+
if (!this.disabled) {
|
|
2908
|
+
this.dropdownEl?.toggle();
|
|
2909
|
+
}
|
|
2910
|
+
};
|
|
2911
|
+
this.handleTriggerKeyDown = (e) => {
|
|
2912
|
+
if (this.disabled)
|
|
2913
|
+
return;
|
|
2914
|
+
if (e.key === 'Enter' || e.key === ' ' || e.key === 'ArrowDown') {
|
|
2915
|
+
e.preventDefault();
|
|
2916
|
+
this.dropdownEl?.show();
|
|
2917
|
+
}
|
|
2918
|
+
};
|
|
2919
|
+
this.handleSearchInput = (e) => {
|
|
2920
|
+
const target = e.target;
|
|
2921
|
+
this.searchQuery = target.value;
|
|
2922
|
+
};
|
|
3035
2923
|
}
|
|
3036
|
-
get el() { return getElement(this); }
|
|
3037
|
-
/**
|
|
3038
|
-
* The options to display in the dropdown.
|
|
3039
|
-
*/
|
|
3040
|
-
options = [];
|
|
3041
|
-
/**
|
|
3042
|
-
* The currently selected value.
|
|
3043
|
-
*/
|
|
3044
|
-
value;
|
|
3045
|
-
/**
|
|
3046
|
-
* Placeholder text when no option is selected.
|
|
3047
|
-
*/
|
|
3048
|
-
placeholder = 'Select an option';
|
|
3049
|
-
/**
|
|
3050
|
-
* Whether the select is disabled.
|
|
3051
|
-
*/
|
|
3052
|
-
disabled = false;
|
|
3053
|
-
/**
|
|
3054
|
-
* Whether selection is required.
|
|
3055
|
-
*/
|
|
3056
|
-
required = false;
|
|
3057
|
-
/**
|
|
3058
|
-
* Name attribute for form submission.
|
|
3059
|
-
*/
|
|
3060
|
-
name;
|
|
3061
|
-
/**
|
|
3062
|
-
* Whether the select should take full width of its container.
|
|
3063
|
-
*/
|
|
3064
|
-
fullWidth = false;
|
|
3065
|
-
/**
|
|
3066
|
-
* Size variant of the select.
|
|
3067
|
-
*/
|
|
3068
|
-
size = 'medium';
|
|
3069
|
-
/**
|
|
3070
|
-
* Visual variant of the select.
|
|
3071
|
-
*/
|
|
3072
|
-
variant = 'default';
|
|
3073
|
-
/**
|
|
3074
|
-
* Whether the input is searchable.
|
|
3075
|
-
*/
|
|
3076
|
-
searchable = false;
|
|
3077
|
-
/**
|
|
3078
|
-
* Text to show when no options match the search.
|
|
3079
|
-
*/
|
|
3080
|
-
emptyText = 'No results found';
|
|
3081
|
-
/**
|
|
3082
|
-
* Whether the dropdown is currently open.
|
|
3083
|
-
*/
|
|
3084
|
-
open = false;
|
|
3085
|
-
/**
|
|
3086
|
-
* Emitted when the selected value changes.
|
|
3087
|
-
*/
|
|
3088
|
-
leChange;
|
|
3089
|
-
/**
|
|
3090
|
-
* Emitted when the dropdown opens.
|
|
3091
|
-
*/
|
|
3092
|
-
leOpen;
|
|
3093
|
-
/**
|
|
3094
|
-
* Emitted when the dropdown closes.
|
|
3095
|
-
*/
|
|
3096
|
-
leClose;
|
|
3097
|
-
selectedOption;
|
|
3098
|
-
searchQuery = '';
|
|
3099
|
-
dropdownEl;
|
|
3100
|
-
inputEl;
|
|
3101
2924
|
handleValueChange() {
|
|
3102
2925
|
this.updateSelectedOption();
|
|
3103
2926
|
}
|
|
@@ -3126,49 +2949,6 @@ const LeSelect = class {
|
|
|
3126
2949
|
this.selectedOption = undefined;
|
|
3127
2950
|
}
|
|
3128
2951
|
}
|
|
3129
|
-
filterOption = (option, query) => {
|
|
3130
|
-
if (!query)
|
|
3131
|
-
return true;
|
|
3132
|
-
const searchLower = query.toLowerCase();
|
|
3133
|
-
return (option.label.toLowerCase().includes(searchLower) ||
|
|
3134
|
-
(option.description?.toLowerCase().includes(searchLower) ?? false));
|
|
3135
|
-
};
|
|
3136
|
-
handleOptionSelect = (e) => {
|
|
3137
|
-
this.value = e.detail.value;
|
|
3138
|
-
this.selectedOption = e.detail.option;
|
|
3139
|
-
this.leChange.emit(e.detail);
|
|
3140
|
-
};
|
|
3141
|
-
handleDropdownOpen = () => {
|
|
3142
|
-
this.open = true;
|
|
3143
|
-
this.leOpen.emit();
|
|
3144
|
-
// Focus search input if searchable
|
|
3145
|
-
if (this.searchable) {
|
|
3146
|
-
setTimeout(() => {
|
|
3147
|
-
this.inputEl?.focus();
|
|
3148
|
-
}, 50);
|
|
3149
|
-
}
|
|
3150
|
-
};
|
|
3151
|
-
handleDropdownClose = () => {
|
|
3152
|
-
this.open = false;
|
|
3153
|
-
this.leClose.emit();
|
|
3154
|
-
};
|
|
3155
|
-
handleTriggerClick = () => {
|
|
3156
|
-
if (!this.disabled) {
|
|
3157
|
-
this.dropdownEl?.toggle();
|
|
3158
|
-
}
|
|
3159
|
-
};
|
|
3160
|
-
handleTriggerKeyDown = (e) => {
|
|
3161
|
-
if (this.disabled)
|
|
3162
|
-
return;
|
|
3163
|
-
if (e.key === 'Enter' || e.key === ' ' || e.key === 'ArrowDown') {
|
|
3164
|
-
e.preventDefault();
|
|
3165
|
-
this.dropdownEl?.show();
|
|
3166
|
-
}
|
|
3167
|
-
};
|
|
3168
|
-
handleSearchInput = (e) => {
|
|
3169
|
-
const target = e.target;
|
|
3170
|
-
this.searchQuery = target.value;
|
|
3171
|
-
};
|
|
3172
2952
|
/**
|
|
3173
2953
|
* Opens the dropdown.
|
|
3174
2954
|
*/
|
|
@@ -3191,14 +2971,15 @@ const LeSelect = class {
|
|
|
3191
2971
|
}
|
|
3192
2972
|
render() {
|
|
3193
2973
|
const hasValue = this.selectedOption !== undefined;
|
|
3194
|
-
return (h("le-component", { key: '
|
|
2974
|
+
return (h("le-component", { key: 'cd0d10eb7ee1cc6f52fcb32bc3675e2f74219d9b', component: "le-select" }, h("le-dropdown-base", { key: '200e03a079caaa6c091f82d0384134a3e2d0154d', ref: el => (this.dropdownEl = el), options: this.parsedOptions, value: this.value, disabled: this.disabled, filterFn: this.searchable ? this.filterOption : undefined, filterQuery: this.searchQuery, onLeOptionSelect: this.handleOptionSelect, onLeDropdownOpen: this.handleDropdownOpen, onLeDropdownClose: this.handleDropdownClose, fullWidth: this.fullWidth }, h("le-button", { key: '0fa315cceaf6f18a5e370351027f27167fe64ce0', variant: this.variant && this.variant !== 'default' ? this.variant : 'outlined', slot: "trigger", align: "space-between", class: {
|
|
3195
2975
|
'select-trigger': true,
|
|
3196
2976
|
'has-value': hasValue,
|
|
3197
2977
|
'is-open': this.open,
|
|
3198
2978
|
}, mode: "default", size: this.size, disabled: this.disabled, "aria-haspopup": "listbox", "aria-expanded": this.open ? 'true' : 'false', onClick: this.handleTriggerClick, onKeyDown: this.handleTriggerKeyDown, fullWidth: this.fullWidth, iconStart: hasValue && this.selectedOption?.iconStart
|
|
3199
2979
|
? this.renderIcon(this.selectedOption.iconStart)
|
|
3200
|
-
: null, iconEnd: h("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("path", { d: "M4 6l4 4 4-4" })) }, h("span", { key: '
|
|
2980
|
+
: null, iconEnd: h("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("path", { d: "M4 6l4 4 4-4" })) }, h("span", { key: 'aae9bb220fb206622dbf6959f125c78adfb13e00', class: "trigger-label" }, hasValue ? this.selectedOption.label : this.placeholder)), this.searchable && this.open && (h("div", { key: '0e7e360672e2e7ce7d32dc726a450ccff245cee0', class: "multiselect-search", slot: "header" }, h("le-string-input", { key: 'a2a36fc139d4b477d35910541fab6071eddc3de5', mode: "default", inputRef: el => (this.inputEl = el), class: "search-input", placeholder: "Search...", value: this.searchQuery, onInput: this.handleSearchInput })))), this.name && h("input", { key: '9555b72d2f433ce9ee3803d0bb3ceb0dae1c37e3', type: "hidden", name: this.name, value: this.value?.toString() ?? '' })));
|
|
3201
2981
|
}
|
|
2982
|
+
get el() { return getElement(this); }
|
|
3202
2983
|
static get watchers() { return {
|
|
3203
2984
|
"value": ["handleValueChange"],
|
|
3204
2985
|
"options": ["handleOptionsChange"]
|
|
@@ -3212,97 +2993,100 @@ const LeSlot = class {
|
|
|
3212
2993
|
constructor(hostRef) {
|
|
3213
2994
|
registerInstance(this, hostRef);
|
|
3214
2995
|
this.leSlotChange = createEvent(this, "leSlotChange");
|
|
2996
|
+
/**
|
|
2997
|
+
* The type of slot content.
|
|
2998
|
+
* - `slot`: Default, shows a dropzone for components (default)
|
|
2999
|
+
* - `text`: Shows a single-line text input
|
|
3000
|
+
* - `textarea`: Shows a multi-line text area
|
|
3001
|
+
*/
|
|
3002
|
+
this.type = 'slot';
|
|
3003
|
+
/**
|
|
3004
|
+
* The name of the slot this placeholder represents.
|
|
3005
|
+
* Should match the slot name in the parent component.
|
|
3006
|
+
*/
|
|
3007
|
+
this.name = '';
|
|
3008
|
+
/**
|
|
3009
|
+
* Whether multiple components can be dropped in this slot.
|
|
3010
|
+
*/
|
|
3011
|
+
this.multiple = true;
|
|
3012
|
+
/**
|
|
3013
|
+
* Whether this slot is required to have content.
|
|
3014
|
+
*/
|
|
3015
|
+
this.required = false;
|
|
3016
|
+
/**
|
|
3017
|
+
* Internal state to track admin mode
|
|
3018
|
+
*/
|
|
3019
|
+
this.adminMode = false;
|
|
3020
|
+
/**
|
|
3021
|
+
* Internal state for text input value (synced from slot content)
|
|
3022
|
+
*/
|
|
3023
|
+
this.textValue = '';
|
|
3024
|
+
/**
|
|
3025
|
+
* Whether the current textValue contains valid HTML
|
|
3026
|
+
*/
|
|
3027
|
+
this.isValidHtml = true;
|
|
3028
|
+
/**
|
|
3029
|
+
* Available components loaded from Custom Elements Manifest
|
|
3030
|
+
*/
|
|
3031
|
+
this.availableComponents = [];
|
|
3032
|
+
/**
|
|
3033
|
+
* Whether the component picker popover is open
|
|
3034
|
+
*/
|
|
3035
|
+
this.pickerOpen = false;
|
|
3036
|
+
/**
|
|
3037
|
+
* Flag to prevent re-reading content right after we updated it
|
|
3038
|
+
*/
|
|
3039
|
+
this.isUpdating = false;
|
|
3040
|
+
this.handleTextInput = (event) => {
|
|
3041
|
+
const target = event.target;
|
|
3042
|
+
this.textValue = target.value;
|
|
3043
|
+
this.isValidHtml = this.validateHtml(this.textValue);
|
|
3044
|
+
if (this.isValidHtml) {
|
|
3045
|
+
// Set flag to prevent slotchange from re-reading what we just wrote
|
|
3046
|
+
this.isUpdating = true;
|
|
3047
|
+
console.log('Updating text value:', this.textValue, 'slottedElement:', this.slottedElement);
|
|
3048
|
+
if (this.slottedElement) {
|
|
3049
|
+
// Update existing slotted element's innerHTML
|
|
3050
|
+
this.slottedElement.innerHTML = this.textValue;
|
|
3051
|
+
}
|
|
3052
|
+
else if (this.tag && this.textValue) {
|
|
3053
|
+
// No slotted element exists
|
|
3054
|
+
// If the slot doesn't have a name, then it's the default slot
|
|
3055
|
+
// remove the existing non-slotted content (text nodes and elements without slot attribute)
|
|
3056
|
+
const rootNode = this.el.getRootNode();
|
|
3057
|
+
if (!this.name && rootNode instanceof ShadowRoot) {
|
|
3058
|
+
const hostComponent = rootNode.host;
|
|
3059
|
+
Array.from(hostComponent.childNodes).forEach(node => {
|
|
3060
|
+
if (node.nodeType === Node.TEXT_NODE || (node.nodeType === Node.ELEMENT_NODE && !node.hasAttribute('slot'))) {
|
|
3061
|
+
node.remove();
|
|
3062
|
+
}
|
|
3063
|
+
});
|
|
3064
|
+
}
|
|
3065
|
+
// create one using the specified tag
|
|
3066
|
+
this.createSlottedElement();
|
|
3067
|
+
}
|
|
3068
|
+
else if (this.textValue) {
|
|
3069
|
+
// no tag specified - just replace everything in the host component
|
|
3070
|
+
const rootNode = this.el.getRootNode();
|
|
3071
|
+
if (rootNode instanceof ShadowRoot) {
|
|
3072
|
+
const hostComponent = rootNode.host;
|
|
3073
|
+
hostComponent.innerHTML = this.textValue;
|
|
3074
|
+
}
|
|
3075
|
+
}
|
|
3076
|
+
}
|
|
3077
|
+
this.leSlotChange.emit({
|
|
3078
|
+
name: this.name,
|
|
3079
|
+
value: this.textValue,
|
|
3080
|
+
isValid: this.isValidHtml,
|
|
3081
|
+
});
|
|
3082
|
+
};
|
|
3083
|
+
/**
|
|
3084
|
+
* Handle slot change event to re-read content when nodes are assigned
|
|
3085
|
+
*/
|
|
3086
|
+
this.handleSlotChange = () => {
|
|
3087
|
+
this.readSlottedContent();
|
|
3088
|
+
};
|
|
3215
3089
|
}
|
|
3216
|
-
get el() { return getElement(this); }
|
|
3217
|
-
/**
|
|
3218
|
-
* The type of slot content.
|
|
3219
|
-
* - `slot`: Default, shows a dropzone for components (default)
|
|
3220
|
-
* - `text`: Shows a single-line text input
|
|
3221
|
-
* - `textarea`: Shows a multi-line text area
|
|
3222
|
-
*/
|
|
3223
|
-
type = 'slot';
|
|
3224
|
-
/**
|
|
3225
|
-
* The name of the slot this placeholder represents.
|
|
3226
|
-
* Should match the slot name in the parent component.
|
|
3227
|
-
*/
|
|
3228
|
-
name = '';
|
|
3229
|
-
/**
|
|
3230
|
-
* Label to display in admin mode.
|
|
3231
|
-
* If not provided, the slot name will be used.
|
|
3232
|
-
*/
|
|
3233
|
-
label;
|
|
3234
|
-
/**
|
|
3235
|
-
* Description of what content this slot accepts.
|
|
3236
|
-
* Shown in admin mode to guide content editors.
|
|
3237
|
-
*/
|
|
3238
|
-
description;
|
|
3239
|
-
/**
|
|
3240
|
-
* Comma-separated list of allowed component tags for this slot.
|
|
3241
|
-
* Used by CMS to filter available components.
|
|
3242
|
-
*
|
|
3243
|
-
* @example "le-card,le-button,le-text"
|
|
3244
|
-
*/
|
|
3245
|
-
allowedComponents;
|
|
3246
|
-
/**
|
|
3247
|
-
* Whether multiple components can be dropped in this slot.
|
|
3248
|
-
*/
|
|
3249
|
-
multiple = true;
|
|
3250
|
-
/**
|
|
3251
|
-
* Whether this slot is required to have content.
|
|
3252
|
-
*/
|
|
3253
|
-
required = false;
|
|
3254
|
-
/**
|
|
3255
|
-
* Placeholder text for text/textarea inputs in admin mode.
|
|
3256
|
-
*/
|
|
3257
|
-
placeholder;
|
|
3258
|
-
/**
|
|
3259
|
-
* The HTML tag to create when there's no slotted element.
|
|
3260
|
-
* Used with type="text" or type="textarea" to auto-create elements.
|
|
3261
|
-
*
|
|
3262
|
-
* @example "h3" - creates <h3 slot="header">content</h3>
|
|
3263
|
-
* @example "p" - creates <p slot="content">content</p>
|
|
3264
|
-
*/
|
|
3265
|
-
tag;
|
|
3266
|
-
/**
|
|
3267
|
-
* CSS styles for the slot dropzone container.
|
|
3268
|
-
* Useful for layouts - e.g., "flex-direction: row" for horizontal stacks.
|
|
3269
|
-
* Only applies in admin mode for type="slot".
|
|
3270
|
-
*/
|
|
3271
|
-
slotStyle;
|
|
3272
|
-
/**
|
|
3273
|
-
* Internal state to track admin mode
|
|
3274
|
-
*/
|
|
3275
|
-
adminMode = false;
|
|
3276
|
-
/**
|
|
3277
|
-
* Internal state for text input value (synced from slot content)
|
|
3278
|
-
*/
|
|
3279
|
-
textValue = '';
|
|
3280
|
-
/**
|
|
3281
|
-
* Whether the current textValue contains valid HTML
|
|
3282
|
-
*/
|
|
3283
|
-
isValidHtml = true;
|
|
3284
|
-
/**
|
|
3285
|
-
* Available components loaded from Custom Elements Manifest
|
|
3286
|
-
*/
|
|
3287
|
-
availableComponents = [];
|
|
3288
|
-
/**
|
|
3289
|
-
* Whether the component picker popover is open
|
|
3290
|
-
*/
|
|
3291
|
-
pickerOpen = false;
|
|
3292
|
-
/**
|
|
3293
|
-
* Reference to the slot element to access assignedNodes
|
|
3294
|
-
*/
|
|
3295
|
-
slotRef;
|
|
3296
|
-
/**
|
|
3297
|
-
* The original slotted element (e.g., <h3 slot="header">)
|
|
3298
|
-
*/
|
|
3299
|
-
slottedElement;
|
|
3300
|
-
/**
|
|
3301
|
-
* Emitted when text content changes in admin mode.
|
|
3302
|
-
* The event detail contains the new text value and validity.
|
|
3303
|
-
*/
|
|
3304
|
-
leSlotChange;
|
|
3305
|
-
disconnectModeObserver;
|
|
3306
3090
|
connectedCallback() {
|
|
3307
3091
|
this.disconnectModeObserver = observeModeChanges(this.el, mode => {
|
|
3308
3092
|
const wasAdmin = this.adminMode;
|
|
@@ -3321,10 +3105,6 @@ const LeSlot = class {
|
|
|
3321
3105
|
disconnectedCallback() {
|
|
3322
3106
|
this.disconnectModeObserver?.();
|
|
3323
3107
|
}
|
|
3324
|
-
/**
|
|
3325
|
-
* Flag to prevent re-reading content right after we updated it
|
|
3326
|
-
*/
|
|
3327
|
-
isUpdating = false;
|
|
3328
3108
|
/**
|
|
3329
3109
|
* Read content from slotted elements via assignedNodes()
|
|
3330
3110
|
*/
|
|
@@ -3388,49 +3168,6 @@ const LeSlot = class {
|
|
|
3388
3168
|
}
|
|
3389
3169
|
return true;
|
|
3390
3170
|
}
|
|
3391
|
-
handleTextInput = (event) => {
|
|
3392
|
-
const target = event.target;
|
|
3393
|
-
this.textValue = target.value;
|
|
3394
|
-
this.isValidHtml = this.validateHtml(this.textValue);
|
|
3395
|
-
if (this.isValidHtml) {
|
|
3396
|
-
// Set flag to prevent slotchange from re-reading what we just wrote
|
|
3397
|
-
this.isUpdating = true;
|
|
3398
|
-
console.log('Updating text value:', this.textValue, 'slottedElement:', this.slottedElement);
|
|
3399
|
-
if (this.slottedElement) {
|
|
3400
|
-
// Update existing slotted element's innerHTML
|
|
3401
|
-
this.slottedElement.innerHTML = this.textValue;
|
|
3402
|
-
}
|
|
3403
|
-
else if (this.tag && this.textValue) {
|
|
3404
|
-
// No slotted element exists
|
|
3405
|
-
// If the slot doesn't have a name, then it's the default slot
|
|
3406
|
-
// remove the existing non-slotted content (text nodes and elements without slot attribute)
|
|
3407
|
-
const rootNode = this.el.getRootNode();
|
|
3408
|
-
if (!this.name && rootNode instanceof ShadowRoot) {
|
|
3409
|
-
const hostComponent = rootNode.host;
|
|
3410
|
-
Array.from(hostComponent.childNodes).forEach(node => {
|
|
3411
|
-
if (node.nodeType === Node.TEXT_NODE || (node.nodeType === Node.ELEMENT_NODE && !node.hasAttribute('slot'))) {
|
|
3412
|
-
node.remove();
|
|
3413
|
-
}
|
|
3414
|
-
});
|
|
3415
|
-
}
|
|
3416
|
-
// create one using the specified tag
|
|
3417
|
-
this.createSlottedElement();
|
|
3418
|
-
}
|
|
3419
|
-
else if (this.textValue) {
|
|
3420
|
-
// no tag specified - just replace everything in the host component
|
|
3421
|
-
const rootNode = this.el.getRootNode();
|
|
3422
|
-
if (rootNode instanceof ShadowRoot) {
|
|
3423
|
-
const hostComponent = rootNode.host;
|
|
3424
|
-
hostComponent.innerHTML = this.textValue;
|
|
3425
|
-
}
|
|
3426
|
-
}
|
|
3427
|
-
}
|
|
3428
|
-
this.leSlotChange.emit({
|
|
3429
|
-
name: this.name,
|
|
3430
|
-
value: this.textValue,
|
|
3431
|
-
isValid: this.isValidHtml,
|
|
3432
|
-
});
|
|
3433
|
-
};
|
|
3434
3171
|
/**
|
|
3435
3172
|
* Create a new slotted element when none exists.
|
|
3436
3173
|
* The element is appended to the host component's light DOM.
|
|
@@ -3532,16 +3269,10 @@ const LeSlot = class {
|
|
|
3532
3269
|
isValid: true,
|
|
3533
3270
|
});
|
|
3534
3271
|
}
|
|
3535
|
-
/**
|
|
3536
|
-
* Handle slot change event to re-read content when nodes are assigned
|
|
3537
|
-
*/
|
|
3538
|
-
handleSlotChange = () => {
|
|
3539
|
-
this.readSlottedContent();
|
|
3540
|
-
};
|
|
3541
3272
|
render() {
|
|
3542
3273
|
const displayLabel = this.label || this.name;
|
|
3543
3274
|
// Always render the same structure, CSS handles visibility via .admin-mode class
|
|
3544
|
-
return (h(Host, { key: '
|
|
3275
|
+
return (h(Host, { key: 'fb2a01670291a714608bc59069991a8ef65dc3e9', class: {
|
|
3545
3276
|
'admin-mode': this.adminMode,
|
|
3546
3277
|
'invalid-html': !this.isValidHtml,
|
|
3547
3278
|
}, role: this.adminMode ? 'region' : undefined, "aria-label": this.adminMode ? `Slot: ${displayLabel}` : undefined, "data-slot-name": this.name, "data-slot-type": this.type, "data-allowed": this.allowedComponents, "data-multiple": this.multiple, "data-required": this.required }, this.adminMode ? (h("div", { class: "le-slot-container" }, h("div", { class: classnames('le-slot-header', {
|
|
@@ -3585,6 +3316,7 @@ const LeSlot = class {
|
|
|
3585
3316
|
return (h("div", { class: "le-slot-dropzone", style: dropzoneStyle }, h("slot", { ref: el => (this.slotRef = el), onSlotchange: this.handleSlotChange })));
|
|
3586
3317
|
}
|
|
3587
3318
|
}
|
|
3319
|
+
get el() { return getElement(this); }
|
|
3588
3320
|
};
|
|
3589
3321
|
LeSlot.style = leSlotDefaultCss();
|
|
3590
3322
|
|
|
@@ -3595,96 +3327,52 @@ const LeStringInput = class {
|
|
|
3595
3327
|
registerInstance(this, hostRef);
|
|
3596
3328
|
this.leChange = createEvent(this, "change");
|
|
3597
3329
|
this.leInput = createEvent(this, "input");
|
|
3330
|
+
/**
|
|
3331
|
+
* The type of the input (text, email, password, etc.)
|
|
3332
|
+
*/
|
|
3333
|
+
this.type = 'text';
|
|
3334
|
+
/**
|
|
3335
|
+
* Hide description slot
|
|
3336
|
+
*/
|
|
3337
|
+
this.hideDescription = false;
|
|
3338
|
+
/**
|
|
3339
|
+
* Whether the input is disabled
|
|
3340
|
+
*/
|
|
3341
|
+
this.disabled = false;
|
|
3342
|
+
/**
|
|
3343
|
+
* Whether the input is read-only
|
|
3344
|
+
*/
|
|
3345
|
+
this.readonly = false;
|
|
3346
|
+
this.handleInput = (ev) => {
|
|
3347
|
+
const input = ev.target;
|
|
3348
|
+
this.value = input.value;
|
|
3349
|
+
this.leInput.emit({
|
|
3350
|
+
value: this.value,
|
|
3351
|
+
name: this.name,
|
|
3352
|
+
externalId: this.externalId,
|
|
3353
|
+
});
|
|
3354
|
+
};
|
|
3355
|
+
this.handleChange = (ev) => {
|
|
3356
|
+
const input = ev.target;
|
|
3357
|
+
this.value = input.value;
|
|
3358
|
+
this.leChange.emit({
|
|
3359
|
+
value: this.value,
|
|
3360
|
+
name: this.name,
|
|
3361
|
+
externalId: this.externalId,
|
|
3362
|
+
});
|
|
3363
|
+
};
|
|
3364
|
+
this.handleClick = (ev) => {
|
|
3365
|
+
ev.stopPropagation();
|
|
3366
|
+
};
|
|
3598
3367
|
}
|
|
3599
|
-
get el() { return getElement(this); }
|
|
3600
|
-
/**
|
|
3601
|
-
* Pass the ref of the input element to the parent component
|
|
3602
|
-
*/
|
|
3603
|
-
inputRef;
|
|
3604
|
-
/**
|
|
3605
|
-
* Mode of the popover should be 'default' for internal use
|
|
3606
|
-
*/
|
|
3607
|
-
mode;
|
|
3608
|
-
/**
|
|
3609
|
-
* The value of the input
|
|
3610
|
-
*/
|
|
3611
|
-
value;
|
|
3612
|
-
/**
|
|
3613
|
-
* The name of the input
|
|
3614
|
-
*/
|
|
3615
|
-
name;
|
|
3616
|
-
/**
|
|
3617
|
-
* The type of the input (text, email, password, etc.)
|
|
3618
|
-
*/
|
|
3619
|
-
type = 'text';
|
|
3620
|
-
/**
|
|
3621
|
-
* Label for the input
|
|
3622
|
-
*/
|
|
3623
|
-
label;
|
|
3624
|
-
/**
|
|
3625
|
-
* Icon for the start icon
|
|
3626
|
-
*/
|
|
3627
|
-
iconStart;
|
|
3628
|
-
/**
|
|
3629
|
-
* Icon for the end icon
|
|
3630
|
-
*/
|
|
3631
|
-
iconEnd;
|
|
3632
|
-
/**
|
|
3633
|
-
* Placeholder text
|
|
3634
|
-
*/
|
|
3635
|
-
placeholder;
|
|
3636
|
-
/**
|
|
3637
|
-
* Hide description slot
|
|
3638
|
-
*/
|
|
3639
|
-
hideDescription = false;
|
|
3640
|
-
/**
|
|
3641
|
-
* Whether the input is disabled
|
|
3642
|
-
*/
|
|
3643
|
-
disabled = false;
|
|
3644
|
-
/**
|
|
3645
|
-
* Whether the input is read-only
|
|
3646
|
-
*/
|
|
3647
|
-
readonly = false;
|
|
3648
|
-
/**
|
|
3649
|
-
* External ID for linking with external systems
|
|
3650
|
-
*/
|
|
3651
|
-
externalId;
|
|
3652
|
-
/**
|
|
3653
|
-
* Emitted when the value changes (on blur or Enter)
|
|
3654
|
-
*/
|
|
3655
|
-
leChange;
|
|
3656
|
-
/**
|
|
3657
|
-
* Emitted when the input value changes (on keystroke)
|
|
3658
|
-
*/
|
|
3659
|
-
leInput;
|
|
3660
|
-
handleInput = (ev) => {
|
|
3661
|
-
const input = ev.target;
|
|
3662
|
-
this.value = input.value;
|
|
3663
|
-
this.leInput.emit({
|
|
3664
|
-
value: this.value,
|
|
3665
|
-
name: this.name,
|
|
3666
|
-
externalId: this.externalId,
|
|
3667
|
-
});
|
|
3668
|
-
};
|
|
3669
|
-
handleChange = (ev) => {
|
|
3670
|
-
const input = ev.target;
|
|
3671
|
-
this.value = input.value;
|
|
3672
|
-
this.leChange.emit({
|
|
3673
|
-
value: this.value,
|
|
3674
|
-
name: this.name,
|
|
3675
|
-
externalId: this.externalId,
|
|
3676
|
-
});
|
|
3677
|
-
};
|
|
3678
|
-
handleClick = (ev) => {
|
|
3679
|
-
ev.stopPropagation();
|
|
3680
|
-
};
|
|
3681
3368
|
render() {
|
|
3682
|
-
return (h("le-component", { key: '
|
|
3369
|
+
return (h("le-component", { key: 'b7d315a0bbe587dae606fec9ee3da32c16b773cb', component: "le-string-input", hostClass: classnames({ disabled: this.disabled }) }, h("div", { key: 'cfefdea8ce0625417cef62d0f432e13df652ab44', class: "le-input-wrapper" }, this.label && (h("label", { key: 'bfc0f2c440e00f2212c1ae9b0d3dd5b484ed0c5d', class: "le-input-label", htmlFor: this.name }, this.label)), h("div", { key: '324d58a4e798c4cd4d44c4f23760e38a24bfa4f6', class: "le-input-container", part: "container" }, this.iconStart && h("span", { key: '7851e3d9a30a304f2472e8de3dea1d6ce703b9ea', class: "icon-start" }, this.iconStart), h("input", { key: 'e51b775e8a9f8f55279ea91f04efbb0c5fdb4d1a', ref: el => {
|
|
3683
3370
|
if (this.inputRef) {
|
|
3684
3371
|
this.inputRef(el);
|
|
3685
3372
|
}
|
|
3686
|
-
}, id: this.name, type: this.type, name: this.name, value: this.value, placeholder: this.placeholder, disabled: this.disabled, readOnly: this.readonly, onInput: this.handleInput, onChange: this.handleChange, onClick: this.handleClick }), this.iconEnd && h("span", { key: '
|
|
3373
|
+
}, id: this.name, type: this.type, name: this.name, value: this.value, placeholder: this.placeholder, disabled: this.disabled, readOnly: this.readonly, onInput: this.handleInput, onChange: this.handleChange, onClick: this.handleClick }), this.iconEnd && h("span", { key: '7018ada874d6b1c85e88a93ba695d00c118c4a6a', class: "icon-end" }, this.iconEnd)), !this.hideDescription && (h("div", { key: '826a2853561ab428e82d879012bc7bfdad4b1dfe', class: "le-input-description" }, h("le-slot", { key: '3a6fc7a46fffacbef6e44fcaa7a80af365754d1c', name: "description", type: "text", tag: "p", label: "Description" }, h("slot", { key: 'b6bbe4efe29c88b1910a53f6704846bfd4280307', name: "description" })))))));
|
|
3687
3374
|
}
|
|
3375
|
+
get el() { return getElement(this); }
|
|
3688
3376
|
};
|
|
3689
3377
|
LeStringInput.style = leStringInputCss();
|
|
3690
3378
|
|