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