luxen-ui 0.6.2 → 0.8.0

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 (270) hide show
  1. package/bin/cli.mjs +54 -10
  2. package/cdn/chunks/decorate.js +1 -1
  3. package/cdn/chunks/floating-ui.dom.js +2 -0
  4. package/cdn/chunks/floating-ui.dom.js.map +1 -0
  5. package/cdn/chunks/lit-html.js +3 -0
  6. package/cdn/chunks/lit-html.js.map +1 -0
  7. package/cdn/chunks/lit.js +1 -2
  8. package/cdn/chunks/lit.js.map +1 -1
  9. package/cdn/chunks/module.js +717 -0
  10. package/cdn/chunks/module.js.map +1 -0
  11. package/cdn/chunks/native.js +2 -0
  12. package/cdn/chunks/native.js.map +1 -0
  13. package/cdn/chunks/static-html.js +2 -0
  14. package/cdn/chunks/static-html.js.map +1 -0
  15. package/cdn/custom-elements.json +1412 -12629
  16. package/cdn/elements/avatar/avatar.d.ts +5 -0
  17. package/cdn/elements/avatar/avatar.d.ts.map +1 -1
  18. package/cdn/elements/avatar/avatar.js +5 -5
  19. package/cdn/elements/avatar/avatar.js.map +1 -1
  20. package/cdn/elements/button/button.meta.d.ts +33 -0
  21. package/cdn/elements/button/button.meta.d.ts.map +1 -0
  22. package/cdn/elements/button/button.meta.js +0 -0
  23. package/cdn/elements/carousel/carousel.d.ts +6 -0
  24. package/cdn/elements/carousel/carousel.d.ts.map +1 -1
  25. package/cdn/elements/carousel/carousel.js +1 -1
  26. package/cdn/elements/carousel/carousel.js.map +1 -1
  27. package/cdn/elements/carousel-item/carousel-item.d.ts +2 -0
  28. package/cdn/elements/carousel-item/carousel-item.d.ts.map +1 -1
  29. package/cdn/elements/carousel-item/carousel-item.js +1 -1
  30. package/cdn/elements/carousel-item/carousel-item.js.map +1 -1
  31. package/cdn/elements/close-button/close-button.meta.d.ts +24 -0
  32. package/cdn/elements/close-button/close-button.meta.d.ts.map +1 -0
  33. package/cdn/elements/close-button/close-button.meta.js +0 -0
  34. package/cdn/elements/dialog/dialog.d.ts +12 -6
  35. package/cdn/elements/dialog/dialog.d.ts.map +1 -1
  36. package/cdn/elements/dialog/dialog.js +8 -5
  37. package/cdn/elements/dialog/dialog.js.map +1 -1
  38. package/cdn/elements/dialog/dialog.styles.js +1 -1
  39. package/cdn/elements/dialog/dialog.styles.js.map +1 -1
  40. package/cdn/elements/disclosure/disclosure.meta.d.ts +28 -0
  41. package/cdn/elements/disclosure/disclosure.meta.d.ts.map +1 -0
  42. package/cdn/elements/disclosure/disclosure.meta.js +0 -0
  43. package/cdn/elements/divider/divider.d.ts +1 -1
  44. package/cdn/elements/divider/divider.js.map +1 -1
  45. package/cdn/elements/drawer/drawer.d.ts +5 -0
  46. package/cdn/elements/drawer/drawer.d.ts.map +1 -1
  47. package/cdn/elements/drawer/drawer.js +1 -1
  48. package/cdn/elements/drawer/drawer.js.map +1 -1
  49. package/cdn/elements/dropdown/dropdown.d.ts +2 -0
  50. package/cdn/elements/dropdown/dropdown.d.ts.map +1 -1
  51. package/cdn/elements/dropdown/dropdown.js +1 -1
  52. package/cdn/elements/dropdown/dropdown.js.map +1 -1
  53. package/cdn/elements/dropdown-item/dropdown-item.d.ts +2 -0
  54. package/cdn/elements/dropdown-item/dropdown-item.d.ts.map +1 -1
  55. package/cdn/elements/dropdown-item/dropdown-item.js +1 -1
  56. package/cdn/elements/dropdown-item/dropdown-item.js.map +1 -1
  57. package/cdn/elements/icon/icon.js +1 -1
  58. package/cdn/elements/icon/icon.js.map +1 -1
  59. package/cdn/elements/input-otp/input-otp.d.ts +2 -0
  60. package/cdn/elements/input-otp/input-otp.d.ts.map +1 -1
  61. package/cdn/elements/input-otp/input-otp.js.map +1 -1
  62. package/cdn/elements/input-stepper/input-stepper.d.ts +2 -0
  63. package/cdn/elements/input-stepper/input-stepper.d.ts.map +1 -1
  64. package/cdn/elements/input-stepper/input-stepper.js +1 -1
  65. package/cdn/elements/input-stepper/input-stepper.js.map +1 -1
  66. package/cdn/elements/kbd/kbd.meta.d.ts +14 -0
  67. package/cdn/elements/kbd/kbd.meta.d.ts.map +1 -0
  68. package/cdn/elements/kbd/kbd.meta.js +0 -0
  69. package/cdn/elements/popover/popover.js +1 -1
  70. package/cdn/elements/popover/popover.js.map +1 -1
  71. package/cdn/elements/progress/progress.meta.d.ts +22 -0
  72. package/cdn/elements/progress/progress.meta.d.ts.map +1 -0
  73. package/cdn/elements/progress/progress.meta.js +0 -0
  74. package/cdn/elements/prose-editor/index.d.ts +2 -0
  75. package/cdn/elements/prose-editor/index.d.ts.map +1 -0
  76. package/cdn/elements/prose-editor/index.js +2 -0
  77. package/cdn/elements/prose-editor/index.js.map +1 -0
  78. package/cdn/elements/prose-editor/prose-editor.d.ts +113 -0
  79. package/cdn/elements/prose-editor/prose-editor.d.ts.map +1 -0
  80. package/cdn/elements/prose-editor/prose-editor.js +180 -0
  81. package/cdn/elements/prose-editor/prose-editor.js.map +1 -0
  82. package/cdn/elements/rating/rating.d.ts +2 -0
  83. package/cdn/elements/rating/rating.d.ts.map +1 -1
  84. package/cdn/elements/rating/rating.js +1 -1
  85. package/cdn/elements/rating/rating.js.map +1 -1
  86. package/cdn/elements/select/select.meta.d.ts +28 -0
  87. package/cdn/elements/select/select.meta.d.ts.map +1 -0
  88. package/cdn/elements/select/select.meta.js +0 -0
  89. package/cdn/elements/skeleton/skeleton.d.ts +3 -0
  90. package/cdn/elements/skeleton/skeleton.d.ts.map +1 -1
  91. package/cdn/elements/skeleton/skeleton.js.map +1 -1
  92. package/cdn/elements/spinner/spinner.js +1 -1
  93. package/cdn/elements/spinner/spinner.js.map +1 -1
  94. package/cdn/elements/sticky-bar/sticky-bar.js +1 -1
  95. package/cdn/elements/sticky-bar/sticky-bar.js.map +1 -1
  96. package/cdn/elements/stories-viewer/stories-viewer.d.ts +1 -1
  97. package/cdn/elements/stories-viewer/stories-viewer.d.ts.map +1 -1
  98. package/cdn/elements/stories-viewer/stories-viewer.js +26 -26
  99. package/cdn/elements/stories-viewer/stories-viewer.js.map +1 -1
  100. package/cdn/elements/story/story.d.ts +10 -1
  101. package/cdn/elements/story/story.d.ts.map +1 -1
  102. package/cdn/elements/story/story.js +20 -20
  103. package/cdn/elements/story/story.js.map +1 -1
  104. package/cdn/elements/toast/toast.d.ts +5 -0
  105. package/cdn/elements/toast/toast.d.ts.map +1 -1
  106. package/cdn/elements/toast/toast.js.map +1 -1
  107. package/cdn/elements/tooltip/tooltip.js +1 -1
  108. package/cdn/elements/tooltip/tooltip.js.map +1 -1
  109. package/cdn/elements/tree/tree.d.ts +2 -0
  110. package/cdn/elements/tree/tree.d.ts.map +1 -1
  111. package/cdn/elements/tree/tree.js +1 -1
  112. package/cdn/elements/tree/tree.js.map +1 -1
  113. package/cdn/elements/tree-item/tree-item.d.ts +2 -0
  114. package/cdn/elements/tree-item/tree-item.d.ts.map +1 -1
  115. package/cdn/elements/tree-item/tree-item.js +1 -1
  116. package/cdn/elements/tree-item/tree-item.js.map +1 -1
  117. package/cdn/registry.d.ts +1 -1
  118. package/cdn/registry.d.ts.map +1 -1
  119. package/cdn/registry.js.map +1 -1
  120. package/cdn/shared/controllers/has-slot-controller.d.ts +37 -0
  121. package/cdn/shared/controllers/has-slot-controller.d.ts.map +1 -0
  122. package/cdn/shared/controllers/has-slot-controller.js +2 -0
  123. package/cdn/shared/controllers/has-slot-controller.js.map +1 -0
  124. package/cdn/shared/controllers/popover.js +1 -1
  125. package/cdn/shared/controllers/popover.js.map +1 -1
  126. package/cdn/shared/styles/host.styles.js +1 -1
  127. package/cdn/standalone.css +132 -1
  128. package/cdn/standalone.js +25743 -191
  129. package/cdn/standalone.js.map +1 -1
  130. package/cdn/static-tag.d.ts +17 -0
  131. package/cdn/static-tag.d.ts.map +1 -0
  132. package/cdn/static-tag.js +2 -0
  133. package/cdn/static-tag.js.map +1 -0
  134. package/cdn/styles/elements/prose-editor.css +129 -0
  135. package/cdn/styles/elements/toast.css +1 -1
  136. package/dist/css/elements/prose-editor.css +129 -0
  137. package/dist/css/elements/toast.css +1 -1
  138. package/dist/custom-elements.json +1412 -12629
  139. package/dist/elements/avatar/avatar.d.ts +5 -0
  140. package/dist/elements/avatar/avatar.d.ts.map +1 -1
  141. package/dist/elements/avatar/avatar.js +5 -0
  142. package/dist/elements/button/button.meta.d.ts +33 -0
  143. package/dist/elements/button/button.meta.d.ts.map +1 -0
  144. package/dist/elements/button/button.meta.js +44 -0
  145. package/dist/elements/carousel/carousel.d.ts +6 -0
  146. package/dist/elements/carousel/carousel.d.ts.map +1 -1
  147. package/dist/elements/carousel/carousel.js +6 -0
  148. package/dist/elements/carousel-item/carousel-item.d.ts +2 -0
  149. package/dist/elements/carousel-item/carousel-item.d.ts.map +1 -1
  150. package/dist/elements/carousel-item/carousel-item.js +2 -0
  151. package/dist/elements/close-button/close-button.meta.d.ts +24 -0
  152. package/dist/elements/close-button/close-button.meta.d.ts.map +1 -0
  153. package/dist/elements/close-button/close-button.meta.js +30 -0
  154. package/dist/elements/dialog/dialog.css +15 -0
  155. package/dist/elements/dialog/dialog.d.ts +12 -6
  156. package/dist/elements/dialog/dialog.d.ts.map +1 -1
  157. package/dist/elements/dialog/dialog.js +21 -7
  158. package/dist/elements/disclosure/disclosure.meta.d.ts +28 -0
  159. package/dist/elements/disclosure/disclosure.meta.d.ts.map +1 -0
  160. package/dist/elements/disclosure/disclosure.meta.js +34 -0
  161. package/dist/elements/divider/divider.d.ts +1 -1
  162. package/dist/elements/divider/divider.js +1 -1
  163. package/dist/elements/drawer/drawer.d.ts +5 -0
  164. package/dist/elements/drawer/drawer.d.ts.map +1 -1
  165. package/dist/elements/drawer/drawer.js +5 -0
  166. package/dist/elements/dropdown/dropdown.d.ts +2 -0
  167. package/dist/elements/dropdown/dropdown.d.ts.map +1 -1
  168. package/dist/elements/dropdown/dropdown.js +2 -0
  169. package/dist/elements/dropdown-item/dropdown-item.d.ts +2 -0
  170. package/dist/elements/dropdown-item/dropdown-item.d.ts.map +1 -1
  171. package/dist/elements/dropdown-item/dropdown-item.js +2 -0
  172. package/dist/elements/input-otp/input-otp.d.ts +2 -0
  173. package/dist/elements/input-otp/input-otp.d.ts.map +1 -1
  174. package/dist/elements/input-otp/input-otp.js +2 -0
  175. package/dist/elements/input-stepper/input-stepper.d.ts +2 -0
  176. package/dist/elements/input-stepper/input-stepper.d.ts.map +1 -1
  177. package/dist/elements/input-stepper/input-stepper.js +5 -1
  178. package/dist/elements/kbd/kbd.meta.d.ts +14 -0
  179. package/dist/elements/kbd/kbd.meta.d.ts.map +1 -0
  180. package/dist/elements/kbd/kbd.meta.js +20 -0
  181. package/dist/elements/progress/progress.meta.d.ts +22 -0
  182. package/dist/elements/progress/progress.meta.d.ts.map +1 -0
  183. package/dist/elements/progress/progress.meta.js +28 -0
  184. package/dist/elements/prose-editor/index.d.ts +2 -0
  185. package/dist/elements/prose-editor/index.d.ts.map +1 -0
  186. package/dist/elements/prose-editor/index.js +4 -0
  187. package/dist/elements/prose-editor/prose-editor.css +133 -0
  188. package/dist/elements/prose-editor/prose-editor.d.ts +114 -0
  189. package/dist/elements/prose-editor/prose-editor.d.ts.map +1 -0
  190. package/dist/elements/prose-editor/prose-editor.js +481 -0
  191. package/dist/elements/rating/rating.d.ts +2 -0
  192. package/dist/elements/rating/rating.d.ts.map +1 -1
  193. package/dist/elements/rating/rating.js +2 -0
  194. package/dist/elements/select/select.meta.d.ts +28 -0
  195. package/dist/elements/select/select.meta.d.ts.map +1 -0
  196. package/dist/elements/select/select.meta.js +34 -0
  197. package/dist/elements/skeleton/skeleton.d.ts +3 -0
  198. package/dist/elements/skeleton/skeleton.d.ts.map +1 -1
  199. package/dist/elements/skeleton/skeleton.js +3 -0
  200. package/dist/elements/stories-viewer/stories-viewer.d.ts +1 -1
  201. package/dist/elements/stories-viewer/stories-viewer.d.ts.map +1 -1
  202. package/dist/elements/stories-viewer/stories-viewer.js +23 -19
  203. package/dist/elements/story/story.d.ts +10 -1
  204. package/dist/elements/story/story.d.ts.map +1 -1
  205. package/dist/elements/story/story.js +29 -17
  206. package/dist/elements/toast/toast.d.ts +5 -0
  207. package/dist/elements/toast/toast.d.ts.map +1 -1
  208. package/dist/elements/toast/toast.js +5 -0
  209. package/dist/elements/tree/tree.d.ts +2 -0
  210. package/dist/elements/tree/tree.d.ts.map +1 -1
  211. package/dist/elements/tree/tree.js +2 -0
  212. package/dist/elements/tree-item/tree-item.d.ts +2 -0
  213. package/dist/elements/tree-item/tree-item.d.ts.map +1 -1
  214. package/dist/elements/tree-item/tree-item.js +2 -0
  215. package/dist/metadata/avatar.json +83 -0
  216. package/dist/metadata/badge.json +59 -0
  217. package/dist/metadata/button.json +138 -0
  218. package/dist/metadata/carousel-item.json +32 -0
  219. package/dist/metadata/carousel.json +388 -0
  220. package/dist/metadata/close-button.json +90 -0
  221. package/dist/metadata/dialog.json +163 -0
  222. package/dist/metadata/disclosure.json +88 -0
  223. package/dist/metadata/divider.json +65 -0
  224. package/dist/metadata/drawer.json +176 -0
  225. package/dist/metadata/dropdown-item.json +85 -0
  226. package/dist/metadata/dropdown.json +157 -0
  227. package/dist/metadata/icon.json +49 -0
  228. package/dist/metadata/index.json +4062 -0
  229. package/dist/metadata/input-otp.json +86 -0
  230. package/dist/metadata/input-stepper.json +122 -0
  231. package/dist/metadata/kbd.json +37 -0
  232. package/dist/metadata/popover.json +157 -0
  233. package/dist/metadata/progress.json +71 -0
  234. package/dist/metadata/prose-editor.json +365 -0
  235. package/dist/metadata/rating.json +126 -0
  236. package/dist/metadata/select.json +82 -0
  237. package/dist/metadata/skeleton.json +56 -0
  238. package/dist/metadata/spinner.json +47 -0
  239. package/dist/metadata/sticky-bar.json +93 -0
  240. package/dist/metadata/stories-viewer.json +316 -0
  241. package/dist/metadata/stories.json +109 -0
  242. package/dist/metadata/story.json +148 -0
  243. package/dist/metadata/tabs.json +74 -0
  244. package/dist/metadata/toast.json +122 -0
  245. package/dist/metadata/tooltip.json +144 -0
  246. package/dist/metadata/tree-item.json +199 -0
  247. package/dist/metadata/tree.json +130 -0
  248. package/dist/registry.d.ts +1 -1
  249. package/dist/registry.d.ts.map +1 -1
  250. package/dist/shared/controllers/has-slot-controller.d.ts +37 -0
  251. package/dist/shared/controllers/has-slot-controller.d.ts.map +1 -0
  252. package/dist/shared/controllers/has-slot-controller.js +66 -0
  253. package/dist/static-tag.d.ts +17 -0
  254. package/dist/static-tag.d.ts.map +1 -0
  255. package/dist/static-tag.js +22 -0
  256. package/dist/templates/elements/avatar.md +21 -24
  257. package/dist/templates/elements/badge.md +9 -15
  258. package/dist/templates/elements/button.md +31 -41
  259. package/dist/templates/elements/close-button.md +24 -36
  260. package/dist/templates/elements/dialog.md +73 -54
  261. package/dist/templates/elements/drawer.md +39 -52
  262. package/dist/templates/elements/progress.md +13 -23
  263. package/dist/templates/elements/prose-editor.md +211 -0
  264. package/dist/templates/elements/select.md +20 -31
  265. package/dist/templates/elements/sticky-bar.md +16 -60
  266. package/dist/templates/elements/toast.md +33 -53
  267. package/dist/templates/elements/tree.md +39 -67
  268. package/elements.json +46 -1
  269. package/package.json +13 -3
  270. package/templates/SKILL.md.tpl +5 -1
