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
@@ -6,10 +6,7 @@ outline: deep
6
6
 
7
7
  Dialogs display critical information or request user input in a modal overlay that blocks interaction with the rest of the page. Commonly used for confirmations, forms, and alerts.
8
8
 
9
- <ElementSpec
10
- tag="l-dialog"
11
- type="shadow"
12
- />
9
+ **`<l-dialog>`** — Custom Element · Shadow DOM
13
10
 
14
11
  ## Options
15
12
 
@@ -345,6 +342,42 @@ Add `autofocus` to any focusable element inside the dialog to focus it automatic
345
342
  </l-dialog>
346
343
  ```
347
344
 
345
+ ### Without footer
346
+
347
+ Omit the `footer` slot and the footer row collapses — no empty space is reserved at the bottom.
348
+
349
+ ```html
350
+ <button
351
+ type="button"
352
+ class="l-button"
353
+ command="--show"
354
+ commandfor="dialog-without-footer"
355
+ >
356
+ Open dialog
357
+ </button>
358
+
359
+ <l-dialog
360
+ id="dialog-without-footer"
361
+ title="Release notes"
362
+ >
363
+ <button
364
+ slot="close"
365
+ type="button"
366
+ class="l-close"
367
+ data-appearance="ring"
368
+ aria-label="Close"
369
+ command="--hide"
370
+ commandfor="dialog-without-footer"
371
+ ></button>
372
+ <article class="h-[340px]">
373
+ <p>
374
+ Leave out the <code>footer</code> slot and the footer row collapses — no empty padded band at
375
+ the bottom.
376
+ </p>
377
+ </article>
378
+ </l-dialog>
379
+ ```
380
+
348
381
  ### Without header
349
382
 
350
383
  Add `without-header` to drop the header row entirely (title and close slot). Useful for confirmation prompts where the body already carries the heading. Provide an accessible heading inside the body and rely on `Escape` or a footer action to close.
@@ -417,27 +450,24 @@ Add `without-header` to drop the header row entirely (title and close slot). Use
417
450
 
418
451
  ### Criteria
419
452
 
420
- | Check | Description |
421
- |-------|-------------|
422
- | Role | Rendered as a native `<dialog>` in the shadow root built-in `dialog` role and modal semantics |
423
- | Accessible name | The `title` property renders as an `<h2>` in the header, or provide a custom heading via `slot="title"` |
424
- | Focus management | Focus is trapped inside the modal; moves to the first focusable element on open |
425
- | Focus restoration | Focus returns to the trigger element when the dialog closes |
426
- | Close button | Consumer provides the close button via `slot="close"` with `aria-label="Close"` |
427
- | Motion | Respects `prefers-reduced-motion` |
453
+ - **Role** Rendered as a native `<dialog>` in the shadow root — built-in `dialog` role and modal semantics
454
+ - **Accessible name** — The `title` property renders as an `<h2>` in the header, or provide a custom heading via `slot="title"`
455
+ - **Focus management** Focus is trapped inside the modal; moves to the first focusable element on open
456
+ - **Focus restoration** Focus returns to the trigger element when the dialog closes
457
+ - **Close button** Consumer provides the close button via `slot="close"` with `aria-label="Close"`
458
+ - **Motion** Respects `prefers-reduced-motion`
428
459
 
429
460
  ### Rules
461
+
430
462
  - Always set a meaningful `title` — it becomes the dialog heading and accessible name
431
463
  - Put the close button in `slot="close"` with `class="l-close"` and `command="--hide"` `commandfor="<id>"`
432
464
  - Use `command="--show"` and `command="--hide"` with `commandfor` pointing at the dialog id. The `--` prefix is mandatory for custom elements
433
465
 
434
466
  ### Keyboard interactions
435
467
 
436
- | Key | Description |
437
- |-----|-------------|
438
- | Escape | Closes the dialog |
439
- | Tab | Cycles focus through focusable elements inside the dialog |
440
- | Shift + Tab | Cycles focus backward through focusable elements inside the dialog |
468
+ - `Escape` Closes the dialog
469
+ - `Tab` — Cycles focus through focusable elements inside the dialog
470
+ - `Shift + Tab` — Cycles focus backward through focusable elements inside the dialog
441
471
 
442
472
  ## API reference
443
473
 
@@ -449,12 +479,10 @@ import 'luxen-ui/dialog';
449
479
 
450
480
  ### Attributes & Properties
451
481
 
452
- <ApiTable :data="[
453
- { Attribute: 'title', Description: 'Dialog title rendered in the header as an `<h2>`' },
454
- { Attribute: 'open', Description: 'Whether the dialog is open. Reflects to attribute' },
455
- { Attribute: 'light-dismiss', Description: 'Close when the backdrop is clicked' },
456
- { Attribute: 'without-header', Description: 'Hide the header entirely (title and close slot)' },
457
- ]" />
482
+ - **title**: `string` — Dialog title rendered in the header.
483
+ - **open**: `boolean` (default: `false`) Whether the dialog is open.
484
+ - **light-dismiss**: `boolean` (default: `false`) — Close when the backdrop is clicked.
485
+ - **without-header**: `boolean` (default: `false`) Hide the header entirely (title and close slot).
458
486
 
459
487
  ### Commands
460
488
 
@@ -468,46 +496,37 @@ Open and close the dialog by toggling its `open` property, or via the [Invoker C
468
496
  > ```
