le-kit 0.1.14 → 0.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (568) hide show
  1. package/dist/{core/cjs/index-B0mg71He.js → cjs/index-CHzu3ydp.js} +10 -3
  2. package/dist/cjs/index-CHzu3ydp.js.map +1 -0
  3. package/dist/{core/cjs → cjs}/index.cjs.js +4 -3
  4. package/dist/cjs/index.cjs.js.map +1 -0
  5. package/dist/{core/cjs → cjs}/le-box.cjs.entry.js +3 -3
  6. package/dist/cjs/le-box.entry.cjs.js.map +1 -0
  7. package/dist/cjs/le-button.le-checkbox.le-collapse.le-component.le-current-heading.le-dropdown-base.le-header.le-popover.le-popup.le-scroll-progress.le-select.le-slot.le-string-input.entry.cjs.js.map +1 -0
  8. package/dist/cjs/le-button_13.cjs.entry.js +2579 -0
  9. package/dist/cjs/le-card.cjs.entry.js +29 -0
  10. package/dist/cjs/le-card.entry.cjs.js.map +1 -0
  11. package/dist/cjs/le-combobox.cjs.entry.js +237 -0
  12. package/dist/cjs/le-combobox.entry.cjs.js.map +1 -0
  13. package/dist/cjs/le-header-placeholder.cjs.entry.js +18 -0
  14. package/dist/cjs/le-header-placeholder.entry.cjs.js.map +1 -0
  15. package/dist/cjs/le-kit.cjs.js +25 -0
  16. package/dist/cjs/le-multiselect.cjs.entry.js +306 -0
  17. package/dist/cjs/le-multiselect.entry.cjs.js.map +1 -0
  18. package/dist/{core/cjs → cjs}/le-number-input.cjs.entry.js +3 -3
  19. package/dist/cjs/le-number-input.entry.cjs.js.map +1 -0
  20. package/dist/{core/cjs → cjs}/le-round-progress.cjs.entry.js +2 -2
  21. package/dist/cjs/le-round-progress.entry.cjs.js.map +1 -0
  22. package/dist/cjs/le-segmented-control.cjs.entry.js +245 -0
  23. package/dist/cjs/le-segmented-control.entry.cjs.js.map +1 -0
  24. package/dist/{core/cjs → cjs}/le-stack.cjs.entry.js +4 -4
  25. package/dist/cjs/le-stack.entry.cjs.js.map +1 -0
  26. package/dist/cjs/le-tab-bar.cjs.entry.js +242 -0
  27. package/dist/cjs/le-tab-bar.entry.cjs.js.map +1 -0
  28. package/dist/cjs/le-tab-panel.cjs.entry.js +100 -0
  29. package/dist/cjs/le-tab-panel.entry.cjs.js.map +1 -0
  30. package/dist/cjs/le-tab.cjs.entry.js +133 -0
  31. package/dist/cjs/le-tab.entry.cjs.js.map +1 -0
  32. package/dist/cjs/le-tabs.cjs.entry.js +307 -0
  33. package/dist/cjs/le-tabs.entry.cjs.js.map +1 -0
  34. package/dist/cjs/le-tag.cjs.entry.js +68 -0
  35. package/dist/cjs/le-tag.entry.cjs.js.map +1 -0
  36. package/dist/{core/cjs → cjs}/le-text.cjs.entry.js +3 -3
  37. package/dist/cjs/le-text.entry.cjs.js.map +1 -0
  38. package/dist/{core/cjs → cjs}/le-turntable.cjs.entry.js +2 -2
  39. package/dist/cjs/le-turntable.entry.cjs.js.map +1 -0
  40. package/dist/cjs/loader.cjs.js +13 -0
  41. package/dist/{core/cjs/utils-jdqP71LP.js → cjs/utils-CYOKcOW8.js} +3 -3
  42. package/dist/cjs/utils-CYOKcOW8.js.map +1 -0
  43. package/dist/collection/collection-manifest.json +41 -0
  44. package/dist/{core/collection → collection}/components/le-box/le-box.js +1 -1
  45. package/dist/collection/components/le-box/le-box.js.map +1 -0
  46. package/dist/{core/collection/components/le-button/le-button.default.css → collection/components/le-button/le-button.css} +65 -38
  47. package/dist/{core/collection → collection}/components/le-button/le-button.js +106 -16
  48. package/dist/collection/components/le-button/le-button.js.map +1 -0
  49. package/dist/{core/collection → collection}/components/le-card/le-card.default.css +6 -6
  50. package/dist/{core/collection → collection}/components/le-card/le-card.js +2 -2
  51. package/dist/collection/components/le-card/le-card.js.map +1 -0
  52. package/dist/{core/collection → collection}/components/le-checkbox/le-checkbox.js +2 -2
  53. package/dist/collection/components/le-checkbox/le-checkbox.js.map +1 -0
  54. package/dist/collection/components/le-collapse/le-collapse.css +31 -0
  55. package/dist/collection/components/le-collapse/le-collapse.js +188 -0
  56. package/dist/collection/components/le-collapse/le-collapse.js.map +1 -0
  57. package/dist/collection/components/le-combobox/le-combobox.css +144 -0
  58. package/dist/collection/components/le-combobox/le-combobox.js +659 -0
  59. package/dist/collection/components/le-combobox/le-combobox.js.map +1 -0
  60. package/dist/collection/components/le-component/le-component.css +189 -0
  61. package/dist/{le-kit/le-component.entry.js → collection/components/le-component/le-component.js} +137 -17
  62. package/dist/collection/components/le-component/le-component.js.map +1 -0
  63. package/dist/collection/components/le-current-heading/le-current-heading.css +12 -0
  64. package/dist/collection/components/le-current-heading/le-current-heading.js +130 -0
  65. package/dist/collection/components/le-current-heading/le-current-heading.js.map +1 -0
  66. package/dist/collection/components/le-dropdown-base/le-dropdown-base.css +167 -0
  67. package/dist/collection/components/le-dropdown-base/le-dropdown-base.js +761 -0
  68. package/dist/collection/components/le-dropdown-base/le-dropdown-base.js.map +1 -0
  69. package/dist/collection/components/le-header/le-header.css +120 -0
  70. package/dist/collection/components/le-header/le-header.js +508 -0
  71. package/dist/collection/components/le-header/le-header.js.map +1 -0
  72. package/dist/collection/components/le-header-placeholder/le-header-placeholder.js +21 -0
  73. package/dist/collection/components/le-header-placeholder/le-header-placeholder.js.map +1 -0
  74. package/dist/collection/components/le-multiselect/le-multiselect.css +163 -0
  75. package/dist/collection/components/le-multiselect/le-multiselect.js +734 -0
  76. package/dist/collection/components/le-multiselect/le-multiselect.js.map +1 -0
  77. package/dist/{core/collection → collection}/components/le-number-input/le-number-input.js +2 -2
  78. package/dist/collection/components/le-number-input/le-number-input.js.map +1 -0
  79. package/dist/{core/collection → collection}/components/le-popover/le-popover.css +20 -0
  80. package/dist/{core/collection → collection}/components/le-popover/le-popover.js +180 -20
  81. package/dist/collection/components/le-popover/le-popover.js.map +1 -0
  82. package/dist/{core/collection → collection}/components/le-popup/le-popup.api.js +2 -1
  83. package/dist/collection/components/le-popup/le-popup.api.js.map +1 -0
  84. package/dist/{core/collection → collection}/components/le-popup/le-popup.js +49 -19
  85. package/dist/collection/components/le-popup/le-popup.js.map +1 -0
  86. package/dist/{core/collection → collection}/components/le-round-progress/le-round-progress.js +1 -1
  87. package/dist/collection/components/le-round-progress/le-round-progress.js.map +1 -0
  88. package/dist/collection/components/le-scroll-progress/le-scroll-progress.css +29 -0
  89. package/dist/collection/components/le-scroll-progress/le-scroll-progress.js +186 -0
  90. package/dist/collection/components/le-scroll-progress/le-scroll-progress.js.map +1 -0
  91. package/dist/collection/components/le-segmented-control/le-segmented-control.css +78 -0
  92. package/dist/collection/components/le-segmented-control/le-segmented-control.js +445 -0
  93. package/dist/collection/components/le-segmented-control/le-segmented-control.js.map +1 -0
  94. package/dist/collection/components/le-select/le-select.css +121 -0
  95. package/dist/collection/components/le-select/le-select.js +578 -0
  96. package/dist/collection/components/le-select/le-select.js.map +1 -0
  97. package/dist/collection/components/le-slot/le-slot.default.css +222 -0
  98. package/dist/{le-kit/le-slot.entry.js → collection/components/le-slot/le-slot.js} +268 -17
  99. package/dist/collection/components/le-slot/le-slot.js.map +1 -0
  100. package/dist/{core/collection → collection}/components/le-stack/le-stack.js +2 -2
  101. package/dist/collection/components/le-stack/le-stack.js.map +1 -0
  102. package/dist/{core/collection → collection}/components/le-string-input/le-string-input.css +1 -1
  103. package/dist/{core/collection → collection}/components/le-string-input/le-string-input.js +60 -6
  104. package/dist/collection/components/le-string-input/le-string-input.js.map +1 -0
  105. package/dist/collection/components/le-tab/le-tab.css +289 -0
  106. package/dist/collection/components/le-tab/le-tab.js +565 -0
  107. package/dist/collection/components/le-tab/le-tab.js.map +1 -0
  108. package/dist/collection/components/le-tab-bar/le-tab-bar.css +89 -0
  109. package/dist/collection/components/le-tab-bar/le-tab-bar.js +467 -0
  110. package/dist/collection/components/le-tab-bar/le-tab-bar.js.map +1 -0
  111. package/dist/collection/components/le-tab-panel/le-tab-panel.css +30 -0
  112. package/dist/collection/components/le-tab-panel/le-tab-panel.js +302 -0
  113. package/dist/collection/components/le-tab-panel/le-tab-panel.js.map +1 -0
  114. package/dist/collection/components/le-tabs/le-tabs.css +146 -0
  115. package/dist/collection/components/le-tabs/le-tabs.js +588 -0
  116. package/dist/collection/components/le-tabs/le-tabs.js.map +1 -0
  117. package/dist/collection/components/le-tag/le-tag.css +139 -0
  118. package/dist/collection/components/le-tag/le-tag.js +266 -0
  119. package/dist/collection/components/le-tag/le-tag.js.map +1 -0
  120. package/dist/{core/collection → collection}/components/le-text/le-text.js +1 -1
  121. package/dist/collection/components/le-text/le-text.js.map +1 -0
  122. package/dist/{core/collection → collection}/components/le-turntable/le-turntable.js +1 -1
  123. package/dist/collection/components/le-turntable/le-turntable.js.map +1 -0
  124. package/dist/collection/dist/components/assets/.gitkeep +1 -0
  125. package/dist/collection/dist/components/assets/custom-elements.json +9234 -0
  126. package/dist/collection/dist/components/themes/base.css +89 -0
  127. package/dist/collection/dist/components/themes/dark.css +103 -0
  128. package/dist/collection/dist/components/themes/default.css +111 -0
  129. package/dist/collection/dist/components/themes/gradient.css +103 -0
  130. package/dist/collection/dist/components/themes/index.css +76 -0
  131. package/dist/collection/dist/components/themes/minimal.css +103 -0
  132. package/dist/collection/dist/components/themes/warm.css +103 -0
  133. package/dist/collection/global/app.js.map +1 -0
  134. package/dist/collection/index.js.map +1 -0
  135. package/dist/collection/types/blocks.js.map +1 -0
  136. package/dist/collection/types/options.js.map +1 -0
  137. package/dist/collection/utils/utils.js.map +1 -0
  138. package/dist/components/assets/.gitkeep +1 -0
  139. package/dist/components/assets/custom-elements.json +9234 -0
  140. package/dist/components/index.js +11 -0
  141. package/dist/components/index.js.map +1 -0
  142. package/dist/{core/components → components}/le-box.js +22 -6
  143. package/dist/components/le-box.js.map +1 -0
  144. package/dist/{core/components → components}/le-button.js +1 -1
  145. package/dist/{core/components → components}/le-button2.js +671 -35
  146. package/dist/components/le-button2.js.map +1 -0
  147. package/dist/{core/components → components}/le-card.js +22 -6
  148. package/dist/components/le-card.js.map +1 -0
  149. package/dist/{core/components → components}/le-checkbox.js +1 -1
  150. package/dist/components/le-collapse.d.ts +11 -0
  151. package/dist/components/le-collapse.js +144 -0
  152. package/dist/components/le-collapse.js.map +1 -0
  153. package/dist/components/le-combobox.d.ts +11 -0
  154. package/dist/components/le-combobox.js +326 -0
  155. package/dist/components/le-combobox.js.map +1 -0
  156. package/dist/{core/components → components}/le-component.js +1 -1
  157. package/dist/components/le-current-heading.d.ts +11 -0
  158. package/dist/components/le-current-heading.js +93 -0
  159. package/dist/components/le-current-heading.js.map +1 -0
  160. package/dist/components/le-dropdown-base.d.ts +11 -0
  161. package/dist/components/le-dropdown-base.js +9 -0
  162. package/dist/components/le-dropdown-base.js.map +1 -0
  163. package/dist/components/le-dropdown-base2.js +393 -0
  164. package/dist/components/le-dropdown-base2.js.map +1 -0
  165. package/dist/components/le-header-placeholder.d.ts +11 -0
  166. package/dist/components/le-header-placeholder.js +37 -0
  167. package/dist/components/le-header-placeholder.js.map +1 -0
  168. package/dist/components/le-header.d.ts +11 -0
  169. package/dist/components/le-header.js +347 -0
  170. package/dist/components/le-header.js.map +1 -0
  171. package/dist/components/le-multiselect.d.ts +11 -0
  172. package/dist/components/le-multiselect.js +405 -0
  173. package/dist/components/le-multiselect.js.map +1 -0
  174. package/dist/{core/components → components}/le-number-input.js +23 -7
  175. package/dist/components/le-number-input.js.map +1 -0
  176. package/dist/{core/components → components}/le-popover2.js +143 -21
  177. package/dist/components/le-popover2.js.map +1 -0
  178. package/dist/{core/components/index.js → components/le-popup.api.js} +5 -12
  179. package/dist/components/le-popup.api.js.map +1 -0
  180. package/dist/components/le-popup.js +9 -0
  181. package/dist/components/le-popup.js.map +1 -0
  182. package/dist/{core/components → components}/le-round-progress.js +1 -1
  183. package/dist/components/le-scroll-progress.d.ts +11 -0
  184. package/dist/components/le-scroll-progress.js +142 -0
  185. package/dist/components/le-scroll-progress.js.map +1 -0
  186. package/dist/components/le-segmented-control.d.ts +11 -0
  187. package/dist/components/le-segmented-control.js +331 -0
  188. package/dist/components/le-segmented-control.js.map +1 -0
  189. package/dist/components/le-select.d.ts +11 -0
  190. package/dist/components/le-select.js +9 -0
  191. package/dist/components/le-select.js.map +1 -0
  192. package/dist/{core/components → components}/le-slot.js +1 -1
  193. package/dist/{core/components → components}/le-stack.js +23 -7
  194. package/dist/components/le-stack.js.map +1 -0
  195. package/dist/{core/components → components}/le-string-input.js +1 -1
  196. package/dist/components/le-tab-bar.d.ts +11 -0
  197. package/dist/components/le-tab-bar.js +330 -0
  198. package/dist/components/le-tab-bar.js.map +1 -0
  199. package/dist/components/le-tab-panel.d.ts +11 -0
  200. package/dist/components/le-tab-panel.js +182 -0
  201. package/dist/components/le-tab-panel.js.map +1 -0
  202. package/dist/components/le-tab.d.ts +11 -0
  203. package/dist/components/le-tab.js +9 -0
  204. package/dist/components/le-tab.js.map +1 -0
  205. package/dist/components/le-tab2.js +217 -0
  206. package/dist/components/le-tab2.js.map +1 -0
  207. package/dist/components/le-tabs.d.ts +11 -0
  208. package/dist/components/le-tabs.js +397 -0
  209. package/dist/components/le-tabs.js.map +1 -0
  210. package/dist/components/le-tag.d.ts +11 -0
  211. package/dist/components/le-tag.js +9 -0
  212. package/dist/components/le-tag.js.map +1 -0
  213. package/dist/components/le-tag2.js +141 -0
  214. package/dist/components/le-tag2.js.map +1 -0
  215. package/dist/{core/components → components}/le-text.js +22 -6
  216. package/dist/components/le-text.js.map +1 -0
  217. package/dist/{core/components → components}/le-turntable.js +1 -1
  218. package/dist/components/themes/base.css +4 -4
  219. package/dist/components/themes/dark.css +4 -1
  220. package/dist/components/themes/default.css +4 -1
  221. package/dist/components/themes/gradient.css +4 -1
  222. package/dist/components/themes/index.css +4 -341
  223. package/dist/components/themes/minimal.css +4 -1
  224. package/dist/components/themes/warm.css +4 -1
  225. package/dist/docs.d.ts +443 -0
  226. package/dist/docs.json +11547 -0
  227. package/dist/{core/esm/index-SKsXnjWI.js → esm/index-hmBwv43R.js} +10 -4
  228. package/dist/esm/index-hmBwv43R.js.map +1 -0
  229. package/dist/{core/esm → esm}/index.js +4 -3
  230. package/dist/esm/index.js.map +1 -0
  231. package/dist/{le-kit → esm}/le-box.entry.js +3 -3
  232. package/dist/esm/le-box.entry.js.map +1 -0
  233. package/dist/esm/le-button.le-checkbox.le-collapse.le-component.le-current-heading.le-dropdown-base.le-header.le-popover.le-popup.le-scroll-progress.le-select.le-slot.le-string-input.entry.js.map +1 -0
  234. package/dist/esm/le-button_13.entry.js +2565 -0
  235. package/dist/{le-kit → esm}/le-card.entry.js +3 -3
  236. package/dist/esm/le-card.entry.js.map +1 -0
  237. package/dist/esm/le-combobox.entry.js +235 -0
  238. package/dist/esm/le-combobox.entry.js.map +1 -0
  239. package/dist/esm/le-header-placeholder.entry.js +16 -0
  240. package/dist/esm/le-header-placeholder.entry.js.map +1 -0
  241. package/dist/esm/le-kit.js +21 -0
  242. package/dist/esm/le-multiselect.entry.js +304 -0
  243. package/dist/esm/le-multiselect.entry.js.map +1 -0
  244. package/dist/{le-kit → esm}/le-number-input.entry.js +6 -6
  245. package/dist/esm/le-number-input.entry.js.map +1 -0
  246. package/dist/{core/esm → esm}/le-round-progress.entry.js +2 -2
  247. package/dist/esm/le-round-progress.entry.js.map +1 -0
  248. package/dist/esm/le-segmented-control.entry.js +243 -0
  249. package/dist/esm/le-segmented-control.entry.js.map +1 -0
  250. package/dist/{le-kit → esm}/le-stack.entry.js +4 -4
  251. package/dist/esm/le-stack.entry.js.map +1 -0
  252. package/dist/esm/le-tab-bar.entry.js +240 -0
  253. package/dist/esm/le-tab-bar.entry.js.map +1 -0
  254. package/dist/esm/le-tab-panel.entry.js +98 -0
  255. package/dist/esm/le-tab-panel.entry.js.map +1 -0
  256. package/dist/esm/le-tab.entry.js +131 -0
  257. package/dist/esm/le-tab.entry.js.map +1 -0
  258. package/dist/esm/le-tabs.entry.js +305 -0
  259. package/dist/esm/le-tabs.entry.js.map +1 -0
  260. package/dist/esm/le-tag.entry.js +66 -0
  261. package/dist/esm/le-tag.entry.js.map +1 -0
  262. package/dist/{le-kit → esm}/le-text.entry.js +3 -3
  263. package/dist/esm/le-text.entry.js.map +1 -0
  264. package/dist/{core/esm → esm}/le-turntable.entry.js +2 -2
  265. package/dist/esm/le-turntable.entry.js.map +1 -0
  266. package/dist/esm/loader.js +11 -0
  267. package/dist/{le-kit/utils-cwSNy7ZS.js → esm/utils-DRTFlnxz.js} +3 -3
  268. package/dist/{le-kit/utils-cwSNy7ZS.js.map → esm/utils-DRTFlnxz.js.map} +1 -1
  269. package/dist/le-kit/dist/components/assets/.gitkeep +1 -0
  270. package/dist/le-kit/dist/components/assets/custom-elements.json +9234 -0
  271. package/dist/le-kit/dist/components/themes/base.css +4 -4
  272. package/dist/le-kit/dist/components/themes/dark.css +4 -1
  273. package/dist/le-kit/dist/components/themes/default.css +4 -1
  274. package/dist/le-kit/dist/components/themes/gradient.css +4 -1
  275. package/dist/le-kit/dist/components/themes/index.css +4 -341
  276. package/dist/le-kit/dist/components/themes/minimal.css +4 -1
  277. package/dist/le-kit/dist/components/themes/warm.css +4 -1
  278. package/dist/le-kit/index.esm.js +2 -116
  279. package/dist/le-kit/index.esm.js.map +1 -1
  280. package/dist/le-kit/le-button.le-checkbox.le-collapse.le-component.le-current-heading.le-dropdown-base.le-header.le-popover.le-popup.le-scroll-progress.le-select.le-slot.le-string-input.entry.esm.js.map +1 -0
  281. package/dist/le-kit/le-combobox.entry.esm.js.map +1 -0
  282. package/dist/le-kit/le-header-placeholder.entry.esm.js.map +1 -0
  283. package/dist/le-kit/le-kit.css +1 -1010
  284. package/dist/le-kit/le-kit.esm.js +2 -48
  285. package/dist/le-kit/le-kit.esm.js.map +1 -1
  286. package/dist/le-kit/le-multiselect.entry.esm.js.map +1 -0
  287. package/dist/le-kit/le-segmented-control.entry.esm.js.map +1 -0
  288. package/dist/le-kit/le-tab-bar.entry.esm.js.map +1 -0
  289. package/dist/le-kit/le-tab-panel.entry.esm.js.map +1 -0
  290. package/dist/le-kit/le-tab.entry.esm.js.map +1 -0
  291. package/dist/le-kit/le-tabs.entry.esm.js.map +1 -0
  292. package/dist/le-kit/le-tag.entry.esm.js.map +1 -0
  293. package/dist/le-kit/p-13a4dc1d.entry.js +2 -0
  294. package/dist/le-kit/p-13a4dc1d.entry.js.map +1 -0
  295. package/dist/{core/le-kit/p-55f70091.entry.js → le-kit/p-1a9e65d0.entry.js} +2 -2
  296. package/dist/le-kit/p-1a9e65d0.entry.js.map +1 -0
  297. package/dist/le-kit/p-2708dc65.entry.js +2 -0
  298. package/dist/le-kit/p-2708dc65.entry.js.map +1 -0
  299. package/dist/le-kit/p-2b96a5bd.entry.js +2 -0
  300. package/dist/le-kit/p-2b96a5bd.entry.js.map +1 -0
  301. package/dist/le-kit/p-32cbb683.entry.js +2 -0
  302. package/dist/le-kit/p-32cbb683.entry.js.map +1 -0
  303. package/dist/le-kit/p-476e1886.entry.js +2 -0
  304. package/dist/le-kit/p-476e1886.entry.js.map +1 -0
  305. package/dist/le-kit/p-67d702f9.entry.js +2 -0
  306. package/dist/le-kit/p-67d702f9.entry.js.map +1 -0
  307. package/dist/{core/le-kit/p-6e414a5c.entry.js → le-kit/p-6884e3e8.entry.js} +2 -2
  308. package/dist/le-kit/p-6884e3e8.entry.js.map +1 -0
  309. package/dist/le-kit/p-704ad5e0.entry.js +2 -0
  310. package/dist/le-kit/p-704ad5e0.entry.js.map +1 -0
  311. package/dist/le-kit/p-88f9aa40.entry.js +2 -0
  312. package/dist/le-kit/p-88f9aa40.entry.js.map +1 -0
  313. package/dist/le-kit/p-8dd8a487.entry.js +2 -0
  314. package/dist/le-kit/p-8dd8a487.entry.js.map +1 -0
  315. package/dist/le-kit/p-97b7658a.entry.js +2 -0
  316. package/dist/le-kit/p-97b7658a.entry.js.map +1 -0
  317. package/dist/le-kit/p-c0925e92.entry.js +2 -0
  318. package/dist/le-kit/p-c0925e92.entry.js.map +1 -0
  319. package/dist/le-kit/p-c2494a0d.entry.js +2 -0
  320. package/dist/le-kit/p-c2494a0d.entry.js.map +1 -0
  321. package/dist/le-kit/p-ded51018.entry.js +2 -0
  322. package/dist/le-kit/p-ded51018.entry.js.map +1 -0
  323. package/dist/{core/le-kit/p-a9d05ef6.entry.js → le-kit/p-e3db7974.entry.js} +2 -2
  324. package/dist/le-kit/p-e3db7974.entry.js.map +1 -0
  325. package/dist/{core/le-kit/p-4f133e72.entry.js → le-kit/p-f9b03aec.entry.js} +2 -2
  326. package/dist/le-kit/p-f9b03aec.entry.js.map +1 -0
  327. package/dist/le-kit/p-hmBwv43R.js +3 -0
  328. package/dist/le-kit/p-hmBwv43R.js.map +1 -0
  329. package/dist/le-kit/p-txKmCJHv.js +2 -0
  330. package/dist/le-kit/p-txKmCJHv.js.map +1 -0
  331. package/dist/themes/base.css +89 -0
  332. package/dist/themes/dark.css +103 -0
  333. package/dist/themes/default.css +111 -0
  334. package/dist/themes/gradient.css +103 -0
  335. package/dist/themes/index.css +76 -0
  336. package/dist/themes/minimal.css +103 -0
  337. package/dist/themes/warm.css +103 -0
  338. package/dist/types/components/le-button/le-button.d.ts +19 -4
  339. package/dist/types/components/le-collapse/le-collapse.d.ts +41 -0
  340. package/dist/types/components/le-combobox/le-combobox.d.ts +128 -0
  341. package/dist/types/components/le-current-heading/le-current-heading.d.ts +25 -0
  342. package/dist/types/components/le-dropdown-base/le-dropdown-base.d.ts +118 -0
  343. package/dist/types/components/le-header/le-header.d.ts +115 -0
  344. package/dist/types/components/le-header-placeholder/le-header-placeholder.d.ts +13 -0
  345. package/dist/types/components/le-multiselect/le-multiselect.d.ts +143 -0
  346. package/dist/types/components/le-popover/le-popover.d.ts +22 -2
  347. package/dist/types/components/le-popup/le-popup.d.ts +5 -0
  348. package/dist/types/components/le-scroll-progress/le-scroll-progress.d.ts +40 -0
  349. package/dist/types/components/le-segmented-control/le-segmented-control.d.ts +82 -0
  350. package/dist/types/components/le-select/le-select.d.ts +125 -0
  351. package/dist/types/components/le-string-input/le-string-input.d.ts +8 -0
  352. package/dist/types/components/le-tab/le-tab.d.ts +116 -0
  353. package/dist/types/components/le-tab-bar/le-tab-bar.d.ts +88 -0
  354. package/dist/types/components/le-tab-panel/le-tab-panel.d.ts +75 -0
  355. package/dist/types/components/le-tabs/le-tabs.d.ts +108 -0
  356. package/dist/types/components/le-tag/le-tag.d.ts +78 -0
  357. package/dist/types/components.d.ts +3061 -273
  358. package/dist/types/types/options.d.ts +9 -0
  359. package/package.json +3 -18
  360. package/dist/core/cjs/index-B0mg71He.js.map +0 -1
  361. package/dist/core/cjs/index.cjs.js.map +0 -1
  362. package/dist/core/cjs/le-box.entry.cjs.js.map +0 -1
  363. package/dist/core/cjs/le-button.cjs.entry.js +0 -92
  364. package/dist/core/cjs/le-button.entry.cjs.js.map +0 -1
  365. package/dist/core/cjs/le-card.cjs.entry.js +0 -29
  366. package/dist/core/cjs/le-card.entry.cjs.js.map +0 -1
  367. package/dist/core/cjs/le-checkbox.cjs.entry.js +0 -61
  368. package/dist/core/cjs/le-checkbox.entry.cjs.js.map +0 -1
  369. package/dist/core/cjs/le-kit.cjs.js +0 -25
  370. package/dist/core/cjs/le-number-input.entry.cjs.js.map +0 -1
  371. package/dist/core/cjs/le-popover.cjs.entry.js +0 -348
  372. package/dist/core/cjs/le-popover.entry.cjs.js.map +0 -1
  373. package/dist/core/cjs/le-popup.cjs.entry.js +0 -212
  374. package/dist/core/cjs/le-popup.entry.cjs.js.map +0 -1
  375. package/dist/core/cjs/le-round-progress.entry.cjs.js.map +0 -1
  376. package/dist/core/cjs/le-stack.entry.cjs.js.map +0 -1
  377. package/dist/core/cjs/le-string-input.cjs.entry.js +0 -95
  378. package/dist/core/cjs/le-string-input.entry.cjs.js.map +0 -1
  379. package/dist/core/cjs/le-text.entry.cjs.js.map +0 -1
  380. package/dist/core/cjs/le-turntable.entry.cjs.js.map +0 -1
  381. package/dist/core/cjs/loader.cjs.js +0 -13
  382. package/dist/core/cjs/utils-jdqP71LP.js.map +0 -1
  383. package/dist/core/collection/collection-manifest.json +0 -24
  384. package/dist/core/collection/components/le-box/le-box.js.map +0 -1
  385. package/dist/core/collection/components/le-button/le-button.js.map +0 -1
  386. package/dist/core/collection/components/le-card/le-card.js.map +0 -1
  387. package/dist/core/collection/components/le-checkbox/le-checkbox.js.map +0 -1
  388. package/dist/core/collection/components/le-number-input/le-number-input.js.map +0 -1
  389. package/dist/core/collection/components/le-popover/le-popover.js.map +0 -1
  390. package/dist/core/collection/components/le-popup/le-popup.api.js.map +0 -1
  391. package/dist/core/collection/components/le-popup/le-popup.js.map +0 -1
  392. package/dist/core/collection/components/le-round-progress/le-round-progress.js.map +0 -1
  393. package/dist/core/collection/components/le-stack/le-stack.js.map +0 -1
  394. package/dist/core/collection/components/le-string-input/le-string-input.js.map +0 -1
  395. package/dist/core/collection/components/le-text/le-text.js.map +0 -1
  396. package/dist/core/collection/components/le-turntable/le-turntable.js.map +0 -1
  397. package/dist/core/collection/global/app.js.map +0 -1
  398. package/dist/core/collection/index.js.map +0 -1
  399. package/dist/core/collection/types/blocks.js.map +0 -1
  400. package/dist/core/collection/types/options.js.map +0 -1
  401. package/dist/core/collection/utils/utils.js.map +0 -1
  402. package/dist/core/components/index.d.ts +0 -33
  403. package/dist/core/components/index.js.map +0 -1
  404. package/dist/core/components/le-box.d.ts +0 -11
  405. package/dist/core/components/le-box.js.map +0 -1
  406. package/dist/core/components/le-button.d.ts +0 -11
  407. package/dist/core/components/le-button2.js.map +0 -1
  408. package/dist/core/components/le-card.d.ts +0 -11
  409. package/dist/core/components/le-card.js.map +0 -1
  410. package/dist/core/components/le-checkbox.d.ts +0 -11
  411. package/dist/core/components/le-component.d.ts +0 -11
  412. package/dist/core/components/le-number-input.d.ts +0 -11
  413. package/dist/core/components/le-number-input.js.map +0 -1
  414. package/dist/core/components/le-popover.d.ts +0 -11
  415. package/dist/core/components/le-popover2.js.map +0 -1
  416. package/dist/core/components/le-popup.d.ts +0 -11
  417. package/dist/core/components/le-popup.js +0 -279
  418. package/dist/core/components/le-popup.js.map +0 -1
  419. package/dist/core/components/le-round-progress.d.ts +0 -11
  420. package/dist/core/components/le-slot.d.ts +0 -11
  421. package/dist/core/components/le-stack.d.ts +0 -11
  422. package/dist/core/components/le-stack.js.map +0 -1
  423. package/dist/core/components/le-string-input.d.ts +0 -11
  424. package/dist/core/components/le-text.d.ts +0 -11
  425. package/dist/core/components/le-text.js.map +0 -1
  426. package/dist/core/components/le-turntable.d.ts +0 -11
  427. package/dist/core/esm/index-SKsXnjWI.js.map +0 -1
  428. package/dist/core/esm/index.js.map +0 -1
  429. package/dist/core/esm/le-box.entry.js +0 -182
  430. package/dist/core/esm/le-box.entry.js.map +0 -1
  431. package/dist/core/esm/le-button.entry.js +0 -90
  432. package/dist/core/esm/le-button.entry.js.map +0 -1
  433. package/dist/core/esm/le-card.entry.js +0 -27
  434. package/dist/core/esm/le-card.entry.js.map +0 -1
  435. package/dist/core/esm/le-checkbox.entry.js +0 -59
  436. package/dist/core/esm/le-checkbox.entry.js.map +0 -1
  437. package/dist/core/esm/le-kit.js +0 -21
  438. package/dist/core/esm/le-number-input.entry.js +0 -200
  439. package/dist/core/esm/le-number-input.entry.js.map +0 -1
  440. package/dist/core/esm/le-popover.entry.js +0 -346
  441. package/dist/core/esm/le-popover.entry.js.map +0 -1
  442. package/dist/core/esm/le-popup.entry.js +0 -210
  443. package/dist/core/esm/le-popup.entry.js.map +0 -1
  444. package/dist/core/esm/le-round-progress.entry.js.map +0 -1
  445. package/dist/core/esm/le-stack.entry.js +0 -133
  446. package/dist/core/esm/le-stack.entry.js.map +0 -1
  447. package/dist/core/esm/le-string-input.entry.js +0 -93
  448. package/dist/core/esm/le-string-input.entry.js.map +0 -1
  449. package/dist/core/esm/le-text.entry.js +0 -333
  450. package/dist/core/esm/le-text.entry.js.map +0 -1
  451. package/dist/core/esm/le-turntable.entry.js.map +0 -1
  452. package/dist/core/esm/loader.js +0 -11
  453. package/dist/core/esm/utils-DZdP1JiG.js +0 -146
  454. package/dist/core/esm/utils-DZdP1JiG.js.map +0 -1
  455. package/dist/core/le-kit/index.esm.js +0 -2
  456. package/dist/core/le-kit/index.esm.js.map +0 -1
  457. package/dist/core/le-kit/le-box.entry.esm.js.map +0 -1
  458. package/dist/core/le-kit/le-button.entry.esm.js.map +0 -1
  459. package/dist/core/le-kit/le-card.entry.esm.js.map +0 -1
  460. package/dist/core/le-kit/le-checkbox.entry.esm.js.map +0 -1
  461. package/dist/core/le-kit/le-kit.css +0 -1
  462. package/dist/core/le-kit/le-kit.esm.js +0 -2
  463. package/dist/core/le-kit/le-kit.esm.js.map +0 -1
  464. package/dist/core/le-kit/le-number-input.entry.esm.js.map +0 -1
  465. package/dist/core/le-kit/le-popover.entry.esm.js.map +0 -1
  466. package/dist/core/le-kit/le-popup.entry.esm.js.map +0 -1
  467. package/dist/core/le-kit/le-round-progress.entry.esm.js.map +0 -1
  468. package/dist/core/le-kit/le-stack.entry.esm.js.map +0 -1
  469. package/dist/core/le-kit/le-string-input.entry.esm.js.map +0 -1
  470. package/dist/core/le-kit/le-text.entry.esm.js.map +0 -1
  471. package/dist/core/le-kit/le-turntable.entry.esm.js.map +0 -1
  472. package/dist/core/le-kit/loader.esm.js.map +0 -1
  473. package/dist/core/le-kit/p--VxUdzYV.js +0 -2
  474. package/dist/core/le-kit/p--VxUdzYV.js.map +0 -1
  475. package/dist/core/le-kit/p-189cb775.entry.js +0 -2
  476. package/dist/core/le-kit/p-189cb775.entry.js.map +0 -1
  477. package/dist/core/le-kit/p-35c1d413.entry.js +0 -2
  478. package/dist/core/le-kit/p-35c1d413.entry.js.map +0 -1
  479. package/dist/core/le-kit/p-4f133e72.entry.js.map +0 -1
  480. package/dist/core/le-kit/p-55f70091.entry.js.map +0 -1
  481. package/dist/core/le-kit/p-5fd7b23a.entry.js +0 -2
  482. package/dist/core/le-kit/p-5fd7b23a.entry.js.map +0 -1
  483. package/dist/core/le-kit/p-6e414a5c.entry.js.map +0 -1
  484. package/dist/core/le-kit/p-7b121ca7.entry.js +0 -2
  485. package/dist/core/le-kit/p-7b121ca7.entry.js.map +0 -1
  486. package/dist/core/le-kit/p-8c81fa95.entry.js +0 -2
  487. package/dist/core/le-kit/p-8c81fa95.entry.js.map +0 -1
  488. package/dist/core/le-kit/p-9aa81442.entry.js +0 -2
  489. package/dist/core/le-kit/p-9aa81442.entry.js.map +0 -1
  490. package/dist/core/le-kit/p-SKsXnjWI.js +0 -3
  491. package/dist/core/le-kit/p-SKsXnjWI.js.map +0 -1
  492. package/dist/core/le-kit/p-a9d05ef6.entry.js.map +0 -1
  493. package/dist/core/le-kit/p-b2bd2a80.entry.js +0 -2
  494. package/dist/core/le-kit/p-b2bd2a80.entry.js.map +0 -1
  495. package/dist/core/le-kit/p-ccac9611.entry.js +0 -2
  496. package/dist/core/le-kit/p-ccac9611.entry.js.map +0 -1
  497. package/dist/core/loader/cdn.js +0 -1
  498. package/dist/core/loader/index.cjs.js +0 -1
  499. package/dist/core/loader/index.d.ts +0 -24
  500. package/dist/core/loader/index.es2017.js +0 -1
  501. package/dist/core/loader/index.js +0 -2
  502. package/dist/core/types/components/le-box/le-box.d.ts +0 -111
  503. package/dist/core/types/components/le-button/le-button.d.ts +0 -78
  504. package/dist/core/types/components/le-card/le-card.d.ts +0 -37
  505. package/dist/core/types/components/le-checkbox/le-checkbox.d.ts +0 -46
  506. package/dist/core/types/components/le-number-input/le-number-input.d.ts +0 -106
  507. package/dist/core/types/components/le-popover/le-popover.d.ts +0 -109
  508. package/dist/core/types/components/le-popup/le-popup.api.d.ts +0 -73
  509. package/dist/core/types/components/le-popup/le-popup.d.ts +0 -122
  510. package/dist/core/types/components/le-round-progress/le-round-progress.d.ts +0 -37
  511. package/dist/core/types/components/le-stack/le-stack.d.ts +0 -73
  512. package/dist/core/types/components/le-string-input/le-string-input.d.ts +0 -83
  513. package/dist/core/types/components/le-text/le-text.d.ts +0 -141
  514. package/dist/core/types/components/le-turntable/le-turntable.d.ts +0 -55
  515. package/dist/core/types/components.d.ts +0 -1752
  516. package/dist/core/types/global/app.d.ts +0 -73
  517. package/dist/core/types/index.d.ts +0 -15
  518. package/dist/core/types/stencil-public-runtime.d.ts +0 -1756
  519. package/dist/core/types/types/blocks.d.ts +0 -136
  520. package/dist/core/types/types/options.d.ts +0 -124
  521. package/dist/core/types/utils/utils.d.ts +0 -54
  522. package/dist/le-kit/assets/custom-elements.json +0 -4305
  523. package/dist/le-kit/index-CAY3Hk_i.js +0 -4559
  524. package/dist/le-kit/index-CAY3Hk_i.js.map +0 -1
  525. package/dist/le-kit/le-button.entry.esm.js.map +0 -1
  526. package/dist/le-kit/le-button.entry.js +0 -90
  527. package/dist/le-kit/le-checkbox.entry.esm.js.map +0 -1
  528. package/dist/le-kit/le-checkbox.entry.js +0 -59
  529. package/dist/le-kit/le-component.entry.esm.js.map +0 -1
  530. package/dist/le-kit/le-popover.entry.esm.js.map +0 -1
  531. package/dist/le-kit/le-popover.entry.js +0 -346
  532. package/dist/le-kit/le-popup.entry.esm.js.map +0 -1
  533. package/dist/le-kit/le-popup.entry.js +0 -210
  534. package/dist/le-kit/le-round-progress.entry.js +0 -104
  535. package/dist/le-kit/le-slot.entry.esm.js.map +0 -1
  536. package/dist/le-kit/le-string-input.entry.esm.js.map +0 -1
  537. package/dist/le-kit/le-string-input.entry.js +0 -93
  538. package/dist/le-kit/le-turntable.entry.js +0 -137
  539. /package/dist/{core/cjs → cjs}/le-kit.cjs.js.map +0 -0
  540. /package/dist/{core/cjs → cjs}/loader.cjs.js.map +0 -0
  541. /package/dist/{core/collection → collection}/components/le-box/le-box.default.css +0 -0
  542. /package/dist/{core/collection → collection}/components/le-checkbox/le-checkbox.css +0 -0
  543. /package/dist/{core/collection → collection}/components/le-number-input/le-number-input.css +0 -0
  544. /package/dist/{core/collection → collection}/components/le-popup/le-popup.css +0 -0
  545. /package/dist/{core/collection → collection}/components/le-round-progress/le-round-progress.css +0 -0
  546. /package/dist/{core/collection → collection}/components/le-stack/le-stack.default.css +0 -0
  547. /package/dist/{core/collection → collection}/components/le-text/le-text.default.css +0 -0
  548. /package/dist/{core/collection → collection}/components/le-turntable/le-turntable.css +0 -0
  549. /package/dist/{core/collection → collection}/global/app.js +0 -0
  550. /package/dist/{core/collection → collection}/index.js +0 -0
  551. /package/dist/{core/collection → collection}/types/blocks.js +0 -0
  552. /package/dist/{core/collection → collection}/types/options.js +0 -0
  553. /package/dist/{core/collection → collection}/utils/utils.js +0 -0
  554. /package/dist/{core/components → components}/le-button.js.map +0 -0
  555. /package/dist/{core/components → components}/le-checkbox.js.map +0 -0
  556. /package/dist/{core/components → components}/le-component.js.map +0 -0
  557. /package/dist/{core/components → components}/le-popover.js +0 -0
  558. /package/dist/{core/components → components}/le-popover.js.map +0 -0
  559. /package/dist/{core/components → components}/le-round-progress.js.map +0 -0
  560. /package/dist/{core/components → components}/le-slot.js.map +0 -0
  561. /package/dist/{core/components → components}/le-string-input.js.map +0 -0
  562. /package/dist/{core/components → components}/le-turntable.js.map +0 -0
  563. /package/dist/{core/components → components}/utils.js +0 -0
  564. /package/dist/{core/components → components}/utils.js.map +0 -0
  565. /package/dist/{core/esm → esm}/le-kit.js.map +0 -0
  566. /package/dist/{core/esm → esm}/loader.js.map +0 -0
  567. /package/dist/{core/index.cjs.js → index.cjs.js} +0 -0
  568. /package/dist/{core/index.js → index.js} +0 -0