@@ -0,0 +1,37 @@
1
+ import type { ReactiveController, ReactiveControllerHost } from 'lit';
2
+ /**
3
+ * Reactive controller that tracks whether one or more slots have content, and
4
+ * requests a host update whenever that changes. Lets a template react to empty
5
+ * slots — e.g. collapse a footer row when nothing is slotted into it.
6
+ *
7
+ * Drives this off `slotchange` rather than a CSS selector because
8
+ * `:host(:has(> [slot='name']))` is invalid (`:has()` can't be nested inside
9
+ * `:host()`, so browsers drop the whole rule). Pair it with a data-attribute:
10
+ *
11
+ * ```ts
12
+ * private _slots = new HasSlotController(this, 'footer');
13
+ *
14
+ * render() {
15
+ * return html`
16
+ * <footer part="footer" ?data-empty=${!this._slots.test('footer')}>
17
+ * <slot name="footer"></slot>
18
+ * </footer>
19
+ * `;
20
+ * }
21
+ * ```
22
+ *
23
+ * Pass `'[default]'` to test the default (unnamed) slot.
24
+ */
25
+ export declare class HasSlotController implements ReactiveController {
26
+ private host;
27
+ private slotNames;
28
+ constructor(host: ReactiveControllerHost & Element, ...slotNames: string[]);
29
+ /** Whether the given slot currently has content. Use `'[default]'` for the default slot. */
30
+ test(slotName: string): boolean;
31
+ private hasNamedSlot;
32
+ private hasDefaultSlot;
33
+ private handleSlotChange;
34
+ hostConnected(): void;
35
+ hostDisconnected(): void;
36
+ }
37
+ //# sourceMappingURL=has-slot-controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"has-slot-controller.d.ts","sourceRoot":"","sources":["../../../src/html/shared/controllers/has-slot-controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,KAAK,CAAC;AAEtE;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,iBAAkB,YAAW,kBAAkB;IAC1D,OAAO,CAAC,IAAI,CAAmC;IAC/C,OAAO,CAAC,SAAS,CAAW;gBAEhB,IAAI,EAAE,sBAAsB,GAAG,OAAO,EAAE,GAAG,SAAS,EAAE,MAAM,EAAE;IAM1E,4FAA4F;IAC5F,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAM/B,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,gBAAgB,CAMtB;IAEF,aAAa;IAIb,gBAAgB;CAGjB"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Reactive controller that tracks whether one or more slots have content, and
3
+ * requests a host update whenever that changes. Lets a template react to empty
4
+ * slots — e.g. collapse a footer row when nothing is slotted into it.
5
+ *
6
+ * Drives this off `slotchange` rather than a CSS selector because
7
+ * `:host(:has(> [slot='name']))` is invalid (`:has()` can't be nested inside
8
+ * `:host()`, so browsers drop the whole rule). Pair it with a data-attribute:
9
+ *
10
+ * ```ts
11
+ * private _slots = new HasSlotController(this, 'footer');
12
+ *
13
+ * render() {
14
+ * return html`
15
+ * <footer part="footer" ?data-empty=${!this._slots.test('footer')}>
16
+ * <slot name="footer"></slot>
17
+ * </footer>
18
+ * `;
19
+ * }
20
+ * ```
21
+ *
22
+ * Pass `'[default]'` to test the default (unnamed) slot.
23
+ */
24
+ export class HasSlotController {
25
+ constructor(host, ...slotNames) {
26
+ this.handleSlotChange = (event) => {
27
+ const slot = event.target;
28
+ const watched = slot.name
29
+ ? this.slotNames.includes(slot.name)
30
+ : this.slotNames.includes('[default]');
31
+ if (watched)
32
+ this.host.requestUpdate();
33
+ };
34
+ this.host = host;
35
+ this.slotNames = slotNames;
36
+ host.addController(this);
37
+ }
38
+ /** Whether the given slot currently has content. Use `'[default]'` for the default slot. */
39
+ test(slotName) {
40
+ return slotName === '[default]' ? this.hasDefaultSlot() : this.hasNamedSlot(slotName);
41
+ }
42
+ // A direct child projected into the named slot. `:scope >` keeps it to direct
43
+ // children, so a nested `[slot="name"]` inside slotted content can't match.
44
+ hasNamedSlot(name) {
45
+ return this.host.querySelector(`:scope > [slot="${name}"]`) !== null;
46
+ }
47
+ // Any non-whitespace text node or any element without a `slot` attribute
48
+ // counts as default-slot content.
49
+ hasDefaultSlot() {
50
+ return [...this.host.childNodes].some((node) => {
51
+ if (node.nodeType === Node.TEXT_NODE) {
52
+ return (node.textContent ?? '').trim() !== '';
53
+ }
54
+ if (node.nodeType === Node.ELEMENT_NODE) {
55
+ return !node.hasAttribute('slot');
56
+ }
57
+ return false;
58
+ });
59
+ }
60
+ hostConnected() {
61
+ this.host.shadowRoot?.addEventListener('slotchange', this.handleSlotChange);
62
+ }
63
+ hostDisconnected() {
64
+ this.host.shadowRoot?.removeEventListener('slotchange', this.handleSlotChange);
65
+ }
66
+ }
@@ -0,0 +1,17 @@
1
+ import { type StaticValue } from 'lit/static-html.js';
2
+ import { type ElementBaseName } from './registry.js';
3
+ /**
4
+ * Prefix-aware static tag for use in Lit static-html templates.
5
+ *
6
+ * Resolves a base name to the registered tag (e.g. `staticTag('icon')` → `po-icon`
7
+ * under `elementPrefix: 'po'`) so elements that render a child custom element inside
8
+ * their own template stay prefix-aware. Without this, the hardcoded `<l-icon>` literal
9
+ * is never defined under a custom prefix and the child never upgrades.
10
+ *
11
+ * Memoized: Lit keys its template cache on `StaticValue` identity, so a fresh
12
+ * `unsafeStatic()` per render would bust the cache. The prefix is set once at startup
13
+ * before any element renders, so a plain memo is correct. If runtime re-prefixing via
14
+ * `setPrefix()` becomes a supported scenario, clear `_cache` there.
15
+ */
16
+ export declare function staticTag(baseName: ElementBaseName): StaticValue;
17
+ //# sourceMappingURL=static-tag.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static-tag.d.ts","sourceRoot":"","sources":["../src/html/static-tag.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAW,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAI9D;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,eAAe,GAAG,WAAW,CAIhE"}
@@ -0,0 +1,22 @@
1
+ import { unsafeStatic } from 'lit/static-html.js';
2
+ import { tagName } from './registry.js';
3
+ const _cache = new Map();
4
+ /**
5
+ * Prefix-aware static tag for use in Lit static-html templates.
6
+ *
7
+ * Resolves a base name to the registered tag (e.g. `staticTag('icon')` → `po-icon`
8
+ * under `elementPrefix: 'po'`) so elements that render a child custom element inside
9
+ * their own template stay prefix-aware. Without this, the hardcoded `<l-icon>` literal
10
+ * is never defined under a custom prefix and the child never upgrades.
11
+ *
12
+ * Memoized: Lit keys its template cache on `StaticValue` identity, so a fresh
13
+ * `unsafeStatic()` per render would bust the cache. The prefix is set once at startup
14
+ * before any element renders, so a plain memo is correct. If runtime re-prefixing via
15
+ * `setPrefix()` becomes a supported scenario, clear `_cache` there.
16
+ */
17
+ export function staticTag(baseName) {
18
+ let t = _cache.get(baseName);
19
+ if (!t)
20
+ _cache.set(baseName, (t = unsafeStatic(tagName(baseName))));
21
+ return t;
22
+ }
@@ -6,10 +6,7 @@ outline: deep
6
6
 