469
497
  >
470
498
 
471
- <ApiTable :data="[
472
- { Command: '--show', Description: 'Sets `open = true`' },
473
- { Command: '--hide', Description: 'Sets `open = false`' },
474
- ]" />
499
+ - `--show` — Sets `open = true`.
500
+ - `--hide` Sets `open = false`.
475
501
 
476
502
  ### Events
477
503
 
478
- <ApiTable :data="[
479
- { Event: 'show', Description: 'Fired when the dialog opens' },
480
- { Event: 'after-show', Description: 'Fired after the open animation completes' },
481
- { Event: 'hide', Description: 'Fired when the dialog is about to close. Cancelable — call `event.preventDefault()` to keep it open' },
482
- { Event: 'after-hide', Description: 'Fired after the close animation completes' },
483
- ]" />
504
+ - **show** — Fired when the dialog opens. Not cancelable.
505
+ - **after-show** Fired after the open animation completes.
506
+ - **hide** (cancelable) Fired when the dialog is about to close. Cancelable — call `event.preventDefault()` to keep it open.
507
+ - **after-hide** Fired after the close animation completes.
484
508
 
485
509
  ### Slots
486
510
 
487
- <ApiTable :data="[
488
- { Slot: '(default)', Description: 'Body content' },
489
- { Slot: 'title', Description: 'Custom heading element. Overrides the default `<h2>` rendered from the `title` property' },
490
- { Slot: 'close', Description: 'Close button (typically `<button class=&quot;l-close&quot;>`)' },
491
- { Slot: 'footer', Description: 'Footer actions' },
492
- ]" />
511
+ - **(default)** — Body content.
512
+ - **title** — Custom heading element. Overrides the default `<h2>` rendered from the `title` property.
513
+ - **close** Close button (typically `<button class="l-close">`).
514
+ - **footer** Footer actions.
493
515
 
494
516
  ### CSS parts
495
517
 
496
- <ApiTable :data="[
497
- { Part: 'dialog', Description: 'The native `<dialog>` element' },
498
- { Part: 'header', Description: 'The header wrapper containing the title and close slot' },
499
- { Part: 'title', Description: 'The dialog title heading' },
500
- { Part: 'body', Description: 'The body wrapper around the default slot' },
501
- { Part: 'footer', Description: 'The footer wrapper around the footer slot' },
502
- ]" />
518
+ - `dialog` — The native `<dialog>` element.
519
+ - `header` The header wrapper containing the title and close slot.
520
+ - `title` The dialog title heading.
521
+ - `body` The body wrapper around the default slot.
522
+ - `footer` The footer wrapper around the footer slot.
503
523
 
504
524
  ### CSS custom properties
505
525
 
