luxen-ui 0.1.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 (201) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +98 -0
  3. package/dist/css/elements/avatar.css +20 -0
  4. package/dist/css/elements/badge.css +159 -0
  5. package/dist/css/elements/button.css +171 -0
  6. package/dist/css/elements/close-button/circle.css +66 -0
  7. package/dist/css/elements/close-button/ring.css +71 -0
  8. package/dist/css/elements/close-button/square.css +70 -0
  9. package/dist/css/elements/disclosure.css +137 -0
  10. package/dist/css/elements/divider.css +75 -0
  11. package/dist/css/elements/input-otp.css +164 -0
  12. package/dist/css/elements/input-stepper/default.css +245 -0
  13. package/dist/css/elements/input-stepper/rounded.css +238 -0
  14. package/dist/css/elements/kbd.css +21 -0
  15. package/dist/css/elements/progress.css +114 -0
  16. package/dist/css/elements/select.css +71 -0
  17. package/dist/css/elements/skeleton.css +89 -0
  18. package/dist/css/elements/tabs/enclosed.css +148 -0
  19. package/dist/css/elements/tabs/line.css +138 -0
  20. package/dist/css/elements/toast.css +260 -0
  21. package/dist/css/index.css +885 -0
  22. package/dist/custom-elements.json +14424 -0
  23. package/dist/define.d.ts +9 -0
  24. package/dist/define.d.ts.map +1 -0
  25. package/dist/define.js +16 -0
  26. package/dist/elements/avatar/avatar.css +128 -0
  27. package/dist/elements/avatar/avatar.d.ts +21 -0
  28. package/dist/elements/avatar/avatar.d.ts.map +1 -0
  29. package/dist/elements/avatar/avatar.js +106 -0
  30. package/dist/elements/avatar/index.d.ts +8 -0
  31. package/dist/elements/avatar/index.d.ts.map +1 -0
  32. package/dist/elements/avatar/index.js +4 -0
  33. package/dist/elements/badge/badge.d.ts +17 -0
  34. package/dist/elements/badge/badge.d.ts.map +1 -0
  35. package/dist/elements/badge/badge.js +34 -0
  36. package/dist/elements/badge/index.d.ts +8 -0
  37. package/dist/elements/badge/index.d.ts.map +1 -0
  38. package/dist/elements/badge/index.js +4 -0
  39. package/dist/elements/carousel/carousel.css +205 -0
  40. package/dist/elements/carousel/carousel.d.ts +148 -0
  41. package/dist/elements/carousel/carousel.d.ts.map +1 -0
  42. package/dist/elements/carousel/carousel.js +473 -0
  43. package/dist/elements/carousel/index.d.ts +8 -0
  44. package/dist/elements/carousel/index.d.ts.map +1 -0
  45. package/dist/elements/carousel/index.js +4 -0
  46. package/dist/elements/carousel-item/carousel-item.css +11 -0
  47. package/dist/elements/carousel-item/carousel-item.d.ts +13 -0
  48. package/dist/elements/carousel-item/carousel-item.d.ts.map +1 -0
  49. package/dist/elements/carousel-item/carousel-item.js +20 -0
  50. package/dist/elements/carousel-item/index.d.ts +8 -0
  51. package/dist/elements/carousel-item/index.d.ts.map +1 -0
  52. package/dist/elements/carousel-item/index.js +4 -0
  53. package/dist/elements/dialog/dialog.css +92 -0
  54. package/dist/elements/dialog/dialog.d.ts +56 -0
  55. package/dist/elements/dialog/dialog.d.ts.map +1 -0
  56. package/dist/elements/dialog/dialog.js +204 -0
  57. package/dist/elements/dialog/dialog.styles.d.ts +8 -0
  58. package/dist/elements/dialog/dialog.styles.d.ts.map +1 -0
  59. package/dist/elements/dialog/dialog.styles.js +8 -0
  60. package/dist/elements/dialog/index.d.ts +8 -0
  61. package/dist/elements/dialog/index.d.ts.map +1 -0
  62. package/dist/elements/dialog/index.js +4 -0
  63. package/dist/elements/divider/divider.d.ts +23 -0
  64. package/dist/elements/divider/divider.d.ts.map +1 -0
  65. package/dist/elements/divider/divider.js +49 -0
  66. package/dist/elements/divider/index.d.ts +8 -0
  67. package/dist/elements/divider/index.d.ts.map +1 -0
  68. package/dist/elements/divider/index.js +4 -0
  69. package/dist/elements/drawer/drawer.css +66 -0
  70. package/dist/elements/drawer/drawer.d.ts +34 -0
  71. package/dist/elements/drawer/drawer.d.ts.map +1 -0
  72. package/dist/elements/drawer/drawer.js +46 -0
  73. package/dist/elements/drawer/index.d.ts +8 -0
  74. package/dist/elements/drawer/index.d.ts.map +1 -0
  75. package/dist/elements/drawer/index.js +4 -0
  76. package/dist/elements/dropdown/dropdown.css +31 -0
  77. package/dist/elements/dropdown/dropdown.d.ts +64 -0
  78. package/dist/elements/dropdown/dropdown.d.ts.map +1 -0
  79. package/dist/elements/dropdown/dropdown.js +322 -0
  80. package/dist/elements/dropdown/index.d.ts +8 -0
  81. package/dist/elements/dropdown/index.d.ts.map +1 -0
  82. package/dist/elements/dropdown/index.js +4 -0
  83. package/dist/elements/dropdown-item/dropdown-item.css +51 -0
  84. package/dist/elements/dropdown-item/dropdown-item.d.ts +25 -0
  85. package/dist/elements/dropdown-item/dropdown-item.d.ts.map +1 -0
  86. package/dist/elements/dropdown-item/dropdown-item.js +110 -0
  87. package/dist/elements/dropdown-item/index.d.ts +8 -0
  88. package/dist/elements/dropdown-item/index.d.ts.map +1 -0
  89. package/dist/elements/dropdown-item/index.js +4 -0
  90. package/dist/elements/icon/icon.css +10 -0
  91. package/dist/elements/icon/icon.d.ts +19 -0
  92. package/dist/elements/icon/icon.d.ts.map +1 -0
  93. package/dist/elements/icon/icon.js +53 -0
  94. package/dist/elements/icon/index.d.ts +8 -0
  95. package/dist/elements/icon/index.d.ts.map +1 -0
  96. package/dist/elements/icon/index.js +4 -0
  97. package/dist/elements/input-otp/index.d.ts +8 -0
  98. package/dist/elements/input-otp/index.d.ts.map +1 -0
  99. package/dist/elements/input-otp/index.js +4 -0
  100. package/dist/elements/input-otp/input-otp.d.ts +31 -0
  101. package/dist/elements/input-otp/input-otp.d.ts.map +1 -0
  102. package/dist/elements/input-otp/input-otp.js +139 -0
  103. package/dist/elements/input-stepper/index.d.ts +8 -0
  104. package/dist/elements/input-stepper/index.d.ts.map +1 -0
  105. package/dist/elements/input-stepper/index.js +4 -0
  106. package/dist/elements/input-stepper/input-stepper.d.ts +63 -0
  107. package/dist/elements/input-stepper/input-stepper.d.ts.map +1 -0
  108. package/dist/elements/input-stepper/input-stepper.js +249 -0
  109. package/dist/elements/popover/index.d.ts +8 -0
  110. package/dist/elements/popover/index.d.ts.map +1 -0
  111. package/dist/elements/popover/index.js +4 -0
  112. package/dist/elements/popover/popover.css +61 -0
  113. package/dist/elements/popover/popover.d.ts +62 -0
  114. package/dist/elements/popover/popover.d.ts.map +1 -0
  115. package/dist/elements/popover/popover.js +244 -0
  116. package/dist/elements/rating/index.d.ts +8 -0
  117. package/dist/elements/rating/index.d.ts.map +1 -0
  118. package/dist/elements/rating/index.js +4 -0
  119. package/dist/elements/rating/rating.css +102 -0
  120. package/dist/elements/rating/rating.d.ts +38 -0
  121. package/dist/elements/rating/rating.d.ts.map +1 -0
  122. package/dist/elements/rating/rating.js +193 -0
  123. package/dist/elements/skeleton/index.d.ts +8 -0
  124. package/dist/elements/skeleton/index.d.ts.map +1 -0
  125. package/dist/elements/skeleton/index.js +4 -0
  126. package/dist/elements/skeleton/skeleton.d.ts +12 -0
  127. package/dist/elements/skeleton/skeleton.d.ts.map +1 -0
  128. package/dist/elements/skeleton/skeleton.js +13 -0
  129. package/dist/elements/spinner/index.d.ts +8 -0
  130. package/dist/elements/spinner/index.d.ts.map +1 -0
  131. package/dist/elements/spinner/index.js +4 -0
  132. package/dist/elements/spinner/spinner.css +28 -0
  133. package/dist/elements/spinner/spinner.d.ts +16 -0
  134. package/dist/elements/spinner/spinner.d.ts.map +1 -0
  135. package/dist/elements/spinner/spinner.js +37 -0
  136. package/dist/elements/tabs/index.d.ts +8 -0
  137. package/dist/elements/tabs/index.d.ts.map +1 -0
  138. package/dist/elements/tabs/index.js +4 -0
  139. package/dist/elements/tabs/tabs.d.ts +48 -0
  140. package/dist/elements/tabs/tabs.d.ts.map +1 -0
  141. package/dist/elements/tabs/tabs.js +210 -0
  142. package/dist/elements/toast/index.d.ts +9 -0
  143. package/dist/elements/toast/index.d.ts.map +1 -0
  144. package/dist/elements/toast/index.js +5 -0
  145. package/dist/elements/toast/toast.d.ts +72 -0
  146. package/dist/elements/toast/toast.d.ts.map +1 -0
  147. package/dist/elements/toast/toast.js +375 -0
  148. package/dist/elements/tooltip/index.d.ts +8 -0
  149. package/dist/elements/tooltip/index.d.ts.map +1 -0
  150. package/dist/elements/tooltip/index.js +4 -0
  151. package/dist/elements/tooltip/tooltip.css +37 -0
  152. package/dist/elements/tooltip/tooltip.d.ts +59 -0
  153. package/dist/elements/tooltip/tooltip.d.ts.map +1 -0
  154. package/dist/elements/tooltip/tooltip.js +231 -0
  155. package/dist/elements/tree/index.d.ts +8 -0
  156. package/dist/elements/tree/index.d.ts.map +1 -0
  157. package/dist/elements/tree/index.js +4 -0
  158. package/dist/elements/tree/tree.css +26 -0
  159. package/dist/elements/tree/tree.d.ts +76 -0
  160. package/dist/elements/tree/tree.d.ts.map +1 -0
  161. package/dist/elements/tree/tree.js +432 -0
  162. package/dist/elements/tree-item/index.d.ts +8 -0
  163. package/dist/elements/tree-item/index.d.ts.map +1 -0
  164. package/dist/elements/tree-item/index.js +4 -0
  165. package/dist/elements/tree-item/tree-item.css +172 -0
  166. package/dist/elements/tree-item/tree-item.d.ts +74 -0
  167. package/dist/elements/tree-item/tree-item.d.ts.map +1 -0
  168. package/dist/elements/tree-item/tree-item.js +301 -0
  169. package/dist/index.d.ts +6 -0
  170. package/dist/index.d.ts.map +1 -0
  171. package/dist/index.js +4 -0
  172. package/dist/registry.d.ts +22 -0
  173. package/dist/registry.d.ts.map +1 -0
  174. package/dist/registry.js +33 -0
  175. package/dist/shared/controllers/popover.d.ts +44 -0
  176. package/dist/shared/controllers/popover.d.ts.map +1 -0
  177. package/dist/shared/controllers/popover.js +359 -0
  178. package/dist/shared/luxen-element.d.ts +20 -0
  179. package/dist/shared/luxen-element.d.ts.map +1 -0
  180. package/dist/shared/luxen-element.js +23 -0
  181. package/dist/shared/luxen-form-associated-element.d.ts +49 -0
  182. package/dist/shared/luxen-form-associated-element.d.ts.map +1 -0
  183. package/dist/shared/luxen-form-associated-element.js +123 -0
  184. package/dist/shared/styles/host.css +13 -0
  185. package/dist/shared/styles/host.styles.d.ts +9 -0
  186. package/dist/shared/styles/host.styles.d.ts.map +1 -0
  187. package/dist/shared/styles/host.styles.js +9 -0
  188. package/dist/skills/luxen-ui/SKILL.md +82 -0
  189. package/dist/skills/luxen-ui/references/avatar.md +259 -0
  190. package/dist/skills/luxen-ui/references/badge.md +289 -0
  191. package/dist/skills/luxen-ui/references/button.md +309 -0
  192. package/dist/skills/luxen-ui/references/close-button.md +104 -0
  193. package/dist/skills/luxen-ui/references/dialog.md +435 -0
  194. package/dist/skills/luxen-ui/references/drawer.md +400 -0
  195. package/dist/skills/luxen-ui/references/progress.md +133 -0
  196. package/dist/skills/luxen-ui/references/select.md +100 -0
  197. package/dist/skills/luxen-ui/references/toast.md +396 -0
  198. package/dist/skills/luxen-ui/references/tree.md +359 -0
  199. package/package.json +116 -0
  200. package/postcss-plugin-prefix.js +63 -0
  201. package/vite-plugin.ts +29 -0
