actual-css 0.2.0 → 0.3.1

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 (214) hide show
  1. package/CHANGELOG.md +49 -1
  2. package/README.md +24 -9
  3. package/dist/actual-themes.min.css +1 -0
  4. package/dist/actual.css +1532 -1114
  5. package/dist/actual.js +1 -3
  6. package/dist/actual.min.css +1 -1
  7. package/dist/optional.css +1048 -0
  8. package/dist/optional.min.css +1 -0
  9. package/docs/design-notes/browser-support.md +94 -14
  10. package/docs/design-notes/cascade-layer.md +7 -6
  11. package/docs/design-notes/enhancement-contract.md +11 -14
  12. package/docs/design-notes/forced-colors.md +105 -0
  13. package/docs/design-notes/naming.md +2 -1
  14. package/docs/design-notes/platform-alignment.md +492 -0
  15. package/docs/design-notes/references.md +8 -0
  16. package/docs/design-notes/widget-primitives.md +37 -1
  17. package/docs/navigation.json +135 -0
  18. package/docs/pages/components/accordion.md +80 -0
  19. package/docs/pages/components/alert.md +203 -0
  20. package/docs/pages/components/aura.md +35 -0
  21. package/docs/pages/components/avatar.md +95 -0
  22. package/docs/pages/components/badge.md +102 -0
  23. package/docs/pages/components/breadcrumb.md +19 -0
  24. package/docs/pages/components/button.md +210 -0
  25. package/docs/pages/components/card.md +195 -0
  26. package/docs/pages/components/chat.md +50 -0
  27. package/docs/pages/components/dialog.md +367 -0
  28. package/docs/pages/components/drawer.md +113 -0
  29. package/docs/pages/components/fab.md +118 -0
  30. package/docs/pages/components/key.md +33 -0
  31. package/docs/pages/components/meter.md +23 -0
  32. package/docs/pages/components/navbar.md +92 -0
  33. package/docs/pages/components/pagination.md +55 -0
  34. package/docs/pages/components/progress.md +29 -0
  35. package/docs/pages/components/skeleton.md +38 -0
  36. package/docs/pages/components/spinner.md +93 -0
  37. package/docs/pages/components/table.md +102 -0
  38. package/docs/pages/enhancements/flyout.md +391 -0
  39. package/docs/pages/enhancements/overview.md +36 -0
  40. package/docs/pages/enhancements/scrollspy.md +71 -0
  41. package/docs/pages/enhancements/status-bar.md +72 -0
  42. package/docs/pages/enhancements/tabs.md +80 -0
  43. package/docs/pages/enhancements/tooltip.md +130 -0
  44. package/docs/pages/examples/overview.md +43 -0
  45. package/docs/pages/forms/choice-cards.md +102 -0
  46. package/docs/pages/forms/controls.md +32 -0
  47. package/docs/pages/forms/detached-actions.md +59 -0
  48. package/docs/pages/forms/floating-field.md +88 -0
  49. package/docs/pages/forms/form-actions.md +56 -0
  50. package/docs/pages/forms/input-policy.md +91 -0
  51. package/docs/pages/forms/joined-controls.md +37 -0
  52. package/docs/pages/forms/labels.md +42 -0
  53. package/docs/pages/forms/otp.md +50 -0
  54. package/docs/pages/forms/overview.md +188 -0
  55. package/docs/pages/forms/password.md +40 -0
  56. package/docs/pages/forms/range.md +17 -0
  57. package/docs/pages/forms/states-and-sizes.md +321 -0
  58. package/docs/pages/forms/sticky-actions.md +187 -0
  59. package/docs/pages/forms/switch.md +31 -0
  60. package/docs/pages/forms/validation.md +241 -0
  61. package/docs/{mental-model.md → pages/foundations/philosophy.md} +33 -18
  62. package/docs/pages/foundations/theming.md +99 -0
  63. package/docs/pages/foundations/tokens.md +421 -0
  64. package/docs/{typography.md → pages/foundations/typography.md} +27 -9
  65. package/docs/pages/guides/bootstrap.md +438 -0
  66. package/docs/pages/guides/introduction.md +157 -0
  67. package/docs/pages/guides/optional-components.md +33 -0
  68. package/docs/pages/guides/progressive-enhancement.md +686 -0
  69. package/docs/pages/guides/tailwind.md +455 -0
  70. package/docs/pages/layout/app-shell.md +25 -0
  71. package/docs/pages/layout/center.md +29 -0
  72. package/docs/pages/layout/cluster.md +59 -0
  73. package/docs/pages/layout/frame.md +30 -0
  74. package/docs/pages/layout/grid.md +142 -0
  75. package/docs/pages/layout/list.md +41 -0
  76. package/docs/pages/layout/media.md +28 -0
  77. package/docs/pages/layout/overview.md +37 -0
  78. package/docs/pages/layout/scroll-snap.md +54 -0
  79. package/docs/pages/layout/sidebar-layout.md +27 -0
  80. package/docs/pages/layout/stack.md +55 -0
  81. package/docs/pages/layout/switcher.md +36 -0
  82. package/docs/pages/layout/topbar.md +23 -0
  83. package/docs/pages/patterns/actions.md +52 -0
  84. package/docs/pages/patterns/code-block.md +36 -0
  85. package/docs/pages/patterns/exclusive-accordion.md +16 -0
  86. package/docs/pages/patterns/hierarchical-nav.md +26 -0
  87. package/docs/pages/patterns/icon-input.md +25 -0
  88. package/docs/pages/patterns/intent-nesting.md +3 -0
  89. package/docs/pages/patterns/navigation-list.md +235 -0
  90. package/docs/pages/patterns/overview.md +58 -0
  91. package/docs/pages/patterns/structured-lists.md +47 -0
  92. package/docs/pages/utilities/accessibility.md +34 -0
  93. package/docs/pages/utilities/flex.md +105 -0
  94. package/docs/pages/utilities/links.md +18 -0
  95. package/docs/pages/utilities/list.md +32 -0
  96. package/docs/pages/utilities/overflow.md +43 -0
  97. package/docs/pages/utilities/overview.md +18 -0
  98. package/docs/pages/utilities/shape.md +25 -0
  99. package/docs/pages/utilities/sizing-wrapping.md +115 -0
  100. package/docs/pages/utilities/spacing.md +79 -0
  101. package/docs/pages/utilities/text.md +43 -0
  102. package/llms.txt +4 -4
  103. package/package.json +21 -12
  104. package/src/css/actual.css +16 -2
  105. package/src/css/base.css +3 -5
  106. package/src/css/components/accordion.css +18 -30
  107. package/src/css/components/actions.css +4 -1
  108. package/src/css/components/alert.css +139 -102
  109. package/src/css/components/avatar.css +16 -10
  110. package/src/css/components/badge.css +69 -42
  111. package/src/css/components/breadcrumb.css +7 -15
  112. package/src/css/components/busy.css +6 -0
  113. package/src/css/components/button.css +84 -34
  114. package/src/css/components/card.css +26 -38
  115. package/src/css/components/drawer.css +30 -13
  116. package/src/css/components/flyout.css +39 -109
  117. package/src/css/components/index.css +1 -0
  118. package/src/css/components/join.css +14 -2
  119. package/src/css/components/key.css +2 -0
  120. package/src/css/components/menu.css +125 -0
  121. package/src/css/components/meter.css +0 -23
  122. package/src/css/components/modal.css +162 -7
  123. package/src/css/components/navbar.css +30 -23
  124. package/src/css/components/overline.css +8 -9
  125. package/src/css/components/pagination.css +1 -1
  126. package/src/css/components/progress.css +8 -26
  127. package/src/css/components/skeleton.css +7 -0
  128. package/src/css/components/spinner.css +6 -7
  129. package/src/css/components/status-bar.css +15 -24
  130. package/src/css/components/surface.css +2 -8
  131. package/src/css/components/tab.css +19 -48
  132. package/src/css/components/table.css +7 -5
  133. package/src/css/components/tooltip.css +14 -7
  134. package/src/css/focus.css +14 -38
  135. package/src/css/forms/choice-card.css +13 -14
  136. package/src/css/forms/choice.css +21 -27
  137. package/src/css/forms/control.css +18 -17
  138. package/src/css/forms/custom-select.css +9 -11
  139. package/src/css/forms/form-actions.css +14 -3
  140. package/src/css/forms/form.css +7 -4
  141. package/src/css/forms/index.css +4 -4
  142. package/src/css/forms/input-icon.css +30 -12
  143. package/src/css/forms/native.css +50 -11
  144. package/src/css/forms/range.css +17 -9
  145. package/src/css/forms/select.css +8 -8
  146. package/src/css/forms/switch.css +14 -12
  147. package/src/css/forms/validation.css +32 -5
  148. package/src/css/grid.css +32 -18
  149. package/src/css/intents.css +2 -2
  150. package/src/css/layout.css +45 -2
  151. package/src/css/optional/aura.css +93 -0
  152. package/src/css/optional/chat.css +105 -0
  153. package/src/css/optional/fab.css +104 -0
  154. package/src/css/optional/floating-field.css +87 -0
  155. package/src/css/optional/index.css +5 -0
  156. package/src/css/optional/layout-extra.css +7 -4
  157. package/src/css/optional/otp.css +115 -0
  158. package/src/css/optional/scroll-snap.css +6 -0
  159. package/src/css/optional/scroller.css +13 -7
  160. package/src/css/optional/typography-fluid.css +5 -0
  161. package/src/css/optional/utilities-extra.css +17 -2
  162. package/src/css/prose.css +18 -8
  163. package/src/css/reset.css +0 -10
  164. package/src/css/theme.css +21 -5
  165. package/src/css/themes/cyberpunk.css +1 -1
  166. package/src/css/themes/dim.css +3 -3
  167. package/src/css/themes/edge.css +8 -10
  168. package/src/css/themes/index.css +8 -4
  169. package/src/css/themes/{dark.css → indigo.css} +5 -4
  170. package/src/css/themes/neon.css +5 -5
  171. package/src/css/themes/square.css +0 -3
  172. package/src/css/tokens.css +74 -20
  173. package/src/css/utilities.css +8 -10
  174. package/src/css/variants.css +51 -66
  175. package/src/js/command.js +1 -3
  176. package/src/js/context-menu.js +67 -35
  177. package/src/js/dialog.js +68 -79
  178. package/src/js/dismiss.js +15 -0
  179. package/src/js/enhance.js +54 -23
  180. package/src/js/enhancement-loader.js +301 -0
  181. package/src/js/events.js +3 -0
  182. package/src/js/filter.js +3 -3
  183. package/src/js/floating.js +101 -131
  184. package/src/js/flyout.js +104 -87
  185. package/src/js/focus-group.js +116 -0
  186. package/src/js/focus.js +6 -1
  187. package/src/js/index.js +4 -2
  188. package/src/js/input.js +1 -1
  189. package/src/js/keys.js +27 -0
  190. package/src/js/mask.js +7 -6
  191. package/src/js/menu.js +87 -34
  192. package/src/js/parse-config.js +47 -0
  193. package/src/js/password.js +9 -1
  194. package/src/js/scrollspy.js +12 -4
  195. package/src/js/selectors.js +0 -7
  196. package/src/js/status.js +3 -1
  197. package/src/js/surface.js +187 -136
  198. package/src/js/tab.js +36 -53
  199. package/src/js/tooltip.js +70 -35
  200. package/src/js/validation.js +34 -8
  201. package/dist/actual.js.map +0 -31
  202. package/docs/README.md +0 -28
  203. package/docs/components.md +0 -860
  204. package/docs/design-notes/previous-work.md +0 -5
  205. package/docs/forms.md +0 -1265
  206. package/docs/javascript.md +0 -496
  207. package/docs/layout.md +0 -480
  208. package/docs/patterns.md +0 -504
  209. package/docs/reserved.md +0 -7
  210. package/docs/tokens.md +0 -455
  211. package/docs/ui.md +0 -929
  212. package/docs/utilities.md +0 -384
  213. package/src/css/dialog-fallback.css +0 -56
  214. package/src/js/dialog-fallback.js +0 -163