7
7
  Avatars are used to represent a user or entity with a profile image, initials, or icon fallback. Commonly used in headers, comments, contact lists, and user cards.
8
8
 
9
- <ElementSpec
10
- tag="l-avatar"
11
- type="shadow"
12
- />
9
+ **`<l-avatar>`** — Custom Element · Shadow DOM
13
10
 
14
11
  ## Options
15
12
 
@@ -211,15 +208,14 @@ Wrap avatars in `.l-avatar-group` for an overlapping stack with a surface-colore
211
208
 
212
209
  ### Criteria
213
210
 
214
- | Check | Description |
215
- |-------|-------------|
216
- | Role | Default `role="img"` communicates the avatar as an image |
217
- | Accessible name | `aria-label` is set automatically from the `name` attribute |
218
- | Interactive mode | When `interactive` is set, renders as a `<button>` with focus ring and hover states |
219
- | Decorative elements | Badge count is hidden from assistive tech with `aria-hidden="true"` |
220
- | Image fallback | Falls back to initials (then default icon) if image fails to load |
211
+ - **Role** Default `role="img"` communicates the avatar as an image
212
+ - **Accessible name** — `aria-label` is set automatically from the `name` attribute
213
+ - **Interactive mode** When `interactive` is set, renders as a `<button>` with focus ring and hover states
214
+ - **Decorative elements** Badge count is hidden from assistive tech with `aria-hidden="true"`
215
+ - **Image fallback** Falls back to initials (then default icon) if image fails to load
221
216
 