@@ -0,0 +1,2579 @@
1
+ 'use strict';
2
+
3
+ var index = require('./index-CHzu3ydp.js');
4
+ var utils = require('./utils-CYOKcOW8.js');
5
+ var index$1 = require('./index.cjs.js');
6
+
7
+ const leButtonCss = ":host{display:inline-block;--le-button-border-radius:var(--le-radius-md);--le-button-padding-x:var(--le-spacing-3);--le-button-padding-y:var(--le-spacing-1);--le-button-padding:var(--le-button-padding-y) var(--le-button-padding-x);--le-button-small-padding:0.25rem;--le-button-font-size:var(--le-font-size-md);--le-button-font-weight:var(--le-font-weight-medium);--le-button-transition:var(--le-transition-fast);--le-transition-easing:ease-in-out;--le-button-icon-aspect-ratio:1;--le-button-color:var(--le-color-primary-contrast);--_btn-bg:var(--le-color-primary);--_btn-bg-hover:var(--le-color-primary-dark);--_btn-bg-system:var(--le-color-black);--_btn-color:var(--le-button-color);--_btn-border-color:var(--le-color-primary)}:host([full-width]){display:block;width:100%}.le-button-container{display:inline-flex;flex-direction:row;align-items:center;justify-content:center;gap:var(--le-spacing-3);width:100%;padding:var(--le-button-padding);border:1px solid var(--_btn-border-color);border-radius:var(--le-button-border-radius);background:var(--_btn-bg);color:var(--_btn-color);font-family:var(--le-font-family-base);font-size:var(--le-button-font-size);font-weight:var(--le-button-font-weight);line-height:var(--le-line-height-tight);text-decoration:none;cursor:pointer;transition:background-color var(--le-button-transition) var(--le-transition-easing),\n border-color var(--le-button-transition) var(--le-transition-easing),\n box-shadow var(--le-button-transition) var(--le-transition-easing),\n transform var(--le-button-transition) var(--le-transition-easing)}.le-button-container:hover:not(:disabled){background:var(--_btn-bg-hover);border-color:var(--_btn-bg-hover)}.le-button-container:active:not(:disabled){box-shadow:inset 0 0 6px var(--le-color-shadow)}.le-button-container:focus-visible{outline:2px solid var(--le-color-focus);outline-offset:2px}.le-button-container:disabled{opacity:0.5;cursor:not-allowed}.le-button-label{display:inline-flex;flex-direction:row;align-items:center;justify-content:center;gap:var(--le-spacing-2)}:host>le-component.color-primary{--_btn-bg:var(--le-color-primary);--_btn-bg-hover:var(--le-color-primary-dark);--_btn-color:var(--le-button-color);--_btn-border-color:var(--le-color-primary)}:host>le-component.color-secondary{--_btn-bg:var(--le-color-secondary);--_btn-bg-hover:var(--le-color-secondary-dark);--_btn-color:var(--le-color-secondary-contrast);--_btn-border-color:var(--le-color-secondary)}:host>le-component.color-success{--_btn-bg:var(--le-color-success);--_btn-bg-hover:var(--le-color-success-dark);--_btn-color:var(--le-color-success-contrast);--_btn-border-color:var(--le-color-success)}:host>le-component.color-warning{--_btn-bg:var(--le-color-warning);--_btn-bg-hover:var(--le-color-warning-dark);--_btn-color:var(--le-color-warning-contrast);--_btn-border-color:var(--le-color-warning)}:host>le-component.color-danger{--_btn-bg:var(--le-color-danger);--_btn-bg-hover:var(--le-color-danger-dark);--_btn-color:var(--le-color-danger-contrast);--_btn-border-color:var(--le-color-danger)}:host>le-component.color-info{--_btn-bg:var(--le-color-info);--_btn-bg-hover:var(--le-color-info-dark);--_btn-color:var(--le-color-info-contrast);--_btn-border-color:var(--le-color-info)}:host>le-component.variant-solid .le-button-container{box-shadow:var(--le-shadow-sm)}:host>le-component.variant-solid .le-button-container:hover:not(:disabled){box-shadow:var(--le-shadow-md)}:host>le-component.variant-outlined .le-button-container{background:transparent;color:var(--_btn-bg);border-color:color-mix(in srgb, var(--_btn-border-color) 33%, transparent)}:host>le-component.variant-outlined .le-button-container:hover:not(:disabled){border-color:var(--_btn-border-color)}:host>le-component.variant-clear .le-button-container{background:transparent;color:var(--_btn-bg);border-color:transparent}:host>le-component.variant-clear .le-button-container:hover:not(:disabled){background:var(--le-color-gray-100);border-color:transparent}:host>le-component.variant-system .le-button-container{background:transparent;color:var(--_btn-bg-system);border-color:transparent}:host>le-component.size-small .le-button-container{--le-button-padding-x:0.4rem;--le-button-padding-y:0.3rem;--le-button-padding-top:0.35rem;--le-button-font-size:var(--le-button-small-font-size, var(--le-font-size-xs))}:host>le-component.size-large .le-button-container{--le-button-padding-x:0.9rem;--le-button-padding-y:0.6rem;--le-button-font-size:var(--le-font-size-xl)}:host>le-component.full-width{display:block;width:100%}:host>le-component.selected .le-button-container{box-shadow:inset 0 0 4px var(--le-color-shadow)}:host>le-component.variant-outlined.selected .le-button-container,:host>le-component.variant-clear.selected .le-button-container{background:var(--_btn-bg);color:var(--_btn-color)}:host>le-component.icon-only .le-button-container{padding:0.5rem;padding-bottom:0.6rem;aspect-ratio:var(--le-button-icon-aspect-ratio, 1)}:host>le-component.icon-only.size-small .le-button-container{padding:var(--le-button-small-padding, 0.25rem)}:host>le-component.icon-only.size-large .le-button-container{padding:0.75rem}:host>le-component.icon-only .content{display:none}.content{display:inline}.content:empty{display:none}.icon-start,.icon-only,.icon-end{display:flex;align-items:center;justify-content:center}.icon-start:empty,.icon-only:empty,.icon-end:empty{display:none}::slotted([slot=\"icon-start\"]),::slotted([slot=\"icon-only\"]),::slotted([slot=\"icon-end\"]){display:flex;align-items:center;justify-content:center;width:1.125em;height:1.125em}.le-button-align-start{justify-content:flex-start}.le-button-align-center{justify-content:center}.le-button-align-space-between{justify-content:space-between}.le-button-align-end{justify-content:flex-end}";
8
+
9
+ const LeButton = class {
10
+ constructor(hostRef) {
11
+ index.registerInstance(this, hostRef);
12
+ this.leClick = index.createEvent(this, "click");
13
+ }
14
+ get el() { return index.getElement(this); }
15
+ /**
16
+ * Mode of the popover should be 'default' for internal use
17
+ */
18
+ mode;
19
+ /**
20
+ * Button variant style
21
+ * @allowedValues solid | outlined | clear
22
+ */
23
+ variant = 'solid';
24
+ /**
25
+ * Button color theme (uses theme semantic colors)
26
+ * @allowedValues primary | secondary | success | warning | danger | info
27
+ */
28
+ color = 'primary';
29
+ /**
30
+ * Button size
31
+ * @allowedValues small | medium | large
32
+ */
33
+ size = 'medium';
34
+ /**
35
+ * Whether the button is in a selected/active state
36
+ */
37
+ selected = false;
38
+ /**
39
+ * Whether the button takes full width of its container
40
+ */
41
+ fullWidth = false;
42
+ /**
43
+ * Icon only button image or emoji
44
+ * if this prop is set, the button will render only the icon slot
45
+ */
46
+ iconOnly;
47
+ /**
48
+ * Start icon image or emoji
49
+ */
50
+ iconStart;
51
+ /**
52
+ * End icon image or emoji
53
+ */
54
+ iconEnd;
55
+ /**
56
+ * Whether the button is disabled
57
+ */
58
+ disabled = false;
59
+ /**
60
+ * The button type attribute
61
+ * @allowedValues button | submit | reset
62
+ */
63
+ type = 'button';
64
+ /**
65
+ * Optional href to make the button act as a link
66
+ */
67
+ href;
68
+ /**
69
+ * Link target when href is set
70
+ */
71
+ target;
72
+ /**
73
+ * Alignment of the button label without the end icon
74
+ * @allowedValues start | center | space-between | end
75
+ */
76
+ align = 'center';
77
+ /**
78
+ * Emitted when the button is clicked.
79
+ * This is a custom event that wraps the native click but ensures the target is the le-button.
80
+ */
81
+ leClick;
82
+ handleClick = (event) => {
83
+ // We stop the internal button click from bubbling up
84
+ event.stopPropagation();
85
+ if (this.disabled) {
86
+ event.preventDefault();
87
+ return;
88
+ }
89
+ // And emit our own click event from the host element
90
+ this.leClick.emit(event);
91
+ };
92
+ render() {
93
+ const classes = utils.classnames(`variant-${this.variant}`, `color-${this.color}`, `size-${this.size}`, {
94
+ 'selected': this.selected,
95
+ 'full-width': this.fullWidth,
96
+ 'icon-only': this.iconOnly,
97
+ 'disabled': this.disabled,
98
+ });
99
+ const TagType = this.href ? 'a' : 'button';
100
+ const attrs = this.href ? { href: this.href, target: this.target, role: 'button' } : { type: this.type, disabled: this.disabled };
101
+ return (index.h("le-component", { key: 'bf247365c4ceeaccdb05cbbb17604265f1608fa4', component: "le-button", hostClass: classes }, index.h(TagType, { key: 'a01540b86ace35d55b5635e2e5ce1049f480a788', class: utils.classnames('le-button-container', `le-button-align-${this.align}`), part: "button", ...attrs, onClick: this.handleClick }, this.iconOnly !== undefined ? (index.h("slot", { name: "icon-only" }, typeof this.iconOnly === 'string' ? this.iconOnly : null)) : (index.h(index.Fragment, null, index.h("span", { class: "le-button-label" }, this.iconStart && (index.h("span", { class: "icon-start", part: "icon-start" }, this.iconStart)), index.h("le-slot", { name: "", description: "Button text", type: "text", class: "content", part: "content" }, index.h("slot", null))), this.iconEnd && (index.h("span", { class: "icon-end", part: "icon-end" }, this.iconEnd)))))));
102
+ }
103
+ };
104
+ LeButton.style = leButtonCss;
105
+
106
+ const leCheckboxCss = ":host{display:block;--le-checkbox-size:18px;--le-checkbox-color:var(--le-color-primary, #007bff);--le-checkbox-label-color:var(--le-color-text-primary, #333);--le-checkbox-desc-color:var(--le-color-text-secondary, #666);--le-checkbox-border-radius:var(--le-radius-sm, 2px);--le-checkbox-marker-color:var(--le-color-surface, #fff)}.le-checkbox-wrapper{display:flex;flex-direction:column;gap:4px}.le-checkbox-label{display:inline-flex;align-items:flex-start;gap:8px;cursor:pointer;user-select:none}:host([disabled]) .le-checkbox-label{cursor:not-allowed;opacity:0.6}.le-checkbox-input{display:flex;align-items:center;justify-content:center;min-height:1.4em}input[type=\"checkbox\"]{appearance:none;-webkit-appearance:none;width:var(--le-checkbox-size);height:var(--le-checkbox-size);border:var(--le-border-width, 2px) solid var(--le-checkbox-color);border-radius:var(--le-checkbox-border-radius);margin:0;margin-top:2px;position:relative;cursor:inherit;background-color:transparent;transition:background-color 0.2s, border-color 0.2s}input[type=\"checkbox\"]:checked{background-color:var(--le-checkbox-color)}input[type=\"checkbox\"]:checked::after{content:'';position:absolute;left:0;top:0;bottom:calc(var(--le-checkbox-size) / 5);right:0;margin:auto;width:calc(var(--le-checkbox-size) / 4);height:calc(var(--le-checkbox-size) / 2);border:solid var(--le-checkbox-marker-color, #fff);border-width:0 calc(var(--le-checkbox-size) / 10) calc(var(--le-checkbox-size) / 10) 0;transform:rotate(45deg)}input[type=\"checkbox\"]:focus-visible{outline:2px solid var(--le-color-focus);outline-offset:2px}.le-checkbox-text{flex:1;flex-wrap:wrap;color:var(--le-checkbox-label-color);line-height:1.5;text-align:start}.le-checkbox-description{margin-left:calc(var(--le-checkbox-size) + 8px);font-size:0.875em;color:var(--le-checkbox-desc-color);line-height:1.4}:host [slot=\"description\"]{margin:0}";
107
+
108
+ const LeCheckbox = class {
109
+ constructor(hostRef) {
110
+ index.registerInstance(this, hostRef);
111
+ this.leChange = index.createEvent(this, "change");
112
+ }
113
+ get el() { return index.getElement(this); }
114
+ /**
115
+ * Whether the checkbox is checked
116
+ */
117
+ checked = false;
118
+ /**
119
+ * Whether the checkbox is disabled
120
+ */
121
+ disabled = false;
122
+ /**
123
+ * The name of the checkbox input
124
+ */
125
+ name;
126
+ /**
127
+ * The value of the checkbox input
128
+ */
129
+ value;
130
+ /**
131
+ * External ID for linking with external systems (e.g. database ID, PDF form field ID)
132
+ */
133
+ externalId;
134
+ /**
135
+ * Emitted when the checked state changes
136
+ */
137
+ leChange;
138
+ handleChange = (event) => {
139
+ // We stop the internal button click from bubbling up
140
+ event.stopPropagation();
141
+ if (this.disabled) {
142
+ event.preventDefault();
143
+ return;
144
+ }
145
+ const input = event.target;
146
+ this.checked = input.checked;
147
+ this.leChange.emit({
148
+ checked: this.checked,
149
+ value: this.value,
150
+ name: this.name,
151
+ externalId: this.externalId
152
+ });
153
+ };
154
+ render() {
155
+ return (index.h("le-component", { key: '43399929e07835e0019d509803e50a151921fa72', component: "le-checkbox", hostClass: utils.classnames({ 'disabled': this.disabled }) }, index.h("div", { key: '7ddbf2ac1690bb09082adfea70b9767c972d007a', class: "le-checkbox-wrapper" }, index.h("label", { key: '8eec4055c713e8b3b155695751b10bff64c9f903', class: "le-checkbox-label" }, index.h("span", { key: '2118b1cbe7911ff1674e522d723949d81cade185', class: "le-checkbox-input" }, index.h("input", { key: 'd0a30af5c14497fa6fa294c07ba74ae2e032481f', type: "checkbox", name: this.name, value: this.value, checked: this.checked, disabled: this.disabled, onChange: this.handleChange })), index.h("span", { key: '02cf9588431240039a53ee50e02b08ba5d63b974', class: "le-checkbox-text" }, index.h("le-slot", { key: 'e7d7b253deab72e627164eb72fc06109abfca6a5', name: "", type: "text", tag: "span" }, index.h("slot", { key: '1d8c443073e48848513a8a6d04cd7805a394e54e' })))), index.h("div", { key: '16c2c927dc0c0f7844a203a0628bf0e561009bd0', class: "le-checkbox-description" }, index.h("le-slot", { key: 'c6898ecc8992dce4786e68ab4b136bf5c3a4d3aa', name: "description", type: "text", tag: "div", label: "Description" }, index.h("slot", { key: '3342add8ed1400ab74681e445163eeb3dd415941', name: "description" }))))));
156
+ }
157
+ };
158
+ LeCheckbox.style = leCheckboxCss;
159
+
160
+ const leCollapseCss = ":host{--le-collapse-duration:var(--le-transition-normal);display:grid;grid-template-rows:1fr;opacity:1;transition:grid-template-rows var(--le-collapse-duration),\n opacity var(--le-collapse-duration)}:host([data-open=\"false\"]),:host([open=\"false\"]){grid-template-rows:0fr;opacity:0}:host([no-fading][data-open=\"false\"]),:host([no-fading][open=\"false\"]){opacity:1}.region{display:flex;flex-direction:column;justify-content:flex-end;overflow:hidden}:host([scroll-down]) .region{justify-content:flex-start}";
161
+
162
+ const LeCollapse = class {
163
+ constructor(hostRef) {
164
+ index.registerInstance(this, hostRef);
165
+ }
166
+ get el() { return index.getElement(this); }
167
+ /** Whether the content should be shown. */
168
+ open = true;
169
+ /** Whether the content should scroll down from the top when open. */
170
+ scrollDown = false;
171
+ /** Stop fading the content when collapsing/expanding. */
172
+ noFading = false;
173
+ /** If true, collapse/expand based on the nearest header shrink event. */
174
+ collapseOnHeaderShrink = false;
175
+ /**
176
+ * Handles `leHeaderShrinkChange` events from the `le-header`.
177
+ * In case multiple headers are present, only the nearest one in the DOM tree is used.
178
+ */
179
+ handleHeaderShrink(ev) {
180
+ const e = ev;
181
+ this.headerShrunk = !!e.detail?.shrunk;
182
+ }
183
+ headerShrunk = false;
184
+ componentWillLoad() {
185
+ // Stencil boolean props default to `false` when the attribute is missing.
186
+ // For this component, the desired default is open=true.
187
+ if (!this.el.hasAttribute('open')) {
188
+ this.open = true;
189
+ }
190
+ }
191
+ componentDidLoad() {
192
+ this.applyOpenState();
193
+ }
194
+ onOpenChange() {
195
+ this.applyOpenState();
196
+ }
197
+ onDrivenStateChange() {
198
+ this.applyOpenState();
199
+ }
200
+ shouldBeOpen() {
201
+ if (!this.open)
202
+ return false;
203
+ if (this.collapseOnHeaderShrink && this.headerShrunk)
204
+ return false;
205
+ return true;
206
+ }
207
+ applyOpenState() {
208
+ const nextOpen = this.shouldBeOpen();
209
+ this.el.toggleAttribute('data-open', nextOpen);
210
+ }
211
+ render() {
212
+ return (index.h(index.Host, { key: '30fe288583bae1645ce00714de95c40ed92b7af0', "data-open": this.shouldBeOpen() ? 'true' : 'false' }, index.h("le-component", { key: '5fdc1e83caaff73fedb61d7286fc56f03fa8127a', component: "le-collapse" }, index.h("div", { key: '185df372a5039be23abf42ff262ef2d3eaa1602f', class: "region", part: "region" }, index.h("slot", { key: '1790f5457264342d71aecb94a67ce4ee11149af2' })))));
213
+ }
214
+ static get watchers() { return {
215
+ "open": ["onOpenChange"],
216
+ "headerShrunk": ["onDrivenStateChange"]
217
+ }; }
218
+ };
219
+ LeCollapse.style = leCollapseCss;
220
+
221
+ const leComponentCss = ":host{display:contents}:host(.admin-mode){display:block}.le-component-wrapper{position:relative;border:2px dashed var(--le-admin-border-color, #90caf9);border-radius:var(--le-radius-md, 8px);background:var(--le-admin-bg, rgba(144, 202, 249, 0.05));transition:border-color 0.2s ease, box-shadow 0.2s ease}.le-component-wrapper:hover{border-color:var(--le-admin-border-hover, #42a5f5);box-shadow:0 0 0 2px var(--le-admin-glow, rgba(66, 165, 245, 0.2))}.le-component-header{display:flex;align-items:center;justify-content:space-between;gap:var(--le-spacing-1, 4px);padding:0 0 0 var(--le-spacing-1, 4px);background:var(--le-admin-header-bg, rgba(144, 202, 249, 0.15));border-bottom:1px solid var(--le-admin-border-color, #90caf9);border-radius:var(--le-radius-md, 8px) var(--le-radius-md, 8px) 0 0;font-size:var(--le-font-size-xs, 11px)}.le-component-name{font-weight:var(--le-font-weight-medium, 500);color:var(--le-admin-text, #1976d2);text-transform:capitalize;text-align:start;overflow:hidden;width:0;flex:1 1 0%}.le-component-content{padding:var(--le-space-xs, 4px)}.le-component-trigger{font-size:24px;line-height:0px;width:12px;height:12px}.le-component-button{width:20px}.property-editor{display:flex;flex-direction:column;gap:var(--le-space-sm, 8px);max-width:380px}.property-field{display:flex;flex-direction:column;gap:var(--le-space-xs, 4px)}.property-field label{display:flex;flex-direction:column;gap:2px;font-size:var(--le-font-size-sm, 13px);font-weight:var(--le-font-weight-medium, 500);color:var(--le-color-text, #333)}.property-hint{font-size:var(--le-font-size-xs, 11px);font-weight:normal;color:var(--le-color-text-secondary, #666);line-height:1.3}.property-field input[type=\"text\"],.property-field input[type=\"number\"],.property-field select{padding:var(--le-space-xs, 4px) var(--le-space-sm, 8px);border:1px solid var(--le-color-border, #ddd);border-radius:var(--le-radius-md, 7px);font-size:var(--le-font-size-sm, 13px);font-family:inherit;background:var(--le-color-surface, #fff);color:var(--le-color-text, #333);transition:border-color 0.15s ease, box-shadow 0.15s ease}.property-field input:focus,.property-field select:focus{outline:none;border-color:var(--le-color-primary, #1976d2);box-shadow:0 0 0 2px var(--le-color-primary-light, rgba(25, 118, 210, 0.2))}.property-field--checkbox{flex-direction:column}.property-field--checkbox label{flex-direction:row;align-items:center;gap:var(--le-space-sm, 8px);cursor:pointer}.property-field--checkbox input[type=\"checkbox\"]{width:16px;height:16px;margin:0;cursor:pointer;accent-color:var(--le-color-primary, #1976d2)}.property-field--checkbox .property-hint{margin-left:24px}.no-properties{margin:0;padding:var(--le-space-sm, 8px);font-size:var(--le-font-size-sm, 13px);color:var(--le-color-text-secondary, #666);text-align:center}.property-editor-container{display:flex;flex-direction:column;gap:var(--le-space-md, 12px)}.property-editor-actions{padding-top:var(--le-space-sm, 8px);border-top:1px solid var(--le-color-border, #e5e5e5)}.delete-component-btn{display:flex;align-items:center;justify-content:center;gap:var(--le-space-xs, 4px);width:100%;padding:var(--le-space-sm, 8px) var(--le-space-md, 12px);border:1px solid var(--le-color-danger, #e53935);border-radius:var(--le-radius-md, 6px);background:transparent;color:var(--le-color-danger, #e53935);font-size:var(--le-font-size-sm, 13px);font-weight:500;cursor:pointer;transition:background-color 0.15s, color 0.15s}.delete-component-btn:hover{background:var(--le-color-danger, #e53935);color:white}.delete-component-btn:active{opacity:0.9}";
222
+
223
+ const LeComponent = class {
224
+ constructor(hostRef) {
225
+ index.registerInstance(this, hostRef);
226
+ }
227
+ get el() { return index.getElement(this); }
228
+ /**
229
+ * The tag name of the component (e.g., 'le-card').
230
+ * Used to look up property metadata and display the component name.
231
+ */
232
+ component;
233
+ /**
234
+ * Optional display name for the component.
235
+ * If not provided, the tag name will be formatted as the display name.
236
+ */
237
+ displayName;
238
+ /**
239
+ * Classes to apply to the host element.
240
+ * Allows parent components to pass their styling classes.
241
+ */
242
+ hostClass;
243
+ /**
244
+ * Inline styles to apply to the host element.
245
+ * Allows parent components to pass dynamic styles (e.g., flex properties).
246
+ */
247
+ hostStyle;
248
+ /**
249
+ * Reference to the host element (found automatically from parent)
250
+ */
251
+ hostElement;
252
+ /**
253
+ * Internal state to track admin mode
254
+ */
255
+ adminMode = false;
256
+ /**
257
+ * Component metadata loaded from Custom Elements Manifest
258
+ */
259
+ componentMeta = null;
260
+ /**
261
+ * Current property values of the host component
262
+ */
263
+ propertyValues = {};
264
+ disconnectModeObserver;
265
+ connectedCallback() {
266
+ // Find the host element - le-component is rendered inside the component's shadow DOM,
267
+ // so we need to find the shadow root's host element
268
+ this.findHostElement();
269
+ this.disconnectModeObserver = utils.observeModeChanges(this.el, mode => {
270
+ this.adminMode = mode === 'admin';
271
+ // Load metadata and refresh property values only when entering admin mode
272
+ if (this.adminMode) {
273
+ if (!this.componentMeta) {
274
+ this.loadComponentMetadata();
275
+ }
276
+ else {
277
+ this.readPropertyValues();
278
+ }
279
+ }
280
+ });
281
+ }
282
+ /**
283
+ * Find the host element by traversing up through shadow DOM
284
+ */
285
+ findHostElement() {
286
+ // Get the shadow root that contains this le-component
287
+ const rootNode = this.el.getRootNode();
288
+ if (rootNode instanceof ShadowRoot) {
289
+ // The host of this shadow root is our target component (e.g., le-card)
290
+ this.hostElement = rootNode.host;
291
+ }
292
+ }
293
+ componentDidLoad() {
294
+ // Read initial property values from the host element
295
+ this.readPropertyValues();
296
+ }
297
+ disconnectedCallback() {
298
+ this.disconnectModeObserver?.();
299
+ }
300
+ /**
301
+ * Formats a tag name into a display name
302
+ * e.g., 'le-card' -> 'Card'
303
+ */
304
+ formatDisplayName(tagName) {
305
+ return tagName
306
+ .replace(/^le-/, '') // Remove 'le-' prefix
307
+ .split('-')
308
+ .map(word => word.charAt(0).toUpperCase() + word.slice(1))
309
+ .join(' ');
310
+ }
311
+ /**
312
+ * Load component metadata from the Custom Elements Manifest
313
+ */
314
+ async loadComponentMetadata() {
315
+ try {
316
+ // Fetch the manifest from configured URL
317
+ const { manifestFile } = index.getLeKitConfig();
318
+ const manifestFileResolved = index.getAssetPath(`./assets/${manifestFile}`);
319
+ const response = await fetch(manifestFileResolved);
320
+ const manifest = await response.json();
321
+ // Find the component definition
322
+ for (const module of manifest.modules) {
323
+ for (const declaration of module.declarations || []) {
324
+ if (declaration.tagName === this.component) {
325
+ const attributes = (declaration.attributes || []).filter((attr) => !this.isInternalAttribute(attr.name));
326
+ this.componentMeta = {
327
+ tagName: declaration.tagName,
328
+ description: declaration.description,
329
+ attributes,
330
+ };
331
+ // console.log(`[le-component] Loaded metadata for ${this.component}:`, this.componentMeta);
332
+ // Read property values after metadata is loaded
333
+ this.readPropertyValues();
334
+ return;
335
+ }
336
+ }
337
+ }
338
+ // console.warn(`[le-component] No metadata found for component: ${this.component}`);
339
+ }
340
+ catch (error) {
341
+ // console.warn(`[le-component] Failed to load metadata for component: ${this.component}`, error);
342
+ }
343
+ }
344
+ /**
345
+ * Check if an attribute is internal (should not be shown in editor)
346
+ */
347
+ isInternalAttribute(name) {
348
+ const internalAttrs = ['mode', 'theme', 'class', 'style', 'id', 'slot'];
349
+ return internalAttrs.includes(name);
350
+ }
351
+ /**
352
+ * Read current property values from the host element
353
+ */
354
+ readPropertyValues() {
355
+ if (!this.hostElement || !this.componentMeta)
356
+ return;
357
+ const values = {};
358
+ for (const attr of this.componentMeta.attributes) {
359
+ const value = this.hostElement.getAttribute(attr.name);
360
+ values[attr.name] = this.parseAttributeValue(value, attr.type?.text);
361
+ }
362
+ this.propertyValues = values;
363
+ }
364
+ /**
365
+ * Parse an attribute value based on its type
366
+ */
367
+ parseAttributeValue(value, type) {
368
+ if (value === null)
369
+ return undefined;
370
+ if (type === 'boolean') {
371
+ return value !== null && value !== 'false';
372
+ }
373
+ if (type === 'number') {
374
+ return parseFloat(value);
375
+ }
376
+ return value;
377
+ }
378
+ /**
379
+ * Handle property value changes from the editor
380
+ */
381
+ handlePropertyChange(attrName, value, type) {
382
+ if (!this.hostElement)
383
+ return;
384
+ // Update the host element's attribute
385
+ if (type === 'boolean') {
386
+ if (value) {
387
+ this.hostElement.setAttribute(attrName, '');
388
+ }
389
+ else {
390
+ this.hostElement.removeAttribute(attrName);
391
+ }
392
+ }
393
+ else if (value === undefined || value === '') {
394
+ this.hostElement.removeAttribute(attrName);
395
+ }
396
+ else {
397
+ this.hostElement.setAttribute(attrName, String(value));
398
+ }
399
+ // Update local state
400
+ this.propertyValues = { ...this.propertyValues, [attrName]: value };
401
+ // update the host element the way the parent element mutation observer would catch it?
402
+ }
403
+ /**
404
+ * Delete this component from the DOM
405
+ */
406
+ deleteComponent() {
407
+ if (!this.hostElement)
408
+ return;
409
+ // Confirm deletion
410
+ const name = this.displayName || this.formatDisplayName(this.component);
411
+ if (!index$1.leConfirm(`Delete this ${name}?`))
412
+ return;
413
+ // Remove the host element from its parent
414
+ const parent = this.hostElement.parentElement;
415
+ if (parent) {
416
+ this.hostElement.remove();
417
+ }
418
+ }
419
+ /**
420
+ * Render the property editor form
421
+ */
422
+ renderPropertyEditor() {
423
+ const hasProperties = this.componentMeta && this.componentMeta.attributes.length > 0;
424
+ return (index.h("div", { class: "property-editor-container" }, hasProperties ? (index.h("form", { class: "property-editor", onSubmit: e => e.preventDefault() }, this.componentMeta.attributes.map(attr => this.renderPropertyField(attr)))) : (index.h("p", { class: "no-properties" }, "No editable properties")), index.h("div", { class: "property-editor-actions" }, index.h("le-button", { type: "button", variant: "outlined", color: "danger", "full-width": true, onClick: () => this.deleteComponent() }, index.h("span", { slot: "icon-start" }, "\uD83D\uDDD1\uFE0F"), index.h("span", null, "Delete Component")))));
425
+ }
426
+ /**
427
+ * Render a single property field based on its type
428
+ */
429
+ renderPropertyField(attr) {
430
+ const value = this.propertyValues[attr.name];
431
+ const type = attr.type?.text || 'string';
432
+ // Check if type is a union of string literals (e.g., "'default' | 'outlined' | 'elevated'")
433
+ const enumMatch = type.match(/^'[^']+'/);
434
+ if (enumMatch) {
435
+ const options = type.split('|').map(opt => opt.trim().replace(/'/g, ''));
436
+ return (index.h("div", { class: "property-field" }, index.h("label", { htmlFor: `prop-${attr.name}` }, attr.name, attr.description && index.h("span", { class: "property-hint" }, attr.description)), index.h("le-select", { options: [...options.map(opt => ({ label: opt, value: opt }))], "full-width": true, value: value ?? attr.default?.replace(/'/g, ''), placeholder: attr.default?.replace(/'/g, ''), onLeChange: (e) => this.handlePropertyChange(attr.name, e.detail.value, type) })));
437
+ }
438
+ // Boolean type
439
+ if (type === 'boolean') {
440
+ return (index.h("div", { class: "property-field property-field--checkbox" }, index.h("le-checkbox", { name: `prop-${attr.name}`, checked: value === true || value === '', onChange: e => this.handlePropertyChange(attr.name, e.target.checked, type) }, attr.name, attr.description && index.h("div", { slot: "description" }, attr.description))));
441
+ }
442
+ // Number type
443
+ if (type === 'number') {
444
+ return (index.h("div", { class: "property-field" }, index.h("label", { htmlFor: `prop-${attr.name}` }, attr.name, attr.description && index.h("span", { class: "property-hint" }, attr.description)), index.h("input", { type: "number", id: `prop-${attr.name}`, value: value ?? '', placeholder: attr.default, onChange: e => this.handlePropertyChange(attr.name, e.target.value, type) })));
445
+ }
446
+ // Default: string/text input
447
+ return (index.h("div", { class: "property-field" }, index.h("le-string-input", { name: `prop-${attr.name}`, label: attr.name, value: value ?? '', placeholder: attr.default?.replace(/'/g, ''), onChange: (e) => this.handlePropertyChange(attr.name, e.detail.value, type) }, index.h("span", { slot: "description" }, attr.description))));
448
+ }
449
+ render() {
450
+ const name = this.displayName || this.formatDisplayName(this.component);
451
+ // In default mode, just pass through content with host classes
452
+ if (!this.adminMode) {
453
+ return (index.h(index.Host, { class: utils.classnames(this.component, this.hostClass), style: this.hostStyle }, index.h("slot", null)));
454
+ }
455
+ // In admin mode, show wrapper with header and settings
456
+ return (index.h(index.Host, { class: utils.classnames(this.component, this.hostClass, 'admin-mode'), style: this.hostStyle }, index.h("div", { class: "le-component-wrapper" }, index.h("div", { class: "le-component-header" }, index.h("span", { class: "le-component-name" }, name), index.h("le-popover", { popoverTitle: `${name} Settings`, position: "right", align: "start", "min-width": "300px", mode: "default" }, index.h("le-button", { type: "button", class: "le-component-button", slot: "trigger", variant: "clear", size: "small", "aria-label": "Edit component properties", "icon-only": true }, index.h("span", { class: "le-component-trigger", slot: "icon-only" }, "\u2699")), this.renderPropertyEditor())), index.h("div", { class: "le-component-content" }, index.h("slot", null)))));
457
+ }
458
+ static get assetsDirs() { return ["assets"]; }
459
+ };
460
+ LeComponent.style = leComponentCss;
461
+
462
+ const leCurrentHeadingCss = ":host{display:inline-flex;min-width:0}.title{font:inherit;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}";
463
+
464
+ const LeCurrentHeading = class {
465
+ constructor(hostRef) {
466
+ index.registerInstance(this, hostRef);
467
+ }
468
+ get el() { return index.getElement(this); }
469
+ /** CSS selector for page title/headings to watch (e.g. `.page-title`, `main h2`). */
470
+ selector = '';
471
+ activeText = null;
472
+ componentWillLoad() {
473
+ this.updateActiveTitle();
474
+ }
475
+ onSelectorChange() {
476
+ this.updateActiveTitle();
477
+ }
478
+ onScroll() {
479
+ this.updateActiveTitle();
480
+ }
481
+ onResize() {
482
+ this.updateActiveTitle();
483
+ }
484
+ updateActiveTitle() {
485
+ if (typeof window === 'undefined')
486
+ return;
487
+ const selector = (this.selector ?? '').trim();
488
+ if (!selector) {
489
+ this.activeText = null;
490
+ return;
491
+ }
492
+ let elements = [];
493
+ try {
494
+ elements = Array.from(document.querySelectorAll(selector));
495
+ }
496
+ catch {
497
+ this.activeText = null;
498
+ return;
499
+ }
500
+ // Pick the last element that is fully above the viewport.
501
+ let nextText = null;
502
+ for (const element of elements) {
503
+ const rect = element.getBoundingClientRect();
504
+ if (rect.height > 0 && rect.bottom <= 0) {
505
+ const t = (element.textContent ?? '').trim();
506
+ if (t)
507
+ nextText = t;
508
+ }
509
+ }
510
+ // Do not create oscillations: update only when the computed title changes.
511
+ if (nextText !== this.activeText) {
512
+ this.activeText = nextText;
513
+ }
514
+ }
515
+ render() {
516
+ return (index.h(index.Host, { key: 'e6b473d3633eb8f194edf19e88850390f4319929' }, this.activeText ? (index.h("span", { class: "title", part: "title" }, this.activeText)) : (index.h("slot", null))));
517
+ }
518
+ static get watchers() { return {
519
+ "selector": ["onSelectorChange"]
520
+ }; }
521
+ };
522
+ LeCurrentHeading.style = leCurrentHeadingCss;
523
+
524
+ const leDropdownBaseCss = ":host{display:block;--le-dropdown-list-padding:var(--le-spacing-1);--le-dropdown-empty-padding:var(--le-spacing-4);--le-dropdown-option-radius:var(--le-radius-md);--le-dropdown-font-size:var(--le-font-size-sm);--le-dropdown-option-padding:var(--le-spacing-1) var(--le-spacing-2);--le-dropdown-group-padding:var(--le-spacing-2) var(--le-spacing-2) var(--le-spacing-1);--le-dropdown-group-font-size:var(--le-font-size-xs)}:host([disabled]){pointer-events:none;opacity:0.5}le-popover::part(content){overflow-y:auto;overflow-x:hidden;padding:var(--le-dropdown-list-padding, 0.25rem)}.dropdown-empty{padding:var(--le-dropdown-empty-padding);text-align:center;color:var(--le-color-text-secondary, #9ca3af);font-size:var(--le-dropdown-font-size)}.dropdown-group-header{padding:var(--le-dropdown-group-padding);font-size:var(--le-dropdown-group-font-size);font-weight:700;color:var(--le-color-text-secondary, #9ca3af);letter-spacing:0.05em}.dropdown-list{text-align:initial}.dropdown-separator{height:1px;margin:var(--le-dropdown-separator-margin, 0.25rem 0);background:var(--le-color-border, #e5e7eb)}.dropdown-option{display:flex;align-items:center;gap:var(--le-dropdown-option-gap, 0.5rem);padding:var(--le-dropdown-option-padding);font-size:var(--le-dropdown-font-size, 0.875rem);line-height:1.4;color:var(--le-color-text, #1f2937);border:1px solid transparent;border-radius:var(--le-dropdown-option-radius, 0.25rem);cursor:pointer;user-select:none;transition:background-color 0.1s ease}.dropdown-option:hover,.dropdown-option.is-focused{border-color:var(--le-color-border-hover, #d1d5db)}.dropdown-option.is-disabled{opacity:0.5;cursor:not-allowed}.dropdown-option.is-disabled:hover{background:transparent}.option-checkbox{display:flex;align-items:center;justify-content:center;width:1rem;height:1rem;border:2px solid var(--le-color-border, #d1d5db);border-radius:0.25rem;background:var(--le-color-surface, #fff);flex-shrink:0}.is-selected .option-checkbox{background:var(--le-color-primary, #3b82f6);border-color:var(--le-color-primary, #3b82f6);color:white}.option-checkbox svg{width:0.75rem;height:0.75rem}.option-icon-start,.option-icon-end{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:1.25rem;height:1.25rem}.option-icon-start img,.option-icon-end img{width:100%;height:100%;object-fit:contain}.option-content{flex:1;min-width:0;display:flex;flex-direction:column}.option-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.option-description{font-size:0.75rem;color:var(--le-color-text-muted, #6b7280);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.option-check{display:flex;align-items:center;justify-content:center;width:1rem;height:1rem;color:var(--le-color-primary, #3b82f6);flex-shrink:0}.option-check svg{width:1rem;height:1rem}";
525
+
526
+ const LeDropdownBase = class {
527
+ constructor(hostRef) {
528
+ index.registerInstance(this, hostRef);
529
+ this.leOptionSelect = index.createEvent(this, "leOptionSelect");
530
+ this.leDropdownOpen = index.createEvent(this, "leDropdownOpen");
531
+ this.leDropdownClose = index.createEvent(this, "leDropdownClose");
532
+ }
533
+ get el() { return index.getElement(this); }
534
+ /**
535
+ * The options to display in the dropdown.
536
+ */
537
+ options = [];
538
+ /**
539
+ * Current value(s) - single value or array for multiselect.
540
+ */
541
+ value;
542
+ /**
543
+ * Whether multiple selection is allowed.
544
+ */
545
+ multiple = false;
546
+ /**
547
+ * Whether the dropdown is open.
548
+ */
549
+ open = false;
550
+ /**
551
+ * Whether the dropdown is disabled.
552
+ */
553
+ disabled = false;
554
+ /**
555
+ * Filter function for options.
556
+ * Return true to include the option.
557
+ */
558
+ filterFn;
559
+ /**
560
+ * Current filter query string.
561
+ */
562
+ filterQuery = '';
563
+ /**
564
+ * Placeholder text when no options match filter.
565
+ */
566
+ emptyText = 'No options';
567
+ /**
568
+ * Whether to show checkboxes for multiselect mode.
569
+ */
570
+ showCheckboxes = true;
571
+ /**
572
+ * Maximum height of the dropdown list.
573
+ */
574
+ maxHeight = '300px';
575
+ /**
576
+ * Width of the dropdown. If not set, matches trigger width.
577
+ */
578
+ width;
579
+ /**
580
+ * Sets the dropdown to full width of the trigger.
581
+ */
582
+ fullWidth = false;
583
+ /**
584
+ * Whether to close the dropdown when clicking outside.
585
+ * (used to support combobox with input focus)
586
+ */
587
+ closeOnClickOutside = true;
588
+ /**
589
+ * Emitted when an option is selected.
590
+ */
591
+ leOptionSelect;
592
+ /**
593
+ * Emitted when the dropdown opens.
594
+ */
595
+ leDropdownOpen;
596
+ /**
597
+ * Emitted when the dropdown closes.
598
+ */
599
+ leDropdownClose;
600
+ focusedIndex = -1;
601
+ filteredOptions = [];
602
+ popoverEl;
603
+ listEl;
604
+ triggerWidth = 0;
605
+ handleOptionsChange() {
606
+ this.updateFilteredOptions();
607
+ }
608
+ componentWillLoad() {
609
+ this.updateFilteredOptions();
610
+ }
611
+ updateFilteredOptions() {
612
+ // Remember previously focused option
613
+ const focusedOption = this.filteredOptions[this.focusedIndex];
614
+ if (!this.filterQuery || !this.filterFn) {
615
+ this.filteredOptions = this.options;
616
+ }
617
+ else {
618
+ this.filteredOptions = this.options.filter(opt => this.filterFn(opt, this.filterQuery));
619
+ }
620
+ // try to maintain focus on same option if still present
621
+ if (focusedOption) {
622
+ const newIndex = this.filteredOptions.indexOf(focusedOption);
623
+ this.focusedIndex = newIndex >= 0 ? newIndex : this.getInitialFocusIndex();
624
+ }
625
+ else {
626
+ this.focusedIndex = -1;
627
+ }
628
+ }
629
+ getSelectableOptions() {
630
+ return this.filteredOptions.filter(opt => !opt.disabled);
631
+ }
632
+ isSelected(option) {
633
+ const optValue = option.value ?? option.label;
634
+ if (this.multiple && Array.isArray(this.value)) {
635
+ setTimeout(() => {
636
+ this.popoverEl?.updatePosition();
637
+ }, 50);
638
+ return this.value.includes(optValue);
639
+ }
640
+ return this.value === optValue;
641
+ }
642
+ handleOptionClick(option, e) {
643
+ e.preventDefault();
644
+ e.stopPropagation();
645
+ if (option.disabled)
646
+ return;
647
+ this.leOptionSelect.emit({
648
+ value: option.value ?? option.label,
649
+ option,
650
+ });
651
+ // Close dropdown for single select
652
+ if (!this.multiple) {
653
+ this.hide();
654
+ }
655
+ }
656
+ handleKeyDown = (e) => {
657
+ if (!this.open)
658
+ return;
659
+ const optionCount = this.filteredOptions.length;
660
+ switch (e.key) {
661
+ case 'ArrowDown':
662
+ e.preventDefault();
663
+ // check for the next non-disabled option and focus
664
+ let nextIndex = this.focusedIndex < optionCount - 1 ? this.focusedIndex + 1 : 0;
665
+ while (this.filteredOptions[nextIndex].disabled) {
666
+ nextIndex = ++nextIndex < optionCount ? nextIndex : 0;
667
+ }
668
+ this.focusedIndex = nextIndex;
669
+ this.scrollToFocused();
670
+ break;
671
+ case 'ArrowUp':
672
+ e.preventDefault();
673
+ // check for the previous non-disabled option and focus
674
+ let prevIndex = this.focusedIndex > 0 ? this.focusedIndex - 1 : optionCount - 1;
675
+ while (this.filteredOptions[prevIndex].disabled) {
676
+ prevIndex = --prevIndex >= 0 ? prevIndex : optionCount - 1;
677
+ }
678
+ this.focusedIndex = prevIndex;
679
+ this.scrollToFocused();
680
+ break;
681
+ case 'Home':
682
+ e.preventDefault();
683
+ // check for the first non-disabled option and focus
684
+ let firstIndex = 0;
685
+ while (this.filteredOptions[firstIndex].disabled) {
686
+ firstIndex++;
687
+ if (firstIndex >= optionCount) {
688
+ firstIndex = -1;
689
+ break;
690
+ }
691
+ }
692
+ this.focusedIndex = firstIndex;
693
+ this.scrollToFocused();
694
+ break;
695
+ case 'End':
696
+ e.preventDefault();
697
+ // check for the last non-disabled option and focus
698
+ let lastIndex = optionCount - 1;
699
+ while (this.filteredOptions[lastIndex].disabled) {
700
+ lastIndex--;
701
+ if (lastIndex < 0) {
702
+ lastIndex = -1;
703
+ break;
704
+ }
705
+ }
706
+ this.focusedIndex = lastIndex;
707
+ this.scrollToFocused();
708
+ break;
709
+ case 'Enter':
710
+ case ' ':
711
+ e.preventDefault();
712
+ if (this.focusedIndex >= 0 && this.focusedIndex < optionCount) {
713
+ const option = this.filteredOptions[this.focusedIndex];
714
+ if (!option || option.disabled)
715
+ return;
716
+ this.leOptionSelect.emit({
717
+ value: option.value ?? option.label,
718
+ option,
719
+ });
720
+ if (!this.multiple) {
721
+ this.hide();
722
+ }
723
+ }
724
+ break;
725
+ case 'Escape':
726
+ e.preventDefault();
727
+ this.hide();
728
+ break;
729
+ case 'Tab':
730
+ this.hide();
731
+ break;
732
+ }
733
+ };
734
+ scrollToFocused() {
735
+ if (!this.listEl || this.focusedIndex < 0)
736
+ return;
737
+ const focusedEl = this.listEl.querySelector(`[data-index="${this.focusedIndex}"]`);
738
+ if (focusedEl) {
739
+ focusedEl.scrollIntoView({ block: 'nearest' });
740
+ }
741
+ }
742
+ handlePopoverOpen = () => {
743
+ this.open = true;
744
+ this.focusedIndex = this.getInitialFocusIndex();
745
+ this.leDropdownOpen.emit();
746
+ // Add keyboard listener
747
+ document.addEventListener('keydown', this.handleKeyDown);
748
+ };
749
+ handlePopoverClose = () => {
750
+ this.open = false;
751
+ this.focusedIndex = -1;
752
+ this.leDropdownClose.emit();
753
+ // Remove keyboard listener
754
+ document.removeEventListener('keydown', this.handleKeyDown);
755
+ };
756
+ getInitialFocusIndex() {
757
+ // Focus on first selected option, or first option
758
+ const selectableOptions = this.getSelectableOptions();
759
+ const selectedIndex = selectableOptions.findIndex(opt => this.isSelected(opt));
760
+ return selectedIndex >= 0 ? selectedIndex : 0;
761
+ }
762
+ /**
763
+ * Opens the dropdown.
764
+ */
765
+ async show() {
766
+ if (this.disabled)
767
+ return;
768
+ // Capture trigger width for matching dropdown width
769
+ const trigger = this.el.querySelector('[slot="trigger"]');
770
+ if (trigger) {
771
+ this.triggerWidth = trigger.offsetWidth;
772
+ }
773
+ await this.popoverEl?.show();
774
+ }
775
+ /**
776
+ * Closes the dropdown.
777
+ */
778
+ async hide() {
779
+ await this.popoverEl?.hide();
780
+ }
781
+ /**
782
+ * Toggles the dropdown.
783
+ */
784
+ async toggle() {
785
+ if (this.open) {
786
+ await this.hide();
787
+ }
788
+ else {
789
+ await this.show();
790
+ }
791
+ }
792
+ renderIcon(icon, className) {
793
+ if (!icon)
794
+ return null;
795
+ if (icon.startsWith('http') || icon.startsWith('/')) {
796
+ return index.h("img", { class: className, src: icon, alt: "" });
797
+ }
798
+ return index.h("span", { class: className }, icon);
799
+ }
800
+ renderOption(option, index$1) {
801
+ const isSelected = this.isSelected(option);
802
+ const isFocused = index$1 === this.focusedIndex;
803
+ const optionId = option.id || utils.generateId();
804
+ return (index.h("div", { class: {
805
+ 'dropdown-option': true,
806
+ 'is-selected': isSelected,
807
+ 'is-focused': isFocused,
808
+ 'is-disabled': !!option.disabled,
809
+ }, role: "option", id: optionId, "aria-selected": isSelected ? 'true' : 'false', "aria-disabled": option.disabled ? 'true' : undefined, "data-index": index$1, onClick: e => this.handleOptionClick(option, e), onMouseEnter: () => {
810
+ if (!option.disabled) {
811
+ this.focusedIndex = index$1;
812
+ }
813
+ } }, this.renderIcon(option.iconStart, 'option-icon-start'), index.h("div", { class: "option-content" }, index.h("span", { class: "option-label" }, option.label), option.description && index.h("span", { class: "option-description" }, option.description)), this.renderIcon(option.iconEnd, 'option-icon-end'), (!this.multiple || this.showCheckboxes) && isSelected && (index.h("span", { class: "option-check" }, index.h("svg", { viewBox: "0 0 16 16", fill: "currentColor" }, index.h("path", { d: "M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z" }))))));
814
+ }
815
+ renderOptions() {
816
+ if (this.filteredOptions.length === 0) {
817
+ return index.h("div", { class: "dropdown-empty" }, this.emptyText);
818
+ }
819
+ // Group options if they have group property
820
+ const grouped = new Map();
821
+ const ungrouped = [];
822
+ this.filteredOptions.forEach(opt => {
823
+ if (opt.group) {
824
+ const group = grouped.get(opt.group) || [];
825
+ group.push(opt);
826
+ grouped.set(opt.group, group);
827
+ }
828
+ else {
829
+ ungrouped.push(opt);
830
+ }
831
+ });
832
+ // Build flat list with group headers for index tracking
833
+ let globalIndex = 0;
834
+ const elements = [];
835
+ // Render ungrouped options first
836
+ ungrouped.forEach(opt => {
837
+ if (opt.separator === 'before') {
838
+ elements.push(index.h("div", { class: "dropdown-separator", role: "separator" }));
839
+ }
840
+ elements.push(this.renderOption(opt, globalIndex++));
841
+ if (opt.separator === 'after') {
842
+ elements.push(index.h("div", { class: "dropdown-separator", role: "separator" }));
843
+ }
844
+ });
845
+ // Render grouped options
846
+ grouped.forEach((options, groupLabel) => {
847
+ elements.push(index.h("div", { class: "dropdown-group-header", role: "presentation" }, groupLabel));
848
+ options.forEach(opt => {
849
+ elements.push(this.renderOption(opt, globalIndex++));
850
+ });
851
+ });
852
+ return elements;
853
+ }
854
+ render() {
855
+ const dropdownWidth = this.width || (this.triggerWidth ? `${this.triggerWidth}px` : undefined);
856
+ return (index.h(index.Host, { key: '838bef3556e494770fbb34cbff69c782ca717fe4' }, index.h("le-popover", { key: 'd72576e799c6cc065d3b0f3f1b918e84a7c5f690', ref: el => (this.popoverEl = el), position: "bottom", align: "start", showClose: false, closeOnClickOutside: this.closeOnClickOutside, closeOnEscape: true, offset: 4, width: dropdownWidth, minWidth: "150px", "trigger-full-width": this.fullWidth, onLePopoverOpen: this.handlePopoverOpen, onLePopoverClose: this.handlePopoverClose }, index.h("slot", { key: 'fbe84a553a126ad34f3ea159b182f825a065d1f6', name: "trigger", slot: "trigger" }), index.h("slot", { key: '957ac9208cdfe8be96a15979853e0b5cfdfc756f', name: "header" }), index.h("div", { key: '8c15f620b55035191979aca56514771c860051e3', class: "dropdown-list", role: "listbox", "aria-multiselectable": this.multiple ? 'true' : undefined, ref: el => (this.listEl = el), style: { maxHeight: this.maxHeight } }, this.renderOptions()))));
857
+ }
858
+ static get watchers() { return {
859
+ "options": ["handleOptionsChange"],
860
+ "filterQuery": ["handleOptionsChange"]
861
+ }; }
862
+ };
863
+ LeDropdownBase.style = leDropdownBaseCss;
864
+
865
+ const leHeaderCss = ":host{display:block;width:100%;--le-header-top-offset:0;--le-header-bg:var(--le-color-surface);--le-header-max-width:var(--le-header-max-width, auto);--le-header-margin:0 auto;--le-header-border:1px solid var(--le-color-border);--le-header-border-radius:0px;--le-header-shadow:var(--le-header-shadow, none);--le-header-color:var(--le-color-text);--le-header-content-max-width:800px;--le-header-padding-x:var(--le-space-md);--le-header-padding-y:var(--le-space-sm);--le-header-gap:var(--le-space-sm);--le-header-transition:var(--le-transition-normal);--le-header-z:1000}.header{width:100%;max-width:var(--le-header-max-width);margin:var(--le-header-margin);background:var(--le-header-bg);color:var(--le-header-color);border-bottom:var(--le-header-border);border-radius:var(--le-header-border-radius);box-shadow:var(--le-header-shadow)}:host(.is-fixed){position:fixed;top:var(--le-header-top-offset);left:0;right:0;z-index:var(--le-header-z)}:host(.is-sticky){position:sticky;top:var(--le-header-top-offset);z-index:var(--le-header-z)}:host(.is-static){position:relative}.inner{max-width:var(--le-header-content-max-width);margin:0 auto;padding:var(--le-header-padding-y) var(--le-header-padding-x)}.row{display:grid;grid-template-columns:minmax(0, 1fr) minmax(0, 2fr) minmax(0, 1fr);align-items:center;gap:var(--le-header-gap);transition:height var(--le-header-transition),\n padding var(--le-header-transition),\n transform var(--le-header-transition)}:host(.is-shrunk) .row{height:var(--le-header-height-condensed)}:host(.is-sticky.is-hidden){transform:translateY(-150%);transition:transform var(--le-header-transition)}:host(.is-sticky.is-revealed){transform:translateY(0);transition:transform var(--le-header-transition)}.start,.title,.end{min-width:0;display:flex;align-items:center}.start{justify-content:flex-start}.end{justify-content:flex-end}.title{justify-content:center;text-align:center}.title-slot ::slotted(*){white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.compact-title{font:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}";
866
+
867
+ const LeHeader = class {
868
+ constructor(hostRef) {
869
+ index.registerInstance(this, hostRef);
870
+ this.leHeaderState = index.createEvent(this, "leHeaderState");
871
+ this.leHeaderShrinkChange = index.createEvent(this, "leHeaderShrinkChange");
872
+ this.leHeaderVisibilityChange = index.createEvent(this, "leHeaderVisibilityChange");
873
+ }
874
+ get el() { return index.getElement(this); }
875
+ /** Force static positioning (default). Ignored if `sticky` or `fixed` are true. */
876
+ isStatic = false;
877
+ /** Sticky positioning (in-flow). Ignored if `fixed` is true. */
878
+ sticky = false;
879
+ /** Fixed positioning (out-of-flow). Takes precedence over `sticky`/`static`. */
880
+ fixed = false;
881
+ /**
882
+ * Sticky-only reveal behavior (hide on scroll down, show on scroll up).
883
+ * - missing/false: disabled
884
+ * - true/empty attribute: enabled with default threshold (16)
885
+ * - number (as string): enabled and used as threshold
886
+ */
887
+ revealOnScroll;
888
+ /**
889
+ * Shrink trigger.
890
+ * - missing/0: disabled
891
+ * - number (px): shrink when scrollY >= that value (but never before header height)
892
+ * - css var name (e.g. --foo): shrink when scrollY >= resolved var value
893
+ * - selector (e.g. .page-title): shrink when that element scrolls out of view above the viewport
894
+ */
895
+ shrinkOffset;
896
+ /**
897
+ * If true, expand the header when hovered
898
+ */
899
+ expandOnHover = false;
900
+ /** Emits whenever scroll-driven state changes. */
901
+ leHeaderState;
902
+ /** Emits when the header shrinks/expands (only on change). */
903
+ leHeaderShrinkChange;
904
+ /** Emits when the header hides/shows (only on change). */
905
+ leHeaderVisibilityChange;
906
+ revealed = true;
907
+ shrunk = false;
908
+ placeholderHeight = null;
909
+ hoverActive = false;
910
+ disconnectModeObserver;
911
+ rafId = null;
912
+ measureRafId = null;
913
+ lastY = 0;
914
+ lastEmittedDirection = 'down';
915
+ headerEl;
916
+ shrinkSelectorEl;
917
+ setShrunk(next, y) {
918
+ if (next === this.shrunk)
919
+ return;
920
+ this.shrunk = next;
921
+ this.leHeaderShrinkChange.emit({ shrunk: this.shrunk, y });
922
+ }
923
+ componentDidLoad() {
924
+ if (typeof window === 'undefined')
925
+ return;
926
+ this.lastY = window.scrollY || 0;
927
+ this.scheduleMeasure(true);
928
+ this.scheduleUpdate(true);
929
+ }
930
+ disconnectedCallback() {
931
+ this.disconnectModeObserver?.();
932
+ if (this.rafId != null) {
933
+ cancelAnimationFrame(this.rafId);
934
+ this.rafId = null;
935
+ }
936
+ if (this.measureRafId != null) {
937
+ cancelAnimationFrame(this.measureRafId);
938
+ this.measureRafId = null;
939
+ }
940
+ }
941
+ onBehaviorPropsChange() {
942
+ this.scheduleUpdate(true);
943
+ this.scheduleMeasure(true);
944
+ }
945
+ onWindowScroll() {
946
+ this.scheduleUpdate();
947
+ }
948
+ onWindowResize() {
949
+ this.scheduleMeasure(true);
950
+ this.scheduleUpdate(true);
951
+ }
952
+ getPosition() {
953
+ if (this.fixed)
954
+ return 'fixed';
955
+ if (this.sticky)
956
+ return 'sticky';
957
+ return 'static';
958
+ }
959
+ parseRevealThreshold() {
960
+ // Only applies in sticky mode.
961
+ if (!this.sticky || this.fixed)
962
+ return null;
963
+ if (this.revealOnScroll == null)
964
+ return null;
965
+ const raw = String(this.revealOnScroll).trim();
966
+ if (raw === '' || raw === 'true')
967
+ return 16;
968
+ if (raw === 'false')
969
+ return null;
970
+ const n = Number(raw);
971
+ return Number.isFinite(n) ? Math.max(0, n) : 16;
972
+ }
973
+ resolveShrinkStartPx() {
974
+ const raw = (this.shrinkOffset ?? '').trim();
975
+ if (!raw || raw === '0')
976
+ return null;
977
+ // Numeric
978
+ const numeric = Number(raw);
979
+ if (Number.isFinite(numeric))
980
+ return Math.max(0, numeric);
981
+ // CSS variable name
982
+ if (raw.startsWith('--')) {
983
+ const value = getComputedStyle(document.documentElement).getPropertyValue(raw).trim();
984
+ const v = Number(value.replace('px', '').trim());
985
+ return Number.isFinite(v) ? Math.max(0, v) : null;
986
+ }
987
+ // Selector
988
+ try {
989
+ const el = document.querySelector(raw);
990
+ this.shrinkSelectorEl = el;
991
+ return null;
992
+ }
993
+ catch {
994
+ this.shrinkSelectorEl = null;
995
+ return null;
996
+ }
997
+ }
998
+ scheduleUpdate(force = false) {
999
+ if (this.rafId != null) {
1000
+ if (!force)
1001
+ return;
1002
+ cancelAnimationFrame(this.rafId);
1003
+ this.rafId = null;
1004
+ }
1005
+ this.rafId = requestAnimationFrame(() => {
1006
+ this.rafId = null;
1007
+ this.updateFromScroll();
1008
+ });
1009
+ }
1010
+ scheduleMeasure(force = false) {
1011
+ if (this.measureRafId != null && !force)
1012
+ return;
1013
+ this.measureRafId = requestAnimationFrame(() => {
1014
+ this.measureRafId = null;
1015
+ this.measurePlaceholderHeight();
1016
+ });
1017
+ }
1018
+ measurePlaceholderHeight() {
1019
+ // Measure the rendered header height once (and on resize/mode change).
1020
+ // This intentionally ignores scroll/shrink behavior; it should reserve the full header height.
1021
+ if (!this.headerEl)
1022
+ return;
1023
+ const next = Math.ceil(this.headerEl.getBoundingClientRect().height);
1024
+ if (!Number.isFinite(next) || next <= 0)
1025
+ return;
1026
+ if (next !== this.placeholderHeight) {
1027
+ this.placeholderHeight = next;
1028
+ // Publish to global root so placeholders anywhere can read it.
1029
+ if (typeof document !== 'undefined') {
1030
+ document.documentElement.style.setProperty('--le-header-height', `${next}px`);
1031
+ }
1032
+ }
1033
+ }
1034
+ updateFromScroll() {
1035
+ const y = typeof window !== 'undefined' ? window.scrollY || 0 : 0;
1036
+ const delta = y - this.lastY;
1037
+ const direction = delta < 0 ? 'up' : 'down';
1038
+ // Shrink behavior
1039
+ let computedShrunk = false;
1040
+ const headerHeight = Math.max(0, this.placeholderHeight ?? 0);
1041
+ const shrinkStartPx = typeof window !== 'undefined' ? this.resolveShrinkStartPx() : null;
1042
+ if (this.shrinkSelectorEl) {
1043
+ const rect = this.shrinkSelectorEl.getBoundingClientRect();
1044
+ computedShrunk = rect.bottom <= 0;
1045
+ }
1046
+ else if (shrinkStartPx != null) {
1047
+ const effectiveStart = Math.max(shrinkStartPx, headerHeight);
1048
+ computedShrunk = y >= effectiveStart;
1049
+ }
1050
+ // Hover override: when enabled and hovered, force expanded.
1051
+ const nextShrunk = this.expandOnHover && this.hoverActive ? false : computedShrunk;
1052
+ this.setShrunk(nextShrunk, y);
1053
+ // Reveal-on-scroll (sticky-only)
1054
+ const revealThreshold = this.parseRevealThreshold();
1055
+ if (revealThreshold != null) {
1056
+ // Always show the header near the top of the page.
1057
+ const topLock = Math.max(0, this.placeholderHeight ?? 0);
1058
+ if (y <= topLock) {
1059
+ if (!this.revealed) {
1060
+ this.revealed = true;
1061
+ this.leHeaderVisibilityChange.emit({ visible: true, y });
1062
+ }
1063
+ }
1064
+ else if (Math.abs(delta) >= revealThreshold) {
1065
+ const nextRevealed = direction === 'up' || y <= 0;
1066
+ if (nextRevealed !== this.revealed) {
1067
+ this.revealed = nextRevealed;
1068
+ this.leHeaderVisibilityChange.emit({ visible: this.revealed, y });
1069
+ }
1070
+ this.lastEmittedDirection = direction;
1071
+ }
1072
+ }
1073
+ else {
1074
+ if (!this.revealed) {
1075
+ this.revealed = true;
1076
+ this.leHeaderVisibilityChange.emit({ visible: true, y });
1077
+ }
1078
+ }
1079
+ this.lastY = y;
1080
+ this.leHeaderState.emit({
1081
+ y,
1082
+ direction: this.lastEmittedDirection,
1083
+ revealed: this.revealed,
1084
+ shrunk: this.shrunk,
1085
+ });
1086
+ }
1087
+ render() {
1088
+ const position = this.getPosition();
1089
+ const hostClass = utils.classnames('le-header', {
1090
+ 'header-is-shrunk': this.shrunk,
1091
+ 'is-fixed': position === 'fixed',
1092
+ 'is-sticky': position === 'sticky',
1093
+ 'is-static': position === 'static',
1094
+ 'is-revealed': this.revealed,
1095
+ 'is-hidden': !this.revealed,
1096
+ 'is-shrunk': this.shrunk,
1097
+ });
1098
+ return (index.h(index.Host, { key: '3fc823975a0ebcae3cb799bf94e35a289813cd35', class: hostClass, onMouseEnter: () => {
1099
+ if (!this.expandOnHover)
1100
+ return;
1101
+ this.hoverActive = true;
1102
+ this.scheduleUpdate(true);
1103
+ }, onMouseLeave: () => {
1104
+ if (!this.expandOnHover)
1105
+ return;
1106
+ this.hoverActive = false;
1107
+ this.scheduleUpdate(true);
1108
+ } }, index.h("le-component", { key: 'bb8e3c5717112e427fd86a6af4231b33147769e7', component: "le-header" }, index.h("header", { key: 'da96d6a1eb91a85ea8050870895fcd13bdb28391', class: "header", part: "header", role: "banner", ref: el => (this.headerEl = el) }, index.h("div", { key: '04386a3d535189012655ee352822812349d386d7', class: "inner", part: "inner" }, index.h("div", { key: '4b1fc43ca08e981f3dc810a23c14e6ed3200a1de', class: "row", part: "row" }, index.h("div", { key: '8fad255865a0d2e2662f3ad1030d48f8586ae8c7', class: "start", part: "start" }, index.h("le-slot", { key: '702eeebfe3133dae44e5268848ce5cac81f3b306', name: "start", label: "Start", description: "Logo / back button / nav", "allowed-components": "le-button,le-text,le-tag,le-box,le-stack" }, index.h("slot", { key: 'bdd3478abbdcd46143ce8a79d096baab84d12588', name: "start" }))), index.h("div", { key: 'e5b7d3d42e28d80b2df89a3ab365a29b39544f14', class: "title", part: "title" }, index.h("le-slot", { key: 'b5a68c8baaf05769ea838ca0482fa1db52b03b3a', name: "title", label: "Title", description: "Header title", type: "text", tag: "span" }, index.h("span", { key: '91763f968886e052a637959253863e583da51b76', class: "title-slot", part: "title" }, index.h("slot", { key: '060be7c91cca50c26db56cd15ad5d38962c8003f', name: "title" })))), index.h("div", { key: '938222741cbe15e531ff355185c4f599a3d26147', class: "end", part: "end" }, index.h("le-slot", { key: '8e1c91426dc87f1bdcb98d33b7da4cc6988781cf', name: "end", label: "End", description: "Actions", "allowed-components": "le-button,le-text,le-tag,le-box,le-stack" }, index.h("slot", { key: '67e4bda7e7c754dda5a7d9505a9b451f2487f47b', name: "end" })))), index.h("div", { key: '84dfedd30ec9bd49b668b2e1676ce3712b9d2faf', class: "secondary", part: "secondary" }, index.h("le-slot", { key: '95c56a8e3dbaaf284b03d72f1d9ec01d24c148d2', name: "", label: "Secondary", description: "Secondary row content", "allowed-components": "le-tabs,le-tab-bar,le-select,le-combobox,le-text,le-stack,le-box" }, index.h("slot", { key: '240df8fc23a9bc4e7aa294c52b229c7abf7c427d' }))))))));
1109
+ }
1110
+ static get watchers() { return {
1111
+ "revealOnScroll": ["onBehaviorPropsChange"],
1112
+ "shrinkOffset": ["onBehaviorPropsChange"],
1113
+ "fixed": ["onBehaviorPropsChange"],
1114
+ "sticky": ["onBehaviorPropsChange"],
1115
+ "isStatic": ["onBehaviorPropsChange"]
1116
+ }; }
1117
+ };
1118
+ LeHeader.style = leHeaderCss;
1119
+
1120
+ const lePopoverCss = "/* ============================================\n le-popover.css\n Popover using native HTML Popover API\n ============================================ */\n\n:host {\n display: inline-block;\n position: relative;\n}\n\n:host([trigger-full-width]) {\n display: block;\n width: 100%;\n}\n\n/* ============================================\n Trigger\n ============================================ */\n\n.le-popover-trigger {\n display: inline-flex;\n cursor: pointer;\n}\n\n.le-popover-trigger-full-width {\n display: flex;\n width: 100%;\n}\n\n.le-popover-default-trigger {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 0;\n border: 1px solid var(--le-color-border, #e0e0e0);\n border-radius: var(--le-radius-md, 6px);\n background: var(--le-color-surface, #fff);\n color: var(--le-color-text-secondary, #666);\n font-size: 16px;\n cursor: pointer;\n transition: all var(--le-transition-fast, 0.15s ease);\n}\n\n.le-popover-default-trigger:hover {\n border-color: var(--le-color-primary, #2196f3);\n color: var(--le-color-primary, #2196f3);\n background: var(--le-color-primary-light, rgba(33, 150, 243, 0.1));\n}\n\n/* ============================================\n Popover Content (native popover)\n ============================================ */\n\n.le-popover-content {\n /* Reset native popover defaults */\n margin: 0;\n padding: 0;\n border: none;\n background: transparent;\n \n /* Positioning - will be set via JS */\n position: fixed;\n inset: unset;\n \n /* Styling */\n background: var(--le-color-surface, #ffffff);\n border: 1px solid var(--le-color-border, #e0e0e0);\n border-radius: var(--le-radius-lg, 8px);\n box-shadow: var(--le-shadow-lg, 0 4px 12px rgba(0, 0, 0, 0.15));\n overflow: hidden;\n font-family: var(--le-font-family, system-ui, -apple-system, sans-serif);\n font-size: var(--le-font-size-sm, 0.875rem);\n color: var(--le-color-text, #333);\n \n /* Animation */\n opacity: 0;\n transform: scale(0.95);\n transition: opacity 0.15s ease, transform 0.15s ease, display 0.15s ease allow-discrete;\n}\n\n/* When popover is open */\n.le-popover-content:popover-open {\n opacity: 1;\n transform: scale(1);\n}\n\n/* Fallback for browsers without the Popover API */\n.le-popover-content[data-fallback-open=\"false\"] {\n display: none;\n}\n\n.le-popover-content[data-fallback-open=\"true\"] {\n opacity: 1;\n transform: scale(1);\n}\n\n/* Starting style for animation (CSS Anchor Positioning spec) */\n@starting-style {\n .le-popover-content:popover-open {\n opacity: 0;\n transform: scale(0.95);\n }\n}\n\n/* ============================================\n Header\n ============================================ */\n\n.le-popover-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--le-space-xs, 4px) var(--le-space-xs, 4px) var(--le-space-xs, 4px) var(--le-space-sm, 8px);\n border-bottom: 1px solid var(--le-color-border, #e0e0e0);\n background: var(--le-color-surface-alt, #f9f9f9);\n min-height: 32px;\n}\n\n.le-popover-title {\n font-weight: var(--le-font-weight-semibold, 600);\n font-size: var(--le-font-size-sm, 0.875rem);\n color: var(--le-color-text, #333);\n}\n\n.le-popover-close {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n padding: 0;\n border: none;\n background: transparent;\n color: var(--le-color-text-secondary, #666);\n font-size: 18px;\n line-height: 1;\n cursor: pointer;\n border-radius: var(--le-radius-sm, 4px);\n transition: background-color 0.15s, color 0.15s;\n}\n\n.le-popover-close:hover {\n background: var(--le-color-surface-hover, rgba(0, 0, 0, 0.05));\n color: var(--le-color-text, #333);\n}\n\n/* ============================================\n Body\n ============================================ */\n\n.le-popover-body {\n padding: var(--le-space-md, 12px);\n}\n\n/* ============================================\n Scrollable content\n ============================================ */\n\n.le-popover-content[style*=\"overflow-y: auto\"] .le-popover-body {\n overflow-y: auto;\n}\n";
1121
+
1122
+ // Keep a simple stack so Escape closes the most recently opened popover first.
1123
+ // This also helps nested popovers behave naturally.
1124
+ const openPopoverStack = [];
1125
+ const LePopover = class {
1126
+ constructor(hostRef) {
1127
+ index.registerInstance(this, hostRef);
1128
+ this.lePopoverOpen = index.createEvent(this, "lePopoverOpen");
1129
+ this.lePopoverClose = index.createEvent(this, "lePopoverClose");
1130
+ }
1131
+ get el() { return index.getElement(this); }
1132
+ /**
1133
+ * Mode of the popover should be 'default' for internal use
1134
+ */
1135
+ mode;
1136
+ /**
1137
+ * Whether the popover is currently open
1138
+ */
1139
+ open = false;
1140
+ /**
1141
+ * Position of the popover relative to its trigger
1142
+ */
1143
+ position = 'bottom';
1144
+ /**
1145
+ * Alignment of the popover
1146
+ */
1147
+ align = 'start';
1148
+ /**
1149
+ * Optional title for the popover header
1150
+ */
1151
+ popoverTitle;
1152
+ /**
1153
+ * Whether to show a close button in the header
1154
+ */
1155
+ showClose = true;
1156
+ /**
1157
+ * Whether clicking outside closes the popover
1158
+ */
1159
+ closeOnClickOutside = true;
1160
+ /**
1161
+ * Whether pressing Escape closes the popover
1162
+ */
1163
+ closeOnEscape = true;
1164
+ /**
1165
+ * Offset from the trigger element (in pixels)
1166
+ */
1167
+ offset = 8;
1168
+ /**
1169
+ * Fixed width for the popover (e.g., '300px', '20rem')
1170
+ */
1171
+ width;
1172
+ /**
1173
+ * Minimum width for the popover (e.g., '200px', '15rem')
1174
+ */
1175
+ minWidth = '200px';
1176
+ /**
1177
+ * Maximum width for the popover (e.g., '400px', '25rem')
1178
+ */
1179
+ maxWidth;
1180
+ /**
1181
+ * Should the popover's trigger take full width of its container
1182
+ */
1183
+ triggerFullWidth = false;
1184
+ /**
1185
+ * Emitted when the popover opens
1186
+ */
1187
+ lePopoverOpen;
1188
+ /**
1189
+ * Emitted when the popover closes
1190
+ */
1191
+ lePopoverClose;
1192
+ /**
1193
+ * Method to update the popover position from a parent component
1194
+ */
1195
+ async updatePosition() {
1196
+ this._updatePosition();
1197
+ }
1198
+ isPositioned = false;
1199
+ triggerEl;
1200
+ popoverEl;
1201
+ uniqueId = `le-popover-${Math.random().toString(36).substr(2, 9)}`;
1202
+ scrollParents = [];
1203
+ isListeningForDismiss = false;
1204
+ get supportsPopoverApi() {
1205
+ return typeof HTMLElement.prototype.showPopover === 'function';
1206
+ }
1207
+ shadowContains(container, node) {
1208
+ let current = node;
1209
+ while (current) {
1210
+ if (current === container)
1211
+ return true;
1212
+ if (current instanceof ShadowRoot) {
1213
+ current = current.host;
1214
+ continue;
1215
+ }
1216
+ if (current.parentNode) {
1217
+ current = current.parentNode;
1218
+ continue;
1219
+ }
1220
+ const root = current.getRootNode?.();
1221
+ if (root instanceof ShadowRoot) {
1222
+ current = root.host;
1223
+ continue;
1224
+ }
1225
+ break;
1226
+ }
1227
+ return false;
1228
+ }
1229
+ componentDidLoad() {
1230
+ // Listen for toggle events from the native popover API
1231
+ this.popoverEl?.addEventListener('toggle', this.handlePopoverToggle);
1232
+ // Listen for other popovers opening to close this one
1233
+ document.addEventListener('le-popover-will-open', this.handleOtherPopoverOpen);
1234
+ // If the popover is initially open (unlikely, but possible), wire listeners.
1235
+ if (this.open) {
1236
+ this.addDismissListeners();
1237
+ }
1238
+ }
1239
+ disconnectedCallback() {
1240
+ this.popoverEl?.removeEventListener('toggle', this.handlePopoverToggle);
1241
+ document.removeEventListener('le-popover-will-open', this.handleOtherPopoverOpen);
1242
+ this.removeScrollListeners();
1243
+ this.removeDismissListeners();
1244
+ }
1245
+ addDismissListeners() {
1246
+ if (this.isListeningForDismiss)
1247
+ return;
1248
+ // Use capture so clicks inside the trigger (which stops propagation) are still observed.
1249
+ document.addEventListener('pointerdown', this.handleDocumentPointerDown, true);
1250
+ document.addEventListener('keydown', this.handleDocumentKeyDown, true);
1251
+ this.isListeningForDismiss = true;
1252
+ }
1253
+ removeDismissListeners() {
1254
+ if (!this.isListeningForDismiss)
1255
+ return;
1256
+ document.removeEventListener('pointerdown', this.handleDocumentPointerDown, true);
1257
+ document.removeEventListener('keydown', this.handleDocumentKeyDown, true);
1258
+ this.isListeningForDismiss = false;
1259
+ }
1260
+ handleDocumentPointerDown = (event) => {
1261
+ if (!this.open || !this.closeOnClickOutside)
1262
+ return;
1263
+ // If the click happens inside this popover component (trigger OR content), don't close.
1264
+ const path = (event.composedPath?.() ?? []);
1265
+ if (path.includes(this.el))
1266
+ return;
1267
+ this.hide();
1268
+ };
1269
+ handleDocumentKeyDown = (event) => {
1270
+ if (!this.open || !this.closeOnEscape)
1271
+ return;
1272
+ if (event.key !== 'Escape')
1273
+ return;
1274
+ // Only the top-most opened popover handles Escape.
1275
+ const top = openPopoverStack[openPopoverStack.length - 1];
1276
+ if (top !== this.el)
1277
+ return;
1278
+ event.preventDefault();
1279
+ event.stopPropagation();
1280
+ this.hide();
1281
+ };
1282
+ /**
1283
+ * Find all scrollable parent elements
1284
+ */
1285
+ getScrollParents(element) {
1286
+ const scrollParents = [];
1287
+ let parent = element.parentElement;
1288
+ while (parent) {
1289
+ const style = getComputedStyle(parent);
1290
+ const overflow = style.overflow + style.overflowY + style.overflowX;
1291
+ if (/(auto|scroll)/.test(overflow)) {
1292
+ scrollParents.push(parent);
1293
+ }
1294
+ parent = parent.parentElement;
1295
+ }
1296
+ // Always include window for page scroll
1297
+ return scrollParents;
1298
+ }
1299
+ /**
1300
+ * Add scroll listeners to all scrollable parents
1301
+ */
1302
+ addScrollListeners() {
1303
+ if (!this.triggerEl)
1304
+ return;
1305
+ this.scrollParents = this.getScrollParents(this.triggerEl);
1306
+ // Listen to each scroll parent
1307
+ this.scrollParents.forEach(parent => {
1308
+ parent.addEventListener('scroll', this.handleScroll, { passive: true });
1309
+ });
1310
+ // Also listen to window scroll and resize
1311
+ window.addEventListener('scroll', this.handleScroll, { passive: true });
1312
+ window.addEventListener('resize', this.handleScroll, { passive: true });
1313
+ }
1314
+ /**
1315
+ * Remove scroll listeners
1316
+ */
1317
+ removeScrollListeners() {
1318
+ this.scrollParents.forEach(parent => {
1319
+ parent.removeEventListener('scroll', this.handleScroll);
1320
+ });
1321
+ window.removeEventListener('scroll', this.handleScroll);
1322
+ window.removeEventListener('resize', this.handleScroll);
1323
+ this.scrollParents = [];
1324
+ }
1325
+ handleScroll = () => {
1326
+ if (this.open) {
1327
+ this._updatePosition();
1328
+ }
1329
+ };
1330
+ handleOpened() {
1331
+ this.open = true;
1332
+ // Track stack order for Escape handling.
1333
+ const existingIndex = openPopoverStack.indexOf(this.el);
1334
+ if (existingIndex >= 0)
1335
+ openPopoverStack.splice(existingIndex, 1);
1336
+ openPopoverStack.push(this.el);
1337
+ this.addDismissListeners();
1338
+ this.addScrollListeners();
1339
+ this._updatePosition();
1340
+ this.lePopoverOpen.emit();
1341
+ }
1342
+ handleClosed() {
1343
+ this.open = false;
1344
+ this.isPositioned = false;
1345
+ this.removeScrollListeners();
1346
+ this.removeDismissListeners();
1347
+ const index = openPopoverStack.indexOf(this.el);
1348
+ if (index >= 0)
1349
+ openPopoverStack.splice(index, 1);
1350
+ this.lePopoverClose.emit();
1351
+ }
1352
+ handlePopoverToggle = (event) => {
1353
+ if (event.newState === 'open') {
1354
+ this.handleOpened();
1355
+ }
1356
+ else {
1357
+ this.handleClosed();
1358
+ }
1359
+ };
1360
+ handleOtherPopoverOpen = (event) => {
1361
+ const customEvent = event;
1362
+ const openingPopover = customEvent.detail?.popover;
1363
+ if (!openingPopover)
1364
+ return;
1365
+ if (openingPopover === this.el)
1366
+ return;
1367
+ // Allow nested popovers (e.g., le-select inside another popover).
1368
+ // Use a shadow-DOM-aware containment check.
1369
+ if (this.shadowContains(this.el, openingPopover) ||
1370
+ this.shadowContains(openingPopover, this.el)) {
1371
+ return;
1372
+ }
1373
+ if (this.open) {
1374
+ this.hide();
1375
+ }
1376
+ };
1377
+ /**
1378
+ * Opens the popover
1379
+ */
1380
+ async show() {
1381
+ document.dispatchEvent(new CustomEvent('le-popover-will-open', {
1382
+ detail: { popover: this.el },
1383
+ }));
1384
+ if (this.supportsPopoverApi) {
1385
+ this.popoverEl?.showPopover();
1386
+ }
1387
+ else {
1388
+ this.handleOpened();
1389
+ }
1390
+ }
1391
+ /**
1392
+ * Closes the popover
1393
+ */
1394
+ async hide() {
1395
+ if (this.supportsPopoverApi) {
1396
+ this.popoverEl?.hidePopover();
1397
+ }
1398
+ else {
1399
+ this.handleClosed();
1400
+ }
1401
+ }
1402
+ /**
1403
+ * Toggles the popover
1404
+ */
1405
+ async toggle() {
1406
+ if (this.open) {
1407
+ await this.hide();
1408
+ }
1409
+ else {
1410
+ await this.show();
1411
+ }
1412
+ }
1413
+ handleTriggerClick = (event) => {
1414
+ event.stopPropagation();
1415
+ this.toggle();
1416
+ };
1417
+ _updatePosition() {
1418
+ if (!this.triggerEl || !this.popoverEl)
1419
+ return;
1420
+ const triggerRect = this.triggerEl.getBoundingClientRect();
1421
+ const popoverRect = this.popoverEl.getBoundingClientRect();
1422
+ const viewportWidth = window.innerWidth;
1423
+ const viewportHeight = window.innerHeight;
1424
+ const viewportPadding = 8;
1425
+ let position = this.position;
1426
+ let align = this.align;
1427
+ // Auto-position logic
1428
+ const spaceBelow = viewportHeight - triggerRect.bottom - viewportPadding;
1429
+ const spaceAbove = triggerRect.top - viewportPadding;
1430
+ const spaceRight = viewportWidth - triggerRect.right - viewportPadding;
1431
+ const spaceLeft = triggerRect.left - viewportPadding;
1432
+ if (position === 'auto') {
1433
+ if (spaceBelow >= popoverRect.height + this.offset) {
1434
+ position = 'bottom';
1435
+ }
1436
+ else if (spaceAbove >= popoverRect.height + this.offset) {
1437
+ position = 'top';
1438
+ }
1439
+ else if (spaceRight >= popoverRect.width + this.offset) {
1440
+ position = 'right';
1441
+ }
1442
+ else if (spaceLeft >= popoverRect.width + this.offset) {
1443
+ position = 'left';
1444
+ }
1445
+ else {
1446
+ const maxSpace = Math.max(spaceBelow, spaceAbove, spaceRight, spaceLeft);
1447
+ if (maxSpace === spaceBelow)
1448
+ position = 'bottom';
1449
+ else if (maxSpace === spaceAbove)
1450
+ position = 'top';
1451
+ else if (maxSpace === spaceRight)
1452
+ position = 'right';
1453
+ else
1454
+ position = 'left';
1455
+ }
1456
+ }
1457
+ // Adjust alignment for horizontal overflow
1458
+ if (position === 'top' || position === 'bottom') {
1459
+ if (align === 'start' &&
1460
+ triggerRect.left + popoverRect.width > viewportWidth - viewportPadding) {
1461
+ align = 'end';
1462
+ }
1463
+ else if (align === 'end' && triggerRect.right - popoverRect.width < viewportPadding) {
1464
+ align = 'start';
1465
+ }
1466
+ else if (align === 'center') {
1467
+ const triggerCenter = triggerRect.left + triggerRect.width / 2;
1468
+ if (triggerCenter - popoverRect.width / 2 < viewportPadding) {
1469
+ align = 'start';
1470
+ }
1471
+ else if (triggerCenter + popoverRect.width / 2 > viewportWidth - viewportPadding) {
1472
+ align = 'end';
1473
+ }
1474
+ }
1475
+ }
1476
+ // Calculate position
1477
+ let top = 0;
1478
+ let left = 0;
1479
+ let maxHeight = null;
1480
+ switch (position) {
1481
+ case 'top':
1482
+ top = triggerRect.top - popoverRect.height - this.offset;
1483
+ if (top < viewportPadding) {
1484
+ maxHeight = triggerRect.top - this.offset - viewportPadding * 2;
1485
+ top = viewportPadding;
1486
+ }
1487
+ break;
1488
+ case 'bottom':
1489
+ top = triggerRect.bottom + this.offset;
1490
+ if (top + popoverRect.height > viewportHeight - viewportPadding) {
1491
+ maxHeight = viewportHeight - top - viewportPadding;
1492
+ }
1493
+ break;
1494
+ case 'left':
1495
+ left = triggerRect.left - popoverRect.width - this.offset;
1496
+ top = triggerRect.top;
1497
+ if (left < viewportPadding)
1498
+ left = viewportPadding;
1499
+ break;
1500
+ case 'right':
1501
+ left = triggerRect.right + this.offset;
1502
+ top = triggerRect.top;
1503
+ if (left + popoverRect.width > viewportWidth - viewportPadding) {
1504
+ left = viewportWidth - popoverRect.width - viewportPadding;
1505
+ }
1506
+ break;
1507
+ }
1508
+ // Calculate horizontal alignment for top/bottom
1509
+ if (position === 'top' || position === 'bottom') {
1510
+ switch (align) {
1511
+ case 'start':
1512
+ left = triggerRect.left;
1513
+ break;
1514
+ case 'center':
1515
+ left = triggerRect.left + triggerRect.width / 2 - popoverRect.width / 2;
1516
+ break;
1517
+ case 'end':
1518
+ left = triggerRect.right - popoverRect.width;
1519
+ break;
1520
+ }
1521
+ // Constrain to viewport
1522
+ if (left < viewportPadding) {
1523
+ left = viewportPadding;
1524
+ }
1525
+ else if (left + popoverRect.width > viewportWidth - viewportPadding) {
1526
+ left = viewportWidth - popoverRect.width - viewportPadding;
1527
+ }
1528
+ }
1529
+ // Calculate vertical alignment for left/right
1530
+ if (position === 'left' || position === 'right') {
1531
+ switch (align) {
1532
+ case 'start':
1533
+ top = triggerRect.top;
1534
+ break;
1535
+ case 'center':
1536
+ top = triggerRect.top + triggerRect.height / 2 - popoverRect.height / 2;
1537
+ break;
1538
+ case 'end':
1539
+ top = triggerRect.bottom - popoverRect.height;
1540
+ break;
1541
+ }
1542
+ if (top < viewportPadding)
1543
+ top = viewportPadding;
1544
+ if (top + popoverRect.height > viewportHeight - viewportPadding) {
1545
+ maxHeight = viewportHeight - top - viewportPadding;
1546
+ }
1547
+ }
1548
+ // Apply styles
1549
+ this.popoverEl.style.top = `${top}px`;
1550
+ this.popoverEl.style.left = `${left}px`;
1551
+ if (maxHeight !== null && maxHeight > 100) {
1552
+ this.popoverEl.style.maxHeight = `${maxHeight}px`;
1553
+ this.popoverEl.style.overflowY = 'auto';
1554
+ }
1555
+ else {
1556
+ this.popoverEl.style.maxHeight = '';
1557
+ this.popoverEl.style.overflowY = '';
1558
+ }
1559
+ this.isPositioned = true;
1560
+ }
1561
+ render() {
1562
+ const popoverStyles = {
1563
+ visibility: this.isPositioned ? 'visible' : 'hidden',
1564
+ };
1565
+ if (this.width)
1566
+ popoverStyles.width = this.width;
1567
+ if (this.minWidth)
1568
+ popoverStyles.minWidth = this.minWidth;
1569
+ if (this.maxWidth)
1570
+ popoverStyles.maxWidth = this.maxWidth;
1571
+ return (index.h(index.Host, { key: '9bbb6c41436ac051529650ef0fbf5e152ec82901', "trigger-full-width": this.triggerFullWidth }, index.h("div", { key: '600f4d8a367e2b52cb6eca2c6bf4d77a3851b078', class: utils.classnames('le-popover-trigger', {
1572
+ 'le-popover-trigger-full-width': this.triggerFullWidth,
1573
+ }), ref: el => (this.triggerEl = el), onClick: this.handleTriggerClick, part: "trigger" }, index.h("slot", { key: '6cfc71e93c2ea7552157398ac4aa12507ba55cc3', name: "trigger" }, index.h("button", { key: '06f35fffce2a5e2129733daf5fda9a35762ff586', type: "button", class: "le-popover-default-trigger" }, index.h("span", { key: 'c7dcb2074e40851db8cb9cc9d5ff42d90be479c2' }, "\u2295")))), index.h("div", { key: '5cc7278cc388bd057df4311a5082f8ad29eaf756', id: this.uniqueId, class: "le-popover-content",
1574
+ // Always use manual mode so nested popovers can be open together.
1575
+ // We implement click-outside and Escape handling ourselves.
1576
+ popover: "manual", ref: el => (this.popoverEl = el), style: popoverStyles, "data-fallback-open": this.supportsPopoverApi ? undefined : String(this.open) }, (this.popoverTitle || this.showClose) && (index.h("div", { key: '56b803332842e42387160ab6ab7df3a8b20f00fc', class: "le-popover-header" }, this.popoverTitle && index.h("span", { key: '034c0acc4c08fb5eb7f10f9e9b310874eafada3e', class: "le-popover-title" }, this.popoverTitle), this.showClose && (index.h("button", { key: '29546e93795dc7aefca86b9d8d8ceef109c230c8', type: "button", class: "le-popover-close", onClick: () => this.hide(), "aria-label": "Close" }, "\u00D7")))), index.h("div", { key: 'dbacc49cf8c8198048443f0b8acfdc795eb72b31', class: "le-popover-body", part: "content" }, index.h("slot", { key: 'ca3ceed750c50ba33c58d0cb99ce8378cc358872' })))));
1577
+ }
1578
+ };
1579
+ LePopover.style = lePopoverCss;
1580
+
1581
+ const lePopupCss = ":host{display:contents}.le-popup-dialog{position:fixed;z-index:100;top:0;right:0;bottom:0;left:0;padding:0;border:none;background:transparent;max-width:none;max-height:none;overflow:visible;--_popup-min-width:var(--le-popup-min-width, 320px);--_popup-max-width:var(--le-popup-max-width, min(500px, 90vw));--_popup-min-height:var(--le-popup-min-height, auto)}.le-popup-dialog::backdrop{background:var(--le-popup-backdrop-color, rgba(0, 0, 0, 0.5));animation:le-popup-backdrop-fade 0.2s ease-out}@keyframes le-popup-backdrop-fade{from{opacity:0}to{opacity:1}}.le-popup-position-center{margin:auto}.le-popup-position-top{margin:var(--le-space-2xl, 48px) auto auto auto}.le-popup-position-top-left{margin:var(--le-space-lg, 24px) auto auto var(--le-space-lg, 24px)}.le-popup-position-top-right{margin:var(--le-space-lg, 24px) var(--le-space-lg, 24px) auto auto}.le-popup-position-bottom{margin:auto auto var(--le-space-2xl, 48px) auto}.le-popup-position-bottom-left{margin:auto auto var(--le-space-lg, 24px) var(--le-space-lg, 24px)}.le-popup-position-bottom-right{margin:auto var(--le-space-lg, 24px) var(--le-space-lg, 24px) auto}.le-popup-container{display:flex;flex-direction:column;min-width:var(--_popup-min-width);max-width:var(--_popup-max-width);min-height:var(--_popup-min-height);max-height:calc(100vh - var(--le-space-2xl, 48px) * 2);background:var(--le-color-surface, #ffffff);border:1px solid var(--le-color-border, #e0e0e0);border-radius:var(--le-radius-lg, 12px);box-shadow:var(--le-shadow-xl, 0 8px 32px rgba(0, 0, 0, 0.15));overflow:hidden;font-family:var(--le-font-family, system-ui, -apple-system, sans-serif);color:var(--le-color-text, #333);animation:le-popup-appear 0.2s ease-out}@keyframes le-popup-appear{from{opacity:0;transform:scale(0.95) translateY(-10px)}to{opacity:1;transform:scale(1) translateY(0)}}.le-popup-header{flex-shrink:0;padding:var(--le-space-md, 16px) var(--le-space-lg, 24px);border-bottom:1px solid var(--le-color-border, #e0e0e0);background:var(--le-color-surface-alt, #f9f9f9);font-size:var(--le-font-size-lg, 1.125rem);font-weight:var(--le-font-weight-semibold, 600);color:var(--le-color-text, #333)}.le-popup-body{flex:1;padding:var(--le-space-lg, 24px);overflow-y:auto}.le-popup-message{margin:0;font-size:var(--le-font-size-md, 1rem);line-height:var(--le-line-height-relaxed, 1.6);color:var(--le-color-text, #333)}.le-popup-message+::slotted(*){margin-top:var(--le-space-md, 16px)}.le-popup-input{display:block;width:100%;margin-top:var(--le-space-md, 16px);padding:var(--le-space-sm, 8px) var(--le-space-md, 16px);font-family:inherit;font-size:var(--le-font-size-md, 1rem);color:var(--le-color-text, #333);background:var(--le-color-background, #fff);border:1px solid var(--le-color-border, #e0e0e0);border-radius:var(--le-radius-md, 8px);outline:none;transition:border-color var(--le-transition-fast, 0.15s ease),\n box-shadow var(--le-transition-fast, 0.15s ease);box-sizing:border-box}.le-popup-input:focus{border-color:var(--le-color-primary, #2196f3);box-shadow:0 0 0 3px var(--le-color-primary-light, rgba(33, 150, 243, 0.2))}.le-popup-input::placeholder{color:var(--le-color-text-muted, #999)}.le-popup-footer{flex-shrink:0;display:flex;justify-content:flex-end;gap:var(--le-space-sm, 8px);padding:var(--le-space-md, 16px) var(--le-space-lg, 24px);border-top:1px solid var(--le-color-border, #e0e0e0);background:var(--le-color-surface-alt, #f9f9f9)}.le-popup-btn{min-width:80px}@media (max-width: 480px){.le-popup-container{min-width:calc(100vw - var(--le-space-md, 16px) * 2);max-width:calc(100vw - var(--le-space-md, 16px) * 2)}.le-popup-footer{flex-direction:column-reverse}.le-popup-btn{width:100%}}";
1582
+
1583
+ const LePopup = class {
1584
+ constructor(hostRef) {
1585
+ index.registerInstance(this, hostRef);
1586
+ this.leConfirm = index.createEvent(this, "leConfirm");
1587
+ this.leCancel = index.createEvent(this, "leCancel");
1588
+ this.leOpen = index.createEvent(this, "leOpen");
1589
+ this.leClose = index.createEvent(this, "leClose");
1590
+ }
1591
+ get el() { return index.getElement(this); }
1592
+ /**
1593
+ * The mode of the Le Kit (e.g., 'default' or 'admin')
1594
+ */
1595
+ mode = 'default';
1596
+ /**
1597
+ * Whether the popup is currently visible
1598
+ */
1599
+ open = false;
1600
+ /**
1601
+ * Type of popup: alert (OK only), confirm (OK/Cancel), prompt (input + OK/Cancel), custom
1602
+ */
1603
+ type = 'alert';
1604
+ /**
1605
+ * Optional title for the popup header
1606
+ */
1607
+ popupTitle;
1608
+ /**
1609
+ * Message text to display (for alert/confirm/prompt types)
1610
+ */
1611
+ message;
1612
+ /**
1613
+ * Whether the popup is modal (blocks interaction with page behind)
1614
+ */
1615
+ modal = true;
1616
+ /**
1617
+ * Position of the popup on screen
1618
+ */
1619
+ position = 'center';
1620
+ /**
1621
+ * Text for the confirm/OK button
1622
+ */
1623
+ confirmText = 'OK';
1624
+ /**
1625
+ * Text for the cancel button
1626
+ */
1627
+ cancelText = 'Cancel';
1628
+ /**
1629
+ * Placeholder text for prompt input
1630
+ */
1631
+ placeholder = '';
1632
+ /**
1633
+ * Default value for prompt input
1634
+ */
1635
+ defaultValue = '';
1636
+ /**
1637
+ * Whether clicking the backdrop closes the popup (modal only)
1638
+ */
1639
+ closeOnBackdrop = true;
1640
+ /**
1641
+ * Internal state for prompt input value
1642
+ */
1643
+ inputValue = '';
1644
+ /**
1645
+ * Emitted when the popup is confirmed (OK clicked)
1646
+ */
1647
+ leConfirm;
1648
+ /**
1649
+ * Emitted when the popup is cancelled (Cancel clicked or dismissed)
1650
+ */
1651
+ leCancel;
1652
+ /**
1653
+ * Emitted when the popup opens
1654
+ */
1655
+ leOpen;
1656
+ /**
1657
+ * Emitted when the popup closes
1658
+ */
1659
+ leClose;
1660
+ dialogEl;
1661
+ inputEl;
1662
+ resolvePromise;
1663
+ componentWillLoad() {
1664
+ this.inputValue = this.defaultValue;
1665
+ }
1666
+ componentDidLoad() {
1667
+ // Native dialog handles Escape key automatically when modal
1668
+ // We just need to listen for the cancel event
1669
+ this.dialogEl?.addEventListener('cancel', this.handleDialogCancel);
1670
+ }
1671
+ disconnectedCallback() {
1672
+ this.dialogEl?.removeEventListener('cancel', this.handleDialogCancel);
1673
+ }
1674
+ handleDialogCancel = (e) => {
1675
+ e.preventDefault(); // Prevent default close to handle it ourselves
1676
+ this.handleCancel();
1677
+ };
1678
+ /**
1679
+ * Opens the popup and returns a promise that resolves when closed
1680
+ */
1681
+ async show() {
1682
+ return new Promise(resolve => {
1683
+ this.resolvePromise = resolve;
1684
+ this.inputValue = this.defaultValue;
1685
+ this.open = true;
1686
+ // Use requestAnimationFrame to ensure the dialog element is rendered
1687
+ requestAnimationFrame(() => {
1688
+ if (this.dialogEl) {
1689
+ if (this.modal) {
1690
+ this.dialogEl.showModal();
1691
+ }
1692
+ else {
1693
+ this.dialogEl.show();
1694
+ }
1695
+ this.leOpen.emit();
1696
+ // Focus input for prompt type
1697
+ if (this.type === 'prompt' && this.inputEl) {
1698
+ this.inputEl.focus();
1699
+ this.inputEl.select();
1700
+ }
1701
+ }
1702
+ });
1703
+ });
1704
+ }
1705
+ /**
1706
+ * Closes the popup with a result
1707
+ */
1708
+ async hide(confirmed = false) {
1709
+ const result = {
1710
+ confirmed,
1711
+ value: this.type === 'prompt' ? this.inputValue : undefined,
1712
+ };
1713
+ this.dialogEl?.close();
1714
+ this.open = false;
1715
+ this.leClose.emit(result);
1716
+ if (this.resolvePromise) {
1717
+ this.resolvePromise(result);
1718
+ this.resolvePromise = undefined;
1719
+ }
1720
+ }
1721
+ handleConfirm = () => {
1722
+ const result = {
1723
+ confirmed: true,
1724
+ value: this.type === 'prompt' ? this.inputValue : undefined,
1725
+ };
1726
+ this.leConfirm.emit(result);
1727
+ this.hide(true);
1728
+ };
1729
+ handleCancel = () => {
1730
+ const result = {
1731
+ confirmed: false,
1732
+ value: undefined,
1733
+ };
1734
+ this.leCancel.emit(result);
1735
+ this.hide(false);
1736
+ };
1737
+ handleBackdropClick = (e) => {
1738
+ // Check if click was on the dialog backdrop (outside the dialog box)
1739
+ if (this.closeOnBackdrop && e.target === this.dialogEl) {
1740
+ const rect = this.dialogEl.getBoundingClientRect();
1741
+ const clickedInDialog = e.clientX >= rect.left &&
1742
+ e.clientX <= rect.right &&
1743
+ e.clientY >= rect.top &&
1744
+ e.clientY <= rect.bottom;
1745
+ if (!clickedInDialog) {
1746
+ this.handleCancel();
1747
+ }
1748
+ }
1749
+ };
1750
+ handleInputChange = (e) => {
1751
+ this.inputValue = e.target.value;
1752
+ };
1753
+ handleKeyDown = (e) => {
1754
+ if (e.key === 'Enter' && this.type !== 'custom') {
1755
+ e.preventDefault();
1756
+ this.handleConfirm();
1757
+ }
1758
+ };
1759
+ hasSlot(name) {
1760
+ return !!this.el.querySelector(`[slot="${name}"]`);
1761
+ }
1762
+ renderHeader() {
1763
+ if (this.hasSlot('header')) {
1764
+ return (index.h("div", { class: "le-popup-header", part: "header" }, index.h("slot", { name: "header" })));
1765
+ }
1766
+ if (this.popupTitle) {
1767
+ return (index.h("div", { class: "le-popup-header", part: "header" }, this.popupTitle));
1768
+ }
1769
+ return null;
1770
+ }
1771
+ renderBody() {
1772
+ return (index.h("div", { class: "le-popup-body", part: "body" }, this.message && index.h("p", { class: "le-popup-message" }, this.message), this.type === 'prompt' && (index.h("input", { type: "text", class: "le-popup-input", part: "input", placeholder: this.placeholder, value: this.inputValue, onInput: this.handleInputChange, onKeyDown: this.handleKeyDown, ref: el => (this.inputEl = el) })), index.h("le-slot", { name: "", tag: "div", description: "Custom popup content", type: "slot" }, index.h("slot", null))));
1773
+ }
1774
+ renderFooter() {
1775
+ if (this.hasSlot('footer')) {
1776
+ return (index.h("div", { class: "le-popup-footer", part: "footer" }, index.h("slot", { name: "footer" })));
1777
+ }
1778
+ // For custom type without footer slot, don't render default buttons
1779
+ if (this.type === 'custom') {
1780
+ return null;
1781
+ }
1782
+ return (index.h("div", { class: "le-popup-footer", part: "footer" }, (this.type === 'confirm' || this.type === 'prompt') && (index.h("le-button", { variant: "outlined", part: "button-cancel", class: "le-popup-btn", onClick: this.handleCancel }, this.cancelText)), index.h("le-button", { variant: "solid", part: "button-confirm", class: "le-popup-btn", onClick: this.handleConfirm }, this.confirmText)));
1783
+ }
1784
+ render() {
1785
+ const positionClass = `le-popup-position-${this.position}`;
1786
+ return (index.h("dialog", { key: '20ac8e086b2999191c769a0ee03b1c1182103809', class: `le-popup-dialog ${positionClass}`, part: "dialog", ref: el => (this.dialogEl = el), onClick: this.handleBackdropClick }, index.h("le-component", { key: '468b1d737c2301b041c2a7a13afc658505f74c5b', component: "le-popup" }, index.h("div", { key: '829cad08439dc5d0b3f9c78092a46faa016bbec2', class: "le-popup-container", part: "container" }, this.renderHeader(), this.renderBody(), this.renderFooter()))));
1787
+ }
1788
+ };
1789
+ LePopup.style = lePopupCss;
1790
+
1791
+ const leScrollProgressCss = ":host{display:block}:host([sticky]){position:sticky;top:var(--le-scroll-progress-sticky-top, 0);z-index:var(--le-scroll-progress-z, calc(var(--le-header-z, 1000) + 1))}:host([fixed]){position:fixed;top:var(--le-scroll-progress-fixed-top, 0);left:var(--le-scroll-progress-fixed-left, 0);right:var(--le-scroll-progress-fixed-right, 0);z-index:var(--le-scroll-progress-z, calc(var(--le-header-z, 1000) + 1))}.track{width:100%;height:var(--le-scroll-progress-height, 4px);background:var(--le-scroll-progress-bg, transparent)}.fill{height:100%;width:0;background:var(--le-scroll-progress-fill, var(--le-color-primary, currentColor));border-radius:var(--le-scroll-progress-border-radius, 2px);transition:width var(--le-transition-fast, 120ms linear)}";
1792
+
1793
+ const LeScrollProgress = class {
1794
+ constructor(hostRef) {
1795
+ index.registerInstance(this, hostRef);
1796
+ }
1797
+ get el() { return index.getElement(this); }
1798
+ /** Boolean or selector string. */
1799
+ trackScrollProgress;
1800
+ progress = 0;
1801
+ rafId = null;
1802
+ targetEl = null;
1803
+ componentWillLoad() {
1804
+ this.updateProgress();
1805
+ }
1806
+ componentDidLoad() {
1807
+ this.resolveTarget();
1808
+ this.updateProgress();
1809
+ }
1810
+ disconnectedCallback() {
1811
+ if (this.rafId != null) {
1812
+ cancelAnimationFrame(this.rafId);
1813
+ this.rafId = null;
1814
+ }
1815
+ }
1816
+ onTrackChange() {
1817
+ this.resolveTarget();
1818
+ this.updateProgress();
1819
+ }
1820
+ onScroll() {
1821
+ this.scheduleUpdate();
1822
+ }
1823
+ onResize() {
1824
+ this.resolveTarget();
1825
+ this.scheduleUpdate(true);
1826
+ }
1827
+ scheduleUpdate(force = false) {
1828
+ if (this.rafId != null && !force)
1829
+ return;
1830
+ this.rafId = requestAnimationFrame(() => {
1831
+ this.rafId = null;
1832
+ this.updateProgress();
1833
+ });
1834
+ }
1835
+ resolveTarget() {
1836
+ if (typeof document === 'undefined')
1837
+ return;
1838
+ const raw = this.trackScrollProgress;
1839
+ // If attribute missing, default to enabled (full document).
1840
+ // If user explicitly sets 'false', treat as disabled.
1841
+ if (raw == null) {
1842
+ this.targetEl = null;
1843
+ return;
1844
+ }
1845
+ const val = String(raw).trim();
1846
+ if (val === '' || val === 'true') {
1847
+ this.targetEl = null;
1848
+ return;
1849
+ }
1850
+ if (val === 'false') {
1851
+ this.targetEl = null;
1852
+ return;
1853
+ }
1854
+ try {
1855
+ this.targetEl = document.querySelector(val);
1856
+ }
1857
+ catch {
1858
+ this.targetEl = null;
1859
+ }
1860
+ }
1861
+ clamp01(n) {
1862
+ return Math.max(0, Math.min(1, n));
1863
+ }
1864
+ updateProgress() {
1865
+ if (typeof window === 'undefined' || typeof document === 'undefined')
1866
+ return;
1867
+ // If explicitly disabled.
1868
+ if (this.trackScrollProgress === 'false') {
1869
+ if (this.progress !== 0)
1870
+ this.progress = 0;
1871
+ return;
1872
+ }
1873
+ const scrollY = window.scrollY || 0;
1874
+ let p = 0;
1875
+ if (this.targetEl) {
1876
+ const rect = this.targetEl.getBoundingClientRect();
1877
+ const top = scrollY + rect.top;
1878
+ const height = rect.height;
1879
+ const viewport = window.innerHeight || 1;
1880
+ const denom = Math.max(1, height - viewport);
1881
+ p = this.clamp01((scrollY - top) / denom);
1882
+ }
1883
+ else {
1884
+ const doc = document.documentElement;
1885
+ const denom = Math.max(1, doc.scrollHeight - doc.clientHeight);
1886
+ p = this.clamp01(scrollY / denom);
1887
+ }
1888
+ const next = Math.round(p * 1000) / 1000;
1889
+ if (next !== this.progress)
1890
+ this.progress = next;
1891
+ }
1892
+ render() {
1893
+ const width = `${this.progress * 100}%`;
1894
+ return (index.h(index.Host, { key: '46e7659497b80795c79365b97813cf57d517f48f' }, index.h("div", { key: '6e42f3479a1081df5355fb229902e9ee8c0a8918', class: "track", part: "track", "aria-hidden": "true" }, index.h("div", { key: '81cbe2ec0fc43a14b8bc0192b1f901be9c6cba3a', class: "fill", part: "fill", style: { width } }))));
1895
+ }
1896
+ static get watchers() { return {
1897
+ "trackScrollProgress": ["onTrackChange"]
1898
+ }; }
1899
+ };
1900
+ LeScrollProgress.style = leScrollProgressCss;
1901
+
1902
+ const leSelectCss = ":host{display:inline-block;min-width:150px;--le-select-color:var(--le-color-text, #1f2937);--le-select-border-radius:var(--le-radius-md);--le-select-content-padding:var(--le-spacing-2)}:host([disabled]){opacity:0.5;pointer-events:none}:host([full-width]){width:100%}.select-trigger{display:flex;align-items:center;gap:0.5rem;width:100%;padding:0;--le-button-padding:var(--le-spacing-1) var(--le-spacing-1) var(--le-spacing-1) var(--le-spacing-2);font-size:var(--le-select-font-size, 0.875rem);font-family:inherit;line-height:1.4;color:var(--le-select-color);background:var(--le-select-bg, var(--le-color-surface, #fff));border-radius:var(--le-select-border-radius);cursor:pointer;text-align:left;transition:border-color 0.15s ease, box-shadow 0.15s ease}.select-trigger:focus{outline:2px solid var(--le-color-focus);outline-offset:2px}.select-trigger:not(.has-value) .trigger-label{color:color-mix(in srgb, var(--le-color-text-secondary) 66%, transparent)}.trigger-icon{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:1.25rem;height:1.25rem}.trigger-icon-end{width:16px;height:16px}.trigger-icon img{width:100%;height:100%;object-fit:contain}.trigger-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--le-color-text)}.trigger-label::not(.has-value){color:var(--le-color-text-disabled, #9ca3af)}le-button::part(icon-end){display:flex;align-items:center;justify-content:center;flex-shrink:0;width:1.25rem;height:1.25rem;margin-left:auto;transition:transform 0.2s ease}le-button::part(icon-end) svg{width:1rem;height:1rem}le-button.is-open::part(icon-end){transform:rotate(180deg)}.search-input::part(container):focus-within{outline:none !important}.search-input{--le-input-radius:var(--le-radius-md)}";
1903
+
1904
+ const LeSelect = class {
1905
+ constructor(hostRef) {
1906
+ index.registerInstance(this, hostRef);
1907
+ this.leChange = index.createEvent(this, "leChange");
1908
+ this.leOpen = index.createEvent(this, "leOpen");
1909
+ this.leClose = index.createEvent(this, "leClose");
1910
+ }
1911
+ get el() { return index.getElement(this); }
1912
+ /**
1913
+ * The options to display in the dropdown.
1914
+ */
1915
+ options = [];
1916
+ /**
1917
+ * The currently selected value.
1918
+ */
1919
+ value;
1920
+ /**
1921
+ * Placeholder text when no option is selected.
1922
+ */
1923
+ placeholder = 'Select an option';
1924
+ /**
1925
+ * Whether the select is disabled.
1926
+ */
1927
+ disabled = false;
1928
+ /**
1929
+ * Whether selection is required.
1930
+ */
1931
+ required = false;
1932
+ /**
1933
+ * Name attribute for form submission.
1934
+ */
1935
+ name;
1936
+ /**
1937
+ * Whether the select should take full width of its container.
1938
+ */
1939
+ fullWidth = false;
1940
+ /**
1941
+ * Size variant of the select.
1942
+ */
1943
+ size = 'medium';
1944
+ /**
1945
+ * Visual variant of the select.
1946
+ */
1947
+ variant = 'default';
1948
+ /**
1949
+ * Whether the input is searchable.
1950
+ */
1951
+ searchable = false;
1952
+ /**
1953
+ * Text to show when no options match the search.
1954
+ */
1955
+ emptyText = 'No results found';
1956
+ /**
1957
+ * Whether the dropdown is currently open.
1958
+ */
1959
+ open = false;
1960
+ /**
1961
+ * Emitted when the selected value changes.
1962
+ */
1963
+ leChange;
1964
+ /**
1965
+ * Emitted when the dropdown opens.
1966
+ */
1967
+ leOpen;
1968
+ /**
1969
+ * Emitted when the dropdown closes.
1970
+ */
1971
+ leClose;
1972
+ selectedOption;
1973
+ searchQuery = '';
1974
+ dropdownEl;
1975
+ inputEl;
1976
+ handleValueChange() {
1977
+ this.updateSelectedOption();
1978
+ }
1979
+ handleOptionsChange() {
1980
+ this.updateSelectedOption();
1981
+ }
1982
+ componentWillLoad() {
1983
+ this.updateSelectedOption();
1984
+ }
1985
+ get parsedOptions() {
1986
+ if (typeof this.options === 'string') {
1987
+ try {
1988
+ return JSON.parse(this.options);
1989
+ }
1990
+ catch {
1991
+ return [];
1992
+ }
1993
+ }
1994
+ return this.options;
1995
+ }
1996
+ updateSelectedOption() {
1997
+ if (this.value !== undefined) {
1998
+ this.selectedOption = this.parsedOptions.find(opt => (opt.value ?? opt.label) === this.value);
1999
+ }
2000
+ else {
2001
+ this.selectedOption = undefined;
2002
+ }
2003
+ }
2004
+ filterOption = (option, query) => {
2005
+ if (!query)
2006
+ return true;
2007
+ const searchLower = query.toLowerCase();
2008
+ return (option.label.toLowerCase().includes(searchLower) ||
2009
+ (option.description?.toLowerCase().includes(searchLower) ?? false));
2010
+ };
2011
+ handleOptionSelect = (e) => {
2012
+ this.value = e.detail.value;
2013
+ this.selectedOption = e.detail.option;
2014
+ this.leChange.emit(e.detail);
2015
+ };
2016
+ handleDropdownOpen = () => {
2017
+ this.open = true;
2018
+ this.leOpen.emit();
2019
+ // Focus search input if searchable
2020
+ if (this.searchable) {
2021
+ setTimeout(() => {
2022
+ this.inputEl?.focus();
2023
+ }, 50);
2024
+ }
2025
+ };
2026
+ handleDropdownClose = () => {
2027
+ this.open = false;
2028
+ this.leClose.emit();
2029
+ };
2030
+ handleTriggerClick = () => {
2031
+ if (!this.disabled) {
2032
+ this.dropdownEl?.toggle();
2033
+ }
2034
+ };
2035
+ handleTriggerKeyDown = (e) => {
2036
+ if (this.disabled)
2037
+ return;
2038
+ if (e.key === 'Enter' || e.key === ' ' || e.key === 'ArrowDown') {
2039
+ e.preventDefault();
2040
+ this.dropdownEl?.show();
2041
+ }
2042
+ };
2043
+ handleSearchInput = (e) => {
2044
+ const target = e.target;
2045
+ this.searchQuery = target.value;
2046
+ };
2047
+ /**
2048
+ * Opens the dropdown.
2049
+ */
2050
+ async showDropdown() {
2051
+ await this.dropdownEl?.show();
2052
+ }
2053
+ /**
2054
+ * Closes the dropdown.
2055
+ */
2056
+ async hideDropdown() {
2057
+ await this.dropdownEl?.hide();
2058
+ }
2059
+ renderIcon(icon) {
2060
+ if (!icon)
2061
+ return null;
2062
+ if (icon.startsWith('http') || icon.startsWith('/')) {
2063
+ return index.h("img", { class: "trigger-icon", src: icon, alt: "" });
2064
+ }
2065
+ return index.h("span", { class: "trigger-icon" }, icon);
2066
+ }
2067
+ render() {
2068
+ const hasValue = this.selectedOption !== undefined;
2069
+ return (index.h("le-component", { key: 'f41bf4f086925b6b37a0131a51e4f7e354797ed5', component: "le-select" }, index.h("le-dropdown-base", { key: '08db701f6b1f7e2c428ea0cc9ee4046c22759757', ref: el => (this.dropdownEl = el), options: this.parsedOptions, value: this.value, disabled: this.disabled, filterFn: this.searchable ? this.filterOption : undefined, filterQuery: this.searchQuery, onLeOptionSelect: this.handleOptionSelect, onLeDropdownOpen: this.handleDropdownOpen, onLeDropdownClose: this.handleDropdownClose, fullWidth: this.fullWidth }, index.h("le-button", { key: 'f994667c5360905a9e6340f0f0331bea55523418', variant: this.variant && this.variant !== 'default' ? this.variant : 'outlined', slot: "trigger", align: "space-between", class: {
2070
+ 'select-trigger': true,
2071
+ 'has-value': hasValue,
2072
+ 'is-open': this.open,
2073
+ }, mode: "default", size: this.size, disabled: this.disabled, "aria-haspopup": "listbox", "aria-expanded": this.open ? 'true' : 'false', onClick: this.handleTriggerClick, onKeyDown: this.handleTriggerKeyDown, fullWidth: this.fullWidth, iconStart: hasValue && this.selectedOption?.iconStart
2074
+ ? this.renderIcon(this.selectedOption.iconStart)
2075
+ : null, iconEnd: index.h("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", "stroke-width": "2" }, index.h("path", { d: "M4 6l4 4 4-4" })) }, index.h("span", { key: 'c807e00d21193e558dcf1b601c4aa5f78144fd14', class: "trigger-label" }, hasValue ? this.selectedOption.label : this.placeholder)), this.searchable && this.open && (index.h("div", { key: 'c285d28f7b0093580484b8d077c4f2ddd014aa2e', class: "multiselect-search", slot: "header" }, index.h("le-string-input", { key: '1dd31e5840a29e3a7e181c80182c20ea5ca28bcb', mode: "default", inputRef: el => (this.inputEl = el), class: "search-input", placeholder: "Search...", value: this.searchQuery, onInput: this.handleSearchInput })))), this.name && index.h("input", { key: '0acb27fafae47b56808e1b1ee20e45c7cb0cfa3e', type: "hidden", name: this.name, value: this.value?.toString() ?? '' })));
2076
+ }
2077
+ static get watchers() { return {
2078
+ "value": ["handleValueChange"],
2079
+ "options": ["handleOptionsChange"]
2080
+ }; }
2081
+ };
2082
+ LeSelect.style = leSelectCss;
2083
+
2084
+ const leSlotDefaultCss = ":host{display:contents;--le-slot-border-color:#0088ff;--le-slot-bg-color:rgba(0, 136, 255, 0.05);--le-slot-header-bg:rgb(218, 238, 255);--le-slot-label-color:#0066cc;--le-slot-description-color:#666;--le-slot-required-color:#e53935;--le-slot-dropzone-min-height:20px;--le-slot-dropzone-border-color:#ccc}.le-slot-container,.le-slot-header,.le-slot-description,.le-slot-dropzone,.le-slot-input{display:none}.hidden-slot{display:none}:host(.admin-mode){display:block;flex:1}:host(.admin-mode) .le-slot-container{position:relative;display:flex;flex-direction:column;border:2px dashed var(--le-slot-border-color);border-radius:4px;background:var(--le-slot-bg-color);margin:4px 0}:host(.admin-mode) .le-slot-header{display:flex;align-items:center;gap:4px;padding:0 0 0 var(--le-spacing-1, 4px);background:var(--le-slot-header-bg);border-bottom:1px solid var(--le-slot-border-color);font-size:var(--le-font-size-xs, 11px);font-weight:400;text-transform:capitalize}:host(.admin-mode) .le-slot-header-no-label{justify-content:flex-end;height:16px;border:none;background-color:transparent}.le-slot-label{color:var(--le-slot-label-color);text-align:start;overflow:hidden;width:0;flex:1 1 0%}.le-slot-required{color:var(--le-slot-required-color);font-weight:bold}:host(.admin-mode) .le-slot-description{display:block;padding:4px 8px;font-size:12px;color:var(--le-slot-description-color);font-style:italic}:host(.admin-mode) .le-slot-description-icon{display:inline-block;font-size:9px;line-height:1;cursor:pointer;color:var(--le-slot-description-color)}:host(.admin-mode) .le-slot-dropzone{display:block;min-height:var(--le-slot-dropzone-min-height);padding:var(--le-spacing-1, 4px);position:relative}:host(.admin-mode) .le-slot-dropzone:empty::before{content:'Drop content here';display:flex;align-items:center;justify-content:center;position:absolute;inset:8px;border:2px dashed var(--le-slot-dropzone-border-color);border-radius:4px;color:#999;font-size:12px;pointer-events:none}:host(.admin-mode.drag-over) .le-slot-container{border-color:#00cc66;background:rgba(0, 204, 102, 0.1)}:host(.admin-mode.drag-over) .le-slot-dropzone:empty::before{border-color:#00cc66;color:#00cc66;content:'Release to drop'}:host(.admin-mode) .le-slot-input{display:block;padding:var(--le-spacing-1, 4px)}:host(.admin-mode) .le-slot-input input,:host(.admin-mode) .le-slot-input textarea{display:block;width:100%;padding:8px 10px;border:1px solid var(--le-slot-dropzone-border-color);border-radius:4px;font-family:inherit;font-size:14px;line-height:1.4;background:#fff;color:#333;box-sizing:border-box;transition:border-color 0.2s, box-shadow 0.2s}:host(.admin-mode) .le-slot-input input:focus,:host(.admin-mode) .le-slot-input textarea:focus{outline:none;border-color:var(--le-slot-border-color);box-shadow:0 0 0 3px rgba(0, 136, 255, 0.15)}:host(.admin-mode) .le-slot-input input::placeholder,:host(.admin-mode) .le-slot-input textarea::placeholder{color:#999}:host(.admin-mode) .le-slot-input textarea{resize:vertical;min-height:60px}:host(.admin-mode) .le-slot-input slot{display:none}.le-slot-invalid{color:var(--le-slot-required-color);font-size:10px;margin-left:auto;font-weight:normal;text-transform:none}:host(.admin-mode) .le-slot-input.has-error input,:host(.admin-mode) .le-slot-input.has-error textarea{border-color:var(--le-slot-required-color);background:rgba(229, 57, 53, 0.05)}:host(.admin-mode) .le-slot-input.has-error input:focus,:host(.admin-mode) .le-slot-input.has-error textarea:focus{border-color:var(--le-slot-required-color);box-shadow:0 0 0 3px rgba(229, 57, 53, 0.15)}.le-slot-add-btn{font-size:24px;line-height:0px;width:12px;height:12px}.le-slot-header-no-label .le-slot-add-btn{font-size:16px}.le-slot-button{width:20px;height:20px}:host(.admin-mode) .le-slot-header-no-label.le-slot-header-text{height:0}";
2085
+
2086
+ const LeSlot = class {
2087
+ constructor(hostRef) {
2088
+ index.registerInstance(this, hostRef);
2089
+ this.leSlotChange = index.createEvent(this, "leSlotChange");
2090
+ }
2091
+ get el() { return index.getElement(this); }
2092
+ /**
2093
+ * The type of slot content.
2094
+ * - `slot`: Default, shows a dropzone for components (default)
2095
+ * - `text`: Shows a single-line text input
2096
+ * - `textarea`: Shows a multi-line text area
2097
+ */
2098
+ type = 'slot';
2099
+ /**
2100
+ * The name of the slot this placeholder represents.
2101
+ * Should match the slot name in the parent component.
2102
+ */
2103
+ name = '';
2104
+ /**
2105
+ * Label to display in admin mode.
2106
+ * If not provided, the slot name will be used.
2107
+ */
2108
+ label;
2109
+ /**
2110
+ * Description of what content this slot accepts.
2111
+ * Shown in admin mode to guide content editors.
2112
+ */
2113
+ description;
2114
+ /**
2115
+ * Comma-separated list of allowed component tags for this slot.
2116
+ * Used by CMS to filter available components.
2117
+ *
2118
+ * @example "le-card,le-button,le-text"
2119
+ */
2120
+ allowedComponents;
2121
+ /**
2122
+ * Whether multiple components can be dropped in this slot.
2123
+ */
2124
+ multiple = true;
2125
+ /**
2126
+ * Whether this slot is required to have content.
2127
+ */
2128
+ required = false;
2129
+ /**
2130
+ * Placeholder text for text/textarea inputs in admin mode.
2131
+ */
2132
+ placeholder;
2133
+ /**
2134
+ * The HTML tag to create when there's no slotted element.
2135
+ * Used with type="text" or type="textarea" to auto-create elements.
2136
+ *
2137
+ * @example "h3" - creates <h3 slot="header">content</h3>
2138
+ * @example "p" - creates <p slot="content">content</p>
2139
+ */
2140
+ tag;
2141
+ /**
2142
+ * CSS styles for the slot dropzone container.
2143
+ * Useful for layouts - e.g., "flex-direction: row" for horizontal stacks.
2144
+ * Only applies in admin mode for type="slot".
2145
+ */
2146
+ slotStyle;
2147
+ /**
2148
+ * Internal state to track admin mode
2149
+ */
2150
+ adminMode = false;
2151
+ /**
2152
+ * Internal state for text input value (synced from slot content)
2153
+ */
2154
+ textValue = '';
2155
+ /**
2156
+ * Whether the current textValue contains valid HTML
2157
+ */
2158
+ isValidHtml = true;
2159
+ /**
2160
+ * Available components loaded from Custom Elements Manifest
2161
+ */
2162
+ availableComponents = [];
2163
+ /**
2164
+ * Whether the component picker popover is open
2165
+ */
2166
+ pickerOpen = false;
2167
+ /**
2168
+ * Reference to the slot element to access assignedNodes
2169
+ */
2170
+ slotRef;
2171
+ /**
2172
+ * The original slotted element (e.g., <h3 slot="header">)
2173
+ */
2174
+ slottedElement;
2175
+ /**
2176
+ * Emitted when text content changes in admin mode.
2177
+ * The event detail contains the new text value and validity.
2178
+ */
2179
+ leSlotChange;
2180
+ disconnectModeObserver;
2181
+ connectedCallback() {
2182
+ this.disconnectModeObserver = utils.observeModeChanges(this.el, mode => {
2183
+ const wasAdmin = this.adminMode;
2184
+ this.adminMode = mode === 'admin';
2185
+ // When entering admin mode, read content from slotted elements
2186
+ if (this.adminMode && !wasAdmin) {
2187
+ // Need to wait for render to access slot ref
2188
+ requestAnimationFrame(() => this.readSlottedContent());
2189
+ // Load available components for the component picker
2190
+ if (this.type === 'slot') {
2191
+ this.loadAvailableComponents();
2192
+ }
2193
+ }
2194
+ });
2195
+ }
2196
+ disconnectedCallback() {
2197
+ this.disconnectModeObserver?.();
2198
+ }
2199
+ /**
2200
+ * Flag to prevent re-reading content right after we updated it
2201
+ */
2202
+ isUpdating = false;
2203
+ /**
2204
+ * Read content from slotted elements via assignedNodes()
2205
+ */
2206
+ readSlottedContent() {
2207
+ if (!this.slotRef)
2208
+ return;
2209
+ // Skip if we just updated the content ourselves
2210
+ if (this.isUpdating) {
2211
+ this.isUpdating = false;
2212
+ return;
2213
+ }
2214
+ const assignedNodes = this.slotRef.assignedNodes({ flatten: true });
2215
+ // For text/textarea types, we want to edit the innerHTML of slotted elements
2216
+ if (this.type === 'text' || this.type === 'textarea') {
2217
+ // Find the first element node (skip text nodes that are just whitespace)
2218
+ const elementNode = assignedNodes.find(node => node.nodeType === Node.ELEMENT_NODE);
2219
+ if (elementNode) {
2220
+ // Only update textValue if slotted element changed or we don't have one yet
2221
+ if (this.slottedElement !== elementNode) {
2222
+ this.slottedElement = elementNode;
2223
+ this.textValue = elementNode.innerHTML?.trim() || '';
2224
+ // console.log(`[le-slot "${this.name}"] Read slotted content:`, this.textValue);
2225
+ }
2226
+ }
2227
+ else {
2228
+ // No element, check for direct text content
2229
+ const textContent = assignedNodes
2230
+ .filter(node => node.nodeType === Node.TEXT_NODE)
2231
+ .map(node => node.textContent)
2232
+ .join('')
2233
+ .trim();
2234
+ if (textContent && !this.textValue) {
2235
+ this.textValue = textContent;
2236
+ // console.log(`[le-slot "${this.name}"] Read text content:`, this.textValue);
2237
+ }
2238
+ }
2239
+ }
2240
+ }
2241
+ /**
2242
+ * Validates if a string contains valid HTML
2243
+ */
2244
+ validateHtml(html) {
2245
+ // Empty string is valid
2246
+ if (!html.trim())
2247
+ return true;
2248
+ // Create a template element to parse the HTML
2249
+ const template = document.createElement('template');
2250
+ template.innerHTML = html;
2251
+ // Check that we don't have obviously broken HTML
2252
+ // Count opening and closing tags for common elements
2253
+ const openTags = (html.match(/<[a-z][^>]*(?<!\/)>/gi) || []).length;
2254
+ const closeTags = (html.match(/<\/[a-z][^>]*>/gi) || []).length;
2255
+ const selfClosing = (html.match(/<[a-z][^>]*\/>/gi) || []).length;
2256
+ // Simple validation: opening tags (minus self-closing) should roughly match closing tags
2257
+ // Allow some tolerance for void elements like <br>, <img>, etc.
2258
+ const voidElements = (html.match(/<(br|hr|img|input|meta|link|area|base|col|embed|param|source|track|wbr)[^>]*>/gi) || []).length;
2259
+ const effectiveOpenTags = openTags - selfClosing - voidElements;
2260
+ // If difference is too large, HTML is likely broken
2261
+ if (Math.abs(effectiveOpenTags - closeTags) > 1) {
2262
+ return false;
2263
+ }
2264
+ return true;
2265
+ }
2266
+ handleTextInput = (event) => {
2267
+ const target = event.target;
2268
+ this.textValue = target.value;
2269
+ this.isValidHtml = this.validateHtml(this.textValue);
2270
+ if (this.isValidHtml) {
2271
+ // Set flag to prevent slotchange from re-reading what we just wrote
2272
+ this.isUpdating = true;
2273
+ console.log('Updating text value:', this.textValue, 'slottedElement:', this.slottedElement);
2274
+ if (this.slottedElement) {
2275
+ // Update existing slotted element's innerHTML
2276
+ this.slottedElement.innerHTML = this.textValue;
2277
+ }
2278
+ else if (this.tag && this.textValue) {
2279
+ // No slotted element exists
2280
+ // If the slot doesn't have a name, then it's the default slot
2281
+ // remove the existing non-slotted content (text nodes and elements without slot attribute)
2282
+ const rootNode = this.el.getRootNode();
2283
+ if (!this.name && rootNode instanceof ShadowRoot) {
2284
+ const hostComponent = rootNode.host;
2285
+ Array.from(hostComponent.childNodes).forEach(node => {
2286
+ if (node.nodeType === Node.TEXT_NODE || (node.nodeType === Node.ELEMENT_NODE && !node.hasAttribute('slot'))) {
2287
+ node.remove();
2288
+ }
2289
+ });
2290
+ }
2291
+ // create one using the specified tag
2292
+ this.createSlottedElement();
2293
+ }
2294
+ else if (this.textValue) {
2295
+ // no tag specified - just replace everything in the host component
2296
+ const rootNode = this.el.getRootNode();
2297
+ if (rootNode instanceof ShadowRoot) {
2298
+ const hostComponent = rootNode.host;
2299
+ hostComponent.innerHTML = this.textValue;
2300
+ }
2301
+ }
2302
+ }
2303
+ this.leSlotChange.emit({
2304
+ name: this.name,
2305
+ value: this.textValue,
2306
+ isValid: this.isValidHtml,
2307
+ });
2308
+ };
2309
+ /**
2310
+ * Create a new slotted element when none exists.
2311
+ * The element is appended to the host component's light DOM.
2312
+ */
2313
+ createSlottedElement() {
2314
+ if (!this.tag)
2315
+ return;
2316
+ // Find the host component (le-card, etc.) by traversing up through shadow DOM
2317
+ // le-slot is inside le-card's shadow DOM, so we need to find le-card's host
2318
+ const rootNode = this.el.getRootNode();
2319
+ if (!(rootNode instanceof ShadowRoot))
2320
+ return;
2321
+ const hostComponent = rootNode.host;
2322
+ if (!hostComponent)
2323
+ return;
2324
+ // Create the new element
2325
+ const newElement = document.createElement(this.tag);
2326
+ newElement.innerHTML = this.textValue;
2327
+ // Set the slot attribute if this is a named slot
2328
+ if (this.name) {
2329
+ newElement.setAttribute('slot', this.name);
2330
+ }
2331
+ // Append to the host component's light DOM
2332
+ hostComponent.appendChild(newElement);
2333
+ // Store reference to the new element
2334
+ this.slottedElement = newElement;
2335
+ // console.log(`[le-slot "${this.name}"] Created new <${this.tag}> element`);
2336
+ }
2337
+ /**
2338
+ * Load available components from Custom Elements Manifest
2339
+ */
2340
+ async loadAvailableComponents() {
2341
+ try {
2342
+ const { manifestFile } = index.getLeKitConfig();
2343
+ const manifestFileResolved = index.getAssetPath(`./assets/${manifestFile}`);
2344
+ const response = await fetch(manifestFileResolved);
2345
+ const manifest = await response.json();
2346
+ const components = [];
2347
+ const allowedList = this.allowedComponents?.split(',').map(s => s.trim()) || [];
2348
+ for (const module of manifest.modules) {
2349
+ for (const declaration of module.declarations || []) {
2350
+ if (declaration.tagName && declaration.customElement) {
2351
+ // Skip internal components (le-slot, le-component, le-popover)
2352
+ const isInternal = ['le-slot', 'le-component', 'le-popover'].includes(declaration.tagName);
2353
+ if (isInternal)
2354
+ continue;
2355
+ // If allowedComponents is specified, filter by it
2356
+ if (allowedList.length > 0 && !allowedList.includes(declaration.tagName)) {
2357
+ continue;
2358
+ }
2359
+ components.push({
2360
+ tagName: declaration.tagName,
2361
+ name: this.formatComponentName(declaration.tagName),
2362
+ description: declaration.description || '',
2363
+ });
2364
+ }
2365
+ }
2366
+ }
2367
+ this.availableComponents = components || [];
2368
+ }
2369
+ catch (error) {
2370
+ console.warn('[le-slot] Failed to load component manifest:', error);
2371
+ }
2372
+ }
2373
+ /**
2374
+ * Format a tag name into a display name
2375
+ * e.g., 'le-card' -> 'Card'
2376
+ */
2377
+ formatComponentName(tagName) {
2378
+ return tagName
2379
+ .replace(/^le-/, '')
2380
+ .split('-')
2381
+ .map(word => word.charAt(0).toUpperCase() + word.slice(1))
2382
+ .join(' ');
2383
+ }
2384
+ /**
2385
+ * Add a new component to the slot
2386
+ */
2387
+ addComponent(tagName) {
2388
+ // Find the host component by traversing up through shadow DOM
2389
+ const rootNode = this.el.getRootNode();
2390
+ if (!(rootNode instanceof ShadowRoot))
2391
+ return;
2392
+ const hostComponent = rootNode.host;
2393
+ if (!hostComponent)
2394
+ return;
2395
+ // Create the new component element
2396
+ const newElement = document.createElement(tagName);
2397
+ // Set the slot attribute if this is a named slot
2398
+ if (this.name) {
2399
+ newElement.setAttribute('slot', this.name);
2400
+ }
2401
+ // Append to the host component's light DOM
2402
+ hostComponent.appendChild(newElement);
2403
+ // Emit change event so the page can save
2404
+ this.leSlotChange.emit({
2405
+ name: this.name,
2406
+ value: hostComponent.innerHTML,
2407
+ isValid: true,
2408
+ });
2409
+ }
2410
+ /**
2411
+ * Handle slot change event to re-read content when nodes are assigned
2412
+ */
2413
+ handleSlotChange = () => {
2414
+ this.readSlottedContent();
2415
+ };
2416
+ render() {
2417
+ const displayLabel = this.label || this.name;
2418
+ // Always render the same structure, CSS handles visibility via .admin-mode class
2419
+ return (index.h(index.Host, { key: '938f14c8d8e46d834031cbfab6756a55bc59307d', class: {
2420
+ 'admin-mode': this.adminMode,
2421
+ 'invalid-html': !this.isValidHtml,
2422
+ }, role: this.adminMode ? 'region' : undefined, "aria-label": this.adminMode ? `Slot: ${displayLabel}` : undefined, "data-slot-name": this.name, "data-slot-type": this.type, "data-allowed": this.allowedComponents, "data-multiple": this.multiple, "data-required": this.required }, this.adminMode ? (index.h("div", { class: "le-slot-container" }, index.h("div", { class: utils.classnames('le-slot-header', {
2423
+ 'le-slot-header-no-label': !displayLabel,
2424
+ 'le-slot-header-text': this.type === 'text',
2425
+ 'le-slot-header-error': !this.isValidHtml,
2426
+ }) }, displayLabel && (index.h("span", { class: "le-slot-label" }, displayLabel, this.required && index.h("span", { class: "le-slot-required" }, "*"))), !this.isValidHtml && index.h("span", { class: "le-slot-invalid" }, "\u26A0 Invalid HTML"), this.type === 'slot' && this.adminMode && (index.h("le-popover", { mode: "default", showClose: true, align: "start", position: "right", popoverTitle: "Add Component", open: this.pickerOpen, onLePopoverOpen: () => (this.pickerOpen = true), onLePopoverClose: () => (this.pickerOpen = false) }, index.h("le-button", { type: "button", class: "le-slot-button", slot: "trigger", variant: "clear", size: "small", "aria-label": "Add component", "icon-only": true }, index.h("span", { class: "le-slot-add-btn", slot: "icon-only" }, "+")), index.h("div", { class: "le-slot-picker" }, this.availableComponents.length > 0 ? (index.h("ul", { class: "le-slot-picker-list" }, this.availableComponents.map(component => (index.h("li", { key: component.tagName }, index.h("button", { class: "le-slot-picker-item", onClick: () => {
2427
+ this.addComponent(component.tagName);
2428
+ this.pickerOpen = false;
2429
+ } }, index.h("span", { class: "le-slot-picker-name" }, component.name), component.description && index.h("span", { class: "le-slot-picker-desc" }, component.description))))))) : (index.h("div", { class: "le-slot-picker-empty" }, "No components available")))))), this.renderContent())) : (
2430
+ // In default mode, just pass through the slot - slotted content renders naturally
2431
+ // Note: We use unnamed slot here because named slots from parent component
2432
+ // are passed as le-slot's light DOM children
2433
+ index.h("slot", null))));
2434
+ }
2435
+ renderContent() {
2436
+ // Create the slot element with ref for reading assignedNodes
2437
+ // Wrap in a hidden div since slot elements can't have style prop in Stencil
2438
+ // Note: We use unnamed slot here because named slots from parent component
2439
+ // are passed as le-slot's light DOM children
2440
+ const slotElement = (index.h("div", { class: "hidden-slot" }, index.h("slot", { ref: el => (this.slotRef = el), onSlotchange: this.handleSlotChange })));
2441
+ switch (this.type) {
2442
+ case 'text':
2443
+ return (index.h("div", { class: { 'le-slot-input': true, 'has-error': !this.isValidHtml } }, index.h("le-string-input", { mode: "default", value: this.textValue, placeholder: this.placeholder || `Enter ${this.label || this.name || 'text'}...`, onChange: this.handleTextInput }), slotElement));
2444
+ case 'textarea':
2445
+ return (index.h("div", { class: { 'le-slot-input': true, 'has-error': !this.isValidHtml } }, index.h("textarea", { value: this.textValue, placeholder: this.placeholder || `Enter ${this.label || this.name || 'text'}...`, onInput: this.handleTextInput, required: this.required, rows: 3 }), slotElement));
2446
+ case 'slot':
2447
+ default:
2448
+ // Parse slotStyle string into style object if provided
2449
+ const dropzoneStyle = {};
2450
+ if (this.slotStyle) {
2451
+ this.slotStyle.split(';').forEach(rule => {
2452
+ const [prop, value] = rule.split(':').map(s => s.trim());
2453
+ if (prop && value) {
2454
+ // Convert kebab-case to camelCase for style object
2455
+ const camelProp = prop.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
2456
+ dropzoneStyle[camelProp] = value;
2457
+ }
2458
+ });
2459
+ }
2460
+ return (index.h("div", { class: "le-slot-dropzone", style: dropzoneStyle }, index.h("slot", { ref: el => (this.slotRef = el), onSlotchange: this.handleSlotChange })));
2461
+ }
2462
+ }
2463
+ };
2464
+ LeSlot.style = leSlotDefaultCss;
2465
+
2466
+ const leStringInputCss = ":host{display:block;--le-input-bg:var(--le-color-surface, #ffffff);--le-input-color:var(--le-color-text-primary, #333333);--le-input-border:var(--le-border-width, 2px) solid var(--le-color-border-input, #007bff);--le-input-radius:var(--le-radius-sm, 4px);--le-input-padding:2px 6px;--le-input-height:1.5rem;--le-input-label-color:var(--le-color-text-primary, #333333);--le-input-desc-color:var(--le-color-text-secondary, #666666);--le-input-placeholder-color:#999999}.le-input-wrapper{display:flex;flex-direction:column;gap:2px}.le-input-label{display:block;font-size:0.9em;font-weight:500;color:var(--le-input-label-color);margin-bottom:2px}.le-input-container{position:relative;display:flex;align-items:center;background:var(--le-input-bg);border:var(--le-input-border);border-radius:var(--le-input-radius);transition:border-color 0.2s}.le-input-container:focus-within{outline:2px solid var(--le-color-focus);outline-offset:2px}:host([disabled]) .le-input-container{opacity:0.6;background-color:rgba(0,0,0,0.05);cursor:not-allowed}input{flex:1;min-height:var(--le-input-height);padding:var(--le-input-padding);border:none;background:transparent;color:var(--le-input-color);font-family:inherit;font-size:inherit;outline:none;width:100%}input::placeholder{color:var(--le-input-placeholder-color)}.icon-start,.icon-end{display:flex;align-items:center;justify-content:center;padding:0 8px;color:var(--le-input-desc-color)}.le-input-description{font-size:0.85em;color:var(--le-input-desc-color);margin-top:2px}.le-input-description::has(le-slot>slot[name=description]:empty){display:none}";
2467
+
2468
+ const LeStringInput = class {
2469
+ constructor(hostRef) {
2470
+ index.registerInstance(this, hostRef);
2471
+ this.leChange = index.createEvent(this, "change");
2472
+ this.leInput = index.createEvent(this, "input");
2473
+ }
2474
+ get el() { return index.getElement(this); }
2475
+ /**
2476
+ * Pass the ref of the input element to the parent component
2477
+ */
2478
+ inputRef;
2479
+ /**
2480
+ * Mode of the popover should be 'default' for internal use
2481
+ */
2482
+ mode;
2483
+ /**
2484
+ * The value of the input
2485
+ */
2486
+ value;
2487
+ /**
2488
+ * The name of the input
2489
+ */
2490
+ name;
2491
+ /**
2492
+ * The type of the input (text, email, password, etc.)
2493
+ */
2494
+ type = 'text';
2495
+ /**
2496
+ * Label for the input
2497
+ */
2498
+ label;
2499
+ /**
2500
+ * Icon for the start icon
2501
+ */
2502
+ iconStart;
2503
+ /**
2504
+ * Icon for the end icon
2505
+ */
2506
+ iconEnd;
2507
+ /**
2508
+ * Placeholder text
2509
+ */
2510
+ placeholder;
2511
+ /**
2512
+ * Hide description slot
2513
+ */
2514
+ hideDescription = false;
2515
+ /**
2516
+ * Whether the input is disabled
2517
+ */
2518
+ disabled = false;
2519
+ /**
2520
+ * Whether the input is read-only
2521
+ */
2522
+ readonly = false;
2523
+ /**
2524
+ * External ID for linking with external systems
2525
+ */
2526
+ externalId;
2527
+ /**
2528
+ * Emitted when the value changes (on blur or Enter)
2529
+ */
2530
+ leChange;
2531
+ /**
2532
+ * Emitted when the input value changes (on keystroke)
2533
+ */
2534
+ leInput;
2535
+ handleInput = (ev) => {
2536
+ const input = ev.target;
2537
+ this.value = input.value;
2538
+ this.leInput.emit({
2539
+ value: this.value,
2540
+ name: this.name,
2541
+ externalId: this.externalId,
2542
+ });
2543
+ };
2544
+ handleChange = (ev) => {
2545
+ const input = ev.target;
2546
+ this.value = input.value;
2547
+ this.leChange.emit({
2548
+ value: this.value,
2549
+ name: this.name,
2550
+ externalId: this.externalId,
2551
+ });
2552
+ };
2553
+ handleClick = (ev) => {
2554
+ ev.stopPropagation();
2555
+ };
2556
+ render() {
2557
+ return (index.h("le-component", { key: 'c51b121a5ff8458f80de07929467d92cff44de9b', component: "le-string-input", hostClass: utils.classnames({ disabled: this.disabled }) }, index.h("div", { key: '450fa313236401fcb762267f426d0556f90ef200', class: "le-input-wrapper" }, this.label && (index.h("label", { key: 'c01ed376e563f472d84c9943a4a542c1ec2cb39c', class: "le-input-label", htmlFor: this.name }, this.label)), index.h("div", { key: 'e41a98671f3bc61e06f66c773536967d60c97df0', class: "le-input-container", part: "container" }, this.iconStart && index.h("span", { key: 'c6eb682444e091378281b7a2e739ef872ca28973', class: "icon-start" }, this.iconStart), index.h("input", { key: 'bc7f9055dcae290e132f4c91887e5f90427209d4', ref: el => {
2558
+ if (this.inputRef) {
2559
+ this.inputRef(el);
2560
+ }
2561
+ }, id: this.name, type: this.type, name: this.name, value: this.value, placeholder: this.placeholder, disabled: this.disabled, readOnly: this.readonly, onInput: this.handleInput, onChange: this.handleChange, onClick: this.handleClick }), this.iconEnd && index.h("span", { key: '3470d5c95e208e52b1913369d734e1d741164633', class: "icon-end" }, this.iconEnd)), !this.hideDescription && (index.h("div", { key: '97a123be35907f950c7480352cee29c32e486fe4', class: "le-input-description" }, index.h("le-slot", { key: '490c2a425b3b58f050aced5dcffc530f624c0957', name: "description", type: "text", tag: "p", label: "Description" }, index.h("slot", { key: 'a34ff8c6300a36d6c65ca5d9a77352459f1c85cc', name: "description" })))))));
2562
+ }
2563
+ };
2564
+ LeStringInput.style = leStringInputCss;
2565
+
2566
+ exports.le_button = LeButton;
2567
+ exports.le_checkbox = LeCheckbox;
2568
+ exports.le_collapse = LeCollapse;
2569
+ exports.le_component = LeComponent;
2570
+ exports.le_current_heading = LeCurrentHeading;
2571
+ exports.le_dropdown_base = LeDropdownBase;
2572
+ exports.le_header = LeHeader;
2573
+ exports.le_popover = LePopover;
2574
+ exports.le_popup = LePopup;
2575
+ exports.le_scroll_progress = LeScrollProgress;
2576
+ exports.le_select = LeSelect;
2577
+ exports.le_slot = LeSlot;
2578
+ exports.le_string_input = LeStringInput;
2579
+ //# sourceMappingURL=le-button.le-checkbox.le-collapse.le-component.le-current-heading.le-dropdown-base.le-header.le-popover.le-popup.le-scroll-progress.le-select.le-slot.le-string-input.entry.cjs.js.map