le-kit 0.5.2 → 0.5.3

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