222
217
  ### Rules
218
+
223
219
  - Always provide the `name` attribute — it drives both `aria-label` and the initials fallback
224
220
  - Add `interactive` only when the avatar triggers an action (e.g., opens a profile menu)
225
221
 
@@ -227,11 +223,9 @@ Wrap avatars in `.l-avatar-group` for an overlapping stack with a surface-colore
227
223
 
228
224
  When `interactive` is set:
229
225
 
230
- | Key | Description |
231
- |-----|-------------|
232
- | Enter | Activates the avatar button |
233
- | Space | Activates the avatar button |
234
- | Tab | Moves focus to the next focusable element |
226
+ - `Enter` Activates the avatar button
227
+ - `Space` — Activates the avatar button
228
+ - `Tab` Moves focus to the next focusable element
235
229
 
236
230
  ## API reference
237
231
 
@@ -243,17 +237,20 @@ import 'luxen-ui/avatar';
243
237
 
244
238
  ### Attributes & Properties
245
239
 
246
- <ApiTable :data="attributes" />
240
+ - **src**: `string`
241
+ - **name**: `string`
242
+ - **size**: `string` (default: `'md'`)
243
+ - **badge**: `number` (default: `0`)
244
+ - **interactive**: `boolean` (default: `false`)
247
245
 