@@ -0,0 +1,367 @@
1
+ # Dialog
2
+
3
+ > Centered modal overlay for focused tasks, confirmations, or forms, built on the native `<dialog>` element.
4
+
5
+ ## Class reference
6
+
7
+ | Class | Kind | Description |
8
+ |---|---|---|
9
+ | `.modal` | Component | Centered modal surface built on the native `<dialog>` element. |
10
+ | `.scrollable` | Variant | Keeps the header and footer visible while the dialog body scrolls. |
11
+ | `.dialog-confirmation` | Variant | Separates a confirmation message from its full-width action band. |
12
+ | `.dialog-icon` | Component | Circular intent-aware icon well for confirmation messages. |
13
+ | `.dialog-close` | Component | Icon-only close button anchored to the modal's top end, out of the content flow. |
14
+
15
+ ## Usage
16
+
17
+ Modals use the platform-native `<dialog class="modal">` element with `commandfor` and `command` buttons.
18
+
19
+ Use `command="show-modal"` to open a modal dialog.
20
+
21
+ Add `aria-haspopup="dialog"` and `aria-controls="<id>"` to opening buttons so
22
+ their semantics are present before either native or framework JavaScript runs.
23
+ The command runtime is stateless and does not pre-scan triggers.
24
+
25
+ Use `command="request-close"` for cancel-style buttons so close requests go
26
+ through the dialog's cancel lifecycle.
27
+
28
+ Use `closedby="any"` as the no-JavaScript light-dismiss path: the native dialog
29
+ closes on backdrop click and Escape. Add `data-dialog-dismissible` so the
30
+ optional runtime takes over backdrop click and closes with the dialog's
31
+ transition; it rewrites `closedby="any"` to `closedby="closerequest"` so the
32
+ native dialog and the runtime never double-handle. `data-dialog-dismissible`
33
+ only gates backdrop click — Escape and explicit close requests always close,
34
+ unless the application cancels the `actual:dialog-cancel` event.
35
+
36
+ ## Alert dialog
37
+
38
+ Use this shape when the dialog interrupts the flow and asks for a decision. It
39
+ has no close icon and no light dismiss; the footer actions are the way out.
40
+ `closedby="none"` keeps Escape and backdrop clicks from closing it, so a
41
+ critical confirmation cannot be dismissed accidentally. With the optional
42
+ runtime, backdrop clicks give a small static feedback instead of closing.
43
+
44
+ ```html demo
45
+ <button class="btn"
46
+ type="button"
47
+ commandfor="delete-dialog"
48
+ command="show-modal"
49
+ aria-haspopup="dialog"
50
+ aria-controls="delete-dialog">
51
+ Delete project
52
+ </button>
53
+
54
+ <dialog class="modal" id="delete-dialog" closedby="none">
55
+ <form method="dialog">
56
+ <header>
57
+ <h3>Delete project?</h3>
58
+ <p>This action cannot be undone.</p>
59
+ </header>
60
+
61
+ <div>
62
+ <p>The project, saved reports, and connected automations will be removed permanently.</p>
63
+ </div>
64
+
65
+ <footer>
66
+ <button class="btn outline" value="cancel">Cancel</button>
67
+
68
+ <button class="btn danger"
69
+ value="delete">
70
+ Delete
71
+ </button>
72
+ </footer>
73
+ </form>
74
+ </dialog>
75
+ ```
76
+
77
+ For a compact destructive confirmation with a leading status icon, compose
78
+ `dialog-confirmation` with the media object. The icon well accepts the shared
79
+ intent and emphasis classes; `dialog-icon danger soft` creates the tinted red
80
+ circle while keeping the glyph centered. The footer becomes a separate action
81
+ band without changing the semantics of the form or its buttons.
82
+
83
+ ```html demo
84
+ <button class="btn danger"
85
+ type="button"
86
+ commandfor="deactivate-dialog"
87
+ command="show-modal"
88
+ aria-haspopup="dialog"
89
+ aria-controls="deactivate-dialog">
90
+ Deactivate account
91
+ </button>
92
+
93
+ <dialog class="modal dialog-confirmation"
94
+ id="deactivate-dialog"
95
+ closedby="none"
96
+ style="--modal-size: 40rem">
97
+ <form method="dialog">
98
+ <div class="media">
99
+ <span class="dialog-icon danger soft" aria-hidden="true">
100
+ <i class="ti ti-alert-triangle"></i>
101
+ </span>
102
+
103
+ <header>
104
+ <h3>Deactivate account</h3>
105
+ <p class="muted">Are you sure you want to deactivate your account? All of your data will be permanently removed. This action cannot be undone.</p>
106
+ </header>
107
+ </div>
108
+
109
+ <footer>
110
+ <button class="btn outline" value="cancel">Cancel</button>
111
+ <button class="btn danger" value="deactivate">Deactivate</button>
112
+ </footer>
113
+ </form>
114
+ </dialog>
115
+ ```
116
+
117
+ ## Information modal
118
+
119
+ Use this shape for contextual information or lightweight secondary content. It
120
+ has no action button; the header close button dismisses the dialog.
121
+
122
+ ```html demo
123
+ <button class="btn"
124
+ type="button"
125
+ commandfor="details-dialog"
126
+ command="show-modal"
127
+ aria-haspopup="dialog"
128
+ aria-controls="details-dialog">
129
+ View details
130
+ </button>
131
+
132
+ <dialog class="modal"
133
+ id="details-dialog"
134
+ closedby="any"
135
+ data-dialog-dismissible>
136
+ <button class="dialog-close"
137
+ type="button"
138
+ commandfor="details-dialog"
139
+ command="request-close"
140
+ aria-controls="details-dialog"
141
+ aria-label="Close dialog"></button>
142
+
143
+ <div class="stack">
144
+ <header>
145
+ <hgroup>
146
+ <h3>Release details</h3>
147
+ <p>Changes included in this version.</p>
148
+ </hgroup>
149
+ </header>
150
+
151
+ <div>
152
+ <p>The release improves dialog behavior, scroll handling, and progressive enhancement for modern browsers.</p>
153
+ <p>There are no decisions to make here; the content can simply be dismissed when finished.</p>
154
+ </div>
155
+ </div>
156
+ </dialog>
157
+ ```
158
+
159
+ ## Scrollable modal
160
+
161
+ Use `modal scrollable` when the header and footer should stay visible while the
162
+ dialog body scrolls. Modal dialogs lock page scroll while a modal is open: the
163
+ runtime writes `html.has-modal-open`, and the stylesheet applies `overflow:
164
+ hidden` (and reserves the scrollbar gutter with `scrollbar-gutter: stable` when
165
+ one was present).
166
+
167
+ ```html demo
168
+ <button class="btn"
169
+ type="button"
170
+ commandfor="scroll-dialog"
171
+ command="show-modal"
172
+ aria-haspopup="dialog"
173
+ aria-controls="scroll-dialog">
174
+ Open scrollable modal
175
+ </button>
176
+
177
+ <dialog class="modal scrollable"
178
+ id="scroll-dialog"
179
+ closedby="any"
180
+ data-dialog-dismissible>
181
+ <form method="dialog">
182
+ <header>
183
+ <h3>Terms review</h3>
184
+ <p>Review the full text before continuing.</p>
185
+ </header>
186
+
187
+ <div class="stack">
188
+ <p>Actual CSS keeps long dialog content inside the dialog surface instead of letting it run past the viewport.</p>
189
+ <p>Section 1. The service stores project settings, interface preferences, and theme choices so teams can keep a consistent working environment.</p>
190
+ <p>Section 2. Administrators can invite users, remove inactive accounts, and review access periodically.</p>
191
+ <p>Section 3. Billing changes may affect future invoices. Existing invoices remain available from the account area.</p>
192
+ <p>Section 4. Export tools are provided for common formats. Large exports may take a few minutes to prepare.</p>
193
+ <p>Section 5. Support requests should include relevant browser, operating system, and account context.</p>
194
+ <p>Section 6. Experimental features can change or disappear before a stable release.</p>
195
+ <p>Section 7. Continued use confirms acceptance of the current terms.</p>
196
+ </div>
197
+
198
+ <footer>
199
+ <button class="btn outline" value="cancel">Cancel</button>
200
+
201
+ <button class="btn primary" value="accept">
202
+ Accept
203
+ </button>
204
+ </footer>
205
+ </form>
206
+ </dialog>
207
+ ```
208
+
209
+ ## Overlays inside modals
210
+
211
+ Flyouts and tooltips opened from inside a modal dialog are mounted inside the
212
+ dialog so they stay in the same top-layer context.
213
+
214
+ ```html demo
215
+ <button class="btn"
216
+ type="button"
217
+ commandfor="overlay-dialog"
218
+ command="show-modal"
219
+ aria-haspopup="dialog"
220
+ aria-controls="overlay-dialog">
221
+ Open modal overlays
222
+ </button>
223
+
224
+ <dialog class="modal"
225
+ id="overlay-dialog"
226
+ closedby="any"
227
+ data-dialog-dismissible>
228
+ <button class="dialog-close"
229
+ type="button"
230
+ commandfor="overlay-dialog"
231
+ command="request-close"
232
+ aria-controls="overlay-dialog"
233
+ aria-label="Close dialog"></button>
234
+
235
+ <div class="stack">
236
+ <header>
237
+ <hgroup>
238
+ <h3>Modal overlays</h3>
239
+ <p>Flyouts and tooltips remain above the dialog surface.</p>
240
+ </hgroup>
241
+ </header>
242
+
243
+ <div class="cluster">
244
+ <button class="btn"
245
+ type="button"
246
+ data-enhance="flyout"
247
+ aria-expanded="false"
248
+ aria-controls="dialog-actions-menu">
249
+ Actions
250
+ </button>
251
+
252
+ <button class="btn outline"
253
+ type="button"
254
+ data-tooltip="Tooltip inside a dialog">
255
+ Tooltip
256
+ </button>
257
+ </div>
258
+
259
+ <menu class="flyout menu" id="dialog-actions-menu" hidden>
260
+ <li><button class="menu-item" type="button">Archive</button></li>
261
+ <li><button class="menu-item" type="button">Duplicate</button></li>
262
+ <li><button class="menu-item" type="button">Share</button></li>
263
+ </menu>
264
+ </div>
265
+ </dialog>
266
+ ```
267
+
268
+ ## JavaScript options
269
+
270
+ Add options directly on the dialog element. Without JavaScript, modern browsers
271
+ still use the native dialog behavior; the runtime adds declarative command
272
+ handling, focus restoration, controlled light dismiss, and optional view
273
+ transitions.
274
+
275
+ Available options:
276
+
277
+ * `data-dialog-dismissible` gates backdrop click only: the runtime takes over
278
+ light dismiss and closes the dialog (or rewrites `closedby="any"` to
279
+ `closedby="closerequest"` so the native dialog does not double-handle).
280
+ It never affects Escape or explicit close requests.
281
+ * `data-dialog-modal="false"` opens with `show()` instead of `showModal()`.
282
+ * `data-dialog-view-transition` enables a view transition that morphs the dialog to/from its trigger. Only active when the browser supports `document.startViewTransition` and the user allows motion.
283
+ * `closedby` keeps its native meaning: `"any"` closes on backdrop click and
284
+ Escape, `"closerequest"` closes on Escape only, `"none"` disables both. The
285
+ runtime rewrites `closedby="any"` to `closedby="closerequest"` only when
286
+ `data-dialog-dismissible` opts it into light dismiss, and never overrides
287
+ `closedby="none"`. Use `closedby="none"` for critical dialogs that must be
288
+ closed by an explicit action.
289
+
290
+ ## Browser support
291
+
292
+ Actual relies on the native `<dialog>` API in its supported JavaScript range
293
+ (Safari 15.4+, Firefox 98+, Chromium 99+). No dialog polyfill or fallback shim
294
+ is shipped.
295
+
296
+ ## Animation
297
+
298
+ The base CSS gives supporting browsers small enter and exit transitions. Exit
299
+ motion relies on `transition-behavior: allow-discrete` so the native dialog can
300
+ remain in the top layer while `display` and `overlay` transition out. Browsers
301
+ without that support keep native close behavior.
302
+
303
+ The open dialog root intentionally ends at `transform: none`; fixed flyouts and
304
+ tooltips mounted inside a modal dialog rely on viewport coordinates.
305
+
306
+ ### View transition
307
+
308
+ Add `data-dialog-view-transition` to morph the dialog to/from its trigger using
309
+ the View Transition API. The dialog appears to grow out of the trigger on open
310
+ and shrink back into it on close, communicating the relationship between the
311
+ two.
312
+
313
+ The effect is progressive: it only runs when the browser supports
314
+ `document.startViewTransition` and the user has not requested reduced motion.
315
+ Otherwise the dialog simply opens and closes with the baseline dialog
316
+ transition.
317
+
318
+ ```html demo
319
+ <button class="btn"
320
+ type="button"
321
+ commandfor="vt-dialog"
322
+ command="show-modal"
323
+ aria-haspopup="dialog"
324
+ aria-controls="vt-dialog">
325
+ Open modal
326
+ </button>
327
+
328
+ <dialog class="modal"
329
+ id="vt-dialog"
330
+ data-dialog-view-transition
331
+ data-dialog-dismissible>
332
+ <form method="dialog">
333
+ <header>
334
+ <h3>Title</h3>
335
+ <p>This dialog morphs to and from the trigger button.</p>
336
+ </header>
337
+
338
+ <footer>
339
+ <button class="btn outline" value="cancel">Cancel</button>
340
+ <button class="btn primary" value="confirm">Confirm</button>
341
+ </footer>
342
+ </form>
343
+ </dialog>
344
+ ```
345
+
346
+ ## Notes
347
+
348
+ Prefer native dialog behavior whenever possible. The framework runtime should
349
+ not replace the platform modal system; it should only make dialogs declarative,
350
+ animation-friendly, and consistent across supported browsers.
351
+
352
+ The close button is anchored to the dialog surface, not the content flow: it
353
+ sits at the top `inline-end`, inside the panel. The button itself is out of
354
+ flow, while the header reserves enough inline padding to keep its title clear.
355
+ Keep the button a direct child of `dialog.modal` so the scrolling content
356
+ (`> form` or `> .stack`) never competes with it.
357
+
358
+ ## CSS hooks
359
+
360
+ - `--modal-size` — maximum dialog width.
361
+ - `--dialog-viewport-gap` — distance kept between the dialog and the viewport edges.
362
+ - `--dialog-icon-size` — diameter of the `.dialog-icon` circle.
363
+ - `--dialog-icon-glyph-size` — size of the glyph centered inside `.dialog-icon`.
364
+ - `--control-size` — inline and block size of the `.dialog-close` button. The
365
+ header reserves `calc(var(--control-size) + var(--space-30))` on its inline
366
+ end so the title never runs under the close.
367
+ - `--dialog-close-icon-size` — size of the close glyph.
@@ -0,0 +1,113 @@
1
+ # Drawer
2
+
3
+ > Modal side-sheet that overlays the page for navigation or filters.
4
+
5
+ ## Class reference
6
+
7
+ | Class | Kind | Description |
8
+ |---|---|---|
9
+ | `.drawer` | Component | Modal side-sheet built on the native `<dialog>` element. |
10
+ | `.drawer-close` | Component | Icon-only close button that sits inside the drawer header. |
11
+
12
+ ## Usage
13
+
14
+ - Use `dialog.drawer` for modal side-sheets that overlay the page.
15
+ - Use `command="show-modal"` and `commandfor="<id>"` to open the drawer without JavaScript.
16
+ - Use `form method="dialog"` for close buttons inside the drawer.
17
+ - Use `data-dialog-dismissible` when backdrop click should close the drawer. It
18
+ only gates backdrop click: Escape and the close button always close.
19
+ - Use `closedby="none"` when the drawer must not be dismissed by the user at all
20
+ (e.g. a form with unsaved changes): no backdrop close and no Escape close.
21
+ - Use `[data-side="end"]` for a right-side drawer.
22
+ - Permanent desktop sidebars belong in layout, not here.
23
+
24
+ ```html demo
25
+ <button class="btn ghost"
26
+ type="button"
27
+ command="show-modal"
28
+ commandfor="main-drawer"
29
+ aria-haspopup="dialog"
30
+ aria-controls="main-drawer"
31
+ aria-label="Open navigation">
32
+ <i class="ti ti-menu-2" aria-hidden="true"></i>
33
+ </button>
34
+
35
+ <dialog class="drawer"
36
+ id="main-drawer"
37
+ aria-label="Main navigation"
38
+ closedby="any"
39
+ data-dialog-dismissible>
40
+ <header>
41
+ <strong>Menu</strong>
42
+
43
+ <form method="dialog">
44
+ <button class="drawer-close" type="submit" aria-label="Close navigation"></button>
45
+ </form>
46
+ </header>
47
+
48
+ <nav>
49
+ <ul class="nav-list stack">
50
+ <li><a href="#" aria-current="page">Home</a></li>
51
+ <li><a href="#">Users</a></li>
52
+ <li><a href="#">Settings</a></li>
53
+ <li><a href="#">Logout</a></li>
54
+ </ul>
55
+ </nav>
56
+ </dialog>
57
+ ```
58
+
59
+ ## Non-dismissible drawer
60
+
61
+ For drawers with unsaved settings or critical actions, use `closedby="none"` so
62
+ the user cannot dismiss the drawer by accident: backdrop click shows a static
63
+ indicator instead of closing, and Escape does nothing. Only the explicit footer
64
+ actions and the close button can close the drawer.
65
+
66
+ ```html demo
67
+ <button class="btn"
68
+ type="button"
69
+ command="show-modal"
70
+ commandfor="settings-drawer"
71
+ aria-haspopup="dialog"
72
+ aria-controls="settings-drawer">
73
+ Edit settings
74
+ </button>
75
+
76
+ <dialog class="drawer"
77
+ id="settings-drawer"
78
+ aria-label="Settings"
79
+ data-side="end"
80
+ closedby="none">
81
+ <form method="dialog">
82
+ <header>
83
+ <strong>Settings</strong>
84
+ <button class="drawer-close" type="submit" aria-label="Close settings"></button>
85
+ </header>
86
+
87
+ <div class="stack">
88
+ <p>Unsaved changes will be lost if you close without saving.</p>
89
+ </div>
90
+
91
+ <footer class="cluster" style="--cluster-justify: end">
92
+ <button class="btn" value="save">Save</button>
93
+ </footer>
94
+ </form>
95
+ </dialog>
96
+ ```
97
+
98
+ Backdrop click dismissal and Escape come from the native dialog element and
99
+ follow its `closedby` value. Add `data-dialog-dismissible` when you want the
100
+ optional runtime to take over backdrop click and close with the drawer's
101
+ transition; the runtime rewrites `closedby="any"` to `closedby="closerequest"`
102
+ so the two never double-handle. Without `data-dialog-dismissible`, a native
103
+ `closedby="any"` dialog keeps its own light dismiss, and dialogs without
104
+ light dismiss briefly flash instead of closing when the backdrop is clicked —
105
+ useful for drawers that should not be dismissed accidentally.
106
+
107
+ ## CSS hooks
108
+
109
+ - `--drawer-size` — panel width.
110
+ - `--drawer-pad` — panel padding.
111
+ - `--control-size` — size of the `.drawer-close` button. The drawer header
112
+ reserves `calc(var(--control-size) + var(--space-30))` on its inline end so
113
+ the title never runs under the close.
@@ -0,0 +1,118 @@
1
+ # Floating action button
2
+
3
+ > **Optional** — import `actual-css/css/optional/fab` or `actual-css/css/optional/index`.
4
+
5
+ FAB fixes a primary action near the viewport's block-end and inline-end edges.
6
+ The existing button component owns its size, shape, intent, and interaction.
7
+
8
+ ```html
9
+ <div class="fab">
10
+ <button class="btn circle primary lg icon-only" type="button" aria-label="Create">
11
+ <span aria-hidden="true">+</span>
12
+ </button>
13
+ </div>
14
+ ```
15
+
16
+ Use native `details` for a no-JavaScript speed dial. List actions in their
17
+ visual top-to-bottom order so keyboard focus follows the same sequence.
18
+
19
+ ```html
20
+ <details class="fab">
21
+ <summary
22
+ class="btn circle primary icon-only"
23
+ style="--btn-min-size: 3.5rem"
24
+ aria-label="Create"
25
+ >
26
+ <span aria-hidden="true">+</span>
27
+ </summary>
28
+
29
+ <div class="fab-actions">
30
+ <div class="fab-action">
31
+ <span class="fab-label">Document</span>
32
+ <button class="btn circle lg icon-only" type="button" aria-label="New document">…</button>
33
+ </div>
34
+ <div class="fab-action">
35
+ <span class="fab-label">Upload</span>
36
+ <button class="btn circle lg icon-only" type="button" aria-label="Upload file">…</button>
37
+ </div>
38
+ <div class="fab-action">
39
+ <span class="fab-label">Folder</span>
40
+ <button class="btn circle lg icon-only" type="button" aria-label="New folder">…</button>
41
+ </div>
42
+ </div>
43
+ </details>
44
+ ```
45
+
46
+ ## Preview
47
+
48
+ This documentation-only surface simulates a viewport by replacing the FAB's
49
+ fixed positioning with absolute positioning. The card is background content,
50
+ not the FAB's containing component. Production `.fab` remains viewport-fixed.
51
+
52
+ ```html demo
53
+ <div class="docs-fab-preview">
54
+ <article class="card">
55
+ <h3>Documents</h3>
56
+ <p>Your recent documents will appear here.</p>
57
+ </article>
58
+
59
+ <details class="fab" open>
60
+ <summary
61
+ class="btn circle primary icon-only"
62
+ style="--btn-min-size: 3.5rem"
63
+ aria-label="Create"
64
+ >
65
+ <span aria-hidden="true">+</span>
66
+ </summary>
67
+
68
+ <div class="fab-actions">
69
+ <div class="fab-action">
70
+ <span class="fab-label">Document</span>
71
+ <button class="btn circle lg icon-only" type="button" aria-label="New document">
72
+ <i class="ti ti-file-plus" aria-hidden="true"></i>
73
+ </button>
74
+ </div>
75
+ <div class="fab-action">
76
+ <span class="fab-label">Upload</span>
77
+ <button class="btn circle lg icon-only" type="button" aria-label="Upload file">
78
+ <i class="ti ti-upload" aria-hidden="true"></i>
79
+ </button>
80
+ </div>
81
+ <div class="fab-action">
82
+ <span class="fab-label">Folder</span>
83
+ <button class="btn circle lg icon-only" type="button" aria-label="New folder">
84
+ <i class="ti ti-folder-plus" aria-hidden="true"></i>
85
+ </button>
86
+ </div>
87
+ </div>
88
+ </details>
89
+ </div>
90
+ ```
91
+
92
+ The native baseline manages click, keyboard activation, and the open state. It
93
+ does not close automatically after an action, on outside click, or on Escape;
94
+ add application behavior only when the product requires those policies.
95
+
96
+ Each `.fab-action` keeps its `.fab-label` and secondary button on one compact
97
+ line. The example uses the button's existing `.lg` density for 44px secondary
98
+ actions and its `--btn-min-size` hook for a dominant 56px trigger. Size still
99
+ belongs to Button rather than introducing FAB-specific size modifiers.
100
+ When the summary contains one decorative icon, FAB rotates it by 45 degrees in
101
+ the open state so a plus naturally becomes a close symbol.
102
+
103
+ ## Class reference
104
+
105
+ | Class | Description |
106
+ |---|---|
107
+ | `.fab` | Fixed viewport placement; use `details` for a speed dial. |
108
+ | `.fab-actions` | Collapsible vertical action list. |
109
+ | `.fab-action` | One horizontal label-and-button unit. |
110
+ | `.fab-label` | Compact floating label for an action. |
111
+
112
+ ## CSS hooks
113
+
114
+ - `--fab-offset` — minimum viewport-edge offset.
115
+ - `--fab-gap` — gap between actions and between the trigger and action list.
116
+
117
+ FAB is hidden in print and uses `--z-menu`, leaving tooltips and status UI above
118
+ it. Dialogs remain in the browser's top layer.
@@ -0,0 +1,33 @@
1
+ # Key
2
+
3
+ > Keyboard keys and shortcut tokens for app UI, command palettes, menus, and help text.
4
+
5
+ - Use `<kbd class="key">` outside prose.
6
+ - Plain `<kbd>` inside `.prose` gets the same visual treatment for authored content.
7
+ - `.shortcut` is a documented composition, not a component class. Compose multiple `.key` elements with text or layout utilities.
8
+ - Use short, familiar labels such as `Ctrl`, `Shift`, `Esc`, or `K`.
9
+
10
+ ## Basic usage
11
+
12
+ ```html demo
13
+ <p>Press <kbd class="key">Esc</kbd> to close the panel.</p>
14
+
15
+ <div class="cluster" aria-label="Keyboard shortcut Control K">
16
+ <kbd class="key">Ctrl</kbd>
17
+ <kbd class="key">K</kbd>
18
+ </div>
19
+ ```
20
+
21
+ ## In menus
22
+
23
+ In menus, keep the command label and shortcut in the same interactive item.
24
+
25
+ ```html demo
26
+ <button type="button">
27
+ <span>Search</span>
28
+ <span class="cluster" aria-label="Keyboard shortcut Control K">
29
+ <kbd class="key">Ctrl</kbd>
30
+ <kbd class="key">K</kbd>
31
+ </span>
32
+ </button>
33
+ ```
@@ -0,0 +1,23 @@
1
+ # Meter
2
+
3
+ > Scalar measurement within a known range, not a progress indicator.
4
+
5
+ - Use native `<meter class="meter">`.
6
+ - Shares progress styling DNA.
7
+ - Represents a scalar measurement within a known range, not task completion.
8
+ - Use explicit bar height to avoid padding issues.
9
+
10
+ ```html demo
11
+ <div class="stack">
12
+ <meter class="meter" value="0.8" min="0" max="1" low="0.3" high="0.7" optimum="1"></meter>
13
+ <meter class="meter" value="0.5" min="0" max="1" low="0.3" high="0.7" optimum="1"></meter>
14
+ <meter class="meter" value="0.2" min="0" max="1" low="0.3" high="0.7" optimum="1"></meter>
15
+ </div>
16
+ ```
17
+
18
+ The three standard meter zones (optimum, suboptimum, even-less-good) map to the
19
+ shared `--success`, `--warning`, and `--danger` colors.
20
+
21
+ ## CSS hooks
22
+
23
+ - `--bar-height` — bar thickness, shared with `.progress`.