@@ -0,0 +1,435 @@
1
+ ---
2
+ outline: deep
3
+ ---
4
+
5
+ # Dialog
6
+
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
+
9
+ <ElementSpec
10
+ tag="l-dialog"
11
+ type="shadow"
12
+ />
13
+
14
+ ## Options
15
+
16
+ ### Basic
17
+
18
+ Open with `command="--show"` on a trigger button. Any descendant with `command="--hide"` closes the dialog. Note the `--` prefix — it's required by the native [Invoker Commands API](https://developer.mozilla.org/en-US/docs/Web/API/Invoker_Commands_API) for custom elements.
19
+
20
+ ```html
21
+ <button
22
+ type="button"
23
+ class="l-button"
24
+ command="--show"
25
+ commandfor="my-dialog"
26
+ >
27
+ Open dialog
28
+ </button>
29
+
30
+ <l-dialog
31
+ id="my-dialog"
32
+ title="Dialog title"
33
+ >
34
+ <button
35
+ slot="close"
36
+ type="button"
37
+ class="l-close"
38
+ data-appearance="ring"
39
+ aria-label="Close"
40
+ command="--hide"
41
+ commandfor="my-dialog"
42
+ ></button>
43
+ <article class="h-[340px]">…</article>
44
+ <menu slot="footer">
45
+ <button
46
+ autofocus
47
+ type="button"
48
+ class="l-button"
49
+ command="--hide"
50
+ commandfor="my-dialog"
51
+ >
52
+ Cancel
53
+ </button>
54
+ <button
55
+ type="button"
56
+ class="l-button"
57
+ data-variant="primary"
58
+ >
59
+ Confirm
60
+ </button>
61
+ </menu>
62
+ </l-dialog>
63
+ ```
64
+
65
+ ### Light dismiss
66
+
67
+ Add `light-dismiss` to close when the backdrop is clicked.
68
+
69
+ ```html
70
+ <button
71
+ type="button"
72
+ class="l-button"
73
+ command="--show"
74
+ commandfor="dialog-light-dismiss"
75
+ >
76
+ Open dialog
77
+ </button>
78
+
79
+ <l-dialog
80
+ id="dialog-light-dismiss"
81
+ title="Dialog title"
82
+ light-dismiss
83
+ >
84
+ <button
85
+ slot="close"
86
+ type="button"
87
+ class="l-close"
88
+ data-appearance="ring"
89
+ aria-label="Close"
90
+ command="--hide"
91
+ commandfor="dialog-light-dismiss"
92
+ ></button>
93
+ <article class="py-4">
94
+ <p>Click the backdrop or press Escape to close.</p>
95
+ </article>
96
+ <menu slot="footer">
97
+ <button
98
+ type="button"
99
+ class="l-button"
100
+ command="--hide"
101
+ commandfor="dialog-light-dismiss"
102
+ >
103
+ Close
104
+ </button>
105
+ </menu>
106
+ </l-dialog>
107
+ ```
108
+
109
+ ### Scrollable content
110
+
111
+ Long content can scroll while the header stays in view.
112
+
113
+ ```html
114
+ <button
115
+ type="button"
116
+ class="l-button"
117
+ command="--show"
118
+ commandfor="dialog-scrollable"
119
+ >
120
+ Open dialog
121
+ </button>
122
+
123
+ <l-dialog
124
+ id="dialog-scrollable"
125
+ title="Terms of Service"
126
+ >
127
+ <button
128
+ slot="close"
129
+ type="button"
130
+ class="l-close"
131
+ data-appearance="ring"
132
+ aria-label="Close"
133
+ command="--hide"
134
+ commandfor="dialog-scrollable"
135
+ ></button>
136
+ <article class="flex flex-col gap-4">
137
+ <h3 class="font-semibold">1. Acceptance</h3>
138
+ <p>
139
+ By accessing or using this service, you agree to be bound by these terms. If you disagree with
140
+ any part of the terms, you may not access the service. These terms apply to all visitors,
141
+ users, and others who access or use the service.
142
+ </p>
143
+ <h3 class="font-semibold">2. Accounts</h3>
144
+ <p>
145
+ When you create an account with us, you must provide accurate, complete, and current
146
+ information at all times. Failure to do so constitutes a breach of the terms, which may result
147
+ in immediate termination of your account on our service.
148
+ </p>
149
+ <p>
150
+ You are responsible for safeguarding the password that you use to access the service and for
151
+ any activities or actions under your password, whether your password is with our service or a
152
+ third-party service.
153
+ </p>
154
+ <h3 class="font-semibold">3. Content</h3>
155
+ <p>
156
+ Our service allows you to post, link, store, share and otherwise make available certain
157
+ information, text, graphics, videos, or other material. You are responsible for the content
158
+ that you post, including its legality, reliability, and appropriateness.
159
+ </p>
160
+ <p>
161
+ By posting content, you grant us the right and license to use, modify, publicly perform,
162
+ publicly display, reproduce, and distribute such content on and through the service. You
163
+ retain any and all of your rights to any content you submit, post or display.
164
+ </p>
165
+ <h3 class="font-semibold">4. Prohibited uses</h3>
166
+ <p>
167
+ You may use the service only for lawful purposes and in accordance with these terms. You agree
168
+ not to use the service in any way that violates any applicable national or international law
169
+ or regulation.
170
+ </p>
171
+ <p>
172
+ You may not exploit, harm, or attempt to exploit or harm minors in any way by exposing them to
173
+ inappropriate content, asking for personally identifiable information, or otherwise.
174
+ </p>
175
+ <p>
176
+ You may not transmit, or procure the sending of, any advertising or promotional material,
177
+ including any junk mail, chain letter, spam, or any other similar solicitation.
178
+ </p>
179
+ <h3 class="font-semibold">5. Termination</h3>
180
+ <p>
181
+ We may terminate or suspend your account immediately, without prior notice or liability, for
182
+ any reason whatsoever, including without limitation if you breach the terms. Upon termination,
183
+ your right to use the service will immediately cease.
184
+ </p>
185
+ <p>
186
+ If you wish to terminate your account, you may simply discontinue using the service. All
187
+ provisions of the terms which by their nature should survive termination shall survive
188
+ termination.
189
+ </p>
190
+ <h3 class="font-semibold">6. Limitation of liability</h3>
191
+ <p>
192
+ In no event shall the company, nor its directors, employees, partners, agents, suppliers, or
193
+ affiliates, be liable for any indirect, incidental, special, consequential, or punitive
194
+ damages resulting from your use of the service.
195
+ </p>
196
+ <h3 class="font-semibold">7. Changes</h3>
197
+ <p>
198
+ We reserve the right, at our sole discretion, to modify or replace these terms at any time. If
199
+ a revision is material, we will provide at least 30 days notice prior to any new terms taking
200
+ effect. What constitutes a material change will be determined at our sole discretion.
201
+ </p>
202
+ </article>
203
+ <menu slot="footer">
204
+ <button
205
+ type="button"
206
+ class="l-button"
207
+ command="--hide"
208
+ commandfor="dialog-scrollable"
209
+ >
210
+ Decline
211
+ </button>
212
+ <button
213
+ type="button"
214
+ class="l-button"
215
+ data-variant="primary"
216
+ command="--hide"
217
+ commandfor="dialog-scrollable"
218
+ >
219
+ Accept
220
+ </button>
221
+ </menu>
222
+ </l-dialog>
223
+ ```
224
+
225
+ ### Blurred backdrop
226
+
227
+ Set `--backdrop-blur` to any CSS length to frost the page behind the dialog. Defaults to `0` (no blur).
228
+
229
+ ```html
230
+ <button
231
+ type="button"
232
+ class="l-button"
233
+ command="--show"
234
+ commandfor="dialog-blurred-backdrop"
235
+ >
236
+ Open dialog
237
+ </button>
238
+
239
+ <l-dialog
240
+ id="dialog-blurred-backdrop"
241
+ title="Dialog title"
242
+ style="--backdrop-blur: 4px"
243
+ >
244
+ <button
245
+ slot="close"
246
+ type="button"
247
+ class="l-close"
248
+ data-appearance="ring"
249
+ aria-label="Close"
250
+ command="--hide"
251
+ commandfor="dialog-blurred-backdrop"
252
+ ></button>
253
+ <p>The page behind this dialog is blurred via <code>--backdrop-blur</code>.</p>
254
+ <menu slot="footer">
255
+ <button
256
+ type="button"
257
+ class="l-button"
258
+ command="--hide"
259
+ commandfor="dialog-blurred-backdrop"
260
+ >
261
+ Cancel
262
+ </button>
263
+ <button
264
+ type="button"
265
+ class="l-button"
266
+ data-variant="primary"
267
+ command="--hide"
268
+ commandfor="dialog-blurred-backdrop"
269
+ >
270
+ Confirm
271
+ </button>
272
+ </menu>
273
+ </l-dialog>
274
+ ```
275
+
276
+ ### Form with autofocus
277
+
278
+ Add `autofocus` to any focusable element inside the dialog to focus it automatically on open.
279
+
280
+ ```html
281
+ <button
282
+ type="button"
283
+ class="l-button"
284
+ command="--show"
285
+ commandfor="dialog-form"
286
+ >
287
+ Edit profile
288
+ </button>
289
+
290
+ <l-dialog
291
+ id="dialog-form"
292
+ title="Edit profile"
293
+ >
294
+ <button
295
+ slot="close"
296
+ type="button"
297
+ class="l-close"
298
+ data-appearance="ring"
299
+ aria-label="Close"
300
+ command="--hide"
301
+ commandfor="dialog-form"
302
+ ></button>
303
+ <form class="flex flex-col gap-4">
304
+ <label class="flex flex-col gap-1">
305
+ <span class="text-sm font-medium">Name</span>
306
+ <input
307
+ autofocus
308
+ type="text"
309
+ name="name"
310
+ value="Ada Lovelace"
311
+ required
312
+ class="rounded border px-3 py-2 text-sm outline-none focus:border-sky-500"
313
+ />
314
+ </label>
315
+ <label class="flex flex-col gap-1">
316
+ <span class="text-sm font-medium">Email</span>
317
+ <input
318
+ type="email"
319
+ name="email"
320
+ value="ada@example.com"
321
+ required
322
+ class="rounded border px-3 py-2 text-sm outline-none focus:border-sky-500"
323
+ />
324
+ </label>
325
+ </form>
326
+ <menu slot="footer">
327
+ <button
328
+ type="button"
329
+ class="l-button"
330
+ command="--hide"
331
+ commandfor="dialog-form"
332
+ >
333
+ Cancel
334
+ </button>
335
+ <button
336
+ type="button"
337
+ class="l-button"
338
+ data-variant="primary"
339
+ command="--hide"
340
+ commandfor="dialog-form"
341
+ >
342
+ Save
343
+ </button>
344
+ </menu>
345
+ </l-dialog>
346
+ ```
347
+
348
+ ## Accessibility
349
+
350
+ ### Criteria
351
+
352
+ | Check | Description |
353
+ |-------|-------------|
354
+ | Role | Rendered as a native `<dialog>` in the shadow root — built-in `dialog` role and modal semantics |
355
+ | Accessible name | The `title` property is rendered as an `<h2>` inside the dialog header |
356
+ | Focus management | Focus is trapped inside the modal; moves to the first focusable element on open |
357
+ | Focus restoration | Focus returns to the trigger element when the dialog closes |
358
+ | Close button | Consumer provides the close button via `slot="close"` with `aria-label="Close"` |
359
+ | Motion | Respects `prefers-reduced-motion` |
360
+
361
+ ### Rules
362
+ - Always set a meaningful `title` — it becomes the dialog heading and accessible name
363
+ - Put the close button in `slot="close"` with `class="l-close"` and `command="--hide"` `commandfor="<id>"`
364
+ - Use `command="--show"` and `command="--hide"` with `commandfor` pointing at the dialog id. The `--` prefix is mandatory for custom elements
365
+
366
+ ### Keyboard interactions
367
+
368
+ | Key | Description |
369
+ |-----|-------------|
370
+ | Escape | Closes the dialog |
371
+ | Tab | Cycles focus through focusable elements inside the dialog |
372
+ | Shift + Tab | Cycles focus backward through focusable elements inside the dialog |
373
+
374
+ ## API reference
375
+
376
+ ### Importing
377
+
378
+ ```js
379
+ import 'luxen-ui/dialog';
380
+ ```
381
+
382
+ ### Attributes & Properties
383
+
384
+ <ApiTable :data="[
385
+ { Attribute: 'title', Description: 'Dialog title rendered in the header as an `<h2>`' },
386
+ { Attribute: 'open', Description: 'Whether the dialog is open. Reflects to attribute' },
387
+ { Attribute: 'light-dismiss', Description: 'Close when the backdrop is clicked' },
388
+ ]" />
389
+
390
+ ### Commands
391
+
392
+ Open and close the dialog by toggling its `open` property, or via the [Invoker Commands API](https://developer.mozilla.org/en-US/docs/Web/API/Invoker_Commands_API) from any light-DOM button. Custom commands must start with `--`.
393
+
394
+ <ApiTable :data="[
395
+ { Command: '--show', Description: 'Sets `open = true`' },
396
+ { Command: '--hide', Description: 'Sets `open = false`' },
397
+ ]" />
398
+
399
+ ### Events
400
+
401
+ <ApiTable :data="[
402
+ { Event: 'show', Description: 'Fired when the dialog opens' },
403
+ { Event: 'after-show', Description: 'Fired after the open animation completes' },
404
+ { Event: 'hide', Description: 'Fired when the dialog is about to close. Cancelable — call `event.preventDefault()` to keep it open' },
405
+ { Event: 'after-hide', Description: 'Fired after the close animation completes' },
406
+ ]" />
407
+
408
+ ### Slots
409
+
410
+ <ApiTable :data="[
411
+ { Slot: '(default)', Description: 'Body content' },
412
+ { Slot: 'close', Description: 'Close button (typically `<button class=&quot;l-close&quot;>`)' },
413
+ { Slot: 'footer', Description: 'Footer actions' },
414
+ ]" />
415
+
416
+ ### CSS parts
417
+
418
+ <ApiTable :data="[
419
+ { Part: 'dialog', Description: 'The native `<dialog>` element' },
420
+ { Part: 'header', Description: 'The header wrapper containing the title and close slot' },
421
+ { Part: 'title', Description: 'The dialog title heading' },
422
+ { Part: 'body', Description: 'The body wrapper around the default slot' },
423
+ { Part: 'footer', Description: 'The footer wrapper around the footer slot' },
424
+ ]" />
425
+
426
+ ### CSS custom properties
427
+
428
+ <ApiTable :data="[
429
+ { Name: '--width', Description: 'Dialog width. Default `31rem`' },
430
+ { Name: '--border-radius', Description: 'Border radius. Default `6px`' },
431
+ { Name: '--show-duration', Description: 'Open transition duration. Default `200ms`' },
432
+ { Name: '--hide-duration', Description: 'Close transition duration. Default `200ms`' },
433
+ { Name: '--backdrop', Description: 'Backdrop color' },
434
+ { Name: '--backdrop-blur', Description: 'Backdrop blur amount (any CSS length). Default `0`' },
435
+ ]" />