506
- <ApiTable :data="[
507
- { Name: '--width', Description: 'Dialog width. Default `31rem`' },
508
- { Name: '--border-radius', Description: 'Border radius. Default `6px`' },
509
- { Name: '--show-duration', Description: 'Open transition duration. Default `200ms`' },
510
- { Name: '--hide-duration', Description: 'Close transition duration. Default `200ms`' },
511
- { Name: '--backdrop', Description: 'Backdrop color' },
512
- { Name: '--backdrop-blur', Description: 'Backdrop blur amount (any CSS length). Default `0`' },
513
- ]" />
526
+ - `--width` (default: `31rem`) — Dialog width.
527
+ - `--border-radius` (default: `6px`) Dialog border radius.
528
+ - `--padding` (default: `1.5rem`) — Padding applied to the header, footer, and inline-padding of the body. Set to `0` to remove all internal spacing (e.g. for edge-to-edge media).
529
+ - `--show-duration` (default: `200ms`) — Open transition duration.
530
+ - `--hide-duration` (default: `200ms`) — Close transition duration.
531
+ - `--backdrop` Backdrop color.
532
+ - `--backdrop-blur` (default: `0`) — Backdrop blur amount (any CSS length). `0` means no blur; set e.g. `4px` for a subtle frost.
@@ -6,10 +6,7 @@ outline: deep
6
6
 
7
7
  Drawers display supplementary content in a panel that slides in from a screen edge. Commonly used for navigation menus, filters, and detail views without leaving the current page.
8
8
 
9
- <ElementSpec
10
- tag="l-drawer"
11
- type="shadow"
12
- />
9
+ **`<l-drawer>`** — Custom Element · Shadow DOM
13
10
 
14
11
  ## Options
15
12
 
@@ -314,27 +311,24 @@ Right-side filter panel with a footer for actions.
314
311
 
315
312
  ### Criteria
316
313
 
317
- | Check | Description |
318
- |-------|-------------|
319
- | Role | Rendered as a native `<dialog>` in the shadow root built-in `dialog` role and modal semantics |
320
- | Accessible name | The `title` property is rendered as an `<h2>` inside the drawer header |
321
- | Focus management | Focus is trapped inside the modal; moves to the first focusable element on open |
322
- | Focus restoration | Focus returns to the trigger element when the drawer closes |
323
- | Close button | Consumer provides the close button via `slot="close"` with `aria-label="Close"` |
324
- | Motion | Slide animation respects `prefers-reduced-motion` |
314
+ - **Role** Rendered as a native `<dialog>` in the shadow root — built-in `dialog` role and modal semantics
315
+ - **Accessible name** — The `title` property is rendered as an `<h2>` inside the drawer header
316
+ - **Focus management** Focus is trapped inside the modal; moves to the first focusable element on open
317
+ - **Focus restoration** Focus returns to the trigger element when the drawer closes
318
+ - **Close button** Consumer provides the close button via `slot="close"` with `aria-label="Close"`
319
+ - **Motion** Slide animation respects `prefers-reduced-motion`
325
320
 
326
321
  ### Rules
322
+
327
323
  - Always set a meaningful `title` — it becomes the drawer heading and accessible name
328
324
  - Put the close button in `slot="close"` with `class="l-close"` and `command="--hide"` `commandfor="<id>"`
329
325
  - Use `command="--show"` and `command="--hide"` with `commandfor` pointing at the drawer id. The `--` prefix is mandatory for custom elements
330
326
 
331
327
  ### Keyboard interactions
332
328
 
333
- | Key | Description |
334
- |-----|-------------|
335
- | Escape | Closes the drawer |
336
- | Tab | Cycles focus through focusable elements inside the drawer |
337
- | Shift + Tab | Cycles focus backward through focusable elements inside the drawer |
329
+ - `Escape` Closes the drawer
330
+ - `Tab` — Cycles focus through focusable elements inside the drawer
331
+ - `Shift + Tab` — Cycles focus backward through focusable elements inside the drawer
338
332
 
339
333
  ## API reference
340
334
 
@@ -346,12 +340,11 @@ import 'luxen-ui/drawer';
346
340
 
347
341
  ### Attributes & Properties
348
342
 
349
- <ApiTable :data="[
350
- { Attribute: 'title', Description: 'Drawer title rendered in the header as an `<h2>`' },
351
- { Attribute: 'open', Description: 'Whether the drawer is open. Reflects to attribute' },
352
- { Attribute: 'light-dismiss', Description: 'Close when the backdrop is clicked' },
353
- { Attribute: 'placement', Description: 'Edge the drawer slides from: `start` (default), `end`, or `bottom`' },
354
- ]" />
343
+ - **placement**: `'start' | 'end' | 'bottom' | undefined` — Edge the drawer slides in from. Defaults to the start (inline-start) edge.
344
+ - **title**: `string` Dialog title rendered in the header.
345
+ - **open**: `boolean` (default: `false`) — Whether the dialog is open.
346
+ - **light-dismiss**: `boolean` (default: `false`) — Close when the backdrop is clicked.
347
+ - **without-header**: `boolean` (default: `false`) Hide the header entirely (title and close slot).
355
348
 