248
246
  ### CSS classes
249
247
 
250
- <ApiTable :data="[
251
- { Class: '.l-avatar-group', Description: 'Flex container with negative margins and surface-colored ring for overlapping avatars' },
252
- ]" />
248
+ - `.l-avatar-group` — Flex wrapper that overlaps a row of stacked avatars.
253
249
 
254
250
  ### CSS custom properties
255
251
 
256
- <ApiTable :data="[
257
- { Property: '--color', Description: 'Base color for initials/icon background. Text color is auto-derived via relative color syntax' },
258
- { Property: '--appearance', Description: 'Set to `circle` for a fully circular shape (default is rounded square)' },
259
- ]" />
252
+ - **src**: `string`
253
+ - **name**: `string`
254
+ - **size**: `string` (default: `'md'`)
255
+ - **badge**: `number` (default: `0`)
256
+ - **interactive**: `boolean` (default: `false`)
@@ -6,10 +6,7 @@ outline: deep
6
6
 
7
7
  Badges are used to draw attention and display statuses or counts. Commonly used in tabular data, lists, and navigation to indicate state or category.
8
8
 
9
- <ElementSpec
10
- tag="l-badge"
11
- type="custom"
12
- />
9
+ **`<l-badge>`** — Custom Element (no Shadow DOM)
13
10
 
