le-kit 0.1.15 → 0.1.16
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/dist/cjs/{index-C3iQZ-Ja.js → index-CHzu3ydp.js} +3 -3
- package/dist/cjs/index-CHzu3ydp.js.map +1 -0
- package/dist/cjs/index.cjs.js +2 -2
- package/dist/cjs/le-box.cjs.entry.js +2 -2
- package/dist/cjs/le-button.le-checkbox.le-collapse.le-component.le-current-heading.le-dropdown-base.le-header.le-popover.le-popup.le-scroll-progress.le-select.le-slot.le-string-input.entry.cjs.js.map +1 -0
- package/dist/cjs/{le-button_7.cjs.entry.js → le-button_13.cjs.entry.js} +1148 -21
- package/dist/cjs/le-card.cjs.entry.js +2 -2
- package/dist/cjs/le-combobox.cjs.entry.js +2 -2
- package/dist/cjs/le-header-placeholder.cjs.entry.js +18 -0
- package/dist/cjs/le-header-placeholder.entry.cjs.js.map +1 -0
- package/dist/cjs/le-kit.cjs.js +2 -2
- package/dist/cjs/le-multiselect.cjs.entry.js +4 -4
- package/dist/cjs/le-number-input.cjs.entry.js +3 -3
- package/dist/cjs/le-round-progress.cjs.entry.js +2 -2
- package/dist/cjs/le-segmented-control.cjs.entry.js +2 -2
- package/dist/cjs/le-stack.cjs.entry.js +3 -3
- package/dist/cjs/le-tab-bar.cjs.entry.js +2 -2
- package/dist/cjs/le-tab-panel.cjs.entry.js +3 -3
- package/dist/cjs/le-tab.cjs.entry.js +3 -3
- package/dist/cjs/le-tabs.cjs.entry.js +4 -4
- package/dist/cjs/le-tag.cjs.entry.js +2 -2
- package/dist/cjs/le-text.cjs.entry.js +2 -2
- package/dist/cjs/le-turntable.cjs.entry.js +2 -2
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/{utils-DjPcLPN9.js → utils-CYOKcOW8.js} +3 -3
- package/dist/cjs/{utils-DjPcLPN9.js.map → utils-CYOKcOW8.js.map} +1 -1
- package/dist/collection/collection-manifest.json +5 -0
- package/dist/collection/components/le-collapse/le-collapse.css +31 -0
- package/dist/collection/components/le-collapse/le-collapse.js +188 -0
- package/dist/collection/components/le-collapse/le-collapse.js.map +1 -0
- package/dist/collection/components/le-combobox/le-combobox.js +1 -1
- package/dist/collection/components/le-component/le-component.js +1 -1
- package/dist/collection/components/le-component/le-component.js.map +1 -1
- package/dist/collection/components/le-current-heading/le-current-heading.css +12 -0
- package/dist/collection/components/le-current-heading/le-current-heading.js +130 -0
- package/dist/collection/components/le-current-heading/le-current-heading.js.map +1 -0
- package/dist/collection/components/le-dropdown-base/le-dropdown-base.css +4 -0
- package/dist/collection/components/le-dropdown-base/le-dropdown-base.js +1 -1
- package/dist/collection/components/le-header/le-header.css +120 -0
- package/dist/collection/components/le-header/le-header.js +508 -0
- package/dist/collection/components/le-header/le-header.js.map +1 -0
- package/dist/collection/components/le-header-placeholder/le-header-placeholder.js +21 -0
- package/dist/collection/components/le-header-placeholder/le-header-placeholder.js.map +1 -0
- package/dist/collection/components/le-multiselect/le-multiselect.js +3 -3
- package/dist/collection/components/le-number-input/le-number-input.js +1 -1
- package/dist/collection/components/le-popover/le-popover.css +10 -0
- package/dist/collection/components/le-popover/le-popover.js +122 -13
- package/dist/collection/components/le-popover/le-popover.js.map +1 -1
- package/dist/collection/components/le-round-progress/le-round-progress.js +1 -1
- package/dist/collection/components/le-scroll-progress/le-scroll-progress.css +29 -0
- package/dist/collection/components/le-scroll-progress/le-scroll-progress.js +186 -0
- package/dist/collection/components/le-scroll-progress/le-scroll-progress.js.map +1 -0
- package/dist/collection/components/le-segmented-control/le-segmented-control.js +1 -1
- package/dist/collection/components/le-select/le-select.js +2 -2
- package/dist/collection/components/le-slot/le-slot.js +1 -1
- package/dist/collection/components/le-stack/le-stack.js +1 -1
- package/dist/collection/components/le-string-input/le-string-input.js +2 -2
- package/dist/collection/components/le-tab/le-tab.js +1 -1
- package/dist/collection/components/le-tab-bar/le-tab-bar.js +1 -1
- package/dist/collection/components/le-tab-panel/le-tab-panel.js +2 -2
- package/dist/collection/components/le-tabs/le-tabs.js +2 -2
- package/dist/collection/components/le-tag/le-tag.js +1 -1
- package/dist/collection/components/le-turntable/le-turntable.js +1 -1
- package/dist/collection/dist/components/assets/custom-elements.json +2029 -965
- package/dist/collection/dist/components/themes/base.css +4 -48
- package/dist/collection/dist/components/themes/index.css +3 -342
- package/dist/components/assets/custom-elements.json +2029 -965
- package/dist/components/index.js.map +1 -1
- package/dist/components/le-box.js +18 -7
- package/dist/components/le-box.js.map +1 -1
- package/dist/components/le-button.js +1 -1
- package/dist/components/le-button2.js +331 -31
- package/dist/components/le-button2.js.map +1 -1
- package/dist/components/le-card.js +18 -7
- package/dist/components/le-card.js.map +1 -1
- package/dist/components/le-checkbox.js +1 -1
- package/dist/components/le-collapse.d.ts +11 -0
- package/dist/components/le-collapse.js +144 -0
- package/dist/components/le-collapse.js.map +1 -0
- package/dist/components/le-combobox.js +15 -10
- package/dist/components/le-combobox.js.map +1 -1
- package/dist/components/le-component.js +1 -1
- package/dist/components/le-current-heading.d.ts +11 -0
- package/dist/components/le-current-heading.js +93 -0
- package/dist/components/le-current-heading.js.map +1 -0
- package/dist/components/le-dropdown-base2.js +2 -2
- package/dist/components/le-dropdown-base2.js.map +1 -1
- package/dist/components/le-header-placeholder.d.ts +11 -0
- package/dist/components/le-header-placeholder.js +37 -0
- package/dist/components/le-header-placeholder.js.map +1 -0
- package/dist/components/le-header.d.ts +11 -0
- package/dist/components/le-header.js +347 -0
- package/dist/components/le-header.js.map +1 -0
- package/dist/components/le-multiselect.js +17 -12
- package/dist/components/le-multiselect.js.map +1 -1
- package/dist/components/le-number-input.js +19 -8
- package/dist/components/le-number-input.js.map +1 -1
- package/dist/components/le-popover2.js +123 -14
- package/dist/components/le-popover2.js.map +1 -1
- package/dist/components/le-popup.js +1 -1
- package/dist/components/le-round-progress.js +1 -1
- package/dist/components/le-scroll-progress.d.ts +11 -0
- package/dist/components/le-scroll-progress.js +142 -0
- package/dist/components/le-scroll-progress.js.map +1 -0
- package/dist/components/le-segmented-control.js +19 -8
- package/dist/components/le-segmented-control.js.map +1 -1
- package/dist/components/le-select.js +1 -263
- package/dist/components/le-select.js.map +1 -1
- package/dist/components/le-slot.js +1 -1
- package/dist/components/le-stack.js +19 -8
- package/dist/components/le-stack.js.map +1 -1
- package/dist/components/le-string-input.js +1 -1
- package/dist/components/le-tab-bar.js +19 -8
- package/dist/components/le-tab-bar.js.map +1 -1
- package/dist/components/le-tab-panel.js +20 -9
- package/dist/components/le-tab-panel.js.map +1 -1
- package/dist/components/le-tab2.js +19 -8
- package/dist/components/le-tab2.js.map +1 -1
- package/dist/components/le-tabs.js +20 -9
- package/dist/components/le-tabs.js.map +1 -1
- package/dist/components/le-tag2.js +19 -8
- package/dist/components/le-tag2.js.map +1 -1
- package/dist/components/le-text.js +18 -7
- package/dist/components/le-text.js.map +1 -1
- package/dist/components/le-turntable.js +1 -1
- package/dist/components/themes/base.css +4 -48
- package/dist/components/themes/index.css +3 -342
- package/dist/docs.json +1089 -30
- package/dist/esm/{index-DzgCnDLJ.js → index-hmBwv43R.js} +3 -3
- package/dist/esm/index-hmBwv43R.js.map +1 -0
- package/dist/esm/index.js +2 -2
- package/dist/esm/le-box.entry.js +2 -2
- package/dist/esm/le-button.le-checkbox.le-collapse.le-component.le-current-heading.le-dropdown-base.le-header.le-popover.le-popup.le-scroll-progress.le-select.le-slot.le-string-input.entry.js.map +1 -0
- package/dist/esm/{le-button_7.entry.js → le-button_13.entry.js} +1143 -22
- package/dist/esm/le-card.entry.js +2 -2
- package/dist/esm/le-combobox.entry.js +2 -2
- package/dist/esm/le-header-placeholder.entry.js +16 -0
- package/dist/esm/le-header-placeholder.entry.js.map +1 -0
- package/dist/esm/le-kit.js +3 -3
- package/dist/esm/le-multiselect.entry.js +4 -4
- package/dist/esm/le-number-input.entry.js +3 -3
- package/dist/esm/le-round-progress.entry.js +2 -2
- package/dist/esm/le-segmented-control.entry.js +2 -2
- package/dist/esm/le-stack.entry.js +3 -3
- package/dist/esm/le-tab-bar.entry.js +2 -2
- package/dist/esm/le-tab-panel.entry.js +3 -3
- package/dist/esm/le-tab.entry.js +3 -3
- package/dist/esm/le-tabs.entry.js +4 -4
- package/dist/esm/le-tag.entry.js +2 -2
- package/dist/esm/le-text.entry.js +2 -2
- package/dist/esm/le-turntable.entry.js +2 -2
- package/dist/esm/loader.js +3 -3
- package/dist/esm/{utils-Dp5xFMCl.js → utils-DRTFlnxz.js} +3 -3
- package/dist/esm/{utils-Dp5xFMCl.js.map → utils-DRTFlnxz.js.map} +1 -1
- package/dist/le-kit/dist/components/assets/custom-elements.json +2029 -965
- package/dist/le-kit/dist/components/themes/base.css +4 -48
- package/dist/le-kit/dist/components/themes/index.css +3 -342
- package/dist/le-kit/index.esm.js +1 -1
- package/dist/le-kit/le-button.le-checkbox.le-collapse.le-component.le-current-heading.le-dropdown-base.le-header.le-popover.le-popup.le-scroll-progress.le-select.le-slot.le-string-input.entry.esm.js.map +1 -0
- package/dist/le-kit/le-header-placeholder.entry.esm.js.map +1 -0
- package/dist/le-kit/le-kit.css +1 -1
- package/dist/le-kit/le-kit.esm.js +1 -1
- package/dist/le-kit/{p-1f55a4a2.entry.js → p-13a4dc1d.entry.js} +2 -2
- package/dist/le-kit/{p-0bd7803f.entry.js → p-1a9e65d0.entry.js} +2 -2
- package/dist/le-kit/p-2708dc65.entry.js +2 -0
- package/dist/le-kit/p-2708dc65.entry.js.map +1 -0
- package/dist/le-kit/p-2b96a5bd.entry.js +2 -0
- package/dist/le-kit/p-2b96a5bd.entry.js.map +1 -0
- package/dist/le-kit/{p-7b180d58.entry.js → p-32cbb683.entry.js} +2 -2
- package/dist/le-kit/{p-71c78784.entry.js → p-476e1886.entry.js} +2 -2
- package/dist/le-kit/p-67d702f9.entry.js +2 -0
- package/dist/le-kit/{p-33612923.entry.js → p-6884e3e8.entry.js} +2 -2
- package/dist/le-kit/{p-6ecdad85.entry.js → p-704ad5e0.entry.js} +2 -2
- package/dist/le-kit/{p-432e8231.entry.js → p-88f9aa40.entry.js} +2 -2
- package/dist/le-kit/{p-91993261.entry.js → p-8dd8a487.entry.js} +2 -2
- package/dist/le-kit/{p-6ee06c44.entry.js → p-97b7658a.entry.js} +2 -2
- package/dist/le-kit/{p-a5d31d40.entry.js → p-c0925e92.entry.js} +2 -2
- package/dist/le-kit/{p-548d130b.entry.js → p-c2494a0d.entry.js} +2 -2
- package/dist/le-kit/{p-3a52c4de.entry.js → p-ded51018.entry.js} +2 -2
- package/dist/le-kit/{p-2c37f174.entry.js → p-e3db7974.entry.js} +2 -2
- package/dist/le-kit/{p-b66fd9e1.entry.js → p-f9b03aec.entry.js} +2 -2
- package/dist/le-kit/p-hmBwv43R.js +3 -0
- package/dist/le-kit/p-hmBwv43R.js.map +1 -0
- package/dist/le-kit/p-txKmCJHv.js +2 -0
- package/dist/le-kit/{p-DaA5gINj.js.map → p-txKmCJHv.js.map} +1 -1
- package/dist/themes/base.css +4 -48
- package/dist/themes/index.css +3 -342
- package/dist/types/components/le-collapse/le-collapse.d.ts +41 -0
- package/dist/types/components/le-current-heading/le-current-heading.d.ts +25 -0
- package/dist/types/components/le-header/le-header.d.ts +115 -0
- package/dist/types/components/le-header-placeholder/le-header-placeholder.d.ts +13 -0
- package/dist/types/components/le-popover/le-popover.d.ts +9 -0
- package/dist/types/components/le-scroll-progress/le-scroll-progress.d.ts +40 -0
- package/dist/types/components.d.ts +518 -0
- package/package.json +1 -1
- package/dist/cjs/index-C3iQZ-Ja.js.map +0 -1
- package/dist/cjs/le-button.le-checkbox.le-component.le-popover.le-popup.le-slot.le-string-input.entry.cjs.js.map +0 -1
- package/dist/cjs/le-dropdown-base.cjs.entry.js +0 -348
- package/dist/cjs/le-dropdown-base.entry.cjs.js.map +0 -1
- package/dist/cjs/le-select.cjs.entry.js +0 -188
- package/dist/cjs/le-select.entry.cjs.js.map +0 -1
- package/dist/esm/index-DzgCnDLJ.js.map +0 -1
- package/dist/esm/le-button.le-checkbox.le-component.le-popover.le-popup.le-slot.le-string-input.entry.js.map +0 -1
- package/dist/esm/le-dropdown-base.entry.js +0 -346
- package/dist/esm/le-dropdown-base.entry.js.map +0 -1
- package/dist/esm/le-select.entry.js +0 -186
- package/dist/esm/le-select.entry.js.map +0 -1
- package/dist/le-kit/le-button.le-checkbox.le-component.le-popover.le-popup.le-slot.le-string-input.entry.esm.js.map +0 -1
- package/dist/le-kit/le-dropdown-base.entry.esm.js.map +0 -1
- package/dist/le-kit/le-select.entry.esm.js.map +0 -1
- package/dist/le-kit/p-4130c60b.entry.js +0 -2
- package/dist/le-kit/p-4130c60b.entry.js.map +0 -1
- package/dist/le-kit/p-DaA5gINj.js +0 -2
- package/dist/le-kit/p-DzgCnDLJ.js +0 -3
- package/dist/le-kit/p-DzgCnDLJ.js.map +0 -1
- package/dist/le-kit/p-beb87e61.entry.js +0 -2
- package/dist/le-kit/p-cc0797b0.entry.js +0 -2
- package/dist/le-kit/p-cc0797b0.entry.js.map +0 -1
- package/dist/le-kit/p-d504a369.entry.js +0 -2
- package/dist/le-kit/p-d504a369.entry.js.map +0 -1
- /package/dist/le-kit/{p-1f55a4a2.entry.js.map → p-13a4dc1d.entry.js.map} +0 -0
- /package/dist/le-kit/{p-0bd7803f.entry.js.map → p-1a9e65d0.entry.js.map} +0 -0
- /package/dist/le-kit/{p-7b180d58.entry.js.map → p-32cbb683.entry.js.map} +0 -0
- /package/dist/le-kit/{p-71c78784.entry.js.map → p-476e1886.entry.js.map} +0 -0
- /package/dist/le-kit/{p-beb87e61.entry.js.map → p-67d702f9.entry.js.map} +0 -0
- /package/dist/le-kit/{p-33612923.entry.js.map → p-6884e3e8.entry.js.map} +0 -0
- /package/dist/le-kit/{p-6ecdad85.entry.js.map → p-704ad5e0.entry.js.map} +0 -0
- /package/dist/le-kit/{p-432e8231.entry.js.map → p-88f9aa40.entry.js.map} +0 -0
- /package/dist/le-kit/{p-91993261.entry.js.map → p-8dd8a487.entry.js.map} +0 -0
- /package/dist/le-kit/{p-6ee06c44.entry.js.map → p-97b7658a.entry.js.map} +0 -0
- /package/dist/le-kit/{p-a5d31d40.entry.js.map → p-c0925e92.entry.js.map} +0 -0
- /package/dist/le-kit/{p-548d130b.entry.js.map → p-c2494a0d.entry.js.map} +0 -0
- /package/dist/le-kit/{p-3a52c4de.entry.js.map → p-ded51018.entry.js.map} +0 -0
- /package/dist/le-kit/{p-2c37f174.entry.js.map → p-e3db7974.entry.js.map} +0 -0
- /package/dist/le-kit/{p-b66fd9e1.entry.js.map → p-f9b03aec.entry.js.map} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as registerInstance, d as createEvent, c as getElement, h, F as Fragment,
|
|
2
|
-
import { c as classnames, o as observeModeChanges } from './utils-
|
|
1
|
+
import { r as registerInstance, d as createEvent, c as getElement, h, F as Fragment, H as Host, e as getAssetPath, f as getLeKitConfig } from './index-hmBwv43R.js';
|
|
2
|
+
import { c as classnames, o as observeModeChanges, g as generateId } from './utils-DRTFlnxz.js';
|
|
3
3
|
import { leConfirm } from './index.js';
|
|
4
4
|
|
|
5
5
|
const leButtonCss = ":host{display:inline-block;--le-button-border-radius:var(--le-radius-md);--le-button-padding-x:var(--le-spacing-3);--le-button-padding-y:var(--le-spacing-1);--le-button-padding:var(--le-button-padding-y) var(--le-button-padding-x);--le-button-small-padding:0.25rem;--le-button-font-size:var(--le-font-size-md);--le-button-font-weight:var(--le-font-weight-medium);--le-button-transition:var(--le-transition-fast);--le-transition-easing:ease-in-out;--le-button-icon-aspect-ratio:1;--le-button-color:var(--le-color-primary-contrast);--_btn-bg:var(--le-color-primary);--_btn-bg-hover:var(--le-color-primary-dark);--_btn-bg-system:var(--le-color-black);--_btn-color:var(--le-button-color);--_btn-border-color:var(--le-color-primary)}:host([full-width]){display:block;width:100%}.le-button-container{display:inline-flex;flex-direction:row;align-items:center;justify-content:center;gap:var(--le-spacing-3);width:100%;padding:var(--le-button-padding);border:1px solid var(--_btn-border-color);border-radius:var(--le-button-border-radius);background:var(--_btn-bg);color:var(--_btn-color);font-family:var(--le-font-family-base);font-size:var(--le-button-font-size);font-weight:var(--le-button-font-weight);line-height:var(--le-line-height-tight);text-decoration:none;cursor:pointer;transition:background-color var(--le-button-transition) var(--le-transition-easing),\n border-color var(--le-button-transition) var(--le-transition-easing),\n box-shadow var(--le-button-transition) var(--le-transition-easing),\n transform var(--le-button-transition) var(--le-transition-easing)}.le-button-container:hover:not(:disabled){background:var(--_btn-bg-hover);border-color:var(--_btn-bg-hover)}.le-button-container:active:not(:disabled){box-shadow:inset 0 0 6px var(--le-color-shadow)}.le-button-container:focus-visible{outline:2px solid var(--le-color-focus);outline-offset:2px}.le-button-container:disabled{opacity:0.5;cursor:not-allowed}.le-button-label{display:inline-flex;flex-direction:row;align-items:center;justify-content:center;gap:var(--le-spacing-2)}:host>le-component.color-primary{--_btn-bg:var(--le-color-primary);--_btn-bg-hover:var(--le-color-primary-dark);--_btn-color:var(--le-button-color);--_btn-border-color:var(--le-color-primary)}:host>le-component.color-secondary{--_btn-bg:var(--le-color-secondary);--_btn-bg-hover:var(--le-color-secondary-dark);--_btn-color:var(--le-color-secondary-contrast);--_btn-border-color:var(--le-color-secondary)}:host>le-component.color-success{--_btn-bg:var(--le-color-success);--_btn-bg-hover:var(--le-color-success-dark);--_btn-color:var(--le-color-success-contrast);--_btn-border-color:var(--le-color-success)}:host>le-component.color-warning{--_btn-bg:var(--le-color-warning);--_btn-bg-hover:var(--le-color-warning-dark);--_btn-color:var(--le-color-warning-contrast);--_btn-border-color:var(--le-color-warning)}:host>le-component.color-danger{--_btn-bg:var(--le-color-danger);--_btn-bg-hover:var(--le-color-danger-dark);--_btn-color:var(--le-color-danger-contrast);--_btn-border-color:var(--le-color-danger)}:host>le-component.color-info{--_btn-bg:var(--le-color-info);--_btn-bg-hover:var(--le-color-info-dark);--_btn-color:var(--le-color-info-contrast);--_btn-border-color:var(--le-color-info)}:host>le-component.variant-solid .le-button-container{box-shadow:var(--le-shadow-sm)}:host>le-component.variant-solid .le-button-container:hover:not(:disabled){box-shadow:var(--le-shadow-md)}:host>le-component.variant-outlined .le-button-container{background:transparent;color:var(--_btn-bg);border-color:color-mix(in srgb, var(--_btn-border-color) 33%, transparent)}:host>le-component.variant-outlined .le-button-container:hover:not(:disabled){border-color:var(--_btn-border-color)}:host>le-component.variant-clear .le-button-container{background:transparent;color:var(--_btn-bg);border-color:transparent}:host>le-component.variant-clear .le-button-container:hover:not(:disabled){background:var(--le-color-gray-100);border-color:transparent}:host>le-component.variant-system .le-button-container{background:transparent;color:var(--_btn-bg-system);border-color:transparent}:host>le-component.size-small .le-button-container{--le-button-padding-x:0.4rem;--le-button-padding-y:0.3rem;--le-button-padding-top:0.35rem;--le-button-font-size:var(--le-button-small-font-size, var(--le-font-size-xs))}:host>le-component.size-large .le-button-container{--le-button-padding-x:0.9rem;--le-button-padding-y:0.6rem;--le-button-font-size:var(--le-font-size-xl)}:host>le-component.full-width{display:block;width:100%}:host>le-component.selected .le-button-container{box-shadow:inset 0 0 4px var(--le-color-shadow)}:host>le-component.variant-outlined.selected .le-button-container,:host>le-component.variant-clear.selected .le-button-container{background:var(--_btn-bg);color:var(--_btn-color)}:host>le-component.icon-only .le-button-container{padding:0.5rem;padding-bottom:0.6rem;aspect-ratio:var(--le-button-icon-aspect-ratio, 1)}:host>le-component.icon-only.size-small .le-button-container{padding:var(--le-button-small-padding, 0.25rem)}:host>le-component.icon-only.size-large .le-button-container{padding:0.75rem}:host>le-component.icon-only .content{display:none}.content{display:inline}.content:empty{display:none}.icon-start,.icon-only,.icon-end{display:flex;align-items:center;justify-content:center}.icon-start:empty,.icon-only:empty,.icon-end:empty{display:none}::slotted([slot=\"icon-start\"]),::slotted([slot=\"icon-only\"]),::slotted([slot=\"icon-end\"]){display:flex;align-items:center;justify-content:center;width:1.125em;height:1.125em}.le-button-align-start{justify-content:flex-start}.le-button-align-center{justify-content:center}.le-button-align-space-between{justify-content:space-between}.le-button-align-end{justify-content:flex-end}";
|
|
@@ -155,6 +155,67 @@ const LeCheckbox = class {
|
|
|
155
155
|
};
|
|
156
156
|
LeCheckbox.style = leCheckboxCss;
|
|
157
157
|
|
|
158
|
+
const leCollapseCss = ":host{--le-collapse-duration:var(--le-transition-normal);display:grid;grid-template-rows:1fr;opacity:1;transition:grid-template-rows var(--le-collapse-duration),\n opacity var(--le-collapse-duration)}:host([data-open=\"false\"]),:host([open=\"false\"]){grid-template-rows:0fr;opacity:0}:host([no-fading][data-open=\"false\"]),:host([no-fading][open=\"false\"]){opacity:1}.region{display:flex;flex-direction:column;justify-content:flex-end;overflow:hidden}:host([scroll-down]) .region{justify-content:flex-start}";
|
|
159
|
+
|
|
160
|
+
const LeCollapse = class {
|
|
161
|
+
constructor(hostRef) {
|
|
162
|
+
registerInstance(this, hostRef);
|
|
163
|
+
}
|
|
164
|
+
get el() { return getElement(this); }
|
|
165
|
+
/** Whether the content should be shown. */
|
|
166
|
+
open = true;
|
|
167
|
+
/** Whether the content should scroll down from the top when open. */
|
|
168
|
+
scrollDown = false;
|
|
169
|
+
/** Stop fading the content when collapsing/expanding. */
|
|
170
|
+
noFading = false;
|
|
171
|
+
/** If true, collapse/expand based on the nearest header shrink event. */
|
|
172
|
+
collapseOnHeaderShrink = false;
|
|
173
|
+
/**
|
|
174
|
+
* Handles `leHeaderShrinkChange` events from the `le-header`.
|
|
175
|
+
* In case multiple headers are present, only the nearest one in the DOM tree is used.
|
|
176
|
+
*/
|
|
177
|
+
handleHeaderShrink(ev) {
|
|
178
|
+
const e = ev;
|
|
179
|
+
this.headerShrunk = !!e.detail?.shrunk;
|
|
180
|
+
}
|
|
181
|
+
headerShrunk = false;
|
|
182
|
+
componentWillLoad() {
|
|
183
|
+
// Stencil boolean props default to `false` when the attribute is missing.
|
|
184
|
+
// For this component, the desired default is open=true.
|
|
185
|
+
if (!this.el.hasAttribute('open')) {
|
|
186
|
+
this.open = true;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
componentDidLoad() {
|
|
190
|
+
this.applyOpenState();
|
|
191
|
+
}
|
|
192
|
+
onOpenChange() {
|
|
193
|
+
this.applyOpenState();
|
|
194
|
+
}
|
|
195
|
+
onDrivenStateChange() {
|
|
196
|
+
this.applyOpenState();
|
|
197
|
+
}
|
|
198
|
+
shouldBeOpen() {
|
|
199
|
+
if (!this.open)
|
|
200
|
+
return false;
|
|
201
|
+
if (this.collapseOnHeaderShrink && this.headerShrunk)
|
|
202
|
+
return false;
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
applyOpenState() {
|
|
206
|
+
const nextOpen = this.shouldBeOpen();
|
|
207
|
+
this.el.toggleAttribute('data-open', nextOpen);
|
|
208
|
+
}
|
|
209
|
+
render() {
|
|
210
|
+
return (h(Host, { key: '30fe288583bae1645ce00714de95c40ed92b7af0', "data-open": this.shouldBeOpen() ? 'true' : 'false' }, h("le-component", { key: '5fdc1e83caaff73fedb61d7286fc56f03fa8127a', component: "le-collapse" }, h("div", { key: '185df372a5039be23abf42ff262ef2d3eaa1602f', class: "region", part: "region" }, h("slot", { key: '1790f5457264342d71aecb94a67ce4ee11149af2' })))));
|
|
211
|
+
}
|
|
212
|
+
static get watchers() { return {
|
|
213
|
+
"open": ["onOpenChange"],
|
|
214
|
+
"headerShrunk": ["onDrivenStateChange"]
|
|
215
|
+
}; }
|
|
216
|
+
};
|
|
217
|
+
LeCollapse.style = leCollapseCss;
|
|
218
|
+
|
|
158
219
|
const leComponentCss = ":host{display:contents}:host(.admin-mode){display:block}.le-component-wrapper{position:relative;border:2px dashed var(--le-admin-border-color, #90caf9);border-radius:var(--le-radius-md, 8px);background:var(--le-admin-bg, rgba(144, 202, 249, 0.05));transition:border-color 0.2s ease, box-shadow 0.2s ease}.le-component-wrapper:hover{border-color:var(--le-admin-border-hover, #42a5f5);box-shadow:0 0 0 2px var(--le-admin-glow, rgba(66, 165, 245, 0.2))}.le-component-header{display:flex;align-items:center;justify-content:space-between;gap:var(--le-spacing-1, 4px);padding:0 0 0 var(--le-spacing-1, 4px);background:var(--le-admin-header-bg, rgba(144, 202, 249, 0.15));border-bottom:1px solid var(--le-admin-border-color, #90caf9);border-radius:var(--le-radius-md, 8px) var(--le-radius-md, 8px) 0 0;font-size:var(--le-font-size-xs, 11px)}.le-component-name{font-weight:var(--le-font-weight-medium, 500);color:var(--le-admin-text, #1976d2);text-transform:capitalize;text-align:start;overflow:hidden;width:0;flex:1 1 0%}.le-component-content{padding:var(--le-space-xs, 4px)}.le-component-trigger{font-size:24px;line-height:0px;width:12px;height:12px}.le-component-button{width:20px}.property-editor{display:flex;flex-direction:column;gap:var(--le-space-sm, 8px);max-width:380px}.property-field{display:flex;flex-direction:column;gap:var(--le-space-xs, 4px)}.property-field label{display:flex;flex-direction:column;gap:2px;font-size:var(--le-font-size-sm, 13px);font-weight:var(--le-font-weight-medium, 500);color:var(--le-color-text, #333)}.property-hint{font-size:var(--le-font-size-xs, 11px);font-weight:normal;color:var(--le-color-text-secondary, #666);line-height:1.3}.property-field input[type=\"text\"],.property-field input[type=\"number\"],.property-field select{padding:var(--le-space-xs, 4px) var(--le-space-sm, 8px);border:1px solid var(--le-color-border, #ddd);border-radius:var(--le-radius-md, 7px);font-size:var(--le-font-size-sm, 13px);font-family:inherit;background:var(--le-color-surface, #fff);color:var(--le-color-text, #333);transition:border-color 0.15s ease, box-shadow 0.15s ease}.property-field input:focus,.property-field select:focus{outline:none;border-color:var(--le-color-primary, #1976d2);box-shadow:0 0 0 2px var(--le-color-primary-light, rgba(25, 118, 210, 0.2))}.property-field--checkbox{flex-direction:column}.property-field--checkbox label{flex-direction:row;align-items:center;gap:var(--le-space-sm, 8px);cursor:pointer}.property-field--checkbox input[type=\"checkbox\"]{width:16px;height:16px;margin:0;cursor:pointer;accent-color:var(--le-color-primary, #1976d2)}.property-field--checkbox .property-hint{margin-left:24px}.no-properties{margin:0;padding:var(--le-space-sm, 8px);font-size:var(--le-font-size-sm, 13px);color:var(--le-color-text-secondary, #666);text-align:center}.property-editor-container{display:flex;flex-direction:column;gap:var(--le-space-md, 12px)}.property-editor-actions{padding-top:var(--le-space-sm, 8px);border-top:1px solid var(--le-color-border, #e5e5e5)}.delete-component-btn{display:flex;align-items:center;justify-content:center;gap:var(--le-space-xs, 4px);width:100%;padding:var(--le-space-sm, 8px) var(--le-space-md, 12px);border:1px solid var(--le-color-danger, #e53935);border-radius:var(--le-radius-md, 6px);background:transparent;color:var(--le-color-danger, #e53935);font-size:var(--le-font-size-sm, 13px);font-weight:500;cursor:pointer;transition:background-color 0.15s, color 0.15s}.delete-component-btn:hover{background:var(--le-color-danger, #e53935);color:white}.delete-component-btn:active{opacity:0.9}";
|
|
159
220
|
|
|
160
221
|
const LeComponent = class {
|
|
@@ -370,7 +431,7 @@ const LeComponent = class {
|
|
|
370
431
|
const enumMatch = type.match(/^'[^']+'/);
|
|
371
432
|
if (enumMatch) {
|
|
372
433
|
const options = type.split('|').map(opt => opt.trim().replace(/'/g, ''));
|
|
373
|
-
return (h("div", { class: "property-field" }, h("label", { htmlFor: `prop-${attr.name}` }, attr.name, attr.description && h("span", { class: "property-hint" }, attr.description)), h("select", {
|
|
434
|
+
return (h("div", { class: "property-field" }, h("label", { htmlFor: `prop-${attr.name}` }, attr.name, attr.description && h("span", { class: "property-hint" }, attr.description)), h("le-select", { options: [...options.map(opt => ({ label: opt, value: opt }))], "full-width": true, value: value ?? attr.default?.replace(/'/g, ''), placeholder: attr.default?.replace(/'/g, ''), onLeChange: (e) => this.handlePropertyChange(attr.name, e.detail.value, type) })));
|
|
374
435
|
}
|
|
375
436
|
// Boolean type
|
|
376
437
|
if (type === 'boolean') {
|
|
@@ -396,8 +457,669 @@ const LeComponent = class {
|
|
|
396
457
|
};
|
|
397
458
|
LeComponent.style = leComponentCss;
|
|
398
459
|
|
|
399
|
-
const
|
|
460
|
+
const leCurrentHeadingCss = ":host{display:inline-flex;min-width:0}.title{font:inherit;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}";
|
|
461
|
+
|
|
462
|
+
const LeCurrentHeading = class {
|
|
463
|
+
constructor(hostRef) {
|
|
464
|
+
registerInstance(this, hostRef);
|
|
465
|
+
}
|
|
466
|
+
get el() { return getElement(this); }
|
|
467
|
+
/** CSS selector for page title/headings to watch (e.g. `.page-title`, `main h2`). */
|
|
468
|
+
selector = '';
|
|
469
|
+
activeText = null;
|
|
470
|
+
componentWillLoad() {
|
|
471
|
+
this.updateActiveTitle();
|
|
472
|
+
}
|
|
473
|
+
onSelectorChange() {
|
|
474
|
+
this.updateActiveTitle();
|
|
475
|
+
}
|
|
476
|
+
onScroll() {
|
|
477
|
+
this.updateActiveTitle();
|
|
478
|
+
}
|
|
479
|
+
onResize() {
|
|
480
|
+
this.updateActiveTitle();
|
|
481
|
+
}
|
|
482
|
+
updateActiveTitle() {
|
|
483
|
+
if (typeof window === 'undefined')
|
|
484
|
+
return;
|
|
485
|
+
const selector = (this.selector ?? '').trim();
|
|
486
|
+
if (!selector) {
|
|
487
|
+
this.activeText = null;
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
let elements = [];
|
|
491
|
+
try {
|
|
492
|
+
elements = Array.from(document.querySelectorAll(selector));
|
|
493
|
+
}
|
|
494
|
+
catch {
|
|
495
|
+
this.activeText = null;
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
// Pick the last element that is fully above the viewport.
|
|
499
|
+
let nextText = null;
|
|
500
|
+
for (const element of elements) {
|
|
501
|
+
const rect = element.getBoundingClientRect();
|
|
502
|
+
if (rect.height > 0 && rect.bottom <= 0) {
|
|
503
|
+
const t = (element.textContent ?? '').trim();
|
|
504
|
+
if (t)
|
|
505
|
+
nextText = t;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
// Do not create oscillations: update only when the computed title changes.
|
|
509
|
+
if (nextText !== this.activeText) {
|
|
510
|
+
this.activeText = nextText;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
render() {
|
|
514
|
+
return (h(Host, { key: 'e6b473d3633eb8f194edf19e88850390f4319929' }, this.activeText ? (h("span", { class: "title", part: "title" }, this.activeText)) : (h("slot", null))));
|
|
515
|
+
}
|
|
516
|
+
static get watchers() { return {
|
|
517
|
+
"selector": ["onSelectorChange"]
|
|
518
|
+
}; }
|
|
519
|
+
};
|
|
520
|
+
LeCurrentHeading.style = leCurrentHeadingCss;
|
|
521
|
+
|
|
522
|
+
const leDropdownBaseCss = ":host{display:block;--le-dropdown-list-padding:var(--le-spacing-1);--le-dropdown-empty-padding:var(--le-spacing-4);--le-dropdown-option-radius:var(--le-radius-md);--le-dropdown-font-size:var(--le-font-size-sm);--le-dropdown-option-padding:var(--le-spacing-1) var(--le-spacing-2);--le-dropdown-group-padding:var(--le-spacing-2) var(--le-spacing-2) var(--le-spacing-1);--le-dropdown-group-font-size:var(--le-font-size-xs)}:host([disabled]){pointer-events:none;opacity:0.5}le-popover::part(content){overflow-y:auto;overflow-x:hidden;padding:var(--le-dropdown-list-padding, 0.25rem)}.dropdown-empty{padding:var(--le-dropdown-empty-padding);text-align:center;color:var(--le-color-text-secondary, #9ca3af);font-size:var(--le-dropdown-font-size)}.dropdown-group-header{padding:var(--le-dropdown-group-padding);font-size:var(--le-dropdown-group-font-size);font-weight:700;color:var(--le-color-text-secondary, #9ca3af);letter-spacing:0.05em}.dropdown-list{text-align:initial}.dropdown-separator{height:1px;margin:var(--le-dropdown-separator-margin, 0.25rem 0);background:var(--le-color-border, #e5e7eb)}.dropdown-option{display:flex;align-items:center;gap:var(--le-dropdown-option-gap, 0.5rem);padding:var(--le-dropdown-option-padding);font-size:var(--le-dropdown-font-size, 0.875rem);line-height:1.4;color:var(--le-color-text, #1f2937);border:1px solid transparent;border-radius:var(--le-dropdown-option-radius, 0.25rem);cursor:pointer;user-select:none;transition:background-color 0.1s ease}.dropdown-option:hover,.dropdown-option.is-focused{border-color:var(--le-color-border-hover, #d1d5db)}.dropdown-option.is-disabled{opacity:0.5;cursor:not-allowed}.dropdown-option.is-disabled:hover{background:transparent}.option-checkbox{display:flex;align-items:center;justify-content:center;width:1rem;height:1rem;border:2px solid var(--le-color-border, #d1d5db);border-radius:0.25rem;background:var(--le-color-surface, #fff);flex-shrink:0}.is-selected .option-checkbox{background:var(--le-color-primary, #3b82f6);border-color:var(--le-color-primary, #3b82f6);color:white}.option-checkbox svg{width:0.75rem;height:0.75rem}.option-icon-start,.option-icon-end{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:1.25rem;height:1.25rem}.option-icon-start img,.option-icon-end img{width:100%;height:100%;object-fit:contain}.option-content{flex:1;min-width:0;display:flex;flex-direction:column}.option-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.option-description{font-size:0.75rem;color:var(--le-color-text-muted, #6b7280);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.option-check{display:flex;align-items:center;justify-content:center;width:1rem;height:1rem;color:var(--le-color-primary, #3b82f6);flex-shrink:0}.option-check svg{width:1rem;height:1rem}";
|
|
523
|
+
|
|
524
|
+
const LeDropdownBase = class {
|
|
525
|
+
constructor(hostRef) {
|
|
526
|
+
registerInstance(this, hostRef);
|
|
527
|
+
this.leOptionSelect = createEvent(this, "leOptionSelect");
|
|
528
|
+
this.leDropdownOpen = createEvent(this, "leDropdownOpen");
|
|
529
|
+
this.leDropdownClose = createEvent(this, "leDropdownClose");
|
|
530
|
+
}
|
|
531
|
+
get el() { return getElement(this); }
|
|
532
|
+
/**
|
|
533
|
+
* The options to display in the dropdown.
|
|
534
|
+
*/
|
|
535
|
+
options = [];
|
|
536
|
+
/**
|
|
537
|
+
* Current value(s) - single value or array for multiselect.
|
|
538
|
+
*/
|
|
539
|
+
value;
|
|
540
|
+
/**
|
|
541
|
+
* Whether multiple selection is allowed.
|
|
542
|
+
*/
|
|
543
|
+
multiple = false;
|
|
544
|
+
/**
|
|
545
|
+
* Whether the dropdown is open.
|
|
546
|
+
*/
|
|
547
|
+
open = false;
|
|
548
|
+
/**
|
|
549
|
+
* Whether the dropdown is disabled.
|
|
550
|
+
*/
|
|
551
|
+
disabled = false;
|
|
552
|
+
/**
|
|
553
|
+
* Filter function for options.
|
|
554
|
+
* Return true to include the option.
|
|
555
|
+
*/
|
|
556
|
+
filterFn;
|
|
557
|
+
/**
|
|
558
|
+
* Current filter query string.
|
|
559
|
+
*/
|
|
560
|
+
filterQuery = '';
|
|
561
|
+
/**
|
|
562
|
+
* Placeholder text when no options match filter.
|
|
563
|
+
*/
|
|
564
|
+
emptyText = 'No options';
|
|
565
|
+
/**
|
|
566
|
+
* Whether to show checkboxes for multiselect mode.
|
|
567
|
+
*/
|
|
568
|
+
showCheckboxes = true;
|
|
569
|
+
/**
|
|
570
|
+
* Maximum height of the dropdown list.
|
|
571
|
+
*/
|
|
572
|
+
maxHeight = '300px';
|
|
573
|
+
/**
|
|
574
|
+
* Width of the dropdown. If not set, matches trigger width.
|
|
575
|
+
*/
|
|
576
|
+
width;
|
|
577
|
+
/**
|
|
578
|
+
* Sets the dropdown to full width of the trigger.
|
|
579
|
+
*/
|
|
580
|
+
fullWidth = false;
|
|
581
|
+
/**
|
|
582
|
+
* Whether to close the dropdown when clicking outside.
|
|
583
|
+
* (used to support combobox with input focus)
|
|
584
|
+
*/
|
|
585
|
+
closeOnClickOutside = true;
|
|
586
|
+
/**
|
|
587
|
+
* Emitted when an option is selected.
|
|
588
|
+
*/
|
|
589
|
+
leOptionSelect;
|
|
590
|
+
/**
|
|
591
|
+
* Emitted when the dropdown opens.
|
|
592
|
+
*/
|
|
593
|
+
leDropdownOpen;
|
|
594
|
+
/**
|
|
595
|
+
* Emitted when the dropdown closes.
|
|
596
|
+
*/
|
|
597
|
+
leDropdownClose;
|
|
598
|
+
focusedIndex = -1;
|
|
599
|
+
filteredOptions = [];
|
|
600
|
+
popoverEl;
|
|
601
|
+
listEl;
|
|
602
|
+
triggerWidth = 0;
|
|
603
|
+
handleOptionsChange() {
|
|
604
|
+
this.updateFilteredOptions();
|
|
605
|
+
}
|
|
606
|
+
componentWillLoad() {
|
|
607
|
+
this.updateFilteredOptions();
|
|
608
|
+
}
|
|
609
|
+
updateFilteredOptions() {
|
|
610
|
+
// Remember previously focused option
|
|
611
|
+
const focusedOption = this.filteredOptions[this.focusedIndex];
|
|
612
|
+
if (!this.filterQuery || !this.filterFn) {
|
|
613
|
+
this.filteredOptions = this.options;
|
|
614
|
+
}
|
|
615
|
+
else {
|
|
616
|
+
this.filteredOptions = this.options.filter(opt => this.filterFn(opt, this.filterQuery));
|
|
617
|
+
}
|
|
618
|
+
// try to maintain focus on same option if still present
|
|
619
|
+
if (focusedOption) {
|
|
620
|
+
const newIndex = this.filteredOptions.indexOf(focusedOption);
|
|
621
|
+
this.focusedIndex = newIndex >= 0 ? newIndex : this.getInitialFocusIndex();
|
|
622
|
+
}
|
|
623
|
+
else {
|
|
624
|
+
this.focusedIndex = -1;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
getSelectableOptions() {
|
|
628
|
+
return this.filteredOptions.filter(opt => !opt.disabled);
|
|
629
|
+
}
|
|
630
|
+
isSelected(option) {
|
|
631
|
+
const optValue = option.value ?? option.label;
|
|
632
|
+
if (this.multiple && Array.isArray(this.value)) {
|
|
633
|
+
setTimeout(() => {
|
|
634
|
+
this.popoverEl?.updatePosition();
|
|
635
|
+
}, 50);
|
|
636
|
+
return this.value.includes(optValue);
|
|
637
|
+
}
|
|
638
|
+
return this.value === optValue;
|
|
639
|
+
}
|
|
640
|
+
handleOptionClick(option, e) {
|
|
641
|
+
e.preventDefault();
|
|
642
|
+
e.stopPropagation();
|
|
643
|
+
if (option.disabled)
|
|
644
|
+
return;
|
|
645
|
+
this.leOptionSelect.emit({
|
|
646
|
+
value: option.value ?? option.label,
|
|
647
|
+
option,
|
|
648
|
+
});
|
|
649
|
+
// Close dropdown for single select
|
|
650
|
+
if (!this.multiple) {
|
|
651
|
+
this.hide();
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
handleKeyDown = (e) => {
|
|
655
|
+
if (!this.open)
|
|
656
|
+
return;
|
|
657
|
+
const optionCount = this.filteredOptions.length;
|
|
658
|
+
switch (e.key) {
|
|
659
|
+
case 'ArrowDown':
|
|
660
|
+
e.preventDefault();
|
|
661
|
+
// check for the next non-disabled option and focus
|
|
662
|
+
let nextIndex = this.focusedIndex < optionCount - 1 ? this.focusedIndex + 1 : 0;
|
|
663
|
+
while (this.filteredOptions[nextIndex].disabled) {
|
|
664
|
+
nextIndex = ++nextIndex < optionCount ? nextIndex : 0;
|
|
665
|
+
}
|
|
666
|
+
this.focusedIndex = nextIndex;
|
|
667
|
+
this.scrollToFocused();
|
|
668
|
+
break;
|
|
669
|
+
case 'ArrowUp':
|
|
670
|
+
e.preventDefault();
|
|
671
|
+
// check for the previous non-disabled option and focus
|
|
672
|
+
let prevIndex = this.focusedIndex > 0 ? this.focusedIndex - 1 : optionCount - 1;
|
|
673
|
+
while (this.filteredOptions[prevIndex].disabled) {
|
|
674
|
+
prevIndex = --prevIndex >= 0 ? prevIndex : optionCount - 1;
|
|
675
|
+
}
|
|
676
|
+
this.focusedIndex = prevIndex;
|
|
677
|
+
this.scrollToFocused();
|
|
678
|
+
break;
|
|
679
|
+
case 'Home':
|
|
680
|
+
e.preventDefault();
|
|
681
|
+
// check for the first non-disabled option and focus
|
|
682
|
+
let firstIndex = 0;
|
|
683
|
+
while (this.filteredOptions[firstIndex].disabled) {
|
|
684
|
+
firstIndex++;
|
|
685
|
+
if (firstIndex >= optionCount) {
|
|
686
|
+
firstIndex = -1;
|
|
687
|
+
break;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
this.focusedIndex = firstIndex;
|
|
691
|
+
this.scrollToFocused();
|
|
692
|
+
break;
|
|
693
|
+
case 'End':
|
|
694
|
+
e.preventDefault();
|
|
695
|
+
// check for the last non-disabled option and focus
|
|
696
|
+
let lastIndex = optionCount - 1;
|
|
697
|
+
while (this.filteredOptions[lastIndex].disabled) {
|
|
698
|
+
lastIndex--;
|
|
699
|
+
if (lastIndex < 0) {
|
|
700
|
+
lastIndex = -1;
|
|
701
|
+
break;
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
this.focusedIndex = lastIndex;
|
|
705
|
+
this.scrollToFocused();
|
|
706
|
+
break;
|
|
707
|
+
case 'Enter':
|
|
708
|
+
case ' ':
|
|
709
|
+
e.preventDefault();
|
|
710
|
+
if (this.focusedIndex >= 0 && this.focusedIndex < optionCount) {
|
|
711
|
+
const option = this.filteredOptions[this.focusedIndex];
|
|
712
|
+
if (!option || option.disabled)
|
|
713
|
+
return;
|
|
714
|
+
this.leOptionSelect.emit({
|
|
715
|
+
value: option.value ?? option.label,
|
|
716
|
+
option,
|
|
717
|
+
});
|
|
718
|
+
if (!this.multiple) {
|
|
719
|
+
this.hide();
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
break;
|
|
723
|
+
case 'Escape':
|
|
724
|
+
e.preventDefault();
|
|
725
|
+
this.hide();
|
|
726
|
+
break;
|
|
727
|
+
case 'Tab':
|
|
728
|
+
this.hide();
|
|
729
|
+
break;
|
|
730
|
+
}
|
|
731
|
+
};
|
|
732
|
+
scrollToFocused() {
|
|
733
|
+
if (!this.listEl || this.focusedIndex < 0)
|
|
734
|
+
return;
|
|
735
|
+
const focusedEl = this.listEl.querySelector(`[data-index="${this.focusedIndex}"]`);
|
|
736
|
+
if (focusedEl) {
|
|
737
|
+
focusedEl.scrollIntoView({ block: 'nearest' });
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
handlePopoverOpen = () => {
|
|
741
|
+
this.open = true;
|
|
742
|
+
this.focusedIndex = this.getInitialFocusIndex();
|
|
743
|
+
this.leDropdownOpen.emit();
|
|
744
|
+
// Add keyboard listener
|
|
745
|
+
document.addEventListener('keydown', this.handleKeyDown);
|
|
746
|
+
};
|
|
747
|
+
handlePopoverClose = () => {
|
|
748
|
+
this.open = false;
|
|
749
|
+
this.focusedIndex = -1;
|
|
750
|
+
this.leDropdownClose.emit();
|
|
751
|
+
// Remove keyboard listener
|
|
752
|
+
document.removeEventListener('keydown', this.handleKeyDown);
|
|
753
|
+
};
|
|
754
|
+
getInitialFocusIndex() {
|
|
755
|
+
// Focus on first selected option, or first option
|
|
756
|
+
const selectableOptions = this.getSelectableOptions();
|
|
757
|
+
const selectedIndex = selectableOptions.findIndex(opt => this.isSelected(opt));
|
|
758
|
+
return selectedIndex >= 0 ? selectedIndex : 0;
|
|
759
|
+
}
|
|
760
|
+
/**
|
|
761
|
+
* Opens the dropdown.
|
|
762
|
+
*/
|
|
763
|
+
async show() {
|
|
764
|
+
if (this.disabled)
|
|
765
|
+
return;
|
|
766
|
+
// Capture trigger width for matching dropdown width
|
|
767
|
+
const trigger = this.el.querySelector('[slot="trigger"]');
|
|
768
|
+
if (trigger) {
|
|
769
|
+
this.triggerWidth = trigger.offsetWidth;
|
|
770
|
+
}
|
|
771
|
+
await this.popoverEl?.show();
|
|
772
|
+
}
|
|
773
|
+
/**
|
|
774
|
+
* Closes the dropdown.
|
|
775
|
+
*/
|
|
776
|
+
async hide() {
|
|
777
|
+
await this.popoverEl?.hide();
|
|
778
|
+
}
|
|
779
|
+
/**
|
|
780
|
+
* Toggles the dropdown.
|
|
781
|
+
*/
|
|
782
|
+
async toggle() {
|
|
783
|
+
if (this.open) {
|
|
784
|
+
await this.hide();
|
|
785
|
+
}
|
|
786
|
+
else {
|
|
787
|
+
await this.show();
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
renderIcon(icon, className) {
|
|
791
|
+
if (!icon)
|
|
792
|
+
return null;
|
|
793
|
+
if (icon.startsWith('http') || icon.startsWith('/')) {
|
|
794
|
+
return h("img", { class: className, src: icon, alt: "" });
|
|
795
|
+
}
|
|
796
|
+
return h("span", { class: className }, icon);
|
|
797
|
+
}
|
|
798
|
+
renderOption(option, index) {
|
|
799
|
+
const isSelected = this.isSelected(option);
|
|
800
|
+
const isFocused = index === this.focusedIndex;
|
|
801
|
+
const optionId = option.id || generateId();
|
|
802
|
+
return (h("div", { class: {
|
|
803
|
+
'dropdown-option': true,
|
|
804
|
+
'is-selected': isSelected,
|
|
805
|
+
'is-focused': isFocused,
|
|
806
|
+
'is-disabled': !!option.disabled,
|
|
807
|
+
}, role: "option", id: optionId, "aria-selected": isSelected ? 'true' : 'false', "aria-disabled": option.disabled ? 'true' : undefined, "data-index": index, onClick: e => this.handleOptionClick(option, e), onMouseEnter: () => {
|
|
808
|
+
if (!option.disabled) {
|
|
809
|
+
this.focusedIndex = index;
|
|
810
|
+
}
|
|
811
|
+
} }, this.renderIcon(option.iconStart, 'option-icon-start'), h("div", { class: "option-content" }, h("span", { class: "option-label" }, option.label), option.description && h("span", { class: "option-description" }, option.description)), this.renderIcon(option.iconEnd, 'option-icon-end'), (!this.multiple || this.showCheckboxes) && isSelected && (h("span", { class: "option-check" }, h("svg", { viewBox: "0 0 16 16", fill: "currentColor" }, h("path", { d: "M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z" }))))));
|
|
812
|
+
}
|
|
813
|
+
renderOptions() {
|
|
814
|
+
if (this.filteredOptions.length === 0) {
|
|
815
|
+
return h("div", { class: "dropdown-empty" }, this.emptyText);
|
|
816
|
+
}
|
|
817
|
+
// Group options if they have group property
|
|
818
|
+
const grouped = new Map();
|
|
819
|
+
const ungrouped = [];
|
|
820
|
+
this.filteredOptions.forEach(opt => {
|
|
821
|
+
if (opt.group) {
|
|
822
|
+
const group = grouped.get(opt.group) || [];
|
|
823
|
+
group.push(opt);
|
|
824
|
+
grouped.set(opt.group, group);
|
|
825
|
+
}
|
|
826
|
+
else {
|
|
827
|
+
ungrouped.push(opt);
|
|
828
|
+
}
|
|
829
|
+
});
|
|
830
|
+
// Build flat list with group headers for index tracking
|
|
831
|
+
let globalIndex = 0;
|
|
832
|
+
const elements = [];
|
|
833
|
+
// Render ungrouped options first
|
|
834
|
+
ungrouped.forEach(opt => {
|
|
835
|
+
if (opt.separator === 'before') {
|
|
836
|
+
elements.push(h("div", { class: "dropdown-separator", role: "separator" }));
|
|
837
|
+
}
|
|
838
|
+
elements.push(this.renderOption(opt, globalIndex++));
|
|
839
|
+
if (opt.separator === 'after') {
|
|
840
|
+
elements.push(h("div", { class: "dropdown-separator", role: "separator" }));
|
|
841
|
+
}
|
|
842
|
+
});
|
|
843
|
+
// Render grouped options
|
|
844
|
+
grouped.forEach((options, groupLabel) => {
|
|
845
|
+
elements.push(h("div", { class: "dropdown-group-header", role: "presentation" }, groupLabel));
|
|
846
|
+
options.forEach(opt => {
|
|
847
|
+
elements.push(this.renderOption(opt, globalIndex++));
|
|
848
|
+
});
|
|
849
|
+
});
|
|
850
|
+
return elements;
|
|
851
|
+
}
|
|
852
|
+
render() {
|
|
853
|
+
const dropdownWidth = this.width || (this.triggerWidth ? `${this.triggerWidth}px` : undefined);
|
|
854
|
+
return (h(Host, { key: '838bef3556e494770fbb34cbff69c782ca717fe4' }, h("le-popover", { key: 'd72576e799c6cc065d3b0f3f1b918e84a7c5f690', ref: el => (this.popoverEl = el), position: "bottom", align: "start", showClose: false, closeOnClickOutside: this.closeOnClickOutside, closeOnEscape: true, offset: 4, width: dropdownWidth, minWidth: "150px", "trigger-full-width": this.fullWidth, onLePopoverOpen: this.handlePopoverOpen, onLePopoverClose: this.handlePopoverClose }, h("slot", { key: 'fbe84a553a126ad34f3ea159b182f825a065d1f6', name: "trigger", slot: "trigger" }), h("slot", { key: '957ac9208cdfe8be96a15979853e0b5cfdfc756f', name: "header" }), h("div", { key: '8c15f620b55035191979aca56514771c860051e3', class: "dropdown-list", role: "listbox", "aria-multiselectable": this.multiple ? 'true' : undefined, ref: el => (this.listEl = el), style: { maxHeight: this.maxHeight } }, this.renderOptions()))));
|
|
855
|
+
}
|
|
856
|
+
static get watchers() { return {
|
|
857
|
+
"options": ["handleOptionsChange"],
|
|
858
|
+
"filterQuery": ["handleOptionsChange"]
|
|
859
|
+
}; }
|
|
860
|
+
};
|
|
861
|
+
LeDropdownBase.style = leDropdownBaseCss;
|
|
862
|
+
|
|
863
|
+
const leHeaderCss = ":host{display:block;width:100%;--le-header-top-offset:0;--le-header-bg:var(--le-color-surface);--le-header-max-width:var(--le-header-max-width, auto);--le-header-margin:0 auto;--le-header-border:1px solid var(--le-color-border);--le-header-border-radius:0px;--le-header-shadow:var(--le-header-shadow, none);--le-header-color:var(--le-color-text);--le-header-content-max-width:800px;--le-header-padding-x:var(--le-space-md);--le-header-padding-y:var(--le-space-sm);--le-header-gap:var(--le-space-sm);--le-header-transition:var(--le-transition-normal);--le-header-z:1000}.header{width:100%;max-width:var(--le-header-max-width);margin:var(--le-header-margin);background:var(--le-header-bg);color:var(--le-header-color);border-bottom:var(--le-header-border);border-radius:var(--le-header-border-radius);box-shadow:var(--le-header-shadow)}:host(.is-fixed){position:fixed;top:var(--le-header-top-offset);left:0;right:0;z-index:var(--le-header-z)}:host(.is-sticky){position:sticky;top:var(--le-header-top-offset);z-index:var(--le-header-z)}:host(.is-static){position:relative}.inner{max-width:var(--le-header-content-max-width);margin:0 auto;padding:var(--le-header-padding-y) var(--le-header-padding-x)}.row{display:grid;grid-template-columns:minmax(0, 1fr) minmax(0, 2fr) minmax(0, 1fr);align-items:center;gap:var(--le-header-gap);transition:height var(--le-header-transition),\n padding var(--le-header-transition),\n transform var(--le-header-transition)}:host(.is-shrunk) .row{height:var(--le-header-height-condensed)}:host(.is-sticky.is-hidden){transform:translateY(-150%);transition:transform var(--le-header-transition)}:host(.is-sticky.is-revealed){transform:translateY(0);transition:transform var(--le-header-transition)}.start,.title,.end{min-width:0;display:flex;align-items:center}.start{justify-content:flex-start}.end{justify-content:flex-end}.title{justify-content:center;text-align:center}.title-slot ::slotted(*){white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.compact-title{font:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}";
|
|
864
|
+
|
|
865
|
+
const LeHeader = class {
|
|
866
|
+
constructor(hostRef) {
|
|
867
|
+
registerInstance(this, hostRef);
|
|
868
|
+
this.leHeaderState = createEvent(this, "leHeaderState");
|
|
869
|
+
this.leHeaderShrinkChange = createEvent(this, "leHeaderShrinkChange");
|
|
870
|
+
this.leHeaderVisibilityChange = createEvent(this, "leHeaderVisibilityChange");
|
|
871
|
+
}
|
|
872
|
+
get el() { return getElement(this); }
|
|
873
|
+
/** Force static positioning (default). Ignored if `sticky` or `fixed` are true. */
|
|
874
|
+
isStatic = false;
|
|
875
|
+
/** Sticky positioning (in-flow). Ignored if `fixed` is true. */
|
|
876
|
+
sticky = false;
|
|
877
|
+
/** Fixed positioning (out-of-flow). Takes precedence over `sticky`/`static`. */
|
|
878
|
+
fixed = false;
|
|
879
|
+
/**
|
|
880
|
+
* Sticky-only reveal behavior (hide on scroll down, show on scroll up).
|
|
881
|
+
* - missing/false: disabled
|
|
882
|
+
* - true/empty attribute: enabled with default threshold (16)
|
|
883
|
+
* - number (as string): enabled and used as threshold
|
|
884
|
+
*/
|
|
885
|
+
revealOnScroll;
|
|
886
|
+
/**
|
|
887
|
+
* Shrink trigger.
|
|
888
|
+
* - missing/0: disabled
|
|
889
|
+
* - number (px): shrink when scrollY >= that value (but never before header height)
|
|
890
|
+
* - css var name (e.g. --foo): shrink when scrollY >= resolved var value
|
|
891
|
+
* - selector (e.g. .page-title): shrink when that element scrolls out of view above the viewport
|
|
892
|
+
*/
|
|
893
|
+
shrinkOffset;
|
|
894
|
+
/**
|
|
895
|
+
* If true, expand the header when hovered
|
|
896
|
+
*/
|
|
897
|
+
expandOnHover = false;
|
|
898
|
+
/** Emits whenever scroll-driven state changes. */
|
|
899
|
+
leHeaderState;
|
|
900
|
+
/** Emits when the header shrinks/expands (only on change). */
|
|
901
|
+
leHeaderShrinkChange;
|
|
902
|
+
/** Emits when the header hides/shows (only on change). */
|
|
903
|
+
leHeaderVisibilityChange;
|
|
904
|
+
revealed = true;
|
|
905
|
+
shrunk = false;
|
|
906
|
+
placeholderHeight = null;
|
|
907
|
+
hoverActive = false;
|
|
908
|
+
disconnectModeObserver;
|
|
909
|
+
rafId = null;
|
|
910
|
+
measureRafId = null;
|
|
911
|
+
lastY = 0;
|
|
912
|
+
lastEmittedDirection = 'down';
|
|
913
|
+
headerEl;
|
|
914
|
+
shrinkSelectorEl;
|
|
915
|
+
setShrunk(next, y) {
|
|
916
|
+
if (next === this.shrunk)
|
|
917
|
+
return;
|
|
918
|
+
this.shrunk = next;
|
|
919
|
+
this.leHeaderShrinkChange.emit({ shrunk: this.shrunk, y });
|
|
920
|
+
}
|
|
921
|
+
componentDidLoad() {
|
|
922
|
+
if (typeof window === 'undefined')
|
|
923
|
+
return;
|
|
924
|
+
this.lastY = window.scrollY || 0;
|
|
925
|
+
this.scheduleMeasure(true);
|
|
926
|
+
this.scheduleUpdate(true);
|
|
927
|
+
}
|
|
928
|
+
disconnectedCallback() {
|
|
929
|
+
this.disconnectModeObserver?.();
|
|
930
|
+
if (this.rafId != null) {
|
|
931
|
+
cancelAnimationFrame(this.rafId);
|
|
932
|
+
this.rafId = null;
|
|
933
|
+
}
|
|
934
|
+
if (this.measureRafId != null) {
|
|
935
|
+
cancelAnimationFrame(this.measureRafId);
|
|
936
|
+
this.measureRafId = null;
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
onBehaviorPropsChange() {
|
|
940
|
+
this.scheduleUpdate(true);
|
|
941
|
+
this.scheduleMeasure(true);
|
|
942
|
+
}
|
|
943
|
+
onWindowScroll() {
|
|
944
|
+
this.scheduleUpdate();
|
|
945
|
+
}
|
|
946
|
+
onWindowResize() {
|
|
947
|
+
this.scheduleMeasure(true);
|
|
948
|
+
this.scheduleUpdate(true);
|
|
949
|
+
}
|
|
950
|
+
getPosition() {
|
|
951
|
+
if (this.fixed)
|
|
952
|
+
return 'fixed';
|
|
953
|
+
if (this.sticky)
|
|
954
|
+
return 'sticky';
|
|
955
|
+
return 'static';
|
|
956
|
+
}
|
|
957
|
+
parseRevealThreshold() {
|
|
958
|
+
// Only applies in sticky mode.
|
|
959
|
+
if (!this.sticky || this.fixed)
|
|
960
|
+
return null;
|
|
961
|
+
if (this.revealOnScroll == null)
|
|
962
|
+
return null;
|
|
963
|
+
const raw = String(this.revealOnScroll).trim();
|
|
964
|
+
if (raw === '' || raw === 'true')
|
|
965
|
+
return 16;
|
|
966
|
+
if (raw === 'false')
|
|
967
|
+
return null;
|
|
968
|
+
const n = Number(raw);
|
|
969
|
+
return Number.isFinite(n) ? Math.max(0, n) : 16;
|
|
970
|
+
}
|
|
971
|
+
resolveShrinkStartPx() {
|
|
972
|
+
const raw = (this.shrinkOffset ?? '').trim();
|
|
973
|
+
if (!raw || raw === '0')
|
|
974
|
+
return null;
|
|
975
|
+
// Numeric
|
|
976
|
+
const numeric = Number(raw);
|
|
977
|
+
if (Number.isFinite(numeric))
|
|
978
|
+
return Math.max(0, numeric);
|
|
979
|
+
// CSS variable name
|
|
980
|
+
if (raw.startsWith('--')) {
|
|
981
|
+
const value = getComputedStyle(document.documentElement).getPropertyValue(raw).trim();
|
|
982
|
+
const v = Number(value.replace('px', '').trim());
|
|
983
|
+
return Number.isFinite(v) ? Math.max(0, v) : null;
|
|
984
|
+
}
|
|
985
|
+
// Selector
|
|
986
|
+
try {
|
|
987
|
+
const el = document.querySelector(raw);
|
|
988
|
+
this.shrinkSelectorEl = el;
|
|
989
|
+
return null;
|
|
990
|
+
}
|
|
991
|
+
catch {
|
|
992
|
+
this.shrinkSelectorEl = null;
|
|
993
|
+
return null;
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
scheduleUpdate(force = false) {
|
|
997
|
+
if (this.rafId != null) {
|
|
998
|
+
if (!force)
|
|
999
|
+
return;
|
|
1000
|
+
cancelAnimationFrame(this.rafId);
|
|
1001
|
+
this.rafId = null;
|
|
1002
|
+
}
|
|
1003
|
+
this.rafId = requestAnimationFrame(() => {
|
|
1004
|
+
this.rafId = null;
|
|
1005
|
+
this.updateFromScroll();
|
|
1006
|
+
});
|
|
1007
|
+
}
|
|
1008
|
+
scheduleMeasure(force = false) {
|
|
1009
|
+
if (this.measureRafId != null && !force)
|
|
1010
|
+
return;
|
|
1011
|
+
this.measureRafId = requestAnimationFrame(() => {
|
|
1012
|
+
this.measureRafId = null;
|
|
1013
|
+
this.measurePlaceholderHeight();
|
|
1014
|
+
});
|
|
1015
|
+
}
|
|
1016
|
+
measurePlaceholderHeight() {
|
|
1017
|
+
// Measure the rendered header height once (and on resize/mode change).
|
|
1018
|
+
// This intentionally ignores scroll/shrink behavior; it should reserve the full header height.
|
|
1019
|
+
if (!this.headerEl)
|
|
1020
|
+
return;
|
|
1021
|
+
const next = Math.ceil(this.headerEl.getBoundingClientRect().height);
|
|
1022
|
+
if (!Number.isFinite(next) || next <= 0)
|
|
1023
|
+
return;
|
|
1024
|
+
if (next !== this.placeholderHeight) {
|
|
1025
|
+
this.placeholderHeight = next;
|
|
1026
|
+
// Publish to global root so placeholders anywhere can read it.
|
|
1027
|
+
if (typeof document !== 'undefined') {
|
|
1028
|
+
document.documentElement.style.setProperty('--le-header-height', `${next}px`);
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
updateFromScroll() {
|
|
1033
|
+
const y = typeof window !== 'undefined' ? window.scrollY || 0 : 0;
|
|
1034
|
+
const delta = y - this.lastY;
|
|
1035
|
+
const direction = delta < 0 ? 'up' : 'down';
|
|
1036
|
+
// Shrink behavior
|
|
1037
|
+
let computedShrunk = false;
|
|
1038
|
+
const headerHeight = Math.max(0, this.placeholderHeight ?? 0);
|
|
1039
|
+
const shrinkStartPx = typeof window !== 'undefined' ? this.resolveShrinkStartPx() : null;
|
|
1040
|
+
if (this.shrinkSelectorEl) {
|
|
1041
|
+
const rect = this.shrinkSelectorEl.getBoundingClientRect();
|
|
1042
|
+
computedShrunk = rect.bottom <= 0;
|
|
1043
|
+
}
|
|
1044
|
+
else if (shrinkStartPx != null) {
|
|
1045
|
+
const effectiveStart = Math.max(shrinkStartPx, headerHeight);
|
|
1046
|
+
computedShrunk = y >= effectiveStart;
|
|
1047
|
+
}
|
|
1048
|
+
// Hover override: when enabled and hovered, force expanded.
|
|
1049
|
+
const nextShrunk = this.expandOnHover && this.hoverActive ? false : computedShrunk;
|
|
1050
|
+
this.setShrunk(nextShrunk, y);
|
|
1051
|
+
// Reveal-on-scroll (sticky-only)
|
|
1052
|
+
const revealThreshold = this.parseRevealThreshold();
|
|
1053
|
+
if (revealThreshold != null) {
|
|
1054
|
+
// Always show the header near the top of the page.
|
|
1055
|
+
const topLock = Math.max(0, this.placeholderHeight ?? 0);
|
|
1056
|
+
if (y <= topLock) {
|
|
1057
|
+
if (!this.revealed) {
|
|
1058
|
+
this.revealed = true;
|
|
1059
|
+
this.leHeaderVisibilityChange.emit({ visible: true, y });
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
else if (Math.abs(delta) >= revealThreshold) {
|
|
1063
|
+
const nextRevealed = direction === 'up' || y <= 0;
|
|
1064
|
+
if (nextRevealed !== this.revealed) {
|
|
1065
|
+
this.revealed = nextRevealed;
|
|
1066
|
+
this.leHeaderVisibilityChange.emit({ visible: this.revealed, y });
|
|
1067
|
+
}
|
|
1068
|
+
this.lastEmittedDirection = direction;
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
else {
|
|
1072
|
+
if (!this.revealed) {
|
|
1073
|
+
this.revealed = true;
|
|
1074
|
+
this.leHeaderVisibilityChange.emit({ visible: true, y });
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
this.lastY = y;
|
|
1078
|
+
this.leHeaderState.emit({
|
|
1079
|
+
y,
|
|
1080
|
+
direction: this.lastEmittedDirection,
|
|
1081
|
+
revealed: this.revealed,
|
|
1082
|
+
shrunk: this.shrunk,
|
|
1083
|
+
});
|
|
1084
|
+
}
|
|
1085
|
+
render() {
|
|
1086
|
+
const position = this.getPosition();
|
|
1087
|
+
const hostClass = classnames('le-header', {
|
|
1088
|
+
'header-is-shrunk': this.shrunk,
|
|
1089
|
+
'is-fixed': position === 'fixed',
|
|
1090
|
+
'is-sticky': position === 'sticky',
|
|
1091
|
+
'is-static': position === 'static',
|
|
1092
|
+
'is-revealed': this.revealed,
|
|
1093
|
+
'is-hidden': !this.revealed,
|
|
1094
|
+
'is-shrunk': this.shrunk,
|
|
1095
|
+
});
|
|
1096
|
+
return (h(Host, { key: '3fc823975a0ebcae3cb799bf94e35a289813cd35', class: hostClass, onMouseEnter: () => {
|
|
1097
|
+
if (!this.expandOnHover)
|
|
1098
|
+
return;
|
|
1099
|
+
this.hoverActive = true;
|
|
1100
|
+
this.scheduleUpdate(true);
|
|
1101
|
+
}, onMouseLeave: () => {
|
|
1102
|
+
if (!this.expandOnHover)
|
|
1103
|
+
return;
|
|
1104
|
+
this.hoverActive = false;
|
|
1105
|
+
this.scheduleUpdate(true);
|
|
1106
|
+
} }, h("le-component", { key: 'bb8e3c5717112e427fd86a6af4231b33147769e7', component: "le-header" }, h("header", { key: 'da96d6a1eb91a85ea8050870895fcd13bdb28391', class: "header", part: "header", role: "banner", ref: el => (this.headerEl = el) }, h("div", { key: '04386a3d535189012655ee352822812349d386d7', class: "inner", part: "inner" }, h("div", { key: '4b1fc43ca08e981f3dc810a23c14e6ed3200a1de', class: "row", part: "row" }, h("div", { key: '8fad255865a0d2e2662f3ad1030d48f8586ae8c7', class: "start", part: "start" }, h("le-slot", { key: '702eeebfe3133dae44e5268848ce5cac81f3b306', name: "start", label: "Start", description: "Logo / back button / nav", "allowed-components": "le-button,le-text,le-tag,le-box,le-stack" }, h("slot", { key: 'bdd3478abbdcd46143ce8a79d096baab84d12588', name: "start" }))), h("div", { key: 'e5b7d3d42e28d80b2df89a3ab365a29b39544f14', class: "title", part: "title" }, h("le-slot", { key: 'b5a68c8baaf05769ea838ca0482fa1db52b03b3a', name: "title", label: "Title", description: "Header title", type: "text", tag: "span" }, h("span", { key: '91763f968886e052a637959253863e583da51b76', class: "title-slot", part: "title" }, h("slot", { key: '060be7c91cca50c26db56cd15ad5d38962c8003f', name: "title" })))), h("div", { key: '938222741cbe15e531ff355185c4f599a3d26147', class: "end", part: "end" }, h("le-slot", { key: '8e1c91426dc87f1bdcb98d33b7da4cc6988781cf', name: "end", label: "End", description: "Actions", "allowed-components": "le-button,le-text,le-tag,le-box,le-stack" }, h("slot", { key: '67e4bda7e7c754dda5a7d9505a9b451f2487f47b', name: "end" })))), h("div", { key: '84dfedd30ec9bd49b668b2e1676ce3712b9d2faf', class: "secondary", part: "secondary" }, h("le-slot", { key: '95c56a8e3dbaaf284b03d72f1d9ec01d24c148d2', name: "", label: "Secondary", description: "Secondary row content", "allowed-components": "le-tabs,le-tab-bar,le-select,le-combobox,le-text,le-stack,le-box" }, h("slot", { key: '240df8fc23a9bc4e7aa294c52b229c7abf7c427d' }))))))));
|
|
1107
|
+
}
|
|
1108
|
+
static get watchers() { return {
|
|
1109
|
+
"revealOnScroll": ["onBehaviorPropsChange"],
|
|
1110
|
+
"shrinkOffset": ["onBehaviorPropsChange"],
|
|
1111
|
+
"fixed": ["onBehaviorPropsChange"],
|
|
1112
|
+
"sticky": ["onBehaviorPropsChange"],
|
|
1113
|
+
"isStatic": ["onBehaviorPropsChange"]
|
|
1114
|
+
}; }
|
|
1115
|
+
};
|
|
1116
|
+
LeHeader.style = leHeaderCss;
|
|
1117
|
+
|
|
1118
|
+
const lePopoverCss = "/* ============================================\n le-popover.css\n Popover using native HTML Popover API\n ============================================ */\n\n:host {\n display: inline-block;\n position: relative;\n}\n\n:host([trigger-full-width]) {\n display: block;\n width: 100%;\n}\n\n/* ============================================\n Trigger\n ============================================ */\n\n.le-popover-trigger {\n display: inline-flex;\n cursor: pointer;\n}\n\n.le-popover-trigger-full-width {\n display: flex;\n width: 100%;\n}\n\n.le-popover-default-trigger {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 0;\n border: 1px solid var(--le-color-border, #e0e0e0);\n border-radius: var(--le-radius-md, 6px);\n background: var(--le-color-surface, #fff);\n color: var(--le-color-text-secondary, #666);\n font-size: 16px;\n cursor: pointer;\n transition: all var(--le-transition-fast, 0.15s ease);\n}\n\n.le-popover-default-trigger:hover {\n border-color: var(--le-color-primary, #2196f3);\n color: var(--le-color-primary, #2196f3);\n background: var(--le-color-primary-light, rgba(33, 150, 243, 0.1));\n}\n\n/* ============================================\n Popover Content (native popover)\n ============================================ */\n\n.le-popover-content {\n /* Reset native popover defaults */\n margin: 0;\n padding: 0;\n border: none;\n background: transparent;\n \n /* Positioning - will be set via JS */\n position: fixed;\n inset: unset;\n \n /* Styling */\n background: var(--le-color-surface, #ffffff);\n border: 1px solid var(--le-color-border, #e0e0e0);\n border-radius: var(--le-radius-lg, 8px);\n box-shadow: var(--le-shadow-lg, 0 4px 12px rgba(0, 0, 0, 0.15));\n overflow: hidden;\n font-family: var(--le-font-family, system-ui, -apple-system, sans-serif);\n font-size: var(--le-font-size-sm, 0.875rem);\n color: var(--le-color-text, #333);\n \n /* Animation */\n opacity: 0;\n transform: scale(0.95);\n transition: opacity 0.15s ease, transform 0.15s ease, display 0.15s ease allow-discrete;\n}\n\n/* When popover is open */\n.le-popover-content:popover-open {\n opacity: 1;\n transform: scale(1);\n}\n\n/* Fallback for browsers without the Popover API */\n.le-popover-content[data-fallback-open=\"false\"] {\n display: none;\n}\n\n.le-popover-content[data-fallback-open=\"true\"] {\n opacity: 1;\n transform: scale(1);\n}\n\n/* Starting style for animation (CSS Anchor Positioning spec) */\n@starting-style {\n .le-popover-content:popover-open {\n opacity: 0;\n transform: scale(0.95);\n }\n}\n\n/* ============================================\n Header\n ============================================ */\n\n.le-popover-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--le-space-xs, 4px) var(--le-space-xs, 4px) var(--le-space-xs, 4px) var(--le-space-sm, 8px);\n border-bottom: 1px solid var(--le-color-border, #e0e0e0);\n background: var(--le-color-surface-alt, #f9f9f9);\n min-height: 32px;\n}\n\n.le-popover-title {\n font-weight: var(--le-font-weight-semibold, 600);\n font-size: var(--le-font-size-sm, 0.875rem);\n color: var(--le-color-text, #333);\n}\n\n.le-popover-close {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n padding: 0;\n border: none;\n background: transparent;\n color: var(--le-color-text-secondary, #666);\n font-size: 18px;\n line-height: 1;\n cursor: pointer;\n border-radius: var(--le-radius-sm, 4px);\n transition: background-color 0.15s, color 0.15s;\n}\n\n.le-popover-close:hover {\n background: var(--le-color-surface-hover, rgba(0, 0, 0, 0.05));\n color: var(--le-color-text, #333);\n}\n\n/* ============================================\n Body\n ============================================ */\n\n.le-popover-body {\n padding: var(--le-space-md, 12px);\n}\n\n/* ============================================\n Scrollable content\n ============================================ */\n\n.le-popover-content[style*=\"overflow-y: auto\"] .le-popover-body {\n overflow-y: auto;\n}\n";
|
|
400
1119
|
|
|
1120
|
+
// Keep a simple stack so Escape closes the most recently opened popover first.
|
|
1121
|
+
// This also helps nested popovers behave naturally.
|
|
1122
|
+
const openPopoverStack = [];
|
|
401
1123
|
const LePopover = class {
|
|
402
1124
|
constructor(hostRef) {
|
|
403
1125
|
registerInstance(this, hostRef);
|
|
@@ -476,17 +1198,85 @@ const LePopover = class {
|
|
|
476
1198
|
popoverEl;
|
|
477
1199
|
uniqueId = `le-popover-${Math.random().toString(36).substr(2, 9)}`;
|
|
478
1200
|
scrollParents = [];
|
|
1201
|
+
isListeningForDismiss = false;
|
|
1202
|
+
get supportsPopoverApi() {
|
|
1203
|
+
return typeof HTMLElement.prototype.showPopover === 'function';
|
|
1204
|
+
}
|
|
1205
|
+
shadowContains(container, node) {
|
|
1206
|
+
let current = node;
|
|
1207
|
+
while (current) {
|
|
1208
|
+
if (current === container)
|
|
1209
|
+
return true;
|
|
1210
|
+
if (current instanceof ShadowRoot) {
|
|
1211
|
+
current = current.host;
|
|
1212
|
+
continue;
|
|
1213
|
+
}
|
|
1214
|
+
if (current.parentNode) {
|
|
1215
|
+
current = current.parentNode;
|
|
1216
|
+
continue;
|
|
1217
|
+
}
|
|
1218
|
+
const root = current.getRootNode?.();
|
|
1219
|
+
if (root instanceof ShadowRoot) {
|
|
1220
|
+
current = root.host;
|
|
1221
|
+
continue;
|
|
1222
|
+
}
|
|
1223
|
+
break;
|
|
1224
|
+
}
|
|
1225
|
+
return false;
|
|
1226
|
+
}
|
|
479
1227
|
componentDidLoad() {
|
|
480
1228
|
// Listen for toggle events from the native popover API
|
|
481
1229
|
this.popoverEl?.addEventListener('toggle', this.handlePopoverToggle);
|
|
482
1230
|
// Listen for other popovers opening to close this one
|
|
483
1231
|
document.addEventListener('le-popover-will-open', this.handleOtherPopoverOpen);
|
|
1232
|
+
// If the popover is initially open (unlikely, but possible), wire listeners.
|
|
1233
|
+
if (this.open) {
|
|
1234
|
+
this.addDismissListeners();
|
|
1235
|
+
}
|
|
484
1236
|
}
|
|
485
1237
|
disconnectedCallback() {
|
|
486
1238
|
this.popoverEl?.removeEventListener('toggle', this.handlePopoverToggle);
|
|
487
1239
|
document.removeEventListener('le-popover-will-open', this.handleOtherPopoverOpen);
|
|
488
1240
|
this.removeScrollListeners();
|
|
1241
|
+
this.removeDismissListeners();
|
|
489
1242
|
}
|
|
1243
|
+
addDismissListeners() {
|
|
1244
|
+
if (this.isListeningForDismiss)
|
|
1245
|
+
return;
|
|
1246
|
+
// Use capture so clicks inside the trigger (which stops propagation) are still observed.
|
|
1247
|
+
document.addEventListener('pointerdown', this.handleDocumentPointerDown, true);
|
|
1248
|
+
document.addEventListener('keydown', this.handleDocumentKeyDown, true);
|
|
1249
|
+
this.isListeningForDismiss = true;
|
|
1250
|
+
}
|
|
1251
|
+
removeDismissListeners() {
|
|
1252
|
+
if (!this.isListeningForDismiss)
|
|
1253
|
+
return;
|
|
1254
|
+
document.removeEventListener('pointerdown', this.handleDocumentPointerDown, true);
|
|
1255
|
+
document.removeEventListener('keydown', this.handleDocumentKeyDown, true);
|
|
1256
|
+
this.isListeningForDismiss = false;
|
|
1257
|
+
}
|
|
1258
|
+
handleDocumentPointerDown = (event) => {
|
|
1259
|
+
if (!this.open || !this.closeOnClickOutside)
|
|
1260
|
+
return;
|
|
1261
|
+
// If the click happens inside this popover component (trigger OR content), don't close.
|
|
1262
|
+
const path = (event.composedPath?.() ?? []);
|
|
1263
|
+
if (path.includes(this.el))
|
|
1264
|
+
return;
|
|
1265
|
+
this.hide();
|
|
1266
|
+
};
|
|
1267
|
+
handleDocumentKeyDown = (event) => {
|
|
1268
|
+
if (!this.open || !this.closeOnEscape)
|
|
1269
|
+
return;
|
|
1270
|
+
if (event.key !== 'Escape')
|
|
1271
|
+
return;
|
|
1272
|
+
// Only the top-most opened popover handles Escape.
|
|
1273
|
+
const top = openPopoverStack[openPopoverStack.length - 1];
|
|
1274
|
+
if (top !== this.el)
|
|
1275
|
+
return;
|
|
1276
|
+
event.preventDefault();
|
|
1277
|
+
event.stopPropagation();
|
|
1278
|
+
this.hide();
|
|
1279
|
+
};
|
|
490
1280
|
/**
|
|
491
1281
|
* Find all scrollable parent elements
|
|
492
1282
|
*/
|
|
@@ -535,24 +1325,49 @@ const LePopover = class {
|
|
|
535
1325
|
this._updatePosition();
|
|
536
1326
|
}
|
|
537
1327
|
};
|
|
1328
|
+
handleOpened() {
|
|
1329
|
+
this.open = true;
|
|
1330
|
+
// Track stack order for Escape handling.
|
|
1331
|
+
const existingIndex = openPopoverStack.indexOf(this.el);
|
|
1332
|
+
if (existingIndex >= 0)
|
|
1333
|
+
openPopoverStack.splice(existingIndex, 1);
|
|
1334
|
+
openPopoverStack.push(this.el);
|
|
1335
|
+
this.addDismissListeners();
|
|
1336
|
+
this.addScrollListeners();
|
|
1337
|
+
this._updatePosition();
|
|
1338
|
+
this.lePopoverOpen.emit();
|
|
1339
|
+
}
|
|
1340
|
+
handleClosed() {
|
|
1341
|
+
this.open = false;
|
|
1342
|
+
this.isPositioned = false;
|
|
1343
|
+
this.removeScrollListeners();
|
|
1344
|
+
this.removeDismissListeners();
|
|
1345
|
+
const index = openPopoverStack.indexOf(this.el);
|
|
1346
|
+
if (index >= 0)
|
|
1347
|
+
openPopoverStack.splice(index, 1);
|
|
1348
|
+
this.lePopoverClose.emit();
|
|
1349
|
+
}
|
|
538
1350
|
handlePopoverToggle = (event) => {
|
|
539
1351
|
if (event.newState === 'open') {
|
|
540
|
-
this.
|
|
541
|
-
this.addScrollListeners();
|
|
542
|
-
this._updatePosition();
|
|
543
|
-
this.lePopoverOpen.emit();
|
|
1352
|
+
this.handleOpened();
|
|
544
1353
|
}
|
|
545
1354
|
else {
|
|
546
|
-
this.
|
|
547
|
-
this.isPositioned = false;
|
|
548
|
-
this.removeScrollListeners();
|
|
549
|
-
this.lePopoverClose.emit();
|
|
1355
|
+
this.handleClosed();
|
|
550
1356
|
}
|
|
551
1357
|
};
|
|
552
1358
|
handleOtherPopoverOpen = (event) => {
|
|
553
1359
|
const customEvent = event;
|
|
554
|
-
|
|
1360
|
+
const openingPopover = customEvent.detail?.popover;
|
|
1361
|
+
if (!openingPopover)
|
|
555
1362
|
return;
|
|
1363
|
+
if (openingPopover === this.el)
|
|
1364
|
+
return;
|
|
1365
|
+
// Allow nested popovers (e.g., le-select inside another popover).
|
|
1366
|
+
// Use a shadow-DOM-aware containment check.
|
|
1367
|
+
if (this.shadowContains(this.el, openingPopover) ||
|
|
1368
|
+
this.shadowContains(openingPopover, this.el)) {
|
|
1369
|
+
return;
|
|
1370
|
+
}
|
|
556
1371
|
if (this.open) {
|
|
557
1372
|
this.hide();
|
|
558
1373
|
}
|
|
@@ -564,13 +1379,23 @@ const LePopover = class {
|
|
|
564
1379
|
document.dispatchEvent(new CustomEvent('le-popover-will-open', {
|
|
565
1380
|
detail: { popover: this.el },
|
|
566
1381
|
}));
|
|
567
|
-
this.
|
|
1382
|
+
if (this.supportsPopoverApi) {
|
|
1383
|
+
this.popoverEl?.showPopover();
|
|
1384
|
+
}
|
|
1385
|
+
else {
|
|
1386
|
+
this.handleOpened();
|
|
1387
|
+
}
|
|
568
1388
|
}
|
|
569
1389
|
/**
|
|
570
1390
|
* Closes the popover
|
|
571
1391
|
*/
|
|
572
1392
|
async hide() {
|
|
573
|
-
this.
|
|
1393
|
+
if (this.supportsPopoverApi) {
|
|
1394
|
+
this.popoverEl?.hidePopover();
|
|
1395
|
+
}
|
|
1396
|
+
else {
|
|
1397
|
+
this.handleClosed();
|
|
1398
|
+
}
|
|
574
1399
|
}
|
|
575
1400
|
/**
|
|
576
1401
|
* Toggles the popover
|
|
@@ -741,9 +1566,12 @@ const LePopover = class {
|
|
|
741
1566
|
popoverStyles.minWidth = this.minWidth;
|
|
742
1567
|
if (this.maxWidth)
|
|
743
1568
|
popoverStyles.maxWidth = this.maxWidth;
|
|
744
|
-
return (h(Host, { key: '
|
|
1569
|
+
return (h(Host, { key: '9bbb6c41436ac051529650ef0fbf5e152ec82901', "trigger-full-width": this.triggerFullWidth }, h("div", { key: '600f4d8a367e2b52cb6eca2c6bf4d77a3851b078', class: classnames('le-popover-trigger', {
|
|
745
1570
|
'le-popover-trigger-full-width': this.triggerFullWidth,
|
|
746
|
-
}), ref: el => (this.triggerEl = el), onClick: this.handleTriggerClick, part: "trigger" }, h("slot", { key: '
|
|
1571
|
+
}), ref: el => (this.triggerEl = el), onClick: this.handleTriggerClick, part: "trigger" }, h("slot", { key: '6cfc71e93c2ea7552157398ac4aa12507ba55cc3', name: "trigger" }, h("button", { key: '06f35fffce2a5e2129733daf5fda9a35762ff586', type: "button", class: "le-popover-default-trigger" }, h("span", { key: 'c7dcb2074e40851db8cb9cc9d5ff42d90be479c2' }, "\u2295")))), h("div", { key: '5cc7278cc388bd057df4311a5082f8ad29eaf756', id: this.uniqueId, class: "le-popover-content",
|
|
1572
|
+
// Always use manual mode so nested popovers can be open together.
|
|
1573
|
+
// We implement click-outside and Escape handling ourselves.
|
|
1574
|
+
popover: "manual", ref: el => (this.popoverEl = el), style: popoverStyles, "data-fallback-open": this.supportsPopoverApi ? undefined : String(this.open) }, (this.popoverTitle || this.showClose) && (h("div", { key: '56b803332842e42387160ab6ab7df3a8b20f00fc', class: "le-popover-header" }, this.popoverTitle && h("span", { key: '034c0acc4c08fb5eb7f10f9e9b310874eafada3e', class: "le-popover-title" }, this.popoverTitle), this.showClose && (h("button", { key: '29546e93795dc7aefca86b9d8d8ceef109c230c8', type: "button", class: "le-popover-close", onClick: () => this.hide(), "aria-label": "Close" }, "\u00D7")))), h("div", { key: 'dbacc49cf8c8198048443f0b8acfdc795eb72b31', class: "le-popover-body", part: "content" }, h("slot", { key: 'ca3ceed750c50ba33c58d0cb99ce8378cc358872' })))));
|
|
747
1575
|
}
|
|
748
1576
|
};
|
|
749
1577
|
LePopover.style = lePopoverCss;
|
|
@@ -958,6 +1786,299 @@ const LePopup = class {
|
|
|
958
1786
|
};
|
|
959
1787
|
LePopup.style = lePopupCss;
|
|
960
1788
|
|
|
1789
|
+
const leScrollProgressCss = ":host{display:block}:host([sticky]){position:sticky;top:var(--le-scroll-progress-sticky-top, 0);z-index:var(--le-scroll-progress-z, calc(var(--le-header-z, 1000) + 1))}:host([fixed]){position:fixed;top:var(--le-scroll-progress-fixed-top, 0);left:var(--le-scroll-progress-fixed-left, 0);right:var(--le-scroll-progress-fixed-right, 0);z-index:var(--le-scroll-progress-z, calc(var(--le-header-z, 1000) + 1))}.track{width:100%;height:var(--le-scroll-progress-height, 4px);background:var(--le-scroll-progress-bg, transparent)}.fill{height:100%;width:0;background:var(--le-scroll-progress-fill, var(--le-color-primary, currentColor));border-radius:var(--le-scroll-progress-border-radius, 2px);transition:width var(--le-transition-fast, 120ms linear)}";
|
|
1790
|
+
|
|
1791
|
+
const LeScrollProgress = class {
|
|
1792
|
+
constructor(hostRef) {
|
|
1793
|
+
registerInstance(this, hostRef);
|
|
1794
|
+
}
|
|
1795
|
+
get el() { return getElement(this); }
|
|
1796
|
+
/** Boolean or selector string. */
|
|
1797
|
+
trackScrollProgress;
|
|
1798
|
+
progress = 0;
|
|
1799
|
+
rafId = null;
|
|
1800
|
+
targetEl = null;
|
|
1801
|
+
componentWillLoad() {
|
|
1802
|
+
this.updateProgress();
|
|
1803
|
+
}
|
|
1804
|
+
componentDidLoad() {
|
|
1805
|
+
this.resolveTarget();
|
|
1806
|
+
this.updateProgress();
|
|
1807
|
+
}
|
|
1808
|
+
disconnectedCallback() {
|
|
1809
|
+
if (this.rafId != null) {
|
|
1810
|
+
cancelAnimationFrame(this.rafId);
|
|
1811
|
+
this.rafId = null;
|
|
1812
|
+
}
|
|
1813
|
+
}
|
|
1814
|
+
onTrackChange() {
|
|
1815
|
+
this.resolveTarget();
|
|
1816
|
+
this.updateProgress();
|
|
1817
|
+
}
|
|
1818
|
+
onScroll() {
|
|
1819
|
+
this.scheduleUpdate();
|
|
1820
|
+
}
|
|
1821
|
+
onResize() {
|
|
1822
|
+
this.resolveTarget();
|
|
1823
|
+
this.scheduleUpdate(true);
|
|
1824
|
+
}
|
|
1825
|
+
scheduleUpdate(force = false) {
|
|
1826
|
+
if (this.rafId != null && !force)
|
|
1827
|
+
return;
|
|
1828
|
+
this.rafId = requestAnimationFrame(() => {
|
|
1829
|
+
this.rafId = null;
|
|
1830
|
+
this.updateProgress();
|
|
1831
|
+
});
|
|
1832
|
+
}
|
|
1833
|
+
resolveTarget() {
|
|
1834
|
+
if (typeof document === 'undefined')
|
|
1835
|
+
return;
|
|
1836
|
+
const raw = this.trackScrollProgress;
|
|
1837
|
+
// If attribute missing, default to enabled (full document).
|
|
1838
|
+
// If user explicitly sets 'false', treat as disabled.
|
|
1839
|
+
if (raw == null) {
|
|
1840
|
+
this.targetEl = null;
|
|
1841
|
+
return;
|
|
1842
|
+
}
|
|
1843
|
+
const val = String(raw).trim();
|
|
1844
|
+
if (val === '' || val === 'true') {
|
|
1845
|
+
this.targetEl = null;
|
|
1846
|
+
return;
|
|
1847
|
+
}
|
|
1848
|
+
if (val === 'false') {
|
|
1849
|
+
this.targetEl = null;
|
|
1850
|
+
return;
|
|
1851
|
+
}
|
|
1852
|
+
try {
|
|
1853
|
+
this.targetEl = document.querySelector(val);
|
|
1854
|
+
}
|
|
1855
|
+
catch {
|
|
1856
|
+
this.targetEl = null;
|
|
1857
|
+
}
|
|
1858
|
+
}
|
|
1859
|
+
clamp01(n) {
|
|
1860
|
+
return Math.max(0, Math.min(1, n));
|
|
1861
|
+
}
|
|
1862
|
+
updateProgress() {
|
|
1863
|
+
if (typeof window === 'undefined' || typeof document === 'undefined')
|
|
1864
|
+
return;
|
|
1865
|
+
// If explicitly disabled.
|
|
1866
|
+
if (this.trackScrollProgress === 'false') {
|
|
1867
|
+
if (this.progress !== 0)
|
|
1868
|
+
this.progress = 0;
|
|
1869
|
+
return;
|
|
1870
|
+
}
|
|
1871
|
+
const scrollY = window.scrollY || 0;
|
|
1872
|
+
let p = 0;
|
|
1873
|
+
if (this.targetEl) {
|
|
1874
|
+
const rect = this.targetEl.getBoundingClientRect();
|
|
1875
|
+
const top = scrollY + rect.top;
|
|
1876
|
+
const height = rect.height;
|
|
1877
|
+
const viewport = window.innerHeight || 1;
|
|
1878
|
+
const denom = Math.max(1, height - viewport);
|
|
1879
|
+
p = this.clamp01((scrollY - top) / denom);
|
|
1880
|
+
}
|
|
1881
|
+
else {
|
|
1882
|
+
const doc = document.documentElement;
|
|
1883
|
+
const denom = Math.max(1, doc.scrollHeight - doc.clientHeight);
|
|
1884
|
+
p = this.clamp01(scrollY / denom);
|
|
1885
|
+
}
|
|
1886
|
+
const next = Math.round(p * 1000) / 1000;
|
|
1887
|
+
if (next !== this.progress)
|
|
1888
|
+
this.progress = next;
|
|
1889
|
+
}
|
|
1890
|
+
render() {
|
|
1891
|
+
const width = `${this.progress * 100}%`;
|
|
1892
|
+
return (h(Host, { key: '46e7659497b80795c79365b97813cf57d517f48f' }, h("div", { key: '6e42f3479a1081df5355fb229902e9ee8c0a8918', class: "track", part: "track", "aria-hidden": "true" }, h("div", { key: '81cbe2ec0fc43a14b8bc0192b1f901be9c6cba3a', class: "fill", part: "fill", style: { width } }))));
|
|
1893
|
+
}
|
|
1894
|
+
static get watchers() { return {
|
|
1895
|
+
"trackScrollProgress": ["onTrackChange"]
|
|
1896
|
+
}; }
|
|
1897
|
+
};
|
|
1898
|
+
LeScrollProgress.style = leScrollProgressCss;
|
|
1899
|
+
|
|
1900
|
+
const leSelectCss = ":host{display:inline-block;min-width:150px;--le-select-color:var(--le-color-text, #1f2937);--le-select-border-radius:var(--le-radius-md);--le-select-content-padding:var(--le-spacing-2)}:host([disabled]){opacity:0.5;pointer-events:none}:host([full-width]){width:100%}.select-trigger{display:flex;align-items:center;gap:0.5rem;width:100%;padding:0;--le-button-padding:var(--le-spacing-1) var(--le-spacing-1) var(--le-spacing-1) var(--le-spacing-2);font-size:var(--le-select-font-size, 0.875rem);font-family:inherit;line-height:1.4;color:var(--le-select-color);background:var(--le-select-bg, var(--le-color-surface, #fff));border-radius:var(--le-select-border-radius);cursor:pointer;text-align:left;transition:border-color 0.15s ease, box-shadow 0.15s ease}.select-trigger:focus{outline:2px solid var(--le-color-focus);outline-offset:2px}.select-trigger:not(.has-value) .trigger-label{color:color-mix(in srgb, var(--le-color-text-secondary) 66%, transparent)}.trigger-icon{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:1.25rem;height:1.25rem}.trigger-icon-end{width:16px;height:16px}.trigger-icon img{width:100%;height:100%;object-fit:contain}.trigger-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--le-color-text)}.trigger-label::not(.has-value){color:var(--le-color-text-disabled, #9ca3af)}le-button::part(icon-end){display:flex;align-items:center;justify-content:center;flex-shrink:0;width:1.25rem;height:1.25rem;margin-left:auto;transition:transform 0.2s ease}le-button::part(icon-end) svg{width:1rem;height:1rem}le-button.is-open::part(icon-end){transform:rotate(180deg)}.search-input::part(container):focus-within{outline:none !important}.search-input{--le-input-radius:var(--le-radius-md)}";
|
|
1901
|
+
|
|
1902
|
+
const LeSelect = class {
|
|
1903
|
+
constructor(hostRef) {
|
|
1904
|
+
registerInstance(this, hostRef);
|
|
1905
|
+
this.leChange = createEvent(this, "leChange");
|
|
1906
|
+
this.leOpen = createEvent(this, "leOpen");
|
|
1907
|
+
this.leClose = createEvent(this, "leClose");
|
|
1908
|
+
}
|
|
1909
|
+
get el() { return getElement(this); }
|
|
1910
|
+
/**
|
|
1911
|
+
* The options to display in the dropdown.
|
|
1912
|
+
*/
|
|
1913
|
+
options = [];
|
|
1914
|
+
/**
|
|
1915
|
+
* The currently selected value.
|
|
1916
|
+
*/
|
|
1917
|
+
value;
|
|
1918
|
+
/**
|
|
1919
|
+
* Placeholder text when no option is selected.
|
|
1920
|
+
*/
|
|
1921
|
+
placeholder = 'Select an option';
|
|
1922
|
+
/**
|
|
1923
|
+
* Whether the select is disabled.
|
|
1924
|
+
*/
|
|
1925
|
+
disabled = false;
|
|
1926
|
+
/**
|
|
1927
|
+
* Whether selection is required.
|
|
1928
|
+
*/
|
|
1929
|
+
required = false;
|
|
1930
|
+
/**
|
|
1931
|
+
* Name attribute for form submission.
|
|
1932
|
+
*/
|
|
1933
|
+
name;
|
|
1934
|
+
/**
|
|
1935
|
+
* Whether the select should take full width of its container.
|
|
1936
|
+
*/
|
|
1937
|
+
fullWidth = false;
|
|
1938
|
+
/**
|
|
1939
|
+
* Size variant of the select.
|
|
1940
|
+
*/
|
|
1941
|
+
size = 'medium';
|
|
1942
|
+
/**
|
|
1943
|
+
* Visual variant of the select.
|
|
1944
|
+
*/
|
|
1945
|
+
variant = 'default';
|
|
1946
|
+
/**
|
|
1947
|
+
* Whether the input is searchable.
|
|
1948
|
+
*/
|
|
1949
|
+
searchable = false;
|
|
1950
|
+
/**
|
|
1951
|
+
* Text to show when no options match the search.
|
|
1952
|
+
*/
|
|
1953
|
+
emptyText = 'No results found';
|
|
1954
|
+
/**
|
|
1955
|
+
* Whether the dropdown is currently open.
|
|
1956
|
+
*/
|
|
1957
|
+
open = false;
|
|
1958
|
+
/**
|
|
1959
|
+
* Emitted when the selected value changes.
|
|
1960
|
+
*/
|
|
1961
|
+
leChange;
|
|
1962
|
+
/**
|
|
1963
|
+
* Emitted when the dropdown opens.
|
|
1964
|
+
*/
|
|
1965
|
+
leOpen;
|
|
1966
|
+
/**
|
|
1967
|
+
* Emitted when the dropdown closes.
|
|
1968
|
+
*/
|
|
1969
|
+
leClose;
|
|
1970
|
+
selectedOption;
|
|
1971
|
+
searchQuery = '';
|
|
1972
|
+
dropdownEl;
|
|
1973
|
+
inputEl;
|
|
1974
|
+
handleValueChange() {
|
|
1975
|
+
this.updateSelectedOption();
|
|
1976
|
+
}
|
|
1977
|
+
handleOptionsChange() {
|
|
1978
|
+
this.updateSelectedOption();
|
|
1979
|
+
}
|
|
1980
|
+
componentWillLoad() {
|
|
1981
|
+
this.updateSelectedOption();
|
|
1982
|
+
}
|
|
1983
|
+
get parsedOptions() {
|
|
1984
|
+
if (typeof this.options === 'string') {
|
|
1985
|
+
try {
|
|
1986
|
+
return JSON.parse(this.options);
|
|
1987
|
+
}
|
|
1988
|
+
catch {
|
|
1989
|
+
return [];
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1992
|
+
return this.options;
|
|
1993
|
+
}
|
|
1994
|
+
updateSelectedOption() {
|
|
1995
|
+
if (this.value !== undefined) {
|
|
1996
|
+
this.selectedOption = this.parsedOptions.find(opt => (opt.value ?? opt.label) === this.value);
|
|
1997
|
+
}
|
|
1998
|
+
else {
|
|
1999
|
+
this.selectedOption = undefined;
|
|
2000
|
+
}
|
|
2001
|
+
}
|
|
2002
|
+
filterOption = (option, query) => {
|
|
2003
|
+
if (!query)
|
|
2004
|
+
return true;
|
|
2005
|
+
const searchLower = query.toLowerCase();
|
|
2006
|
+
return (option.label.toLowerCase().includes(searchLower) ||
|
|
2007
|
+
(option.description?.toLowerCase().includes(searchLower) ?? false));
|
|
2008
|
+
};
|
|
2009
|
+
handleOptionSelect = (e) => {
|
|
2010
|
+
this.value = e.detail.value;
|
|
2011
|
+
this.selectedOption = e.detail.option;
|
|
2012
|
+
this.leChange.emit(e.detail);
|
|
2013
|
+
};
|
|
2014
|
+
handleDropdownOpen = () => {
|
|
2015
|
+
this.open = true;
|
|
2016
|
+
this.leOpen.emit();
|
|
2017
|
+
// Focus search input if searchable
|
|
2018
|
+
if (this.searchable) {
|
|
2019
|
+
setTimeout(() => {
|
|
2020
|
+
this.inputEl?.focus();
|
|
2021
|
+
}, 50);
|
|
2022
|
+
}
|
|
2023
|
+
};
|
|
2024
|
+
handleDropdownClose = () => {
|
|
2025
|
+
this.open = false;
|
|
2026
|
+
this.leClose.emit();
|
|
2027
|
+
};
|
|
2028
|
+
handleTriggerClick = () => {
|
|
2029
|
+
if (!this.disabled) {
|
|
2030
|
+
this.dropdownEl?.toggle();
|
|
2031
|
+
}
|
|
2032
|
+
};
|
|
2033
|
+
handleTriggerKeyDown = (e) => {
|
|
2034
|
+
if (this.disabled)
|
|
2035
|
+
return;
|
|
2036
|
+
if (e.key === 'Enter' || e.key === ' ' || e.key === 'ArrowDown') {
|
|
2037
|
+
e.preventDefault();
|
|
2038
|
+
this.dropdownEl?.show();
|
|
2039
|
+
}
|
|
2040
|
+
};
|
|
2041
|
+
handleSearchInput = (e) => {
|
|
2042
|
+
const target = e.target;
|
|
2043
|
+
this.searchQuery = target.value;
|
|
2044
|
+
};
|
|
2045
|
+
/**
|
|
2046
|
+
* Opens the dropdown.
|
|
2047
|
+
*/
|
|
2048
|
+
async showDropdown() {
|
|
2049
|
+
await this.dropdownEl?.show();
|
|
2050
|
+
}
|
|
2051
|
+
/**
|
|
2052
|
+
* Closes the dropdown.
|
|
2053
|
+
*/
|
|
2054
|
+
async hideDropdown() {
|
|
2055
|
+
await this.dropdownEl?.hide();
|
|
2056
|
+
}
|
|
2057
|
+
renderIcon(icon) {
|
|
2058
|
+
if (!icon)
|
|
2059
|
+
return null;
|
|
2060
|
+
if (icon.startsWith('http') || icon.startsWith('/')) {
|
|
2061
|
+
return h("img", { class: "trigger-icon", src: icon, alt: "" });
|
|
2062
|
+
}
|
|
2063
|
+
return h("span", { class: "trigger-icon" }, icon);
|
|
2064
|
+
}
|
|
2065
|
+
render() {
|
|
2066
|
+
const hasValue = this.selectedOption !== undefined;
|
|
2067
|
+
return (h("le-component", { key: 'f41bf4f086925b6b37a0131a51e4f7e354797ed5', component: "le-select" }, h("le-dropdown-base", { key: '08db701f6b1f7e2c428ea0cc9ee4046c22759757', ref: el => (this.dropdownEl = el), options: this.parsedOptions, value: this.value, disabled: this.disabled, filterFn: this.searchable ? this.filterOption : undefined, filterQuery: this.searchQuery, onLeOptionSelect: this.handleOptionSelect, onLeDropdownOpen: this.handleDropdownOpen, onLeDropdownClose: this.handleDropdownClose, fullWidth: this.fullWidth }, h("le-button", { key: 'f994667c5360905a9e6340f0f0331bea55523418', variant: this.variant && this.variant !== 'default' ? this.variant : 'outlined', slot: "trigger", align: "space-between", class: {
|
|
2068
|
+
'select-trigger': true,
|
|
2069
|
+
'has-value': hasValue,
|
|
2070
|
+
'is-open': this.open,
|
|
2071
|
+
}, 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
|
|
2072
|
+
? this.renderIcon(this.selectedOption.iconStart)
|
|
2073
|
+
: null, iconEnd: h("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", "stroke-width": "2" }, h("path", { d: "M4 6l4 4 4-4" })) }, h("span", { key: 'c807e00d21193e558dcf1b601c4aa5f78144fd14', class: "trigger-label" }, hasValue ? this.selectedOption.label : this.placeholder)), this.searchable && this.open && (h("div", { key: 'c285d28f7b0093580484b8d077c4f2ddd014aa2e', class: "multiselect-search", slot: "header" }, h("le-string-input", { key: '1dd31e5840a29e3a7e181c80182c20ea5ca28bcb', mode: "default", inputRef: el => (this.inputEl = el), class: "search-input", placeholder: "Search...", value: this.searchQuery, onInput: this.handleSearchInput })))), this.name && h("input", { key: '0acb27fafae47b56808e1b1ee20e45c7cb0cfa3e', type: "hidden", name: this.name, value: this.value?.toString() ?? '' })));
|
|
2074
|
+
}
|
|
2075
|
+
static get watchers() { return {
|
|
2076
|
+
"value": ["handleValueChange"],
|
|
2077
|
+
"options": ["handleOptionsChange"]
|
|
2078
|
+
}; }
|
|
2079
|
+
};
|
|
2080
|
+
LeSelect.style = leSelectCss;
|
|
2081
|
+
|
|
961
2082
|
const leSlotDefaultCss = ":host{display:contents;--le-slot-border-color:#0088ff;--le-slot-bg-color:rgba(0, 136, 255, 0.05);--le-slot-header-bg:rgb(218, 238, 255);--le-slot-label-color:#0066cc;--le-slot-description-color:#666;--le-slot-required-color:#e53935;--le-slot-dropzone-min-height:20px;--le-slot-dropzone-border-color:#ccc}.le-slot-container,.le-slot-header,.le-slot-description,.le-slot-dropzone,.le-slot-input{display:none}.hidden-slot{display:none}:host(.admin-mode){display:block;flex:1}:host(.admin-mode) .le-slot-container{position:relative;display:flex;flex-direction:column;border:2px dashed var(--le-slot-border-color);border-radius:4px;background:var(--le-slot-bg-color);margin:4px 0}:host(.admin-mode) .le-slot-header{display:flex;align-items:center;gap:4px;padding:0 0 0 var(--le-spacing-1, 4px);background:var(--le-slot-header-bg);border-bottom:1px solid var(--le-slot-border-color);font-size:var(--le-font-size-xs, 11px);font-weight:400;text-transform:capitalize}:host(.admin-mode) .le-slot-header-no-label{justify-content:flex-end;height:16px;border:none;background-color:transparent}.le-slot-label{color:var(--le-slot-label-color);text-align:start;overflow:hidden;width:0;flex:1 1 0%}.le-slot-required{color:var(--le-slot-required-color);font-weight:bold}:host(.admin-mode) .le-slot-description{display:block;padding:4px 8px;font-size:12px;color:var(--le-slot-description-color);font-style:italic}:host(.admin-mode) .le-slot-description-icon{display:inline-block;font-size:9px;line-height:1;cursor:pointer;color:var(--le-slot-description-color)}:host(.admin-mode) .le-slot-dropzone{display:block;min-height:var(--le-slot-dropzone-min-height);padding:var(--le-spacing-1, 4px);position:relative}:host(.admin-mode) .le-slot-dropzone:empty::before{content:'Drop content here';display:flex;align-items:center;justify-content:center;position:absolute;inset:8px;border:2px dashed var(--le-slot-dropzone-border-color);border-radius:4px;color:#999;font-size:12px;pointer-events:none}:host(.admin-mode.drag-over) .le-slot-container{border-color:#00cc66;background:rgba(0, 204, 102, 0.1)}:host(.admin-mode.drag-over) .le-slot-dropzone:empty::before{border-color:#00cc66;color:#00cc66;content:'Release to drop'}:host(.admin-mode) .le-slot-input{display:block;padding:var(--le-spacing-1, 4px)}:host(.admin-mode) .le-slot-input input,:host(.admin-mode) .le-slot-input textarea{display:block;width:100%;padding:8px 10px;border:1px solid var(--le-slot-dropzone-border-color);border-radius:4px;font-family:inherit;font-size:14px;line-height:1.4;background:#fff;color:#333;box-sizing:border-box;transition:border-color 0.2s, box-shadow 0.2s}:host(.admin-mode) .le-slot-input input:focus,:host(.admin-mode) .le-slot-input textarea:focus{outline:none;border-color:var(--le-slot-border-color);box-shadow:0 0 0 3px rgba(0, 136, 255, 0.15)}:host(.admin-mode) .le-slot-input input::placeholder,:host(.admin-mode) .le-slot-input textarea::placeholder{color:#999}:host(.admin-mode) .le-slot-input textarea{resize:vertical;min-height:60px}:host(.admin-mode) .le-slot-input slot{display:none}.le-slot-invalid{color:var(--le-slot-required-color);font-size:10px;margin-left:auto;font-weight:normal;text-transform:none}:host(.admin-mode) .le-slot-input.has-error input,:host(.admin-mode) .le-slot-input.has-error textarea{border-color:var(--le-slot-required-color);background:rgba(229, 57, 53, 0.05)}:host(.admin-mode) .le-slot-input.has-error input:focus,:host(.admin-mode) .le-slot-input.has-error textarea:focus{border-color:var(--le-slot-required-color);box-shadow:0 0 0 3px rgba(229, 57, 53, 0.15)}.le-slot-add-btn{font-size:24px;line-height:0px;width:12px;height:12px}.le-slot-header-no-label .le-slot-add-btn{font-size:16px}.le-slot-button{width:20px;height:20px}:host(.admin-mode) .le-slot-header-no-label.le-slot-header-text{height:0}";
|
|
962
2083
|
|
|
963
2084
|
const LeSlot = class {
|
|
@@ -1293,7 +2414,7 @@ const LeSlot = class {
|
|
|
1293
2414
|
render() {
|
|
1294
2415
|
const displayLabel = this.label || this.name;
|
|
1295
2416
|
// Always render the same structure, CSS handles visibility via .admin-mode class
|
|
1296
|
-
return (h(Host, { key: '
|
|
2417
|
+
return (h(Host, { key: '938f14c8d8e46d834031cbfab6756a55bc59307d', class: {
|
|
1297
2418
|
'admin-mode': this.adminMode,
|
|
1298
2419
|
'invalid-html': !this.isValidHtml,
|
|
1299
2420
|
}, role: this.adminMode ? 'region' : undefined, "aria-label": this.adminMode ? `Slot: ${displayLabel}` : undefined, "data-slot-name": this.name, "data-slot-type": this.type, "data-allowed": this.allowedComponents, "data-multiple": this.multiple, "data-required": this.required }, this.adminMode ? (h("div", { class: "le-slot-container" }, h("div", { class: classnames('le-slot-header', {
|
|
@@ -1431,14 +2552,14 @@ const LeStringInput = class {
|
|
|
1431
2552
|
ev.stopPropagation();
|
|
1432
2553
|
};
|
|
1433
2554
|
render() {
|
|
1434
|
-
return (h("le-component", { key: '
|
|
2555
|
+
return (h("le-component", { key: 'c51b121a5ff8458f80de07929467d92cff44de9b', component: "le-string-input", hostClass: classnames({ disabled: this.disabled }) }, h("div", { key: '450fa313236401fcb762267f426d0556f90ef200', class: "le-input-wrapper" }, this.label && (h("label", { key: 'c01ed376e563f472d84c9943a4a542c1ec2cb39c', class: "le-input-label", htmlFor: this.name }, this.label)), h("div", { key: 'e41a98671f3bc61e06f66c773536967d60c97df0', class: "le-input-container", part: "container" }, this.iconStart && h("span", { key: 'c6eb682444e091378281b7a2e739ef872ca28973', class: "icon-start" }, this.iconStart), h("input", { key: 'bc7f9055dcae290e132f4c91887e5f90427209d4', ref: el => {
|
|
1435
2556
|
if (this.inputRef) {
|
|
1436
2557
|
this.inputRef(el);
|
|
1437
2558
|
}
|
|
1438
|
-
}, id: this.name, type: this.type, name: this.name, value: this.value, placeholder: this.placeholder, disabled: this.disabled, readOnly: this.readonly, onInput: this.handleInput, onChange: this.handleChange, onClick: this.handleClick }), this.iconEnd && h("span", { key: '
|
|
2559
|
+
}, id: this.name, type: this.type, name: this.name, value: this.value, placeholder: this.placeholder, disabled: this.disabled, readOnly: this.readonly, onInput: this.handleInput, onChange: this.handleChange, onClick: this.handleClick }), this.iconEnd && h("span", { key: '3470d5c95e208e52b1913369d734e1d741164633', class: "icon-end" }, this.iconEnd)), !this.hideDescription && (h("div", { key: '97a123be35907f950c7480352cee29c32e486fe4', class: "le-input-description" }, h("le-slot", { key: '490c2a425b3b58f050aced5dcffc530f624c0957', name: "description", type: "text", tag: "p", label: "Description" }, h("slot", { key: 'a34ff8c6300a36d6c65ca5d9a77352459f1c85cc', name: "description" })))))));
|
|
1439
2560
|
}
|
|
1440
2561
|
};
|
|
1441
2562
|
LeStringInput.style = leStringInputCss;
|
|
1442
2563
|
|
|
1443
|
-
export { LeButton as le_button, LeCheckbox as le_checkbox, LeComponent as le_component, LePopover as le_popover, LePopup as le_popup, LeSlot as le_slot, LeStringInput as le_string_input };
|
|
1444
|
-
//# sourceMappingURL=le-button.le-checkbox.le-component.le-popover.le-popup.le-slot.le-string-input.entry.js.map
|
|
2564
|
+
export { LeButton as le_button, LeCheckbox as le_checkbox, LeCollapse as le_collapse, LeComponent as le_component, LeCurrentHeading as le_current_heading, LeDropdownBase as le_dropdown_base, LeHeader as le_header, LePopover as le_popover, LePopup as le_popup, LeScrollProgress as le_scroll_progress, LeSelect as le_select, LeSlot as le_slot, LeStringInput as le_string_input };
|
|
2565
|
+
//# sourceMappingURL=le-button.le-checkbox.le-collapse.le-component.le-current-heading.le-dropdown-base.le-header.le-popover.le-popup.le-scroll-progress.le-select.le-slot.le-string-input.entry.js.map
|