356
349
  ### Commands
357
350
 
@@ -365,44 +358,38 @@ Open and close the drawer by toggling its `open` property, or via the [Invoker C
365
358
  > ```
366
359
  >
367
360
 
368
- <ApiTable :data="[
369
- { Command: '--show', Description: 'Sets `open = true`' },
370
- { Command: '--hide', Description: 'Sets `open = false`' },
371
- ]" />
361
+ - `--show` — Sets `open = true`.
362
+ - `--hide` Sets `open = false`.
372
363
 
373
364
  ### Events
374
365
 
375
- <ApiTable :data="[
376
- { Event: 'show', Description: 'Fired when the drawer opens' },
377
- { Event: 'after-show', Description: 'Fired after the open animation completes' },
378
- { Event: 'hide', Description: 'Fired when the drawer is about to close. Cancelable — call `event.preventDefault()` to keep it open' },
379
- { Event: 'after-hide', Description: 'Fired after the close animation completes' },
380
- ]" />
366
+ - **show** — Fired when the drawer opens. Not cancelable.
367
+ - **after-show** Fired after the open animation completes.
368
+ - **hide** (cancelable) Fired when the drawer is about to close. Cancelable — call `event.preventDefault()` to keep it open.
369
+ - **after-hide** Fired after the close animation completes.
381
370
 
382
371
  ### Slots
383
372
 
384
- <ApiTable :data="[
385
- { Slot: '(default)', Description: 'Body content' },
386
- { Slot: 'close', Description: 'Close button (typically `<button class=&quot;l-close&quot;>`)' },
387
- { Slot: 'footer', Description: 'Footer actions' },
388
- ]" />
373
+ - **(default)** — Body content.
374
+ - **close** Close button (typically `<button class="l-close">`).
375
+ - **footer** Footer actions.
376
+ - **title** Custom heading element. Overrides the default `<h2>` rendered from the `title` property.
389
377
 
390
378
  ### CSS parts
391
379
 
392
- <ApiTable :data="[
393
- { Part: 'dialog', Description: 'The native `<dialog>` element' },
394
- { Part: 'header', Description: 'The header wrapper containing the title and close slot' },
395
- { Part: 'title', Description: 'The drawer title heading' },
396
- { Part: 'body', Description: 'The body wrapper around the default slot' },
397
- { Part: 'footer', Description: 'The footer wrapper around the footer slot' },
398
- ]" />
380
+ - `dialog` — The native `<dialog>` element.
381
+ - `header` The header wrapper containing the title and close slot.
382
+ - `title` The drawer title heading.
383
+ - `body` The body wrapper around the default slot.
384
+ - `footer` The footer wrapper around the footer slot.
399
385
 
400
386
  ### CSS custom properties
401
387
 
402
- <ApiTable :data="[
403
- { Name: '--size', Description: 'Drawer size on the axis perpendicular to its edge (width for `start`/`end`, height for `bottom`). Default `320px`' },
404
- { Name: '--border-radius', Description: 'Border radius on the inner edges. Default `0.75rem`' },
405
- { Name: '--show-duration', Description: 'Open transition duration. Default `200ms`' },
406
- { Name: '--hide-duration', Description: 'Close transition duration. Default `200ms`' },
407
- { Name: '--backdrop', Description: 'Backdrop color' },
408
- ]" />
388
+ - `--size` (default: `320px`) — Drawer size on the axis perpendicular to its edge (width for `start`/`end`, height for `bottom`).
389
+ - `--border-radius` (default: `6px`) Drawer border radius on the inner edges.
390
+ - `--show-duration` (default: `200ms`) Open transition duration.
391
+ - `--hide-duration` (default: `200ms`) — Close transition duration.
392
+ - `--backdrop` Backdrop color.
393
+ - `--width` (default: `31rem`) Dialog width.
394
+ - `--padding` (default: `1.5rem`) — Padding applied to the header, footer, and inline-padding of the body. Set to `0` to remove all internal spacing (e.g. for edge-to-edge media).
395
+ - `--backdrop-blur` (default: `0`) — Backdrop blur amount (any CSS length). `0` means no blur; set e.g. `4px` for a subtle frost.
@@ -6,10 +6,7 @@ outline: deep
6
6
 
7
7
  Progress bars are used to indicate the completion status of a task. Commonly used for file uploads, multi-step processes, and loading indicators with a known duration.
8
8
 
9
- <ElementSpec
10
- tag="progress"
11
- type="native"
12
- />
9
+ **`.l-progress`** — Native HTML Element
13
10
 
14
11
  ## Options
15
12
 
@@ -91,14 +88,13 @@ Add `data-orientation="vertical"` attribute.
91
88
 
92
89
  ### Criteria
93
90
 
94
- | Check | Description |
95
- |-------|-------------|
96
- | Role | Uses native `<progress>` implicit `progressbar` role |
97
- | Accessible name | Must have an associated `<label>` or `aria-label` |
98
- | Color | Indicator and track colors meet non-text contrast ratio |
99
- | Motion | Indeterminate animation respects `prefers-reduced-motion` |
91
+ - **Role** Uses native `<progress>` — implicit `progressbar` role
92
+ - **Accessible name** — Must have an associated `<label>` or `aria-label`
93
+ - **Color** Indicator and track colors meet non-text contrast ratio
94
+ - **Motion** Indeterminate animation respects `prefers-reduced-motion`
100
95
 
101
96
  ### Rules
97
+
102
98
  - Always pair the `<progress>` element with a visible `<label>` or `aria-label`
103
99
  - Set `value` for determinate progress; omit for indeterminate
104
100
 
@@ -112,22 +108,16 @@ Add `data-orientation="vertical"` attribute.
112
108
 
113
109
  ### Attributes & Properties
114
110
 
115
- <ApiTable :data="[
116
- { Attribute: 'value', Description: 'Current progress between `0` and `1` (omit for indeterminate)' },
117
- { Attribute: 'data-orientation=&quot;vertical&quot;', Description: 'Vertical orientation' },
118
- ]" />
111
+ - **value** — Current progress between `0` and `1` (omit for indeterminate).
112
+ - **data-orientation** vertical Vertical orientation.
119
113
 
120
114
  ### CSS classes
121
115
 
122
- <ApiTable :data="[
123
- { Class: '.l-progress', Description: 'Base progress bar style' },
124
- ]" />
116
+ - `.l-progress` — Base progress bar style.
125
117
 
126
118
  ### CSS custom properties
127
119
 
128
- <ApiTable :data="[
129
- { Name: '--size', Description: 'Bar thickness (default: 4px)' },
130
- { Name: '--track-color', Description: 'Track background color' },
131
- { Name: '--indicator-color', Description: 'Fill/indicator color' },
132
- { Name: '--indeterminate-animation', Description: 'Animation name for indeterminate state' },
133
- ]" />
120
+ - `--size` (default: `4px`) — Bar thickness.
121
+ - `--track-color` Track background color.
122
+ - `--indicator-color` Fill/indicator color.
123
+ - `--indeterminate-animation` Animation name for the indeterminate state.
@@ -0,0 +1,211 @@
1
+ ---
2
+ outline: deep
3
+ ---
4
+
5
+ # Prose Editor
6
+
7
+ A rich text editor built on [Tiptap](https://tiptap.dev) (ProseMirror). Form-associated — its value is the editor HTML, so it submits inside a `<form>` like a native field.
8
+
9
+ ```html
10
+ <l-prose-editor placeholder="Write something…"></l-prose-editor>
11
+ ```
12
+
13
+ The editable area renders in light DOM, so its content styles ship as a separate stylesheet you import once globally. See [Importing](#importing).
14
+
15
+ **`<l-prose-editor>`** — Custom Element · Shadow DOM
16
+
17
+ ## Options
18
+
19
+ ### Basic
20
+
21
+ The default toolbar covers headings, marks, lists, links, code, an emoji picker and undo/redo. Set initial content with `initial-html`.
22
+
23
+ ```html
24
+ <l-prose-editor
25
+ placeholder="Write something…"
26
+ initial-html="<h2>Release notes</h2><p>This editor ships with a <strong>default</strong> toolbar covering headings, marks, lists, links and more.</p><ul><li>Built on Tiptap</li><li>Form-associated</li></ul>"
27
+ ></l-prose-editor>
28
+ ```
29
+
30
+ ### Toolbar preset
31
+
32
+ Set `toolbar-preset="minimal"` for a compact bold/italic/underline toolbar.
33
+
34
+ ```html
35
+ <l-prose-editor
36
+ toolbar-preset="minimal"
37
+ placeholder="Bold, italic, underline only…"
38
+ ></l-prose-editor>
39
+ ```
40
+
41
+ ### Custom toolbar
42
+
43
+ Set `toolbar` to a comma-separated list of commands to build your own layout. Use `divider` to insert a separator.
44
+
45
+ ```html
46
+ <l-prose-editor
47
+ toolbar="bold,italic,link,divider,bulletlist,orderedlist,divider,undo,redo"
48
+ placeholder="Custom toolbar…"
49
+ ></l-prose-editor>
50
+ ```
51
+
52
+ Available commands: `heading-1`, `heading-2`, `heading-3`, `bold`, `italic`, `underline`, `strike`, `highlight`, `bulletlist`, `orderedlist`, `blockquote`, `code-block`, `horizontal-rule`, `link`, `emoji`, `attachment`, `undo`, `redo`, `divider`.
53
+
54
+ ### Toolbar placement
55
+
56
+ Set `toolbar-placement="bottom"` to move the toolbar below the content.
57
+
58
+ ```html
59
+ <l-prose-editor
60
+ toolbar-placement="bottom"
61
+ placeholder="Toolbar sits below the content…"
62
+ ></l-prose-editor>
63
+ ```
64
+
65
+ ## Examples
66
+
67
+ ### Form integration
68
+
69
+ The editor participates in forms via its `name` attribute. The submitted value is the HTML string; `required` blocks submission while empty.
70
+
71
+ ```html
72
+ <form
73
+ class="flex flex-col items-start gap-4"
74
+ onsubmit="
75
+ event.preventDefault();
76
+ const data = new FormData(event.target);
77
+ alert('description = ' + data.get('description'));
78
+ "
79
+ >
80
+ <label class="flex w-full flex-col gap-1">
81
+ <span class="text-sm font-medium">Description</span>
82
+ <l-prose-editor
83
+ name="description"
84
+ required
85
+ toolbar-preset="minimal"
86
+ placeholder="Describe your product…"
87
+ ></l-prose-editor>
88
+ </label>
89
+ <button
90
+ type="submit"
91
+ class="l-button"
92
+ data-variant="primary"
93
+ >
94
+ Submit
95
+ </button>
96
+ </form>
97
+ ```
98
+
99
+ ## Accessibility
100
+
101
+ ### Criteria
102
+
103
+ - **Toolbar role** — The toolbar uses `role="toolbar"` with an accessible label
104
+ - **Button state** — Each toolbar button exposes `aria-pressed` reflecting whether the mark/format is active
105
+ - **Button label** — Icon-only buttons carry an `aria-label` and `title` describing the action
106
+ - **Focus state** — Visible focus ring on toolbar buttons for keyboard users
107
+ - **Form validation** — When `required`, an empty editor reports a `valueMissing` validation message to the form
108
+
109
+ ### Rules
110
+
111
+ - Associate a visible `<label>` with the editor, or set `aria-label` on the host element
112
+ - Keep custom toolbars logically ordered so keyboard users encounter commands in a predictable sequence
113
+
114
+ ### Keyboard interactions
115
+
116
+ - `Tab` — Moves focus into the toolbar, then into the editable content
117
+ - `Ctrl/Cmd + B` — Toggles bold
118
+ - `Ctrl/Cmd + I` — Toggles italic
119
+ - `Ctrl/Cmd + U` — Toggles underline
120
+ - `Ctrl/Cmd + Z` — Undo
121
+ - `Ctrl/Cmd + Shift + Z` — Redo
122
+ - `Escape` — Closes the emoji picker when open
123
+
124
+ ## API reference
125
+
126
+ ### Importing
127
+
128
+ Import the element and the content stylesheet once globally. The stylesheet styles the editable area, which renders in light DOM to avoid `contenteditable` caret bugs inside shadow trees.
129
+
130
+ ```js
131
+ import 'luxen-ui/prose-editor';
132
+ ```
133
+
134
+ ```css
135
+ @import 'luxen-ui/css/prose-editor';
136
+ ```
137
+
138
+ ### Attributes & Properties
139
+
140
+ - **editor**: `Editor` — The Tiptap editor instance. Available after the first render.
141
+ - **initial-html**: `string` — Initial HTML content.
142
+ - **initial-json**: `string` — Initial content as a serialized ProseMirror JSON string.
143
+ - **editor-class**: `string` (default: `'prose'`) — Class applied to the `.ProseMirror` editable element (e.g. for Tailwind Typography `prose`).
144
+ - **toolbar**: `ToolbarCommandName[]` (default: `[]`) — Explicit list of toolbar commands. Overrides `toolbar-preset` when set.
145
+ - **toolbar-preset**: `'default' | 'minimal'` (default: `'default'`) — Built-in toolbar layout used when `toolbar` is not set.
146
+ - **toolbar-placement**: `'top' | 'bottom'` (default: `'top'`) — Where the toolbar sits relative to the content.
147
+ - **autofocus**: `boolean` (default: `false`) — Focus the editor on creation.
148
+ - **placeholder**: `string` — Placeholder shown when the editor is empty.
149
+ - **validationTarget**: `HTMLElement | undefined`
150
+
151
+ ### Methods
152
+
153
+ - **getHTML()** → `string` — Get the current content as an HTML string. Empty paragraph resolves to `''`.
154
+ - **getJSON()** → `JSONContent` — Get the current content as ProseMirror JSON.
155
+ - **clear()** — Remove all content.
156
+ - **focus()**
157
+ - **blur()**
158
+ - **toggleBold()**
159
+ - **toggleItalic()**
160
+ - **toggleUnderline()**
161
+ - **toggleStrike()**
162
+ - **toggleHighlight()**
163
+ - **toggleHeading(level: 1 | 2 | 3)**
164
+ - **toggleBulletList()**
165
+ - **toggleOrderedList()**
166
+ - **toggleBlockquote()**
167
+ - **toggleCodeBlock()**
168
+ - **setHorizontalRule()**
169
+ - **undo()**
170
+ - **redo()**
171
+ - **toggleLink()**
172
+ - **formResetCallback()**
173
+
174
+ ### Events
175
+
176
+ - **change** — Fired when the content changes. `detail` is `{ html, json }`.
177
+ - **add-file** — Fired when the attachment toolbar button is clicked.
178
+
179
+ ### Slots
180
+
181
+ - **toolbar-start** — Content placed before the generated toolbar buttons.
182
+ - **toolbar-end** — Content placed after the generated toolbar buttons.
183
+
184
+ ### CSS Parts
185
+
186
+ - `wrapper` — The editor frame wrapping the toolbar and content.
187
+ - `toolbar` — The toolbar row.
188
+ - `toolbar-button` — Any toolbar button.
189
+ - `divider` — A toolbar divider.
190
+ - `editor` — The container around the editable content.
191
+
192
+ ### CSS custom properties
193
+
194
+ - `--border-color` — Color of the editor frame border.
195
+ - `--border-width` — Width of the editor frame border.
196
+ - `--border-radius` — Corner radius of the editor frame.
197
+ - `--background` — Background color of the editor.
198
+ - `--color` — Text color of the editor.
199
+ - `--toolbar-background` — Background color of the toolbar.
200
+ - `--toolbar-padding` — Padding around the toolbar.
201
+ - `--toolbar-gap` — Gap between toolbar buttons.
202
+ - `--toolbar-divider-color` — Color of toolbar dividers.
203
+ - `--toolbar-button-size` — Size of toolbar buttons.
204
+ - `--toolbar-button-radius` — Corner radius of toolbar buttons.
205
+ - `--toolbar-button-color` — Icon color of inactive toolbar buttons.
206
+ - `--toolbar-button-color-active` — Icon color of hovered/active toolbar buttons.
207
+ - `--toolbar-button-background-hover` — Background of hovered toolbar buttons.
208
+ - `--toolbar-button-background-active` — Background of active toolbar buttons.
209
+ - `--content-padding` (default: `0.75rem 1rem`) — Padding inside the editable content region.
210
+ - `--content-min-height` (default: `8rem`) — Minimum height of the editable content region.
211
+ - `--placeholder-color` — Placeholder text color.