14
11
  ## Options
15
12
 
@@ -257,13 +254,12 @@ Add `variant="info"`, `variant="success"`, `variant="warning"`, or `variant="dan
257
254
 
258
255
  ### Criteria
259
256
 
260
- | Check | Description |
261
- |-------|-------------|
262
- | Color contrast | Text and background meet minimum contrast ratio across all appearances and variants |
263
- | Non-text contrast | Badge borders meet non-text contrast minimum against adjacent surfaces |
264
- | Not color alone | Do not rely on badge color alone to convey status — always include a text label |
257
+ - **Color contrast** Text and background meet minimum contrast ratio across all appearances and variants
258
+ - **Non-text contrast** — Badge borders meet non-text contrast minimum against adjacent surfaces
259
+ - **Not color alone** Do not rely on badge color alone to convey status always include a text label
265
260
 
266
261
  ### Rules
262
+
267
263
  - Always include visible text inside the badge — do not use color alone to convey meaning
268
264
  - When a badge conveys dynamic status, wrap it in a `role="status"` container so screen readers announce changes
269
265
 
@@ -281,9 +277,7 @@ import 'luxen-ui/badge';
281
277
 
282
278
  ### Attributes & Properties
283
279
 
284
- <ApiTable :data="[
285
- { Attribute: 'size', Description: 'Badge size (`sm`, `lg`). Default is md.' },
286
- { Attribute: 'appearance', Description: 'Visual appearance (`filled`, `filled-outlined`, `accent`). Default is outlined.' },
287
- { Attribute: 'variant', Description: 'Style variant (`info`, `success`, `warning`, `danger`). Default is neutral.' },
288
- { Attribute: 'pill', Description: 'Fully rounded pill shape' },
289
- ]" />
280
+ - **variant**: `BadgeVariant | undefined` — Style variant: `info`, `success`, `warning`, `danger`, or `neutral` (default)
281
+ - **pill**: `boolean` (default: `false`) Display as pill shape
282
+ - **size**: `BadgeSize | undefined` Badge size: `sm`, `lg`. Default is md.
283
+ - **appearance**: `BadgeAppearance | undefined` Visual appearance: `filled`, `filled-outlined`, `accent`. Default is outlined.
@@ -6,10 +6,7 @@ outline: deep
6
6
 
7
7
  Buttons are used to trigger actions such as submitting forms, confirming dialogs, or navigating. They are the primary interactive control in any interface.
8
8
 
9
- <ElementSpec
10
- tag="button"
11
- type="native"
12
- />
9
+ **`.l-button`** — Native HTML Element
13
10
 
14
11
  ## Options
15
12
 
@@ -244,17 +241,16 @@ Add an `<l-spinner>` inside the button. The spinner inherits the button's text c
244
241
 
245
242
  ### Criteria
246
243
 
247
- | Check | Description |
248
- |-------|-------------|
249
- | Color | Text and background colors meet AA contrast ratios across all variants |
250
- | Focus state | Visible 2px focus ring for keyboard users |
251
- | Hover state | Clear visual change on hover |
252
- | Active state | Visual feedback on press |
253
- | Disabled state | Reduced opacity, `cursor: not-allowed`, not focusable when disabled |
254
- | Icon-only | Icon-only buttons must have `aria-label` for an accessible name |
255
- | Role | Uses native `<button>` or `<a>` — no extra ARIA role needed |
244
+ - **Color** Text and background colors meet AA contrast ratios across all variants
245
+ - **Focus state** — Visible 2px focus ring for keyboard users
246
+ - **Hover state** Clear visual change on hover
247
+ - **Active state** Visual feedback on press
248
+ - **Disabled state** Reduced opacity, `cursor: not-allowed`, not focusable when disabled
249
+ - **Icon-only** Icon-only buttons must have `aria-label` for an accessible name
250
+ - **Role** Uses native `<button>` or `<a>` no extra ARIA role needed
256
251
 
257
252
  ### Rules
253
+
258
254
  - Use a native `<button>` element — never a `<div>` or `<span>`
259
255
  - Always add `aria-label` to icon-only buttons
260
256
  - Include `type="button"` to prevent form submission (except for submit buttons)
@@ -262,12 +258,10 @@ Add an `<l-spinner>` inside the button. The spinner inherits the button's text c
262
258
 
263
259
  ### Keyboard interactions
264
260
 
265
- | Key | Description |
266
- |-----|-------------|
267
- | Enter | Activates the button |
268
- | Space | Activates the button |
269
- | Tab | Moves focus to the next focusable element |
270
- | Shift + Tab | Moves focus to the previous focusable element |
261
+ - `Enter` Activates the button
262
+ - `Space` — Activates the button
263
+ - `Tab` Moves focus to the next focusable element
264
+ - `Shift + Tab` — Moves focus to the previous focusable element
271
265
 
272
266
  ## API reference
273
267
 
@@ -279,31 +273,27 @@ Add an `<l-spinner>` inside the button. The spinner inherits the button's text c
279
273
 
280
274
  ### Attributes & Properties
281
275
 
282
- <ApiTable :data="[
283
- { Attribute: 'disabled', Description: 'Disables the button' },
284
- { Attribute: 'command', Description: 'Invoker command (`show-modal`, `close`, `show-popover`, etc.)' },
285
- { Attribute: 'commandfor', Description: 'ID of the target element for `command`' },
286
- { Attribute: 'data-variant', Description: 'Visual variant (`primary`, `destructive`)' },
287
- { Attribute: 'data-size', Description: 'Size (`sm`, `lg`, `xl`). Default is md.' },
288
- { Attribute: 'data-icon-only', Description: 'Icon-only mode (square button, width equals height)' },
289
- { Attribute: 'data-press-effect', Description: 'Press effect (scale + translate on active)' },
290
- ]" />
276
+ - **disabled** — Disables the button.
277
+ - **command** Invoker command (`show-modal`, `close`, `show-popover`, etc.).
278
+ - **commandfor** ID of the target element for `command`.
279
+ - **data-variant**: `primary | destructive` Visual variant. Default is the secondary style.
280
+ - **data-size**: `sm | lg | xl` — Control size. Default is md.
281
+ - **data-icon-only** Icon-only mode (square button, width equals height). Auto-detected for a single icon child.
282
+ - **data-press-effect** Press effect (scale + translate on active).
291
283
 
292
284
  ### CSS classes
293
285
 
294
- <ApiTable :data="cssClasses" />
286
+ - `.l-button` — Base button style.
295
287
 
296
288
  ### CSS custom properties
297
289
 
298
- <ApiTable :data="[
299
- { Name: '--height', Description: 'Button height' },
300
- { Name: '--padding-inline', Description: 'Horizontal padding' },
301
- { Name: '--background-color', Description: 'Background color' },
302
- { Name: '--background-color-hover', Description: 'Background on hover' },
303
- { Name: '--background-color-active', Description: 'Background on press' },
304
- { Name: '--text-color', Description: 'Text color' },
305
- { Name: '--text-hover', Description: 'Text color on hover' },
306
- { Name: '--border-color', Description: 'Border color' },
307
- { Name: '--border-color-hover', Description: 'Border color on hover' },
308
- { Name: '--font-size', Description: 'Font size' },
309
- ]" />
290
+ - `--height` (default: `32px`) — Button height (md size).
291
+ - `--padding-inline` (default: `0.625rem`) Horizontal padding.
292
+ - `--background-color` Background color.
293
+ - `--background-color-hover` Background color on hover.
294
+ - `--background-color-active` Background color on press.
295
+ - `--text-color` Text color.
296
+ - `--text-color-hover` Text color on hover.
297
+ - `--border-color` Border color.
298
+ - `--border-color-hover` Border color on hover.
299
+ - `--font-size` Font size.
@@ -6,10 +6,7 @@ outline: deep
6
6
 
7
7
  Close buttons are used to dismiss overlays such as dialogs, drawers, toasts, and popovers. They render a close icon without any visible label.
8
8
 
9
- <ElementSpec
10
- tag="button"
11
- type="native"
12
- />
9
+ **`.l-close`** — Native HTML Element
13
10
 
14
11
  ## Options
15
12
 
@@ -66,31 +63,28 @@ Pick a visual style via `data-appearance`. Each appearance has its own CSS impor
66
63
 
67
64
  ### Criteria
68
65
 
69
- | Check | Description |
70
- |-------|-------------|
71
- | Color | Icon and background colors meet AA contrast ratios |
72
- | Size | Minimum 24×24px target size; larger for touch contexts |
73
- | Icon | Decorative icon; `aria-label` on the button provides the accessible name |
74
- | Hover state | Clear visual change on hover |
75
- | Focus state | Visible focus ring for keyboard users |
76
- | Active state | Visual feedback on press |
77
- | Disabled state | Appears inactive, not focusable when disabled |
78
- | Accessible name | Always provide `aria-label` or context-specific label |
79
- | Role | Uses native `<button>` — no extra ARIA role needed |
66
+ - **Color** Icon and background colors meet AA contrast ratios
67
+ - **Size** — Minimum 24×24px target size; larger for touch contexts
68
+ - **Icon** Decorative icon; `aria-label` on the button provides the accessible name
69
+ - **Hover state** Clear visual change on hover
70
+ - **Focus state** Visible focus ring for keyboard users
71
+ - **Active state** Visual feedback on press
72
+ - **Disabled state** Appears inactive, not focusable when disabled
73
+ - **Accessible name** Always provide `aria-label` or context-specific label
74
+ - **Role** Uses native `<button>` no extra ARIA role needed
80
75
 
81
76
  ### Rules
77
+
82
78
  - Always add `aria-label="Close"` (or a context-specific label like `aria-label="Close dialog"`)
83
79
  - Use a native `<button>` element — never a `<div>` or `<span>`
84
80
  - Include `type="button"` to prevent form submission
85
81
 
86
82
  ### Keyboard interactions
87
83
 
88
- | Key | Description |
89
- |-----|-------------|
90
- | Enter | Activates the close button |
91
- | Space | Activates the close button |
92
- | Tab | Moves focus to the next focusable element |
93
- | Shift + Tab | Moves focus to the previous focusable element |
84
+ - `Enter` Activates the close button
85
+ - `Space` — Activates the close button
86
+ - `Tab` Moves focus to the next focusable element
87
+ - `Shift + Tab` — Moves focus to the previous focusable element
94
88
 
95
89
  ## API reference
96
90
 
@@ -102,24 +96,18 @@ Pick a visual style via `data-appearance`. Each appearance has its own CSS impor
102
96
 
103
97
  ### Attributes & Properties
104
98
 
105
- <ApiTable :data="[
106
- { Attribute: 'data-appearance', Description: '`ring` · `square` · `circle`' },
107
- { Attribute: 'command', Description: 'Invoker command (typically `close`)' },
108
- { Attribute: 'commandfor', Description: 'ID of the target element to close' },
109
- ]" />
99
+ - **data-appearance**: `ring | square | circle` — Visual appearance (matches the imported appearance CSS).
100
+ - **command** Invoker command (typically `close`).
101
+ - **commandfor** ID of the target element to close.
110
102
 
111
103
  ### CSS classes
112
104
 
113
- <ApiTable :data="[
114
- { Class: '.l-close', Description: 'Base close button with X icon via CSS mask' },
115
- ]" />
105
+ - `.l-close` — Base close button with X icon via CSS mask.
116
106
 
117
107
  ### CSS custom properties
118
108
 
119
- <ApiTable :data="[
120
- { Name: '--size', Description: 'Button size (default: 36px)' },
121
- { Name: '--icon-color', Description: 'Icon color' },
122
- { Name: '--icon-size', Description: 'Icon size (default: 24px)' },
123
- { Name: '--ring-color', Description: 'Hover ring color (`ring` appearance only)' },
124
- { Name: '--ring-tickness', Description: 'Hover ring thickness (`ring` appearance only)' },
125
- ]" />
109
+ - `--size` (default: `36px`) — Button size.
110
+ - `--icon-color` Icon color.
111
+ - `--icon-size` (default: `24px`) — Icon size.
112
+ - `--ring-color` Hover ring color (`ring` appearance only).
113
+ - `--ring-tickness` Hover ring thickness (`ring` appearance only).