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