le-kit 0.1.11 → 0.1.13

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 (279) hide show
  1. package/custom-elements.json +1192 -1192
  2. package/dist/{core/cjs/index-D7B9TPh8.js → cjs/index-o1DRKw1g.js} +11 -4
  3. package/dist/cjs/index-o1DRKw1g.js.map +1 -0
  4. package/dist/cjs/index.cjs.js +3 -3
  5. package/dist/cjs/le-box.cjs.entry.js +2 -2
  6. package/dist/cjs/le-button.le-checkbox.le-component.le-popover.le-slot.le-string-input.entry.cjs.js.map +1 -1
  7. package/dist/cjs/le-button_6.cjs.entry.js +11 -5
  8. package/dist/cjs/le-card.cjs.entry.js +2 -2
  9. package/dist/cjs/le-kit.cjs.js +1 -1
  10. package/dist/cjs/le-number-input.cjs.entry.js +2 -2
  11. package/dist/cjs/le-popup.cjs.entry.js +1 -1
  12. package/dist/cjs/le-round-progress.cjs.entry.js +1 -1
  13. package/dist/cjs/le-stack.cjs.entry.js +2 -2
  14. package/dist/cjs/le-text.cjs.entry.js +2 -2
  15. package/dist/cjs/le-turntable.cjs.entry.js +1 -1
  16. package/dist/cjs/loader.cjs.js +1 -1
  17. package/dist/{core/cjs/utils-DrsoID-a.js → cjs/utils-DqhadIxH.js} +3 -3
  18. package/dist/cjs/{utils-DrsoID-a.js.map → utils-DqhadIxH.js.map} +1 -1
  19. package/dist/collection/assets/custom-elements.json +4305 -0
  20. package/dist/collection/components/le-component/le-component.js +5 -2
  21. package/dist/collection/components/le-component/le-component.js.map +1 -1
  22. package/dist/collection/components/le-slot/le-slot.js +6 -3
  23. package/dist/collection/components/le-slot/le-slot.js.map +1 -1
  24. package/dist/collection/dist/collection/themes/base.css +89 -0
  25. package/dist/collection/dist/collection/themes/dark.css +100 -0
  26. package/dist/collection/dist/collection/themes/default.css +108 -0
  27. package/dist/collection/dist/collection/themes/gradient.css +100 -0
  28. package/dist/collection/dist/collection/themes/index.css +413 -0
  29. package/dist/collection/dist/collection/themes/minimal.css +100 -0
  30. package/dist/collection/dist/collection/themes/warm.css +100 -0
  31. package/dist/collection/global/app.js +1 -1
  32. package/dist/collection/global/app.js.map +1 -1
  33. package/dist/collection/index.js +1 -1
  34. package/dist/collection/index.js.map +1 -1
  35. package/dist/collection/themes/base.css +89 -0
  36. package/dist/collection/themes/dark.css +100 -0
  37. package/dist/collection/themes/default.css +108 -0
  38. package/dist/collection/themes/gradient.css +100 -0
  39. package/dist/collection/themes/index.css +413 -0
  40. package/dist/collection/themes/minimal.css +100 -0
  41. package/dist/collection/themes/warm.css +100 -0
  42. package/dist/components/index.d.ts +33 -0
  43. package/dist/components/index.js +113 -0
  44. package/dist/components/index.js.map +1 -0
  45. package/dist/components/le-box.d.ts +11 -0
  46. package/dist/components/le-box.js +257 -0
  47. package/dist/components/le-box.js.map +1 -0
  48. package/dist/components/le-button.d.ts +11 -0
  49. package/dist/components/le-button.js +9 -0
  50. package/dist/components/le-button.js.map +1 -0
  51. package/dist/components/le-button2.js +1149 -0
  52. package/dist/components/le-button2.js.map +1 -0
  53. package/dist/components/le-card.d.ts +11 -0
  54. package/dist/components/le-card.js +84 -0
  55. package/dist/components/le-card.js.map +1 -0
  56. package/dist/components/le-checkbox.d.ts +11 -0
  57. package/dist/components/le-checkbox.js +9 -0
  58. package/dist/components/le-checkbox.js.map +1 -0
  59. package/dist/components/le-component.d.ts +11 -0
  60. package/dist/components/le-component.js +9 -0
  61. package/dist/components/le-component.js.map +1 -0
  62. package/dist/components/le-number-input.d.ts +11 -0
  63. package/dist/components/le-number-input.js +272 -0
  64. package/dist/components/le-number-input.js.map +1 -0
  65. package/dist/components/le-popover.d.ts +11 -0
  66. package/dist/components/le-popover.js +9 -0
  67. package/dist/components/le-popover.js.map +1 -0
  68. package/dist/components/le-popover2.js +382 -0
  69. package/dist/components/le-popover2.js.map +1 -0
  70. package/dist/components/le-popup.d.ts +11 -0
  71. package/dist/components/le-popup.js +279 -0
  72. package/dist/components/le-popup.js.map +1 -0
  73. package/dist/components/le-round-progress.d.ts +11 -0
  74. package/dist/components/le-round-progress.js +135 -0
  75. package/dist/components/le-round-progress.js.map +1 -0
  76. package/dist/components/le-slot.d.ts +11 -0
  77. package/dist/components/le-slot.js +9 -0
  78. package/dist/components/le-slot.js.map +1 -0
  79. package/dist/components/le-stack.d.ts +11 -0
  80. package/dist/components/le-stack.js +199 -0
  81. package/dist/components/le-stack.js.map +1 -0
  82. package/dist/components/le-string-input.d.ts +11 -0
  83. package/dist/components/le-string-input.js +9 -0
  84. package/dist/components/le-string-input.js.map +1 -0
  85. package/dist/components/le-text.d.ts +11 -0
  86. package/dist/components/le-text.js +399 -0
  87. package/dist/components/le-text.js.map +1 -0
  88. package/dist/components/le-turntable.d.ts +11 -0
  89. package/dist/components/le-turntable.js +164 -0
  90. package/dist/components/le-turntable.js.map +1 -0
  91. package/dist/components/utils.js +310 -0
  92. package/dist/components/utils.js.map +1 -0
  93. package/dist/{cjs/index-D7B9TPh8.js → core/cjs/index-BsRb_UTe.js} +4 -4
  94. package/dist/core/cjs/index-BsRb_UTe.js.map +1 -0
  95. package/dist/core/cjs/index.cjs.js +3 -3
  96. package/dist/core/cjs/le-box.cjs.entry.js +2 -2
  97. package/dist/core/cjs/le-button.cjs.entry.js +2 -2
  98. package/dist/core/cjs/le-card.cjs.entry.js +2 -2
  99. package/dist/core/cjs/le-checkbox.cjs.entry.js +2 -2
  100. package/dist/core/cjs/le-kit.cjs.js +1 -1
  101. package/dist/core/cjs/le-number-input.cjs.entry.js +2 -2
  102. package/dist/core/cjs/le-popover.cjs.entry.js +1 -1
  103. package/dist/core/cjs/le-popup.cjs.entry.js +1 -1
  104. package/dist/core/cjs/le-round-progress.cjs.entry.js +1 -1
  105. package/dist/core/cjs/le-stack.cjs.entry.js +2 -2
  106. package/dist/core/cjs/le-string-input.cjs.entry.js +2 -2
  107. package/dist/core/cjs/le-text.cjs.entry.js +2 -2
  108. package/dist/core/cjs/le-turntable.cjs.entry.js +1 -1
  109. package/dist/core/cjs/loader.cjs.js +1 -1
  110. package/dist/{cjs/utils-DrsoID-a.js → core/cjs/utils-nsP8_w8_.js} +3 -3
  111. package/dist/core/cjs/{utils-DrsoID-a.js.map → utils-nsP8_w8_.js.map} +1 -1
  112. package/dist/core/collection/assets/custom-elements.json +4305 -0
  113. package/dist/core/collection/global/app.js +1 -1
  114. package/dist/core/collection/global/app.js.map +1 -1
  115. package/dist/core/collection/index.js +1 -1
  116. package/dist/core/collection/index.js.map +1 -1
  117. package/dist/core/collection/themes/base.css +89 -0
  118. package/dist/core/collection/themes/dark.css +100 -0
  119. package/dist/core/collection/themes/default.css +108 -0
  120. package/dist/core/collection/themes/gradient.css +100 -0
  121. package/dist/core/collection/themes/index.css +413 -0
  122. package/dist/core/collection/themes/minimal.css +100 -0
  123. package/dist/core/collection/themes/warm.css +100 -0
  124. package/dist/core/components/index.d.ts +33 -0
  125. package/dist/core/components/index.js +113 -0
  126. package/dist/core/components/index.js.map +1 -0
  127. package/dist/core/components/le-box.d.ts +11 -0
  128. package/dist/core/components/le-box.js +225 -0
  129. package/dist/core/components/le-box.js.map +1 -0
  130. package/dist/core/components/le-button.d.ts +11 -0
  131. package/dist/core/components/le-button.js +9 -0
  132. package/dist/core/components/le-button.js.map +1 -0
  133. package/dist/core/components/le-button2.js +121 -0
  134. package/dist/core/components/le-button2.js.map +1 -0
  135. package/dist/core/components/le-card.d.ts +11 -0
  136. package/dist/core/components/le-card.js +52 -0
  137. package/dist/core/components/le-card.js.map +1 -0
  138. package/dist/core/components/le-checkbox.d.ts +11 -0
  139. package/dist/core/components/le-checkbox.js +87 -0
  140. package/dist/core/components/le-checkbox.js.map +1 -0
  141. package/dist/core/components/le-number-input.d.ts +11 -0
  142. package/dist/core/components/le-number-input.js +246 -0
  143. package/dist/core/components/le-number-input.js.map +1 -0
  144. package/dist/core/components/le-popover.d.ts +11 -0
  145. package/dist/core/components/le-popover.js +385 -0
  146. package/dist/core/components/le-popover.js.map +1 -0
  147. package/dist/core/components/le-popup.d.ts +11 -0
  148. package/dist/core/components/le-popup.js +253 -0
  149. package/dist/core/components/le-popup.js.map +1 -0
  150. package/dist/core/components/le-round-progress.d.ts +11 -0
  151. package/dist/core/components/le-round-progress.js +135 -0
  152. package/dist/core/components/le-round-progress.js.map +1 -0
  153. package/dist/core/components/le-stack.d.ts +11 -0
  154. package/dist/core/components/le-stack.js +167 -0
  155. package/dist/core/components/le-stack.js.map +1 -0
  156. package/dist/core/components/le-string-input.d.ts +11 -0
  157. package/dist/core/components/le-string-input.js +127 -0
  158. package/dist/core/components/le-string-input.js.map +1 -0
  159. package/dist/core/components/le-text.d.ts +11 -0
  160. package/dist/core/components/le-text.js +367 -0
  161. package/dist/core/components/le-text.js.map +1 -0
  162. package/dist/core/components/le-turntable.d.ts +11 -0
  163. package/dist/core/components/le-turntable.js +164 -0
  164. package/dist/core/components/le-turntable.js.map +1 -0
  165. package/dist/core/components/utils.js +310 -0
  166. package/dist/core/components/utils.js.map +1 -0
  167. package/dist/core/esm/{index-PS-3Rz-c.js → index-CJ-z5Zj1.js} +4 -4
  168. package/dist/core/esm/index-CJ-z5Zj1.js.map +1 -0
  169. package/dist/core/esm/index.js +2 -2
  170. package/dist/core/esm/le-box.entry.js +2 -2
  171. package/dist/core/esm/le-button.entry.js +2 -2
  172. package/dist/core/esm/le-card.entry.js +2 -2
  173. package/dist/core/esm/le-checkbox.entry.js +2 -2
  174. package/dist/core/esm/le-kit.js +2 -2
  175. package/dist/core/esm/le-number-input.entry.js +2 -2
  176. package/dist/core/esm/le-popover.entry.js +1 -1
  177. package/dist/core/esm/le-popup.entry.js +1 -1
  178. package/dist/core/esm/le-round-progress.entry.js +1 -1
  179. package/dist/core/esm/le-stack.entry.js +2 -2
  180. package/dist/core/esm/le-string-input.entry.js +2 -2
  181. package/dist/core/esm/le-text.entry.js +2 -2
  182. package/dist/core/esm/le-turntable.entry.js +1 -1
  183. package/dist/core/esm/loader.js +2 -2
  184. package/dist/core/esm/{utils-lgjSfQP0.js → utils-Bxmld82M.js} +3 -3
  185. package/dist/core/esm/{utils-lgjSfQP0.js.map → utils-Bxmld82M.js.map} +1 -1
  186. package/dist/core/le-kit/index.esm.js +1 -1
  187. package/dist/core/le-kit/le-kit.esm.js +1 -1
  188. package/dist/core/le-kit/{p-a5f1e539.entry.js → p-0308bd1f.entry.js} +2 -2
  189. package/dist/core/le-kit/{p-1c5262eb.entry.js → p-257495cc.entry.js} +2 -2
  190. package/dist/core/le-kit/{p-32c08678.entry.js → p-2ac4789a.entry.js} +2 -2
  191. package/dist/core/le-kit/{p-4bf51acc.entry.js → p-45eace7c.entry.js} +2 -2
  192. package/dist/core/le-kit/{p-fd665f35.entry.js → p-556086ca.entry.js} +2 -2
  193. package/dist/core/le-kit/{p-dcf1343d.entry.js → p-5ef81068.entry.js} +2 -2
  194. package/dist/core/le-kit/{p-a24b042d.entry.js → p-66d35f48.entry.js} +2 -2
  195. package/dist/core/le-kit/{p-4a9a9805.entry.js → p-73682c5e.entry.js} +2 -2
  196. package/dist/{le-kit/p-PS-3Rz-c.js → core/le-kit/p-CJ-z5Zj1.js} +1 -1
  197. package/dist/core/le-kit/p-CJ-z5Zj1.js.map +1 -0
  198. package/dist/core/le-kit/{p-DN2JVY-7.js → p-Drz36PDp.js} +2 -2
  199. package/dist/core/le-kit/{p-DN2JVY-7.js.map → p-Drz36PDp.js.map} +1 -1
  200. package/dist/core/le-kit/{p-bbc9e13e.entry.js → p-aa6e906f.entry.js} +2 -2
  201. package/dist/core/le-kit/{p-38e7ec05.entry.js → p-d75214f9.entry.js} +2 -2
  202. package/dist/core/le-kit/{p-9ee92c29.entry.js → p-df552906.entry.js} +2 -2
  203. package/dist/core/le-kit/{p-c4223c60.entry.js → p-e0861e82.entry.js} +2 -2
  204. package/dist/core/types/global/app.d.ts +1 -1
  205. package/dist/core/types/index.d.ts +1 -1
  206. package/dist/docs.json +1 -1
  207. package/dist/esm/{index-PS-3Rz-c.js → index-CwNQ1GTa.js} +10 -4
  208. package/dist/esm/index-CwNQ1GTa.js.map +1 -0
  209. package/dist/esm/index.js +2 -2
  210. package/dist/esm/le-box.entry.js +2 -2
  211. package/dist/esm/le-button.le-checkbox.le-component.le-popover.le-slot.le-string-input.entry.js.map +1 -1
  212. package/dist/esm/le-button_6.entry.js +11 -5
  213. package/dist/esm/le-card.entry.js +2 -2
  214. package/dist/esm/le-kit.js +2 -2
  215. package/dist/esm/le-number-input.entry.js +2 -2
  216. package/dist/esm/le-popup.entry.js +1 -1
  217. package/dist/esm/le-round-progress.entry.js +1 -1
  218. package/dist/esm/le-stack.entry.js +2 -2
  219. package/dist/esm/le-text.entry.js +2 -2
  220. package/dist/esm/le-turntable.entry.js +1 -1
  221. package/dist/esm/loader.js +2 -2
  222. package/dist/esm/{utils-lgjSfQP0.js → utils-Cf7fMI0j.js} +3 -3
  223. package/dist/esm/{utils-lgjSfQP0.js.map → utils-Cf7fMI0j.js.map} +1 -1
  224. package/dist/le-kit/assets/custom-elements.json +4305 -0
  225. package/dist/le-kit/dist/collection/themes/base.css +89 -0
  226. package/dist/le-kit/dist/collection/themes/dark.css +100 -0
  227. package/dist/le-kit/dist/collection/themes/default.css +108 -0
  228. package/dist/le-kit/dist/collection/themes/gradient.css +100 -0
  229. package/dist/le-kit/dist/collection/themes/index.css +413 -0
  230. package/dist/le-kit/dist/collection/themes/minimal.css +100 -0
  231. package/dist/le-kit/dist/collection/themes/warm.css +100 -0
  232. package/dist/le-kit/index.esm.js +1 -1
  233. package/dist/le-kit/le-button.le-checkbox.le-component.le-popover.le-slot.le-string-input.entry.esm.js.map +1 -1
  234. package/dist/le-kit/le-kit.esm.js +1 -1
  235. package/dist/le-kit/{p-935bb2d4.entry.js → p-08dbcc25.entry.js} +2 -2
  236. package/dist/le-kit/{p-d8157b06.entry.js → p-5dc35729.entry.js} +2 -2
  237. package/dist/le-kit/{p-34102cef.entry.js → p-64374730.entry.js} +2 -2
  238. package/dist/le-kit/{p-27710b5b.entry.js → p-79ec6f7c.entry.js} +2 -2
  239. package/dist/le-kit/{p-ccabc638.entry.js → p-8daf3c7f.entry.js} +2 -2
  240. package/dist/le-kit/p-9c69235d.entry.js +2 -0
  241. package/dist/le-kit/p-9c69235d.entry.js.map +1 -0
  242. package/dist/{core/le-kit/p-PS-3Rz-c.js → le-kit/p-CwNQ1GTa.js} +2 -2
  243. package/dist/le-kit/p-CwNQ1GTa.js.map +1 -0
  244. package/dist/le-kit/{p-e8c2ca0e.entry.js → p-ad398acd.entry.js} +2 -2
  245. package/dist/le-kit/{p-9d3dc4e5.entry.js → p-b8122ad6.entry.js} +2 -2
  246. package/dist/le-kit/{p-56a80e6d.entry.js → p-f9008505.entry.js} +2 -2
  247. package/dist/le-kit/{p-DN2JVY-7.js → p-y3FECAx9.js} +2 -2
  248. package/dist/le-kit/{p-DN2JVY-7.js.map → p-y3FECAx9.js.map} +1 -1
  249. package/dist/types/global/app.d.ts +1 -1
  250. package/dist/types/index.d.ts +1 -1
  251. package/package.json +2 -2
  252. package/dist/cjs/index-D7B9TPh8.js.map +0 -1
  253. package/dist/core/cjs/index-D7B9TPh8.js.map +0 -1
  254. package/dist/core/esm/index-PS-3Rz-c.js.map +0 -1
  255. package/dist/core/le-kit/p-PS-3Rz-c.js.map +0 -1
  256. package/dist/esm/index-PS-3Rz-c.js.map +0 -1
  257. package/dist/le-kit/p-615ea10f.entry.js +0 -2
  258. package/dist/le-kit/p-615ea10f.entry.js.map +0 -1
  259. package/dist/le-kit/p-PS-3Rz-c.js.map +0 -1
  260. /package/dist/core/le-kit/{p-a5f1e539.entry.js.map → p-0308bd1f.entry.js.map} +0 -0
  261. /package/dist/core/le-kit/{p-1c5262eb.entry.js.map → p-257495cc.entry.js.map} +0 -0
  262. /package/dist/core/le-kit/{p-32c08678.entry.js.map → p-2ac4789a.entry.js.map} +0 -0
  263. /package/dist/core/le-kit/{p-4bf51acc.entry.js.map → p-45eace7c.entry.js.map} +0 -0
  264. /package/dist/core/le-kit/{p-fd665f35.entry.js.map → p-556086ca.entry.js.map} +0 -0
  265. /package/dist/core/le-kit/{p-dcf1343d.entry.js.map → p-5ef81068.entry.js.map} +0 -0
  266. /package/dist/core/le-kit/{p-a24b042d.entry.js.map → p-66d35f48.entry.js.map} +0 -0
  267. /package/dist/core/le-kit/{p-4a9a9805.entry.js.map → p-73682c5e.entry.js.map} +0 -0
  268. /package/dist/core/le-kit/{p-bbc9e13e.entry.js.map → p-aa6e906f.entry.js.map} +0 -0
  269. /package/dist/core/le-kit/{p-38e7ec05.entry.js.map → p-d75214f9.entry.js.map} +0 -0
  270. /package/dist/core/le-kit/{p-9ee92c29.entry.js.map → p-df552906.entry.js.map} +0 -0
  271. /package/dist/core/le-kit/{p-c4223c60.entry.js.map → p-e0861e82.entry.js.map} +0 -0
  272. /package/dist/le-kit/{p-935bb2d4.entry.js.map → p-08dbcc25.entry.js.map} +0 -0
  273. /package/dist/le-kit/{p-d8157b06.entry.js.map → p-5dc35729.entry.js.map} +0 -0
  274. /package/dist/le-kit/{p-34102cef.entry.js.map → p-64374730.entry.js.map} +0 -0
  275. /package/dist/le-kit/{p-27710b5b.entry.js.map → p-79ec6f7c.entry.js.map} +0 -0
  276. /package/dist/le-kit/{p-ccabc638.entry.js.map → p-8daf3c7f.entry.js.map} +0 -0
  277. /package/dist/le-kit/{p-e8c2ca0e.entry.js.map → p-ad398acd.entry.js.map} +0 -0
  278. /package/dist/le-kit/{p-9d3dc4e5.entry.js.map → p-b8122ad6.entry.js.map} +0 -0
  279. /package/dist/le-kit/{p-56a80e6d.entry.js.map → p-f9008505.entry.js.map} +0 -0
