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.
Files changed (235) hide show
  1. package/dist/cjs/{index-C3iQZ-Ja.js → index-CHzu3ydp.js} +3 -3
  2. package/dist/cjs/index-CHzu3ydp.js.map +1 -0
  3. package/dist/cjs/index.cjs.js +2 -2
  4. package/dist/cjs/le-box.cjs.entry.js +2 -2
  5. 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
  6. package/dist/cjs/{le-button_7.cjs.entry.js → le-button_13.cjs.entry.js} +1148 -21
  7. package/dist/cjs/le-card.cjs.entry.js +2 -2
  8. package/dist/cjs/le-combobox.cjs.entry.js +2 -2
  9. package/dist/cjs/le-header-placeholder.cjs.entry.js +18 -0
  10. package/dist/cjs/le-header-placeholder.entry.cjs.js.map +1 -0
  11. package/dist/cjs/le-kit.cjs.js +2 -2
  12. package/dist/cjs/le-multiselect.cjs.entry.js +4 -4
  13. package/dist/cjs/le-number-input.cjs.entry.js +3 -3
  14. package/dist/cjs/le-round-progress.cjs.entry.js +2 -2
  15. package/dist/cjs/le-segmented-control.cjs.entry.js +2 -2
  16. package/dist/cjs/le-stack.cjs.entry.js +3 -3
  17. package/dist/cjs/le-tab-bar.cjs.entry.js +2 -2
  18. package/dist/cjs/le-tab-panel.cjs.entry.js +3 -3
  19. package/dist/cjs/le-tab.cjs.entry.js +3 -3
  20. package/dist/cjs/le-tabs.cjs.entry.js +4 -4
  21. package/dist/cjs/le-tag.cjs.entry.js +2 -2
  22. package/dist/cjs/le-text.cjs.entry.js +2 -2
  23. package/dist/cjs/le-turntable.cjs.entry.js +2 -2
  24. package/dist/cjs/loader.cjs.js +2 -2
  25. package/dist/cjs/{utils-DjPcLPN9.js → utils-CYOKcOW8.js} +3 -3
  26. package/dist/cjs/{utils-DjPcLPN9.js.map → utils-CYOKcOW8.js.map} +1 -1
  27. package/dist/collection/collection-manifest.json +5 -0
  28. package/dist/collection/components/le-collapse/le-collapse.css +31 -0
  29. package/dist/collection/components/le-collapse/le-collapse.js +188 -0
  30. package/dist/collection/components/le-collapse/le-collapse.js.map +1 -0
  31. package/dist/collection/components/le-combobox/le-combobox.js +1 -1
  32. package/dist/collection/components/le-component/le-component.js +1 -1
  33. package/dist/collection/components/le-component/le-component.js.map +1 -1
  34. package/dist/collection/components/le-current-heading/le-current-heading.css +12 -0
  35. package/dist/collection/components/le-current-heading/le-current-heading.js +130 -0
  36. package/dist/collection/components/le-current-heading/le-current-heading.js.map +1 -0
  37. package/dist/collection/components/le-dropdown-base/le-dropdown-base.css +4 -0
  38. package/dist/collection/components/le-dropdown-base/le-dropdown-base.js +1 -1
  39. package/dist/collection/components/le-header/le-header.css +120 -0
  40. package/dist/collection/components/le-header/le-header.js +508 -0
  41. package/dist/collection/components/le-header/le-header.js.map +1 -0
  42. package/dist/collection/components/le-header-placeholder/le-header-placeholder.js +21 -0
  43. package/dist/collection/components/le-header-placeholder/le-header-placeholder.js.map +1 -0
  44. package/dist/collection/components/le-multiselect/le-multiselect.js +3 -3
  45. package/dist/collection/components/le-number-input/le-number-input.js +1 -1
  46. package/dist/collection/components/le-popover/le-popover.css +10 -0
  47. package/dist/collection/components/le-popover/le-popover.js +122 -13
  48. package/dist/collection/components/le-popover/le-popover.js.map +1 -1
  49. package/dist/collection/components/le-round-progress/le-round-progress.js +1 -1
  50. package/dist/collection/components/le-scroll-progress/le-scroll-progress.css +29 -0
  51. package/dist/collection/components/le-scroll-progress/le-scroll-progress.js +186 -0
  52. package/dist/collection/components/le-scroll-progress/le-scroll-progress.js.map +1 -0
  53. package/dist/collection/components/le-segmented-control/le-segmented-control.js +1 -1
  54. package/dist/collection/components/le-select/le-select.js +2 -2
  55. package/dist/collection/components/le-slot/le-slot.js +1 -1
  56. package/dist/collection/components/le-stack/le-stack.js +1 -1
  57. package/dist/collection/components/le-string-input/le-string-input.js +2 -2
  58. package/dist/collection/components/le-tab/le-tab.js +1 -1
  59. package/dist/collection/components/le-tab-bar/le-tab-bar.js +1 -1
  60. package/dist/collection/components/le-tab-panel/le-tab-panel.js +2 -2
  61. package/dist/collection/components/le-tabs/le-tabs.js +2 -2
  62. package/dist/collection/components/le-tag/le-tag.js +1 -1
  63. package/dist/collection/components/le-turntable/le-turntable.js +1 -1
  64. package/dist/collection/dist/components/assets/custom-elements.json +2029 -965
  65. package/dist/collection/dist/components/themes/base.css +4 -48
  66. package/dist/collection/dist/components/themes/index.css +3 -342
  67. package/dist/components/assets/custom-elements.json +2029 -965
  68. package/dist/components/index.js.map +1 -1
  69. package/dist/components/le-box.js +18 -7
  70. package/dist/components/le-box.js.map +1 -1
  71. package/dist/components/le-button.js +1 -1
  72. package/dist/components/le-button2.js +331 -31
  73. package/dist/components/le-button2.js.map +1 -1
  74. package/dist/components/le-card.js +18 -7
  75. package/dist/components/le-card.js.map +1 -1
  76. package/dist/components/le-checkbox.js +1 -1
  77. package/dist/components/le-collapse.d.ts +11 -0
  78. package/dist/components/le-collapse.js +144 -0
  79. package/dist/components/le-collapse.js.map +1 -0
  80. package/dist/components/le-combobox.js +15 -10
  81. package/dist/components/le-combobox.js.map +1 -1
  82. package/dist/components/le-component.js +1 -1
  83. package/dist/components/le-current-heading.d.ts +11 -0
  84. package/dist/components/le-current-heading.js +93 -0
  85. package/dist/components/le-current-heading.js.map +1 -0
  86. package/dist/components/le-dropdown-base2.js +2 -2
  87. package/dist/components/le-dropdown-base2.js.map +1 -1
  88. package/dist/components/le-header-placeholder.d.ts +11 -0
  89. package/dist/components/le-header-placeholder.js +37 -0
  90. package/dist/components/le-header-placeholder.js.map +1 -0
  91. package/dist/components/le-header.d.ts +11 -0
  92. package/dist/components/le-header.js +347 -0
  93. package/dist/components/le-header.js.map +1 -0
  94. package/dist/components/le-multiselect.js +17 -12
  95. package/dist/components/le-multiselect.js.map +1 -1
  96. package/dist/components/le-number-input.js +19 -8
  97. package/dist/components/le-number-input.js.map +1 -1
  98. package/dist/components/le-popover2.js +123 -14
  99. package/dist/components/le-popover2.js.map +1 -1
  100. package/dist/components/le-popup.js +1 -1
  101. package/dist/components/le-round-progress.js +1 -1
  102. package/dist/components/le-scroll-progress.d.ts +11 -0
  103. package/dist/components/le-scroll-progress.js +142 -0
  104. package/dist/components/le-scroll-progress.js.map +1 -0
  105. package/dist/components/le-segmented-control.js +19 -8
  106. package/dist/components/le-segmented-control.js.map +1 -1
  107. package/dist/components/le-select.js +1 -263
  108. package/dist/components/le-select.js.map +1 -1
  109. package/dist/components/le-slot.js +1 -1
  110. package/dist/components/le-stack.js +19 -8
  111. package/dist/components/le-stack.js.map +1 -1
  112. package/dist/components/le-string-input.js +1 -1
  113. package/dist/components/le-tab-bar.js +19 -8
  114. package/dist/components/le-tab-bar.js.map +1 -1
  115. package/dist/components/le-tab-panel.js +20 -9
  116. package/dist/components/le-tab-panel.js.map +1 -1
  117. package/dist/components/le-tab2.js +19 -8
  118. package/dist/components/le-tab2.js.map +1 -1
  119. package/dist/components/le-tabs.js +20 -9
  120. package/dist/components/le-tabs.js.map +1 -1
  121. package/dist/components/le-tag2.js +19 -8
  122. package/dist/components/le-tag2.js.map +1 -1
  123. package/dist/components/le-text.js +18 -7
  124. package/dist/components/le-text.js.map +1 -1
  125. package/dist/components/le-turntable.js +1 -1
  126. package/dist/components/themes/base.css +4 -48
  127. package/dist/components/themes/index.css +3 -342
  128. package/dist/docs.json +1089 -30
  129. package/dist/esm/{index-DzgCnDLJ.js → index-hmBwv43R.js} +3 -3
  130. package/dist/esm/index-hmBwv43R.js.map +1 -0
  131. package/dist/esm/index.js +2 -2
  132. package/dist/esm/le-box.entry.js +2 -2
  133. 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
  134. package/dist/esm/{le-button_7.entry.js → le-button_13.entry.js} +1143 -22
  135. package/dist/esm/le-card.entry.js +2 -2
  136. package/dist/esm/le-combobox.entry.js +2 -2
  137. package/dist/esm/le-header-placeholder.entry.js +16 -0
  138. package/dist/esm/le-header-placeholder.entry.js.map +1 -0
  139. package/dist/esm/le-kit.js +3 -3
  140. package/dist/esm/le-multiselect.entry.js +4 -4
  141. package/dist/esm/le-number-input.entry.js +3 -3
  142. package/dist/esm/le-round-progress.entry.js +2 -2
  143. package/dist/esm/le-segmented-control.entry.js +2 -2
  144. package/dist/esm/le-stack.entry.js +3 -3
  145. package/dist/esm/le-tab-bar.entry.js +2 -2
  146. package/dist/esm/le-tab-panel.entry.js +3 -3
  147. package/dist/esm/le-tab.entry.js +3 -3
  148. package/dist/esm/le-tabs.entry.js +4 -4
  149. package/dist/esm/le-tag.entry.js +2 -2
  150. package/dist/esm/le-text.entry.js +2 -2
  151. package/dist/esm/le-turntable.entry.js +2 -2
  152. package/dist/esm/loader.js +3 -3
  153. package/dist/esm/{utils-Dp5xFMCl.js → utils-DRTFlnxz.js} +3 -3
  154. package/dist/esm/{utils-Dp5xFMCl.js.map → utils-DRTFlnxz.js.map} +1 -1
  155. package/dist/le-kit/dist/components/assets/custom-elements.json +2029 -965
  156. package/dist/le-kit/dist/components/themes/base.css +4 -48
  157. package/dist/le-kit/dist/components/themes/index.css +3 -342
  158. package/dist/le-kit/index.esm.js +1 -1
  159. 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
  160. package/dist/le-kit/le-header-placeholder.entry.esm.js.map +1 -0
  161. package/dist/le-kit/le-kit.css +1 -1
  162. package/dist/le-kit/le-kit.esm.js +1 -1
  163. package/dist/le-kit/{p-1f55a4a2.entry.js → p-13a4dc1d.entry.js} +2 -2
  164. package/dist/le-kit/{p-0bd7803f.entry.js → p-1a9e65d0.entry.js} +2 -2
  165. package/dist/le-kit/p-2708dc65.entry.js +2 -0
  166. package/dist/le-kit/p-2708dc65.entry.js.map +1 -0
  167. package/dist/le-kit/p-2b96a5bd.entry.js +2 -0
  168. package/dist/le-kit/p-2b96a5bd.entry.js.map +1 -0
  169. package/dist/le-kit/{p-7b180d58.entry.js → p-32cbb683.entry.js} +2 -2
  170. package/dist/le-kit/{p-71c78784.entry.js → p-476e1886.entry.js} +2 -2
  171. package/dist/le-kit/p-67d702f9.entry.js +2 -0
  172. package/dist/le-kit/{p-33612923.entry.js → p-6884e3e8.entry.js} +2 -2
  173. package/dist/le-kit/{p-6ecdad85.entry.js → p-704ad5e0.entry.js} +2 -2
  174. package/dist/le-kit/{p-432e8231.entry.js → p-88f9aa40.entry.js} +2 -2
  175. package/dist/le-kit/{p-91993261.entry.js → p-8dd8a487.entry.js} +2 -2
  176. package/dist/le-kit/{p-6ee06c44.entry.js → p-97b7658a.entry.js} +2 -2
  177. package/dist/le-kit/{p-a5d31d40.entry.js → p-c0925e92.entry.js} +2 -2
  178. package/dist/le-kit/{p-548d130b.entry.js → p-c2494a0d.entry.js} +2 -2
  179. package/dist/le-kit/{p-3a52c4de.entry.js → p-ded51018.entry.js} +2 -2
  180. package/dist/le-kit/{p-2c37f174.entry.js → p-e3db7974.entry.js} +2 -2
  181. package/dist/le-kit/{p-b66fd9e1.entry.js → p-f9b03aec.entry.js} +2 -2
  182. package/dist/le-kit/p-hmBwv43R.js +3 -0
  183. package/dist/le-kit/p-hmBwv43R.js.map +1 -0
  184. package/dist/le-kit/p-txKmCJHv.js +2 -0
  185. package/dist/le-kit/{p-DaA5gINj.js.map → p-txKmCJHv.js.map} +1 -1
  186. package/dist/themes/base.css +4 -48
  187. package/dist/themes/index.css +3 -342
  188. package/dist/types/components/le-collapse/le-collapse.d.ts +41 -0
  189. package/dist/types/components/le-current-heading/le-current-heading.d.ts +25 -0
  190. package/dist/types/components/le-header/le-header.d.ts +115 -0
  191. package/dist/types/components/le-header-placeholder/le-header-placeholder.d.ts +13 -0
  192. package/dist/types/components/le-popover/le-popover.d.ts +9 -0
  193. package/dist/types/components/le-scroll-progress/le-scroll-progress.d.ts +40 -0
  194. package/dist/types/components.d.ts +518 -0
  195. package/package.json +1 -1
  196. package/dist/cjs/index-C3iQZ-Ja.js.map +0 -1
  197. package/dist/cjs/le-button.le-checkbox.le-component.le-popover.le-popup.le-slot.le-string-input.entry.cjs.js.map +0 -1
  198. package/dist/cjs/le-dropdown-base.cjs.entry.js +0 -348
  199. package/dist/cjs/le-dropdown-base.entry.cjs.js.map +0 -1
  200. package/dist/cjs/le-select.cjs.entry.js +0 -188
  201. package/dist/cjs/le-select.entry.cjs.js.map +0 -1
  202. package/dist/esm/index-DzgCnDLJ.js.map +0 -1
  203. package/dist/esm/le-button.le-checkbox.le-component.le-popover.le-popup.le-slot.le-string-input.entry.js.map +0 -1
  204. package/dist/esm/le-dropdown-base.entry.js +0 -346
  205. package/dist/esm/le-dropdown-base.entry.js.map +0 -1
  206. package/dist/esm/le-select.entry.js +0 -186
  207. package/dist/esm/le-select.entry.js.map +0 -1
  208. 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
  209. package/dist/le-kit/le-dropdown-base.entry.esm.js.map +0 -1
  210. package/dist/le-kit/le-select.entry.esm.js.map +0 -1
  211. package/dist/le-kit/p-4130c60b.entry.js +0 -2
  212. package/dist/le-kit/p-4130c60b.entry.js.map +0 -1
  213. package/dist/le-kit/p-DaA5gINj.js +0 -2
  214. package/dist/le-kit/p-DzgCnDLJ.js +0 -3
  215. package/dist/le-kit/p-DzgCnDLJ.js.map +0 -1
  216. package/dist/le-kit/p-beb87e61.entry.js +0 -2
  217. package/dist/le-kit/p-cc0797b0.entry.js +0 -2
  218. package/dist/le-kit/p-cc0797b0.entry.js.map +0 -1
  219. package/dist/le-kit/p-d504a369.entry.js +0 -2
  220. package/dist/le-kit/p-d504a369.entry.js.map +0 -1
  221. /package/dist/le-kit/{p-1f55a4a2.entry.js.map → p-13a4dc1d.entry.js.map} +0 -0
  222. /package/dist/le-kit/{p-0bd7803f.entry.js.map → p-1a9e65d0.entry.js.map} +0 -0
  223. /package/dist/le-kit/{p-7b180d58.entry.js.map → p-32cbb683.entry.js.map} +0 -0
  224. /package/dist/le-kit/{p-71c78784.entry.js.map → p-476e1886.entry.js.map} +0 -0
  225. /package/dist/le-kit/{p-beb87e61.entry.js.map → p-67d702f9.entry.js.map} +0 -0
  226. /package/dist/le-kit/{p-33612923.entry.js.map → p-6884e3e8.entry.js.map} +0 -0
  227. /package/dist/le-kit/{p-6ecdad85.entry.js.map → p-704ad5e0.entry.js.map} +0 -0
  228. /package/dist/le-kit/{p-432e8231.entry.js.map → p-88f9aa40.entry.js.map} +0 -0
  229. /package/dist/le-kit/{p-91993261.entry.js.map → p-8dd8a487.entry.js.map} +0 -0
  230. /package/dist/le-kit/{p-6ee06c44.entry.js.map → p-97b7658a.entry.js.map} +0 -0
  231. /package/dist/le-kit/{p-a5d31d40.entry.js.map → p-c0925e92.entry.js.map} +0 -0
  232. /package/dist/le-kit/{p-548d130b.entry.js.map → p-c2494a0d.entry.js.map} +0 -0
  233. /package/dist/le-kit/{p-3a52c4de.entry.js.map → p-ded51018.entry.js.map} +0 -0
  234. /package/dist/le-kit/{p-2c37f174.entry.js.map → p-e3db7974.entry.js.map} +0 -0
  235. /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, e as getAssetPath, H as Host, f as getLeKitConfig } from './index-DzgCnDLJ.js';
2
- import { c as classnames, o as observeModeChanges } from './utils-Dp5xFMCl.js';
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", { id: `prop-${attr.name}`, onChange: e => this.handlePropertyChange(attr.name, e.target.value, type) }, options.map(opt => (h("option", { value: opt, selected: value === opt || (!value && attr.default?.replace(/'/g, '') === opt) }, opt))))));
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 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/* 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";
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.open = true;
541
- this.addScrollListeners();
542
- this._updatePosition();
543
- this.lePopoverOpen.emit();
1352
+ this.handleOpened();
544
1353
  }
545
1354
  else {
546
- this.open = false;
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
- if (customEvent.detail?.popover === this.el)
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.popoverEl?.showPopover();
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.popoverEl?.hidePopover();
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: 'f3e1ae33b67abbaa13ac506271961b3dfcfaeec2', "trigger-full-width": this.triggerFullWidth }, h("div", { key: '4fc806cb1b4b59612bd7820d263b54db53f2d6d2', class: classnames('le-popover-trigger', {
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: 'b62f6201f31246ccbb047b7a6539fd54604cc45e', name: "trigger" }, h("button", { key: '17a1a253776424812e82e4c747d2f0a2414efd48', type: "button", class: "le-popover-default-trigger" }, h("span", { key: '3c9c4d0390222cd3c1afea8f864d7287c3d55a8f' }, "\u2295")))), h("div", { key: '5c786402b8e1c9a5b60894f201de1bccf20f5288', id: this.uniqueId, class: "le-popover-content", popover: this.closeOnClickOutside ? 'auto' : 'manual', ref: el => (this.popoverEl = el), style: popoverStyles }, (this.popoverTitle || this.showClose) && (h("div", { key: 'b9e810e52400b9f3246621e80ecd432ea4fca3e5', class: "le-popover-header" }, this.popoverTitle && h("span", { key: 'b4164ebd8da381274b2eca584a221d5fddfcb473', class: "le-popover-title" }, this.popoverTitle), this.showClose && (h("button", { key: 'e5dc86d2aeef127cf9eaa54af50363a1ad7a80a8', type: "button", class: "le-popover-close", onClick: () => this.hide(), "aria-label": "Close" }, "\u00D7")))), h("div", { key: '4b4cf379cec1e3ec083dc2aa48b5919b35761648', class: "le-popover-body", part: "content" }, h("slot", { key: '767680e6675b50024ec4baa22343e08c26317962' })))));
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: 'da1fce97fbec16e12affe4d53272f406379c229c', class: {
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: '51f1342de987ff5431a982f472106e1e34868b3a', component: "le-string-input", hostClass: classnames({ disabled: this.disabled }) }, h("div", { key: '2c5ad62aff36c5af5a3a5f1eab2038ba15210f89', class: "le-input-wrapper" }, this.label && (h("label", { key: 'bdcd6967df6fef291d5938c04f2fa4bd4a8f3925', class: "le-input-label", htmlFor: this.name }, this.label)), h("div", { key: '9bf86514adc36c1f2a112ff981befbd1d95b1d0c', class: "le-input-container", part: "container" }, this.iconStart && h("span", { key: '8d5d2221f4361f164df89e34579997f3c99bb9f8', class: "icon-start" }, this.iconStart), h("input", { key: '9cad21ae3f64608754c1f147b61bd1db42fd850c', ref: el => {
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: '39598782f14338e64567227f4df177af6092827c', class: "icon-end" }, this.iconEnd)), !this.hideDescription && (h("div", { key: '2ad752082be8c3aba9cc611eb93eeb41c3bfa994', class: "le-input-description" }, h("le-slot", { key: 'd42c8a263f3b0542b0a14860ad2f49b2ee4954a5', name: "description", type: "text", tag: "p", label: "Description" }, h("slot", { key: '4b689e56d07f003f38d28201b0dee597dbc2f955', name: "description" })))))));
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