@@ -1,4 +1,4 @@
1
- import { h, Host } from "@stencil/core";
1
+ import { h, Host, getAssetPath } from "@stencil/core";
2
2
  import { classnames, observeModeChanges } from "../../utils/utils";
3
3
  import { getLeKitConfig } from "../../global/app";
4
4
  /**
@@ -121,7 +121,10 @@ export class LeComponent {
121
121
  try {
122
122
  // Fetch the manifest from configured URL
123
123
  const { manifestUrl } = getLeKitConfig();
124
- const response = await fetch(manifestUrl);
124
+ const manifestUrlResolved = manifestUrl.startsWith('/')
125
+ ? getAssetPath(`./assets${manifestUrl}`)
126
+ : manifestUrl;
127
+ const response = await fetch(manifestUrlResolved);
125
128
  const manifest = await response.json();
126
129
  // Find the component definition
127
130
  for (const module of manifest.modules) {
@@ -1 +1 @@
1
- {"version":3,"file":"le-component.js","sourceRoot":"","sources":["../../../src/components/le-component/le-component.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Component, Prop, State, h, Host, Element } from '@stencil/core';\nimport { classnames, observeModeChanges } from '../../utils/utils';\nimport { getLeKitConfig } from '../../global/app';\n\n/**\n * Component wrapper for admin mode editing.\n *\n * This component is used internally by other components to provide admin-mode\n * editing capabilities. It wraps the component's rendered output and shows\n * a settings popover for editing properties.\n *\n * In default mode, it acts as a simple passthrough (display: contents).\n * In admin mode, it shows a border, component name header, and settings popover.\n *\n * The host element is found automatically by traversing up through the shadow DOM.\n *\n * Usage inside a component's render method:\n * ```tsx\n * render() {\n * return (\n * <le-component component=\"le-card\">\n * <Host>...</Host>\n * </le-component>\n * );\n * }\n * ```\n *\n * @slot - The component's rendered content\n *\n * @cmsInternal true\n * @cmsCategory System\n */\n@Component({\n tag: 'le-component',\n styleUrl: 'le-component.css',\n shadow: true,\n})\nexport class LeComponent {\n @Element() el: HTMLElement;\n\n /**\n * The tag name of the component (e.g., 'le-card').\n * Used to look up property metadata and display the component name.\n */\n @Prop() component!: string;\n\n /**\n * Optional display name for the component.\n * If not provided, the tag name will be formatted as the display name.\n */\n @Prop() displayName?: string;\n\n /**\n * Classes to apply to the host element.\n * Allows parent components to pass their styling classes.\n */\n @Prop() hostClass?: string;\n\n /**\n * Inline styles to apply to the host element.\n * Allows parent components to pass dynamic styles (e.g., flex properties).\n */\n @Prop() hostStyle?: { [key: string]: string };\n\n /**\n * Reference to the host element (found automatically from parent)\n */\n private hostElement?: HTMLElement;\n\n /**\n * Internal state to track admin mode\n */\n @State() private adminMode: boolean = false;\n\n /**\n * Component metadata loaded from Custom Elements Manifest\n */\n @State() private componentMeta: ComponentMetadata | null = null;\n\n /**\n * Current property values of the host component\n */\n @State() private propertyValues: Record<string, any> = {};\n\n private disconnectModeObserver?: () => void;\n\n connectedCallback() {\n // Find the host element - le-component is rendered inside the component's shadow DOM,\n // so we need to find the shadow root's host element\n this.findHostElement();\n\n this.disconnectModeObserver = observeModeChanges(this.el, mode => {\n this.adminMode = mode === 'admin';\n // Load metadata and refresh property values only when entering admin mode\n if (this.adminMode) {\n if (!this.componentMeta) {\n this.loadComponentMetadata();\n } else {\n this.readPropertyValues();\n }\n }\n });\n }\n\n /**\n * Find the host element by traversing up through shadow DOM\n */\n private findHostElement() {\n // Get the shadow root that contains this le-component\n const rootNode = this.el.getRootNode();\n if (rootNode instanceof ShadowRoot) {\n // The host of this shadow root is our target component (e.g., le-card)\n this.hostElement = rootNode.host as HTMLElement;\n }\n }\n\n componentDidLoad() {\n // Read initial property values from the host element\n this.readPropertyValues();\n }\n\n disconnectedCallback() {\n this.disconnectModeObserver?.();\n }\n\n /**\n * Formats a tag name into a display name\n * e.g., 'le-card' -> 'Card'\n */\n private formatDisplayName(tagName: string): string {\n return tagName\n .replace(/^le-/, '') // Remove 'le-' prefix\n .split('-')\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n }\n\n /**\n * Load component metadata from the Custom Elements Manifest\n */\n private async loadComponentMetadata() {\n try {\n // Fetch the manifest from configured URL\n const { manifestUrl } = getLeKitConfig();\n const response = await fetch(manifestUrl);\n const manifest = await response.json();\n\n // Find the component definition\n for (const module of manifest.modules) {\n for (const declaration of module.declarations || []) {\n if (declaration.tagName === this.component) {\n const attributes = (declaration.attributes || []).filter((attr: AttributeMetadata) => !this.isInternalAttribute(attr.name));\n this.componentMeta = {\n tagName: declaration.tagName,\n description: declaration.description,\n attributes,\n };\n // console.log(`[le-component] Loaded metadata for ${this.component}:`, this.componentMeta);\n // Read property values after metadata is loaded\n this.readPropertyValues();\n return;\n }\n }\n }\n // console.warn(`[le-component] No metadata found for component: ${this.component}`);\n } catch (error) {\n // console.warn(`[le-component] Failed to load metadata for component: ${this.component}`, error);\n }\n }\n\n /**\n * Check if an attribute is internal (should not be shown in editor)\n */\n private isInternalAttribute(name: string): boolean {\n const internalAttrs = ['mode', 'theme', 'class', 'style', 'id', 'slot'];\n return internalAttrs.includes(name);\n }\n\n /**\n * Read current property values from the host element\n */\n private readPropertyValues() {\n if (!this.hostElement || !this.componentMeta) return;\n\n const values: Record<string, any> = {};\n for (const attr of this.componentMeta.attributes) {\n const value = this.hostElement.getAttribute(attr.name);\n values[attr.name] = this.parseAttributeValue(value, attr.type?.text);\n }\n this.propertyValues = values;\n }\n\n /**\n * Parse an attribute value based on its type\n */\n private parseAttributeValue(value: string | null, type?: string): any {\n if (value === null) return undefined;\n\n if (type === 'boolean') {\n return value !== null && value !== 'false';\n }\n if (type === 'number') {\n return parseFloat(value);\n }\n return value;\n }\n\n /**\n * Handle property value changes from the editor\n */\n private handlePropertyChange(attrName: string, value: any, type?: string) {\n if (!this.hostElement) return;\n\n // Update the host element's attribute\n if (type === 'boolean') {\n if (value) {\n this.hostElement.setAttribute(attrName, '');\n } else {\n this.hostElement.removeAttribute(attrName);\n }\n } else if (value === undefined || value === '') {\n this.hostElement.removeAttribute(attrName);\n } else {\n this.hostElement.setAttribute(attrName, String(value));\n }\n\n // Update local state\n this.propertyValues = { ...this.propertyValues, [attrName]: value };\n }\n\n /**\n * Delete this component from the DOM\n */\n private deleteComponent() {\n if (!this.hostElement) return;\n\n // Confirm deletion\n const name = this.displayName || this.formatDisplayName(this.component);\n if (!confirm(`Delete this ${name}?`)) return;\n\n // Remove the host element from its parent\n const parent = this.hostElement.parentElement;\n if (parent) {\n this.hostElement.remove();\n }\n }\n\n /**\n * Render the property editor form\n */\n private renderPropertyEditor() {\n const hasProperties = this.componentMeta && this.componentMeta.attributes.length > 0;\n\n return (\n <div class=\"property-editor-container\">\n {hasProperties ? (\n <form class=\"property-editor\" onSubmit={e => e.preventDefault()}>\n {this.componentMeta!.attributes.map(attr => this.renderPropertyField(attr))}\n </form>\n ) : (\n <p class=\"no-properties\">No editable properties</p>\n )}\n <div class=\"property-editor-actions\">\n <le-button type=\"button\" variant=\"outlined\" color=\"danger\" full-width onClick={() => this.deleteComponent()}>\n <span slot=\"icon-start\">🗑️</span>\n <span>Delete Component</span>\n </le-button>\n </div>\n </div>\n );\n }\n\n /**\n * Render a single property field based on its type\n */\n private renderPropertyField(attr: AttributeMetadata) {\n const value = this.propertyValues[attr.name];\n const type = attr.type?.text || 'string';\n\n // Check if type is a union of string literals (e.g., \"'default' | 'outlined' | 'elevated'\")\n const enumMatch = type.match(/^'[^']+'/);\n if (enumMatch) {\n const options = type.split('|').map(opt => opt.trim().replace(/'/g, ''));\n return (\n <div class=\"property-field\">\n <label htmlFor={`prop-${attr.name}`}>\n {attr.name}\n {attr.description && <span class=\"property-hint\">{attr.description}</span>}\n </label>\n <select id={`prop-${attr.name}`} onChange={e => this.handlePropertyChange(attr.name, (e.target as HTMLSelectElement).value, type)}>\n {options.map(opt => (\n <option value={opt} selected={value === opt || (!value && attr.default?.replace(/'/g, '') === opt)}>\n {opt}\n </option>\n ))}\n </select>\n </div>\n );\n }\n\n // Boolean type\n if (type === 'boolean') {\n return (\n <div class=\"property-field property-field--checkbox\">\n <le-checkbox\n name={`prop-${attr.name}`}\n checked={value === true || value === ''}\n onChange={e => this.handlePropertyChange(attr.name, (e.target as HTMLInputElement).checked, type)}\n >\n {attr.name}\n {attr.description && <div slot=\"description\">{attr.description}</div>}\n </le-checkbox>\n </div>\n );\n }\n\n // Number type\n if (type === 'number') {\n return (\n <div class=\"property-field\">\n <label htmlFor={`prop-${attr.name}`}>\n {attr.name}\n {attr.description && <span class=\"property-hint\">{attr.description}</span>}\n </label>\n <input\n type=\"number\"\n id={`prop-${attr.name}`}\n value={value ?? ''}\n placeholder={attr.default}\n onChange={e => this.handlePropertyChange(attr.name, (e.target as HTMLInputElement).value, type)}\n />\n </div>\n );\n }\n\n // Default: string/text input\n return (\n <div class=\"property-field\">\n <le-string-input\n name={`prop-${attr.name}`}\n label={attr.name}\n value={value ?? ''}\n placeholder={attr.default?.replace(/'/g, '')}\n onChange={(e: any) => this.handlePropertyChange(attr.name, e.detail.value, type)}\n >\n <span slot=\"description\">{attr.description}</span>\n </le-string-input>\n </div>\n );\n }\n\n render() {\n const name = this.displayName || this.formatDisplayName(this.component);\n\n // In default mode, just pass through content with host classes\n if (!this.adminMode) {\n return (\n <Host class={classnames(this.component, this.hostClass)} style={this.hostStyle}>\n <slot></slot>\n </Host>\n );\n }\n\n // In admin mode, show wrapper with header and settings\n return (\n <Host class={classnames(this.component, this.hostClass, 'admin-mode')} style={this.hostStyle}>\n <div class=\"le-component-wrapper\">\n <div class=\"le-component-header\">\n <span class=\"le-component-name\">{name}</span>\n <le-popover popoverTitle={`${name} Settings`} position=\"right\" align=\"start\" min-width=\"300px\" mode=\"default\">\n <le-button type=\"button\" class=\"le-component-button\" slot=\"trigger\" variant=\"clear\" size=\"small\" aria-label=\"Edit component properties\" icon-only>\n <span class=\"le-component-trigger\" slot=\"icon-only\">\n ⚙\n </span>\n </le-button>\n {this.renderPropertyEditor()}\n </le-popover>\n </div>\n <div class=\"le-component-content\">\n <slot></slot>\n </div>\n </div>\n </Host>\n );\n }\n}\n\n/**\n * Type definitions for component metadata\n */\ninterface ComponentMetadata {\n tagName: string;\n description?: string;\n attributes: AttributeMetadata[];\n}\n\ninterface AttributeMetadata {\n name: string;\n fieldName?: string;\n description?: string;\n default?: string;\n type?: {\n text: string;\n };\n}\n"]}
1
+ {"version":3,"file":"le-component.js","sourceRoot":"","sources":["../../../src/components/le-component/le-component.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Component, Prop, State, h, Host, Element, getAssetPath } from '@stencil/core';\nimport { classnames, observeModeChanges } from '../../utils/utils';\nimport { getLeKitConfig } from '../../global/app';\n\n/**\n * Component wrapper for admin mode editing.\n *\n * This component is used internally by other components to provide admin-mode\n * editing capabilities. It wraps the component's rendered output and shows\n * a settings popover for editing properties.\n *\n * In default mode, it acts as a simple passthrough (display: contents).\n * In admin mode, it shows a border, component name header, and settings popover.\n *\n * The host element is found automatically by traversing up through the shadow DOM.\n *\n * Usage inside a component's render method:\n * ```tsx\n * render() {\n * return (\n * <le-component component=\"le-card\">\n * <Host>...</Host>\n * </le-component>\n * );\n * }\n * ```\n *\n * @slot - The component's rendered content\n *\n * @cmsInternal true\n * @cmsCategory System\n */\n@Component({\n tag: 'le-component',\n styleUrl: 'le-component.css',\n shadow: true,\n})\nexport class LeComponent {\n @Element() el: HTMLElement;\n\n /**\n * The tag name of the component (e.g., 'le-card').\n * Used to look up property metadata and display the component name.\n */\n @Prop() component!: string;\n\n /**\n * Optional display name for the component.\n * If not provided, the tag name will be formatted as the display name.\n */\n @Prop() displayName?: string;\n\n /**\n * Classes to apply to the host element.\n * Allows parent components to pass their styling classes.\n */\n @Prop() hostClass?: string;\n\n /**\n * Inline styles to apply to the host element.\n * Allows parent components to pass dynamic styles (e.g., flex properties).\n */\n @Prop() hostStyle?: { [key: string]: string };\n\n /**\n * Reference to the host element (found automatically from parent)\n */\n private hostElement?: HTMLElement;\n\n /**\n * Internal state to track admin mode\n */\n @State() private adminMode: boolean = false;\n\n /**\n * Component metadata loaded from Custom Elements Manifest\n */\n @State() private componentMeta: ComponentMetadata | null = null;\n\n /**\n * Current property values of the host component\n */\n @State() private propertyValues: Record<string, any> = {};\n\n private disconnectModeObserver?: () => void;\n\n connectedCallback() {\n // Find the host element - le-component is rendered inside the component's shadow DOM,\n // so we need to find the shadow root's host element\n this.findHostElement();\n\n this.disconnectModeObserver = observeModeChanges(this.el, mode => {\n this.adminMode = mode === 'admin';\n // Load metadata and refresh property values only when entering admin mode\n if (this.adminMode) {\n if (!this.componentMeta) {\n this.loadComponentMetadata();\n } else {\n this.readPropertyValues();\n }\n }\n });\n }\n\n /**\n * Find the host element by traversing up through shadow DOM\n */\n private findHostElement() {\n // Get the shadow root that contains this le-component\n const rootNode = this.el.getRootNode();\n if (rootNode instanceof ShadowRoot) {\n // The host of this shadow root is our target component (e.g., le-card)\n this.hostElement = rootNode.host as HTMLElement;\n }\n }\n\n componentDidLoad() {\n // Read initial property values from the host element\n this.readPropertyValues();\n }\n\n disconnectedCallback() {\n this.disconnectModeObserver?.();\n }\n\n /**\n * Formats a tag name into a display name\n * e.g., 'le-card' -> 'Card'\n */\n private formatDisplayName(tagName: string): string {\n return tagName\n .replace(/^le-/, '') // Remove 'le-' prefix\n .split('-')\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n }\n\n /**\n * Load component metadata from the Custom Elements Manifest\n */\n private async loadComponentMetadata() {\n try {\n // Fetch the manifest from configured URL\n const { manifestUrl } = getLeKitConfig();\n const manifestUrlResolved = manifestUrl.startsWith('/')\n ? getAssetPath(`./assets${manifestUrl}`)\n : manifestUrl;\n const response = await fetch(manifestUrlResolved);\n const manifest = await response.json();\n\n // Find the component definition\n for (const module of manifest.modules) {\n for (const declaration of module.declarations || []) {\n if (declaration.tagName === this.component) {\n const attributes = (declaration.attributes || []).filter((attr: AttributeMetadata) => !this.isInternalAttribute(attr.name));\n this.componentMeta = {\n tagName: declaration.tagName,\n description: declaration.description,\n attributes,\n };\n // console.log(`[le-component] Loaded metadata for ${this.component}:`, this.componentMeta);\n // Read property values after metadata is loaded\n this.readPropertyValues();\n return;\n }\n }\n }\n // console.warn(`[le-component] No metadata found for component: ${this.component}`);\n } catch (error) {\n // console.warn(`[le-component] Failed to load metadata for component: ${this.component}`, error);\n }\n }\n\n /**\n * Check if an attribute is internal (should not be shown in editor)\n */\n private isInternalAttribute(name: string): boolean {\n const internalAttrs = ['mode', 'theme', 'class', 'style', 'id', 'slot'];\n return internalAttrs.includes(name);\n }\n\n /**\n * Read current property values from the host element\n */\n private readPropertyValues() {\n if (!this.hostElement || !this.componentMeta) return;\n\n const values: Record<string, any> = {};\n for (const attr of this.componentMeta.attributes) {\n const value = this.hostElement.getAttribute(attr.name);\n values[attr.name] = this.parseAttributeValue(value, attr.type?.text);\n }\n this.propertyValues = values;\n }\n\n /**\n * Parse an attribute value based on its type\n */\n private parseAttributeValue(value: string | null, type?: string): any {\n if (value === null) return undefined;\n\n if (type === 'boolean') {\n return value !== null && value !== 'false';\n }\n if (type === 'number') {\n return parseFloat(value);\n }\n return value;\n }\n\n /**\n * Handle property value changes from the editor\n */\n private handlePropertyChange(attrName: string, value: any, type?: string) {\n if (!this.hostElement) return;\n\n // Update the host element's attribute\n if (type === 'boolean') {\n if (value) {\n this.hostElement.setAttribute(attrName, '');\n } else {\n this.hostElement.removeAttribute(attrName);\n }\n } else if (value === undefined || value === '') {\n this.hostElement.removeAttribute(attrName);\n } else {\n this.hostElement.setAttribute(attrName, String(value));\n }\n\n // Update local state\n this.propertyValues = { ...this.propertyValues, [attrName]: value };\n }\n\n /**\n * Delete this component from the DOM\n */\n private deleteComponent() {\n if (!this.hostElement) return;\n\n // Confirm deletion\n const name = this.displayName || this.formatDisplayName(this.component);\n if (!confirm(`Delete this ${name}?`)) return;\n\n // Remove the host element from its parent\n const parent = this.hostElement.parentElement;\n if (parent) {\n this.hostElement.remove();\n }\n }\n\n /**\n * Render the property editor form\n */\n private renderPropertyEditor() {\n const hasProperties = this.componentMeta && this.componentMeta.attributes.length > 0;\n\n return (\n <div class=\"property-editor-container\">\n {hasProperties ? (\n <form class=\"property-editor\" onSubmit={e => e.preventDefault()}>\n {this.componentMeta!.attributes.map(attr => this.renderPropertyField(attr))}\n </form>\n ) : (\n <p class=\"no-properties\">No editable properties</p>\n )}\n <div class=\"property-editor-actions\">\n <le-button type=\"button\" variant=\"outlined\" color=\"danger\" full-width onClick={() => this.deleteComponent()}>\n <span slot=\"icon-start\">🗑️</span>\n <span>Delete Component</span>\n </le-button>\n </div>\n </div>\n );\n }\n\n /**\n * Render a single property field based on its type\n */\n private renderPropertyField(attr: AttributeMetadata) {\n const value = this.propertyValues[attr.name];\n const type = attr.type?.text || 'string';\n\n // Check if type is a union of string literals (e.g., \"'default' | 'outlined' | 'elevated'\")\n const enumMatch = type.match(/^'[^']+'/);\n if (enumMatch) {\n const options = type.split('|').map(opt => opt.trim().replace(/'/g, ''));\n return (\n <div class=\"property-field\">\n <label htmlFor={`prop-${attr.name}`}>\n {attr.name}\n {attr.description && <span class=\"property-hint\">{attr.description}</span>}\n </label>\n <select id={`prop-${attr.name}`} onChange={e => this.handlePropertyChange(attr.name, (e.target as HTMLSelectElement).value, type)}>\n {options.map(opt => (\n <option value={opt} selected={value === opt || (!value && attr.default?.replace(/'/g, '') === opt)}>\n {opt}\n </option>\n ))}\n </select>\n </div>\n );\n }\n\n // Boolean type\n if (type === 'boolean') {\n return (\n <div class=\"property-field property-field--checkbox\">\n <le-checkbox\n name={`prop-${attr.name}`}\n checked={value === true || value === ''}\n onChange={e => this.handlePropertyChange(attr.name, (e.target as HTMLInputElement).checked, type)}\n >\n {attr.name}\n {attr.description && <div slot=\"description\">{attr.description}</div>}\n </le-checkbox>\n </div>\n );\n }\n\n // Number type\n if (type === 'number') {\n return (\n <div class=\"property-field\">\n <label htmlFor={`prop-${attr.name}`}>\n {attr.name}\n {attr.description && <span class=\"property-hint\">{attr.description}</span>}\n </label>\n <input\n type=\"number\"\n id={`prop-${attr.name}`}\n value={value ?? ''}\n placeholder={attr.default}\n onChange={e => this.handlePropertyChange(attr.name, (e.target as HTMLInputElement).value, type)}\n />\n </div>\n );\n }\n\n // Default: string/text input\n return (\n <div class=\"property-field\">\n <le-string-input\n name={`prop-${attr.name}`}\n label={attr.name}\n value={value ?? ''}\n placeholder={attr.default?.replace(/'/g, '')}\n onChange={(e: any) => this.handlePropertyChange(attr.name, e.detail.value, type)}\n >\n <span slot=\"description\">{attr.description}</span>\n </le-string-input>\n </div>\n );\n }\n\n render() {\n const name = this.displayName || this.formatDisplayName(this.component);\n\n // In default mode, just pass through content with host classes\n if (!this.adminMode) {\n return (\n <Host class={classnames(this.component, this.hostClass)} style={this.hostStyle}>\n <slot></slot>\n </Host>\n );\n }\n\n // In admin mode, show wrapper with header and settings\n return (\n <Host class={classnames(this.component, this.hostClass, 'admin-mode')} style={this.hostStyle}>\n <div class=\"le-component-wrapper\">\n <div class=\"le-component-header\">\n <span class=\"le-component-name\">{name}</span>\n <le-popover popoverTitle={`${name} Settings`} position=\"right\" align=\"start\" min-width=\"300px\" mode=\"default\">\n <le-button type=\"button\" class=\"le-component-button\" slot=\"trigger\" variant=\"clear\" size=\"small\" aria-label=\"Edit component properties\" icon-only>\n <span class=\"le-component-trigger\" slot=\"icon-only\">\n ⚙\n </span>\n </le-button>\n {this.renderPropertyEditor()}\n </le-popover>\n </div>\n <div class=\"le-component-content\">\n <slot></slot>\n </div>\n </div>\n </Host>\n );\n }\n}\n\n/**\n * Type definitions for component metadata\n */\ninterface ComponentMetadata {\n tagName: string;\n description?: string;\n attributes: AttributeMetadata[];\n}\n\ninterface AttributeMetadata {\n name: string;\n fieldName?: string;\n description?: string;\n default?: string;\n type?: {\n text: string;\n };\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { h, Host } from "@stencil/core";
1
+ import { h, Host, getAssetPath } from "@stencil/core";
2
2
  import { classnames, observeModeChanges } from "../../utils/utils";
3
3
  import { getLeKitConfig } from "../../global/app";
4
4
  /**
@@ -267,7 +267,10 @@ export class LeSlot {
267
267
  async loadAvailableComponents() {
268
268
  try {
269
269
  const { manifestUrl } = getLeKitConfig();
270
- const response = await fetch(manifestUrl);
270
+ const manifestUrlResolved = manifestUrl.startsWith('/')
271
+ ? getAssetPath(`./assets${manifestUrl}`)
272
+ : manifestUrl;
273
+ const response = await fetch(manifestUrlResolved);
271
274
  const manifest = await response.json();
272
275
  const components = [];
273
276
  const allowedList = this.allowedComponents?.split(',').map(s => s.trim()) || [];
@@ -342,7 +345,7 @@ export class LeSlot {
342
345
  render() {
343
346
  const displayLabel = this.label || this.name;
344
347
  // Always render the same structure, CSS handles visibility via .admin-mode class
345
- return (h(Host, { key: '5ff8f0dd3c07f92e0584450fabf57b89ea0c0a10', class: {
348
+ return (h(Host, { key: 'e89effa647f07ae271cffc05aad6730b51da6447', class: {
346
349
  'admin-mode': this.adminMode,
347
350
  'invalid-html': !this.isValidHtml,
348
351
  }, role: this.adminMode ? 'region' : undefined, "aria-label": this.adminMode ? `Slot: ${displayLabel}` : undefined, "data-slot-name": this.name, "data-slot-type": this.type, "data-allowed": this.allowedComponents, "data-multiple": this.multiple, "data-required": this.required }, this.adminMode ? (h("div", { class: "le-slot-container" }, h("div", { class: classnames('le-slot-header', {
@@ -1 +1 @@
1
- {"version":3,"file":"le-slot.js","sourceRoot":"","sources":["../../../src/components/le-slot/le-slot.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Component, Prop, State, h, Host, Element, Event, EventEmitter } from '@stencil/core';\nimport { classnames, observeModeChanges } from '../../utils/utils';\nimport { getLeKitConfig } from '../../global/app';\n\n/**\n * Slot placeholder component for admin/CMS mode.\n *\n * This component renders a visual placeholder for slots when in admin mode,\n * allowing CMS systems to show available drop zones for content or inline editing.\n *\n * In non-admin mode, this component renders nothing and acts as a passthrough.\n *\n * @slot - Default slot for placeholder content or drop zone UI\n *\n * @cmsInternal true\n * @cmsCategory System\n */\n@Component({\n tag: 'le-slot',\n styleUrl: 'le-slot.default.css',\n shadow: true,\n})\nexport class LeSlot {\n @Element() el: HTMLElement;\n\n /**\n * The type of slot content.\n * - `slot`: Default, shows a dropzone for components (default)\n * - `text`: Shows a single-line text input\n * - `textarea`: Shows a multi-line text area\n */\n @Prop() type: 'slot' | 'text' | 'textarea' = 'slot';\n\n /**\n * The name of the slot this placeholder represents.\n * Should match the slot name in the parent component.\n */\n @Prop() name: string = '';\n\n /**\n * Label to display in admin mode.\n * If not provided, the slot name will be used.\n */\n @Prop() label?: string;\n\n /**\n * Description of what content this slot accepts.\n * Shown in admin mode to guide content editors.\n */\n @Prop() description?: string;\n\n /**\n * Comma-separated list of allowed component tags for this slot.\n * Used by CMS to filter available components.\n *\n * @example \"le-card,le-button,le-text\"\n */\n @Prop() allowedComponents?: string;\n\n /**\n * Whether multiple components can be dropped in this slot.\n */\n @Prop() multiple: boolean = true;\n\n /**\n * Whether this slot is required to have content.\n */\n @Prop() required: boolean = false;\n\n /**\n * Placeholder text for text/textarea inputs in admin mode.\n */\n @Prop() placeholder?: string;\n\n /**\n * The HTML tag to create when there's no slotted element.\n * Used with type=\"text\" or type=\"textarea\" to auto-create elements.\n *\n * @example \"h3\" - creates <h3 slot=\"header\">content</h3>\n * @example \"p\" - creates <p slot=\"content\">content</p>\n */\n @Prop() tag?: string;\n\n /**\n * CSS styles for the slot dropzone container.\n * Useful for layouts - e.g., \"flex-direction: row\" for horizontal stacks.\n * Only applies in admin mode for type=\"slot\".\n */\n @Prop() slotStyle?: string;\n\n /**\n * Internal state to track admin mode\n */\n @State() private adminMode: boolean = false;\n\n /**\n * Internal state for text input value (synced from slot content)\n */\n @State() private textValue: string = '';\n\n /**\n * Whether the current textValue contains valid HTML\n */\n @State() private isValidHtml: boolean = true;\n\n /**\n * Available components loaded from Custom Elements Manifest\n */\n @State() private availableComponents: ComponentInfo[] = [];\n\n /**\n * Whether the component picker popover is open\n */\n @State() private pickerOpen: boolean = false;\n\n /**\n * Reference to the slot element to access assignedNodes\n */\n private slotRef?: HTMLSlotElement;\n\n /**\n * The original slotted element (e.g., <h3 slot=\"header\">)\n */\n private slottedElement?: Element;\n\n /**\n * Emitted when text content changes in admin mode.\n * The event detail contains the new text value and validity.\n */\n @Event() leSlotChange: EventEmitter<{ name: string; value: string; isValid: boolean }>;\n\n private disconnectModeObserver?: () => void;\n\n connectedCallback() {\n this.disconnectModeObserver = observeModeChanges(this.el, mode => {\n const wasAdmin = this.adminMode;\n this.adminMode = mode === 'admin';\n\n // When entering admin mode, read content from slotted elements\n if (this.adminMode && !wasAdmin) {\n // Need to wait for render to access slot ref\n requestAnimationFrame(() => this.readSlottedContent());\n\n // Load available components for the component picker\n if (this.type === 'slot') {\n this.loadAvailableComponents();\n }\n }\n });\n }\n\n disconnectedCallback() {\n this.disconnectModeObserver?.();\n }\n\n /**\n * Flag to prevent re-reading content right after we updated it\n */\n private isUpdating: boolean = false;\n\n /**\n * Read content from slotted elements via assignedNodes()\n */\n private readSlottedContent() {\n if (!this.slotRef) return;\n\n // Skip if we just updated the content ourselves\n if (this.isUpdating) {\n this.isUpdating = false;\n return;\n }\n\n const assignedNodes = this.slotRef.assignedNodes({ flatten: true });\n\n // For text/textarea types, we want to edit the innerHTML of slotted elements\n if (this.type === 'text' || this.type === 'textarea') {\n // Find the first element node (skip text nodes that are just whitespace)\n const elementNode = assignedNodes.find(node => node.nodeType === Node.ELEMENT_NODE) as Element | undefined;\n\n if (elementNode) {\n // Only update textValue if slotted element changed or we don't have one yet\n if (this.slottedElement !== elementNode) {\n this.slottedElement = elementNode;\n this.textValue = elementNode.innerHTML?.trim() || '';\n // console.log(`[le-slot \"${this.name}\"] Read slotted content:`, this.textValue);\n }\n } else {\n // No element, check for direct text content\n const textContent = assignedNodes\n .filter(node => node.nodeType === Node.TEXT_NODE)\n .map(node => node.textContent)\n .join('')\n .trim();\n\n if (textContent && !this.textValue) {\n this.textValue = textContent;\n // console.log(`[le-slot \"${this.name}\"] Read text content:`, this.textValue);\n }\n }\n }\n }\n\n /**\n * Validates if a string contains valid HTML\n */\n private validateHtml(html: string): boolean {\n // Empty string is valid\n if (!html.trim()) return true;\n\n // Create a template element to parse the HTML\n const template = document.createElement('template');\n template.innerHTML = html;\n\n // Check that we don't have obviously broken HTML\n // Count opening and closing tags for common elements\n const openTags = (html.match(/<[a-z][^>]*(?<!\\/)>/gi) || []).length;\n const closeTags = (html.match(/<\\/[a-z][^>]*>/gi) || []).length;\n const selfClosing = (html.match(/<[a-z][^>]*\\/>/gi) || []).length;\n\n // Simple validation: opening tags (minus self-closing) should roughly match closing tags\n // Allow some tolerance for void elements like <br>, <img>, etc.\n const voidElements = (html.match(/<(br|hr|img|input|meta|link|area|base|col|embed|param|source|track|wbr)[^>]*>/gi) || []).length;\n\n const effectiveOpenTags = openTags - selfClosing - voidElements;\n\n // If difference is too large, HTML is likely broken\n if (Math.abs(effectiveOpenTags - closeTags) > 1) {\n return false;\n }\n\n return true;\n }\n\n private handleTextInput = (event: Event) => {\n const target = event.target as HTMLInputElement | HTMLTextAreaElement;\n this.textValue = target.value;\n this.isValidHtml = this.validateHtml(this.textValue);\n\n if (this.isValidHtml) {\n // Set flag to prevent slotchange from re-reading what we just wrote\n this.isUpdating = true;\n\n console.log('Updating text value:', this.textValue, 'slottedElement:', this.slottedElement);\n\n if (this.slottedElement) {\n // Update existing slotted element's innerHTML\n this.slottedElement.innerHTML = this.textValue;\n } else if (this.tag && this.textValue) {\n // No slotted element exists\n // If the slot doesn't have a name, then it's the default slot\n // remove the existing non-slotted content (text nodes and elements without slot attribute)\n const rootNode = this.el.getRootNode();\n if (!this.name && rootNode instanceof ShadowRoot) {\n const hostComponent = rootNode.host;\n Array.from(hostComponent.childNodes).forEach(node => {\n if (node.nodeType === Node.TEXT_NODE || (node.nodeType === Node.ELEMENT_NODE && !(node as Element).hasAttribute('slot'))) {\n node.remove();\n }\n });\n }\n // create one using the specified tag\n this.createSlottedElement();\n } else if (this.textValue) {\n // no tag specified - just replace everything in the host component\n const rootNode = this.el.getRootNode();\n if (rootNode instanceof ShadowRoot) {\n const hostComponent = rootNode.host;\n hostComponent.innerHTML = this.textValue;\n }\n }\n }\n\n this.leSlotChange.emit({\n name: this.name,\n value: this.textValue,\n isValid: this.isValidHtml,\n });\n };\n\n /**\n * Create a new slotted element when none exists.\n * The element is appended to the host component's light DOM.\n */\n private createSlottedElement() {\n if (!this.tag) return;\n\n // Find the host component (le-card, etc.) by traversing up through shadow DOM\n // le-slot is inside le-card's shadow DOM, so we need to find le-card's host\n const rootNode = this.el.getRootNode();\n if (!(rootNode instanceof ShadowRoot)) return;\n\n const hostComponent = rootNode.host;\n if (!hostComponent) return;\n\n // Create the new element\n const newElement = document.createElement(this.tag);\n newElement.innerHTML = this.textValue;\n\n // Set the slot attribute if this is a named slot\n if (this.name) {\n newElement.setAttribute('slot', this.name);\n }\n\n // Append to the host component's light DOM\n hostComponent.appendChild(newElement);\n\n // Store reference to the new element\n this.slottedElement = newElement;\n\n // console.log(`[le-slot \"${this.name}\"] Created new <${this.tag}> element`);\n }\n\n /**\n * Load available components from Custom Elements Manifest\n */\n private async loadAvailableComponents() {\n try {\n const { manifestUrl } = getLeKitConfig();\n const response = await fetch(manifestUrl);\n const manifest = await response.json();\n\n const components: ComponentInfo[] = [];\n const allowedList = this.allowedComponents?.split(',').map(s => s.trim()) || [];\n\n for (const module of manifest.modules) {\n for (const declaration of module.declarations || []) {\n if (declaration.tagName && declaration.customElement) {\n // Skip internal components (le-slot, le-component, le-popover)\n const isInternal = ['le-slot', 'le-component', 'le-popover'].includes(declaration.tagName);\n if (isInternal) continue;\n\n // If allowedComponents is specified, filter by it\n if (allowedList.length > 0 && !allowedList.includes(declaration.tagName)) {\n continue;\n }\n\n components.push({\n tagName: declaration.tagName,\n name: this.formatComponentName(declaration.tagName),\n description: declaration.description || '',\n });\n }\n }\n }\n\n this.availableComponents = components || [];\n } catch (error) {\n console.warn('[le-slot] Failed to load component manifest:', error);\n }\n }\n\n /**\n * Format a tag name into a display name\n * e.g., 'le-card' -> 'Card'\n */\n private formatComponentName(tagName: string): string {\n return tagName\n .replace(/^le-/, '')\n .split('-')\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n }\n\n /**\n * Add a new component to the slot\n */\n private addComponent(tagName: string) {\n // Find the host component by traversing up through shadow DOM\n const rootNode = this.el.getRootNode();\n if (!(rootNode instanceof ShadowRoot)) return;\n\n const hostComponent = rootNode.host;\n if (!hostComponent) return;\n\n // Create the new component element\n const newElement = document.createElement(tagName);\n\n // Set the slot attribute if this is a named slot\n if (this.name) {\n newElement.setAttribute('slot', this.name);\n }\n\n // Append to the host component's light DOM\n hostComponent.appendChild(newElement);\n\n // Emit change event so the page can save\n this.leSlotChange.emit({\n name: this.name,\n value: hostComponent.innerHTML,\n isValid: true,\n });\n }\n\n /**\n * Handle slot change event to re-read content when nodes are assigned\n */\n private handleSlotChange = () => {\n this.readSlottedContent();\n };\n\n render() {\n const displayLabel = this.label || this.name;\n\n // Always render the same structure, CSS handles visibility via .admin-mode class\n return (\n <Host\n class={{\n 'admin-mode': this.adminMode,\n 'invalid-html': !this.isValidHtml,\n }}\n role={this.adminMode ? 'region' : undefined}\n aria-label={this.adminMode ? `Slot: ${displayLabel}` : undefined}\n data-slot-name={this.name}\n data-slot-type={this.type}\n data-allowed={this.allowedComponents}\n data-multiple={this.multiple}\n data-required={this.required}\n >\n {this.adminMode ? (\n <div class=\"le-slot-container\">\n <div\n class={classnames('le-slot-header', {\n 'le-slot-header-no-label': !displayLabel,\n 'le-slot-header-text': this.type === 'text',\n 'le-slot-header-error': !this.isValidHtml,\n })}\n >\n {displayLabel && (\n <span class=\"le-slot-label\">\n {displayLabel}\n {this.required && <span class=\"le-slot-required\">*</span>}\n </span>\n )}\n {/* {this.description && <le-popover mode=\"default\" showClose={false} align=\"end\" position=\"bottom\">\n <span slot=\"trigger\" class=\"le-slot-description-icon\">ℹ️</span>\n {this.description}\n </le-popover>} */}\n {!this.isValidHtml && <span class=\"le-slot-invalid\">⚠ Invalid HTML</span>}\n {this.type === 'slot' && this.adminMode && (\n <le-popover\n mode=\"default\"\n showClose={true}\n align=\"start\"\n position=\"right\"\n popoverTitle=\"Add Component\"\n open={this.pickerOpen}\n onLePopoverOpen={() => (this.pickerOpen = true)}\n onLePopoverClose={() => (this.pickerOpen = false)}\n >\n <le-button type=\"button\" class=\"le-slot-button\" slot=\"trigger\" variant=\"clear\" size=\"small\" aria-label=\"Add component\" icon-only>\n <span class=\"le-slot-add-btn\" slot=\"icon-only\">\n +\n </span>\n </le-button>\n <div class=\"le-slot-picker\">\n {this.availableComponents.length > 0 ? (\n <ul class=\"le-slot-picker-list\">\n {this.availableComponents.map(component => (\n <li key={component.tagName}>\n <button\n class=\"le-slot-picker-item\"\n onClick={() => {\n this.addComponent(component.tagName);\n this.pickerOpen = false;\n }}\n >\n <span class=\"le-slot-picker-name\">{component.name}</span>\n {component.description && <span class=\"le-slot-picker-desc\">{component.description}</span>}\n </button>\n </li>\n ))}\n </ul>\n ) : (\n <div class=\"le-slot-picker-empty\">No components available</div>\n )}\n </div>\n </le-popover>\n )}\n </div>\n {this.renderContent()}\n </div>\n ) : (\n // In default mode, just pass through the slot - slotted content renders naturally\n // Note: We use unnamed slot here because named slots from parent component\n // are passed as le-slot's light DOM children\n <slot\n // ref={(el) => this.slotRef = el as HTMLSlotElement}\n // onSlotchange={this.handleSlotChange}\n ></slot>\n )}\n </Host>\n );\n }\n\n private renderContent() {\n // Create the slot element with ref for reading assignedNodes\n // Wrap in a hidden div since slot elements can't have style prop in Stencil\n // Note: We use unnamed slot here because named slots from parent component\n // are passed as le-slot's light DOM children\n const slotElement = (\n <div class=\"hidden-slot\">\n <slot ref={el => (this.slotRef = el as HTMLSlotElement)} onSlotchange={this.handleSlotChange}></slot>\n </div>\n );\n\n switch (this.type) {\n case 'text':\n return (\n <div class={{ 'le-slot-input': true, 'has-error': !this.isValidHtml }}>\n <le-string-input\n mode=\"default\"\n value={this.textValue}\n placeholder={this.placeholder || `Enter ${this.label || this.name || 'text'}...`}\n onChange={this.handleTextInput}\n // required={this.required}\n ></le-string-input>\n {slotElement}\n </div>\n );\n\n case 'textarea':\n return (\n <div class={{ 'le-slot-input': true, 'has-error': !this.isValidHtml }}>\n <textarea\n value={this.textValue}\n placeholder={this.placeholder || `Enter ${this.label || this.name || 'text'}...`}\n onInput={this.handleTextInput}\n required={this.required}\n rows={3}\n ></textarea>\n {slotElement}\n </div>\n );\n\n case 'slot':\n default:\n // Parse slotStyle string into style object if provided\n const dropzoneStyle: { [key: string]: string } = {};\n if (this.slotStyle) {\n this.slotStyle.split(';').forEach(rule => {\n const [prop, value] = rule.split(':').map(s => s.trim());\n if (prop && value) {\n // Convert kebab-case to camelCase for style object\n const camelProp = prop.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());\n dropzoneStyle[camelProp] = value;\n }\n });\n }\n return (\n <div class=\"le-slot-dropzone\" style={dropzoneStyle}>\n <slot ref={el => (this.slotRef = el as HTMLSlotElement)} onSlotchange={this.handleSlotChange}></slot>\n </div>\n );\n }\n }\n}\n\n/**\n * Component info from the manifest\n */\ninterface ComponentInfo {\n tagName: string;\n name: string;\n description: string;\n}\n"]}
1
+ {"version":3,"file":"le-slot.js","sourceRoot":"","sources":["../../../src/components/le-slot/le-slot.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Component, Prop, State, h, Host, Element, Event, EventEmitter, getAssetPath } from '@stencil/core';\nimport { classnames, observeModeChanges } from '../../utils/utils';\nimport { getLeKitConfig } from '../../global/app';\n\n/**\n * Slot placeholder component for admin/CMS mode.\n *\n * This component renders a visual placeholder for slots when in admin mode,\n * allowing CMS systems to show available drop zones for content or inline editing.\n *\n * In non-admin mode, this component renders nothing and acts as a passthrough.\n *\n * @slot - Default slot for placeholder content or drop zone UI\n *\n * @cmsInternal true\n * @cmsCategory System\n */\n@Component({\n tag: 'le-slot',\n styleUrl: 'le-slot.default.css',\n shadow: true,\n})\nexport class LeSlot {\n @Element() el: HTMLElement;\n\n /**\n * The type of slot content.\n * - `slot`: Default, shows a dropzone for components (default)\n * - `text`: Shows a single-line text input\n * - `textarea`: Shows a multi-line text area\n */\n @Prop() type: 'slot' | 'text' | 'textarea' = 'slot';\n\n /**\n * The name of the slot this placeholder represents.\n * Should match the slot name in the parent component.\n */\n @Prop() name: string = '';\n\n /**\n * Label to display in admin mode.\n * If not provided, the slot name will be used.\n */\n @Prop() label?: string;\n\n /**\n * Description of what content this slot accepts.\n * Shown in admin mode to guide content editors.\n */\n @Prop() description?: string;\n\n /**\n * Comma-separated list of allowed component tags for this slot.\n * Used by CMS to filter available components.\n *\n * @example \"le-card,le-button,le-text\"\n */\n @Prop() allowedComponents?: string;\n\n /**\n * Whether multiple components can be dropped in this slot.\n */\n @Prop() multiple: boolean = true;\n\n /**\n * Whether this slot is required to have content.\n */\n @Prop() required: boolean = false;\n\n /**\n * Placeholder text for text/textarea inputs in admin mode.\n */\n @Prop() placeholder?: string;\n\n /**\n * The HTML tag to create when there's no slotted element.\n * Used with type=\"text\" or type=\"textarea\" to auto-create elements.\n *\n * @example \"h3\" - creates <h3 slot=\"header\">content</h3>\n * @example \"p\" - creates <p slot=\"content\">content</p>\n */\n @Prop() tag?: string;\n\n /**\n * CSS styles for the slot dropzone container.\n * Useful for layouts - e.g., \"flex-direction: row\" for horizontal stacks.\n * Only applies in admin mode for type=\"slot\".\n */\n @Prop() slotStyle?: string;\n\n /**\n * Internal state to track admin mode\n */\n @State() private adminMode: boolean = false;\n\n /**\n * Internal state for text input value (synced from slot content)\n */\n @State() private textValue: string = '';\n\n /**\n * Whether the current textValue contains valid HTML\n */\n @State() private isValidHtml: boolean = true;\n\n /**\n * Available components loaded from Custom Elements Manifest\n */\n @State() private availableComponents: ComponentInfo[] = [];\n\n /**\n * Whether the component picker popover is open\n */\n @State() private pickerOpen: boolean = false;\n\n /**\n * Reference to the slot element to access assignedNodes\n */\n private slotRef?: HTMLSlotElement;\n\n /**\n * The original slotted element (e.g., <h3 slot=\"header\">)\n */\n private slottedElement?: Element;\n\n /**\n * Emitted when text content changes in admin mode.\n * The event detail contains the new text value and validity.\n */\n @Event() leSlotChange: EventEmitter<{ name: string; value: string; isValid: boolean }>;\n\n private disconnectModeObserver?: () => void;\n\n connectedCallback() {\n this.disconnectModeObserver = observeModeChanges(this.el, mode => {\n const wasAdmin = this.adminMode;\n this.adminMode = mode === 'admin';\n\n // When entering admin mode, read content from slotted elements\n if (this.adminMode && !wasAdmin) {\n // Need to wait for render to access slot ref\n requestAnimationFrame(() => this.readSlottedContent());\n\n // Load available components for the component picker\n if (this.type === 'slot') {\n this.loadAvailableComponents();\n }\n }\n });\n }\n\n disconnectedCallback() {\n this.disconnectModeObserver?.();\n }\n\n /**\n * Flag to prevent re-reading content right after we updated it\n */\n private isUpdating: boolean = false;\n\n /**\n * Read content from slotted elements via assignedNodes()\n */\n private readSlottedContent() {\n if (!this.slotRef) return;\n\n // Skip if we just updated the content ourselves\n if (this.isUpdating) {\n this.isUpdating = false;\n return;\n }\n\n const assignedNodes = this.slotRef.assignedNodes({ flatten: true });\n\n // For text/textarea types, we want to edit the innerHTML of slotted elements\n if (this.type === 'text' || this.type === 'textarea') {\n // Find the first element node (skip text nodes that are just whitespace)\n const elementNode = assignedNodes.find(node => node.nodeType === Node.ELEMENT_NODE) as Element | undefined;\n\n if (elementNode) {\n // Only update textValue if slotted element changed or we don't have one yet\n if (this.slottedElement !== elementNode) {\n this.slottedElement = elementNode;\n this.textValue = elementNode.innerHTML?.trim() || '';\n // console.log(`[le-slot \"${this.name}\"] Read slotted content:`, this.textValue);\n }\n } else {\n // No element, check for direct text content\n const textContent = assignedNodes\n .filter(node => node.nodeType === Node.TEXT_NODE)\n .map(node => node.textContent)\n .join('')\n .trim();\n\n if (textContent && !this.textValue) {\n this.textValue = textContent;\n // console.log(`[le-slot \"${this.name}\"] Read text content:`, this.textValue);\n }\n }\n }\n }\n\n /**\n * Validates if a string contains valid HTML\n */\n private validateHtml(html: string): boolean {\n // Empty string is valid\n if (!html.trim()) return true;\n\n // Create a template element to parse the HTML\n const template = document.createElement('template');\n template.innerHTML = html;\n\n // Check that we don't have obviously broken HTML\n // Count opening and closing tags for common elements\n const openTags = (html.match(/<[a-z][^>]*(?<!\\/)>/gi) || []).length;\n const closeTags = (html.match(/<\\/[a-z][^>]*>/gi) || []).length;\n const selfClosing = (html.match(/<[a-z][^>]*\\/>/gi) || []).length;\n\n // Simple validation: opening tags (minus self-closing) should roughly match closing tags\n // Allow some tolerance for void elements like <br>, <img>, etc.\n const voidElements = (html.match(/<(br|hr|img|input|meta|link|area|base|col|embed|param|source|track|wbr)[^>]*>/gi) || []).length;\n\n const effectiveOpenTags = openTags - selfClosing - voidElements;\n\n // If difference is too large, HTML is likely broken\n if (Math.abs(effectiveOpenTags - closeTags) > 1) {\n return false;\n }\n\n return true;\n }\n\n private handleTextInput = (event: Event) => {\n const target = event.target as HTMLInputElement | HTMLTextAreaElement;\n this.textValue = target.value;\n this.isValidHtml = this.validateHtml(this.textValue);\n\n if (this.isValidHtml) {\n // Set flag to prevent slotchange from re-reading what we just wrote\n this.isUpdating = true;\n\n console.log('Updating text value:', this.textValue, 'slottedElement:', this.slottedElement);\n\n if (this.slottedElement) {\n // Update existing slotted element's innerHTML\n this.slottedElement.innerHTML = this.textValue;\n } else if (this.tag && this.textValue) {\n // No slotted element exists\n // If the slot doesn't have a name, then it's the default slot\n // remove the existing non-slotted content (text nodes and elements without slot attribute)\n const rootNode = this.el.getRootNode();\n if (!this.name && rootNode instanceof ShadowRoot) {\n const hostComponent = rootNode.host;\n Array.from(hostComponent.childNodes).forEach(node => {\n if (node.nodeType === Node.TEXT_NODE || (node.nodeType === Node.ELEMENT_NODE && !(node as Element).hasAttribute('slot'))) {\n node.remove();\n }\n });\n }\n // create one using the specified tag\n this.createSlottedElement();\n } else if (this.textValue) {\n // no tag specified - just replace everything in the host component\n const rootNode = this.el.getRootNode();\n if (rootNode instanceof ShadowRoot) {\n const hostComponent = rootNode.host;\n hostComponent.innerHTML = this.textValue;\n }\n }\n }\n\n this.leSlotChange.emit({\n name: this.name,\n value: this.textValue,\n isValid: this.isValidHtml,\n });\n };\n\n /**\n * Create a new slotted element when none exists.\n * The element is appended to the host component's light DOM.\n */\n private createSlottedElement() {\n if (!this.tag) return;\n\n // Find the host component (le-card, etc.) by traversing up through shadow DOM\n // le-slot is inside le-card's shadow DOM, so we need to find le-card's host\n const rootNode = this.el.getRootNode();\n if (!(rootNode instanceof ShadowRoot)) return;\n\n const hostComponent = rootNode.host;\n if (!hostComponent) return;\n\n // Create the new element\n const newElement = document.createElement(this.tag);\n newElement.innerHTML = this.textValue;\n\n // Set the slot attribute if this is a named slot\n if (this.name) {\n newElement.setAttribute('slot', this.name);\n }\n\n // Append to the host component's light DOM\n hostComponent.appendChild(newElement);\n\n // Store reference to the new element\n this.slottedElement = newElement;\n\n // console.log(`[le-slot \"${this.name}\"] Created new <${this.tag}> element`);\n }\n\n /**\n * Load available components from Custom Elements Manifest\n */\n private async loadAvailableComponents() {\n try {\n const { manifestUrl } = getLeKitConfig();\n const manifestUrlResolved = manifestUrl.startsWith('/')\n ? getAssetPath(`./assets${manifestUrl}`)\n : manifestUrl;\n const response = await fetch(manifestUrlResolved);\n const manifest = await response.json();\n\n const components: ComponentInfo[] = [];\n const allowedList = this.allowedComponents?.split(',').map(s => s.trim()) || [];\n\n for (const module of manifest.modules) {\n for (const declaration of module.declarations || []) {\n if (declaration.tagName && declaration.customElement) {\n // Skip internal components (le-slot, le-component, le-popover)\n const isInternal = ['le-slot', 'le-component', 'le-popover'].includes(declaration.tagName);\n if (isInternal) continue;\n\n // If allowedComponents is specified, filter by it\n if (allowedList.length > 0 && !allowedList.includes(declaration.tagName)) {\n continue;\n }\n\n components.push({\n tagName: declaration.tagName,\n name: this.formatComponentName(declaration.tagName),\n description: declaration.description || '',\n });\n }\n }\n }\n\n this.availableComponents = components || [];\n } catch (error) {\n console.warn('[le-slot] Failed to load component manifest:', error);\n }\n }\n\n /**\n * Format a tag name into a display name\n * e.g., 'le-card' -> 'Card'\n */\n private formatComponentName(tagName: string): string {\n return tagName\n .replace(/^le-/, '')\n .split('-')\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n }\n\n /**\n * Add a new component to the slot\n */\n private addComponent(tagName: string) {\n // Find the host component by traversing up through shadow DOM\n const rootNode = this.el.getRootNode();\n if (!(rootNode instanceof ShadowRoot)) return;\n\n const hostComponent = rootNode.host;\n if (!hostComponent) return;\n\n // Create the new component element\n const newElement = document.createElement(tagName);\n\n // Set the slot attribute if this is a named slot\n if (this.name) {\n newElement.setAttribute('slot', this.name);\n }\n\n // Append to the host component's light DOM\n hostComponent.appendChild(newElement);\n\n // Emit change event so the page can save\n this.leSlotChange.emit({\n name: this.name,\n value: hostComponent.innerHTML,\n isValid: true,\n });\n }\n\n /**\n * Handle slot change event to re-read content when nodes are assigned\n */\n private handleSlotChange = () => {\n this.readSlottedContent();\n };\n\n render() {\n const displayLabel = this.label || this.name;\n\n // Always render the same structure, CSS handles visibility via .admin-mode class\n return (\n <Host\n class={{\n 'admin-mode': this.adminMode,\n 'invalid-html': !this.isValidHtml,\n }}\n role={this.adminMode ? 'region' : undefined}\n aria-label={this.adminMode ? `Slot: ${displayLabel}` : undefined}\n data-slot-name={this.name}\n data-slot-type={this.type}\n data-allowed={this.allowedComponents}\n data-multiple={this.multiple}\n data-required={this.required}\n >\n {this.adminMode ? (\n <div class=\"le-slot-container\">\n <div\n class={classnames('le-slot-header', {\n 'le-slot-header-no-label': !displayLabel,\n 'le-slot-header-text': this.type === 'text',\n 'le-slot-header-error': !this.isValidHtml,\n })}\n >\n {displayLabel && (\n <span class=\"le-slot-label\">\n {displayLabel}\n {this.required && <span class=\"le-slot-required\">*</span>}\n </span>\n )}\n {/* {this.description && <le-popover mode=\"default\" showClose={false} align=\"end\" position=\"bottom\">\n <span slot=\"trigger\" class=\"le-slot-description-icon\">ℹ️</span>\n {this.description}\n </le-popover>} */}\n {!this.isValidHtml && <span class=\"le-slot-invalid\">⚠ Invalid HTML</span>}\n {this.type === 'slot' && this.adminMode && (\n <le-popover\n mode=\"default\"\n showClose={true}\n align=\"start\"\n position=\"right\"\n popoverTitle=\"Add Component\"\n open={this.pickerOpen}\n onLePopoverOpen={() => (this.pickerOpen = true)}\n onLePopoverClose={() => (this.pickerOpen = false)}\n >\n <le-button type=\"button\" class=\"le-slot-button\" slot=\"trigger\" variant=\"clear\" size=\"small\" aria-label=\"Add component\" icon-only>\n <span class=\"le-slot-add-btn\" slot=\"icon-only\">\n +\n </span>\n </le-button>\n <div class=\"le-slot-picker\">\n {this.availableComponents.length > 0 ? (\n <ul class=\"le-slot-picker-list\">\n {this.availableComponents.map(component => (\n <li key={component.tagName}>\n <button\n class=\"le-slot-picker-item\"\n onClick={() => {\n this.addComponent(component.tagName);\n this.pickerOpen = false;\n }}\n >\n <span class=\"le-slot-picker-name\">{component.name}</span>\n {component.description && <span class=\"le-slot-picker-desc\">{component.description}</span>}\n </button>\n </li>\n ))}\n </ul>\n ) : (\n <div class=\"le-slot-picker-empty\">No components available</div>\n )}\n </div>\n </le-popover>\n )}\n </div>\n {this.renderContent()}\n </div>\n ) : (\n // In default mode, just pass through the slot - slotted content renders naturally\n // Note: We use unnamed slot here because named slots from parent component\n // are passed as le-slot's light DOM children\n <slot\n // ref={(el) => this.slotRef = el as HTMLSlotElement}\n // onSlotchange={this.handleSlotChange}\n ></slot>\n )}\n </Host>\n );\n }\n\n private renderContent() {\n // Create the slot element with ref for reading assignedNodes\n // Wrap in a hidden div since slot elements can't have style prop in Stencil\n // Note: We use unnamed slot here because named slots from parent component\n // are passed as le-slot's light DOM children\n const slotElement = (\n <div class=\"hidden-slot\">\n <slot ref={el => (this.slotRef = el as HTMLSlotElement)} onSlotchange={this.handleSlotChange}></slot>\n </div>\n );\n\n switch (this.type) {\n case 'text':\n return (\n <div class={{ 'le-slot-input': true, 'has-error': !this.isValidHtml }}>\n <le-string-input\n mode=\"default\"\n value={this.textValue}\n placeholder={this.placeholder || `Enter ${this.label || this.name || 'text'}...`}\n onChange={this.handleTextInput}\n // required={this.required}\n ></le-string-input>\n {slotElement}\n </div>\n );\n\n case 'textarea':\n return (\n <div class={{ 'le-slot-input': true, 'has-error': !this.isValidHtml }}>\n <textarea\n value={this.textValue}\n placeholder={this.placeholder || `Enter ${this.label || this.name || 'text'}...`}\n onInput={this.handleTextInput}\n required={this.required}\n rows={3}\n ></textarea>\n {slotElement}\n </div>\n );\n\n case 'slot':\n default:\n // Parse slotStyle string into style object if provided\n const dropzoneStyle: { [key: string]: string } = {};\n if (this.slotStyle) {\n this.slotStyle.split(';').forEach(rule => {\n const [prop, value] = rule.split(':').map(s => s.trim());\n if (prop && value) {\n // Convert kebab-case to camelCase for style object\n const camelProp = prop.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());\n dropzoneStyle[camelProp] = value;\n }\n });\n }\n return (\n <div class=\"le-slot-dropzone\" style={dropzoneStyle}>\n <slot ref={el => (this.slotRef = el as HTMLSlotElement)} onSlotchange={this.handleSlotChange}></slot>\n </div>\n );\n }\n }\n}\n\n/**\n * Component info from the manifest\n */\ninterface ComponentInfo {\n tagName: string;\n name: string;\n description: string;\n}\n"]}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Le-Kit Base Design Tokens
3
+ *
4
+ * Structural tokens that rarely change between themes:
5
+ * - Spacing scale
6
+ * - Typography (font families, sizes, weights, line heights)
7
+ * - Transitions
8
+ * - Z-index layers
9
+ *
10
+ * Import this file along with a theme file (default.css, dark.css, etc.)
11
+ */
12
+
13
+ :root {
14
+ -webkit-font-smoothing: antialiased;
15
+ -moz-osx-font-smoothing: grayscale;
16
+
17
+ /* ============================================
18
+ * SPACING SCALE
19
+ * ============================================ */
20
+ --le-spacing-0: 0;
21
+ --le-spacing-1: 0.25rem; /* 4px */
22
+ --le-spacing-2: 0.5rem; /* 8px */
23
+ --le-spacing-3: 0.75rem; /* 12px */
24
+ --le-spacing-4: 1rem; /* 16px */
25
+ --le-spacing-5: 1.25rem; /* 20px */
26
+ --le-spacing-6: 1.5rem; /* 24px */
27
+ --le-spacing-8: 2rem; /* 32px */
28
+ --le-spacing-10: 2.5rem; /* 40px */
29
+ --le-spacing-12: 3rem; /* 48px */
30
+ --le-spacing-16: 4rem; /* 64px */
31
+
32
+ /* ============================================
33
+ * TYPOGRAPHY
34
+ * ============================================ */
35
+ --le-font-family-base: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
36
+ --le-font-family-mono: 'SF Mono', 'Monaco', 'Inconsolata', 'Fira Code', monospace;
37
+
38
+ /* Font sizes */
39
+ --le-font-size-xs: 0.75rem; /* 12px */
40
+ --le-font-size-sm: 0.875rem; /* 14px */
41
+ --le-font-size-md: 1rem; /* 16px */
42
+ --le-font-size-lg: 1.125rem; /* 18px */
43
+ --le-font-size-xl: 1.25rem; /* 20px */
44
+ --le-font-size-2xl: 1.5rem; /* 24px */
45
+ --le-font-size-3xl: 1.875rem; /* 30px */
46
+ --le-font-size-4xl: 2.25rem; /* 36px */
47
+
48
+ /* Font weights */
49
+ --le-font-weight-normal: 400;
50
+ --le-font-weight-medium: 500;
51
+ --le-font-weight-semibold: 600;
52
+ --le-font-weight-bold: 700;
53
+
54
+ /* Line heights */
55
+ --le-line-height-tight: 1.25;
56
+ --le-line-height-normal: 1.5;
57
+ --le-line-height-relaxed: 1.75;
58
+
59
+ /* ============================================
60
+ * RADIUSES
61
+ * ============================================ */
62
+ --le-radius-none: 0;
63
+ --le-radius-xs: 0.066rem; /* 1px */
64
+ --le-radius-sm: 0.125rem; /* 2px */
65
+ --le-radius-md: 0.25rem; /* 4px */
66
+ --le-radius-lg: 0.5rem; /* 8px */
67
+ --le-radius-xl: 0.75rem; /* 12px */
68
+ --le-radius-2xl: 1rem; /* 16px */
69
+ --le-radius-full: 9999px;
70
+
71
+ /* ============================================
72
+ * TRANSITIONS
73
+ * ============================================ */
74
+ --le-transition-fast: 100ms;
75
+ --le-transition-normal: 200ms;
76
+ --le-transition-slow: 300ms;
77
+ --le-transition-easing: cubic-bezier(0.4, 0, 0.2, 1);
78
+
79
+ /* ============================================
80
+ * Z-INDEX LAYERS
81
+ * ============================================ */
82
+ --le-z-dropdown: 1000;
83
+ --le-z-sticky: 1020;
84
+ --le-z-fixed: 1030;
85
+ --le-z-modal-backdrop: 1040;
86
+ --le-z-modal: 1050;
87
+ --le-z-popover: 1060;
88
+ --le-z-tooltip: 1070;
89
+ }
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Le-Kit Dark Theme
3
+ *
4
+ * Dark mode with light text on dark backgrounds.
5
+ *
6
+ * Usage: set theme="dark" on any element, or import as your default.
7
+ */
8
+
9
+ [theme="dark"] {
10
+ /* Primary brand color - lighter for dark backgrounds */
11
+ --le-color-primary: #4da6ff;
12
+ --le-color-primary-light: #80c1ff;
13
+ --le-color-primary-dark: #0088ff;
14
+ --le-color-primary-contrast: #000000;
15
+
16
+ /* Secondary accent color */
17
+ --le-color-secondary: #868e96;
18
+ --le-color-secondary-light: #adb5bd;
19
+ --le-color-secondary-dark: #6c757d;
20
+ --le-color-secondary-contrast: #000000;
21
+
22
+ /* Semantic colors - adjusted for dark mode */
23
+ --le-color-success: #48c764;
24
+ --le-color-success-light: #6dd587;
25
+ --le-color-success-dark: #28a745;
26
+ --le-color-success-contrast: #000000;
27
+
28
+ --le-color-warning: #ffcd39;
29
+ --le-color-warning-light: #ffda6a;
30
+ --le-color-warning-dark: #ffc107;
31
+ --le-color-warning-contrast: #000000;
32
+
33
+ --le-color-danger: #e4606d;
34
+ --le-color-danger-light: #ea868f;
35
+ --le-color-danger-dark: #dc3545;
36
+ --le-color-danger-contrast: #000000;
37
+
38
+ --le-color-info: #3ab0c3;
39
+ --le-color-info-light: #6dc4d3;
40
+ --le-color-info-dark: #17a2b8;
41
+ --le-color-info-contrast: #000000;
42
+
43
+ /* Neutral colors - inverted */
44
+ --le-color-white: #ffffff;
45
+ --le-color-black: #000000;
46
+ --le-color-gray-50: #212121;
47
+ --le-color-gray-100: #424242;
48
+ --le-color-gray-200: #616161;
49
+ --le-color-gray-300: #757575;
50
+ --le-color-gray-400: #9e9e9e;
51
+ --le-color-gray-500: #bdbdbd;
52
+ --le-color-gray-600: #e0e0e0;
53
+ --le-color-gray-700: #eeeeee;
54
+ --le-color-gray-800: #f5f5f5;
55
+ --le-color-gray-900: #fafafa;
56
+
57
+ /* Background colors */
58
+ --le-color-background: #121212;
59
+ --le-color-background-secondary: #1e1e1e;
60
+ --le-color-background-tertiary: #2d2d2d;
61
+
62
+ /* Surface colors */
63
+ --le-color-surface: #1e1e1e;
64
+ --le-color-surface-elevated: #2d2d2d;
65
+
66
+ /* Text colors */
67
+ --le-color-text-primary: #ffffff;
68
+ --le-color-text-secondary: #b3b3b3;
69
+ --le-color-text-disabled: #666666;
70
+ --le-color-text-inverse: #121212;
71
+
72
+ /* Border colors */
73
+ --le-color-border: #333333;
74
+ --le-color-border-light: #2d2d2d;
75
+ --le-color-border-dark: #444444;
76
+
77
+ /** Input borders */
78
+ --le-border-width: 2px;
79
+ --le-color-border-input: #515c6b;
80
+
81
+ /* Focus ring */
82
+ --le-color-focus: rgba(77, 166, 255, 0.5);
83
+
84
+ /* Border radius - same as default */
85
+ --le-radius-none: 0;
86
+ --le-radius-sm: 0.125rem;
87
+ --le-radius-md: 0.25rem;
88
+ --le-radius-lg: 0.5rem;
89
+ --le-radius-xl: 0.75rem;
90
+ --le-radius-2xl: 1rem;
91
+ --le-radius-full: 9999px;
92
+
93
+ /* Shadows - darker for dark mode */
94
+ --le-shadow-none: none;
95
+ --le-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
96
+ --le-shadow-md: 0 1px 3px rgba(0, 0, 0, 0.4), 0 1px 2px rgba(0, 0, 0, 0.3);
97
+ --le-shadow-lg: 0 4px 6px rgba(0, 0, 0, 0.4), 0 2px 4px rgba(0, 0, 0, 0.3);
98
+ --le-shadow-xl: 0 10px 15px rgba(0, 0, 0, 0.4), 0 4px 6px rgba(0, 0, 0, 0.3);
99
+ --le-shadow-2xl: 0 20px 25px rgba(0, 0, 0, 0.4), 0 10px 10px rgba(0, 0, 0, 0.3);
100
+ }
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Le-Kit Default Theme
3
+ *
4
+ * Clean, professional light theme with blue primary color.
5
+ *
6
+ * Usage:
7
+ * 1. As default: import alongside base.css
8
+ * 2. For switching: set theme="default" on any element
9
+ *
10
+ * To create a custom theme:
11
+ * 1. Copy this file
12
+ * 2. Change selector to :root or [theme="your-theme"]
13
+ * 3. Modify the variables you need
14
+ */
15
+
16
+ :root,
17
+ [theme="default"] {
18
+ /* Primary brand color */
19
+ --le-color-primary: #0088ff;
20
+ --le-color-primary-light: #4da6ff;
21
+ --le-color-primary-dark: #0066cc;
22
+ --le-color-primary-contrast: #ffffff;
23
+
24
+ /* Secondary accent color */
25
+ --le-color-secondary: #6c757d;
26
+ --le-color-secondary-light: #868e96;
27
+ --le-color-secondary-dark: #545b62;
28
+ --le-color-secondary-contrast: #ffffff;
29
+
30
+ /* Semantic colors */
31
+ --le-color-success: #28a745;
32
+ --le-color-success-light: #48c764;
33
+ --le-color-success-dark: #1e7e34;
34
+ --le-color-success-contrast: #ffffff;
35
+
36
+ --le-color-warning: #ffc107;
37
+ --le-color-warning-light: #ffcd39;
38
+ --le-color-warning-dark: #d39e00;
39
+ --le-color-warning-contrast: #212529;
40
+
41
+ --le-color-danger: #dc3545;
42
+ --le-color-danger-light: #e4606d;
43
+ --le-color-danger-dark: #bd2130;
44
+ --le-color-danger-contrast: #ffffff;
45
+
46
+ --le-color-info: #17a2b8;
47
+ --le-color-info-light: #3ab0c3;
48
+ --le-color-info-dark: #117a8b;
49
+ --le-color-info-contrast: #ffffff;
50
+
51
+ /* Neutral colors */
52
+ --le-color-white: #ffffff;
53
+ --le-color-black: #000000;
54
+ --le-color-gray-50: #fafafa;
55
+ --le-color-gray-100: #f5f5f5;
56
+ --le-color-gray-200: #eeeeee;
57
+ --le-color-gray-300: #e0e0e0;
58
+ --le-color-gray-400: #bdbdbd;
59
+ --le-color-gray-500: #9e9e9e;
60
+ --le-color-gray-600: #757575;
61
+ --le-color-gray-700: #616161;
62
+ --le-color-gray-800: #424242;
63
+ --le-color-gray-900: #212121;
64
+
65
+ /* Background colors */
66
+ --le-color-background: #ffffff;
67
+ --le-color-background-secondary: #f5f5f5;
68
+ --le-color-background-tertiary: #eeeeee;
69
+
70
+ /* Surface colors (cards, modals, etc.) */
71
+ --le-color-surface: #ffffff;
72
+ --le-color-surface-elevated: #ffffff;
73
+
74
+ /* Text colors */
75
+ --le-color-text-primary: #212121;
76
+ --le-color-text-secondary: #757575;
77
+ --le-color-text-disabled: #9e9e9e;
78
+ --le-color-text-inverse: #ffffff;
79
+
80
+ /* Border colors */
81
+ --le-color-border: #e0e0e0;
82
+ --le-color-border-light: #eeeeee;
83
+ --le-color-border-dark: #bdbdbd;
84
+
85
+ /** Input borders */
86
+ --le-border-width: 2px;
87
+ --le-color-border-input: #c4d6e6;
88
+
89
+ /* Focus ring */
90
+ --le-color-focus: rgba(0, 136, 255, 0.5);
91
+
92
+ /* Border radius */
93
+ --le-radius-none: 0;
94
+ --le-radius-sm: 0.125rem; /* 2px */
95
+ --le-radius-md: 0.25rem; /* 4px */
96
+ --le-radius-lg: 0.5rem; /* 8px */
97
+ --le-radius-xl: 0.75rem; /* 12px */
98
+ --le-radius-2xl: 1rem; /* 16px */
99
+ --le-radius-full: 9999px;
100
+
101
+ /* Shadows */
102
+ --le-shadow-none: none;
103
+ --le-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
104
+ --le-shadow-md: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06);
105
+ --le-shadow-lg: 0 4px 6px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.06);
106
+ --le-shadow-xl: 0 10px 15px rgba(0, 0, 0, 0.1), 0 4px 6px rgba(0, 0, 0, 0.05);
107
+ --le-shadow-2xl: 0 20px 25px rgba(0, 0, 0, 0.1), 0 10px 10px rgba(0, 0, 0, 0.04);
108
+ }