actual-css 0.5.0 → 0.7.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 (101) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/dist/actual.css +1 -0
  3. package/dist/actual.full.css +589 -131
  4. package/dist/actual.full.js +1 -1
  5. package/dist/actual.full.min.css +1 -1
  6. package/dist/actual.min.css +1 -1
  7. package/docs/design-notes/browser-support.md +39 -14
  8. package/docs/design-notes/css-anchor.md +1 -1
  9. package/docs/design-notes/enhancement-contract.md +30 -13
  10. package/docs/design-notes/forced-colors.md +11 -7
  11. package/docs/design-notes/grid.md +4 -4
  12. package/docs/design-notes/naming.md +15 -9
  13. package/docs/design-notes/platform-alignment.md +60 -0
  14. package/docs/design-notes/popover-manual-poc.md +248 -0
  15. package/docs/design-notes/references.md +4 -0
  16. package/docs/design-notes/steps.md +748 -0
  17. package/docs/design-notes/surface-reparenting.md +122 -0
  18. package/docs/design-notes/widget-primitives.md +32 -15
  19. package/docs/navigation.json +1 -0
  20. package/docs/pages/components/alert.md +13 -8
  21. package/docs/pages/components/aura.md +102 -6
  22. package/docs/pages/components/avatar.md +9 -6
  23. package/docs/pages/components/badge.md +11 -7
  24. package/docs/pages/components/button.md +17 -17
  25. package/docs/pages/components/card.md +15 -8
  26. package/docs/pages/components/chat.md +1 -1
  27. package/docs/pages/components/dialog.md +10 -7
  28. package/docs/pages/components/drawer.md +1 -1
  29. package/docs/pages/components/fab.md +12 -10
  30. package/docs/pages/components/indicator.md +6 -6
  31. package/docs/pages/components/list.md +11 -2
  32. package/docs/pages/components/navbar.md +1 -1
  33. package/docs/pages/components/pagination.md +1 -1
  34. package/docs/pages/components/rating.md +4 -4
  35. package/docs/pages/components/skeleton.md +1 -1
  36. package/docs/pages/components/spinner.md +1 -1
  37. package/docs/pages/components/steps.md +376 -52
  38. package/docs/pages/components/table.md +5 -5
  39. package/docs/pages/enhancements/flyout.md +104 -12
  40. package/docs/pages/enhancements/overview.md +2 -2
  41. package/docs/pages/enhancements/scrollspy.md +1 -1
  42. package/docs/pages/enhancements/status-bar.md +20 -0
  43. package/docs/pages/enhancements/tabs.md +1 -1
  44. package/docs/pages/enhancements/tooltip.md +12 -0
  45. package/docs/pages/examples/overview.md +2 -0
  46. package/docs/pages/forms/choice-cards.md +4 -4
  47. package/docs/pages/forms/combobox.md +87 -0
  48. package/docs/pages/forms/floating-field.md +5 -3
  49. package/docs/pages/forms/joined-controls.md +4 -4
  50. package/docs/pages/forms/labels.md +8 -5
  51. package/docs/pages/forms/overview.md +25 -18
  52. package/docs/pages/forms/password.md +3 -2
  53. package/docs/pages/forms/range.md +13 -2
  54. package/docs/pages/forms/states-and-sizes.md +6 -4
  55. package/docs/pages/forms/validation.md +13 -9
  56. package/docs/pages/foundations/philosophy.md +15 -1
  57. package/docs/pages/foundations/theming.md +8 -0
  58. package/docs/pages/foundations/tokens.md +9 -6
  59. package/docs/pages/foundations/typography.md +1 -1
  60. package/docs/pages/guides/bootstrap.md +3 -3
  61. package/docs/pages/guides/introduction.md +1 -1
  62. package/docs/pages/guides/modular-import.md +21 -10
  63. package/docs/pages/guides/progressive-enhancement.md +96 -73
  64. package/docs/pages/guides/tailwind.md +2 -2
  65. package/docs/pages/layout/app-shell.md +4 -4
  66. package/docs/pages/layout/choosing.md +10 -6
  67. package/docs/pages/layout/grid.md +11 -10
  68. package/docs/pages/layout/stack.md +10 -6
  69. package/docs/pages/patterns/structured-lists.md +7 -7
  70. package/docs/pages/utilities/accessibility.md +1 -1
  71. package/docs/pages/utilities/flex.md +20 -13
  72. package/docs/pages/utilities/links.md +1 -1
  73. package/docs/pages/utilities/list.md +1 -1
  74. package/docs/pages/utilities/overflow.md +14 -7
  75. package/docs/pages/utilities/overview.md +22 -0
  76. package/docs/pages/utilities/shape.md +1 -1
  77. package/docs/pages/utilities/sizing-wrapping.md +10 -8
  78. package/docs/pages/utilities/spacing.md +26 -19
  79. package/docs/pages/utilities/text.md +1 -1
  80. package/llms.txt +27 -4
  81. package/package.json +7 -4
  82. package/scripts/reserved-classes.json +4 -1
  83. package/src/css/components/fab.css +44 -8
  84. package/src/css/components/flyout.css +49 -3
  85. package/src/css/components/join.css +7 -0
  86. package/src/css/components/list.css +3 -1
  87. package/src/css/components/menu.css +16 -10
  88. package/src/css/components/steps.css +277 -69
  89. package/src/css/components/tooltip.css +37 -1
  90. package/src/css/core/tokens.css +1 -0
  91. package/src/css/effects/aura.css +101 -11
  92. package/src/css/forms/custom-select.css +1 -1
  93. package/src/css/forms/floating-field.css +8 -6
  94. package/src/css/layout/container-query.css +37 -13
  95. package/src/css/layout/grid.css +7 -7
  96. package/src/css/layout/index.css +1 -1
  97. package/src/js/password.js +1 -1
  98. package/src/js/status.js +38 -2
  99. package/src/js/surface.js +28 -12
  100. package/src/js/tooltip.js +2 -2
  101. package/src/js/floating.js +0 -432
@@ -43,7 +43,7 @@ Remove the compatibility mechanism when Bootstrap is gone. The public Actual API
43
43
  Many common Bootstrap components translate directly.
44
44
 
45
45
  | Bootstrap | Actual CSS |
46
- |----------------------------|-------------------------|
46
+ | -------------------------- | ----------------------- |
47
47
  | `.btn .btn-primary` | `.btn .primary` |
48
48
  | `.btn .btn-outline-danger` | `.btn .danger .outline` |
49
49
  | `.btn .btn-sm` | `.btn .sm` |
@@ -101,7 +101,7 @@ Actual:
101
101
  Common translations include:
102
102
 
103
103
  | Bootstrap | Actual CSS |
104
- |-------------------------------|--------------------------------|
104
+ | ----------------------------- | ------------------------------ |
105
105
  | `.form-control` on an input | `.input` |
106
106
  | `.form-control` on a textarea | `.textarea` |
107
107
  | `.form-select` | `.select` |
@@ -213,7 +213,7 @@ Think in terms of the relationship between children rather than translating each
213
213
  Typical choices are:
214
214
 
215
215
  | Bootstrap pattern | Actual approach |
216
- |--------------------------------------------|--------------------------------------------|
216
+ | ------------------------------------------ | ------------------------------------------ |
217
217
  | flex row that may wrap | `.cluster` |
218
218
  | vertical flex stack | `.stack` |
219
219
  | exact structural columns | `.grid-2`, `.grid-3`, `.grid-4`, `.grid-6` |
@@ -140,7 +140,7 @@ internal design documents for contributors.
140
140
  Actual CSS is built around progressive enhancement.
141
141
 
142
142
  | Tier | Firefox | Safari | Chromium |
143
- |--------------|---------|-----------|----------|
143
+ | ------------ | ------- | --------- | -------- |
144
144
  | Degraded | 78+ | 14+ | 88+ |
145
145
  | **Minimal** | **98+** | **15.4+** | **99+** |
146
146
  | Intermediate | 121+ | 16+ | 106+ |
@@ -29,16 +29,27 @@ When an interactive state replaces the outline, it must preserve a visible focus
29
29
 
30
30
  ## Family manifests
31
31
 
32
- | Family | Import | Contents |
33
- | ---------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
34
- | Core | `actual-css/css` | reset, tokens, theme, base, intents, variants, focus, print |
35
- | Typography | `actual-css/css/typography` | prose, overline, fluid |
36
- | Layout | `actual-css/css/layout` | stack, cluster, center, frame, media, switcher, sidebar-layout, grid, scroller, scroll-snap, topbar, container-query, app-shell |
37
- | Forms | `actual-css/css/forms` | native control baseline |
38
- | Forms (complete) | `actual-css/css/forms/all` | base plus input-icon, switch, range, choice-card, custom-select, floating-field, otp |
39
- | Components | `actual-css/css/components` | buttons, surfaces, overlays, feedback, navigation, data and composed controls |
40
- | Effects | `actual-css/css/effects` | aura |
41
- | Utilities | `actual-css/css/utilities` | base and extra utilities |
32
+ Each family is one import. The contents are enumerations rather than table
33
+ cells, so they read as a list:
34
+
35
+ - **Core** — `actual-css/css`
36
+ reset, tokens, theme, base, intents, variants, focus, print
37
+ - **Typography** — `actual-css/css/typography`
38
+ prose, overline, fluid
39
+ - **Layout** — `actual-css/css/layout`
40
+ stack, cluster, center, frame, media, switcher, sidebar-layout, grid,
41
+ scroller, scroll-snap, topbar, container-query, app-shell
42
+ - **Forms** — `actual-css/css/forms`
43
+ native control baseline
44
+ - **Forms (complete)** — `actual-css/css/forms/all`
45
+ base plus input-icon, switch, range, choice-card, custom-select,
46
+ floating-field, otp
47
+ - **Components** — `actual-css/css/components`
48
+ buttons, surfaces, overlays, feedback, navigation, data and composed controls
49
+ - **Effects** — `actual-css/css/effects`
50
+ aura
51
+ - **Utilities** — `actual-css/css/utilities`
52
+ base and extra utilities
42
53
 
43
54
  Individual modules can be imported through their domain path:
44
55
 
@@ -3,7 +3,7 @@
3
3
  > The optional JavaScript runtime that progressively enhances Actual's semantic markup — self-registering side-effect modules, the `enhance()` DOM lifecycle, stateless command routing, and the floating and surface contracts for custom widgets.
4
4
 
5
5
  Actual's JavaScript modules are optional. Importing `actual-css/js/full`
6
- registers the complete default runtime — every built-in enhancer, including
6
+ registers the full runtime — every built-in enhancer, including
7
7
  validation and status. Importing `actual-css/js` registers only the enhancement
8
8
  manifest loader; importing a specific module registers only that behavior. The
9
9
  runtime does not require `DOMContentLoaded` or manual init calls, and it never
@@ -18,7 +18,7 @@ runtime evolves. The runtime assumes the modern platform primitives available
18
18
  across Minimal and ships no compatibility layer or polyfill.
19
19
 
20
20
  | Tier | Firefox | Safari | Chromium |
21
- |--------------|---------|-----------|----------|
21
+ | ------------ | ------- | --------- | -------- |
22
22
  | Degraded | 78+ | 14+ | 88+ |
23
23
  | **Minimal** | **98+** | **15.4+** | **99+** |
24
24
  | Intermediate | 121+ | 16+ | 106+ |
@@ -56,7 +56,7 @@ Modules are safe to import during SSR — registration is a no-op when there is
56
56
  DOM. The runtime remains active until the page unloads; there is no teardown
57
57
  handle, and cleanup happens per element when an element leaves the DOM.
58
58
 
59
- ## The default runtime
59
+ ## The full runtime
60
60
 
61
61
  Loading `dist/actual.full.js` as a plain `<script>` (no `type="module"`, no
62
62
  bundler, no `import`) gets the full runtime. Static HTML that needs to trigger
@@ -74,22 +74,25 @@ example:
74
74
  </script>
75
75
  ```
76
76
 
77
- | Module | Behavior |
78
- |------------------------------------|-------------------------------------------------------------------------------|
79
- | `actual-css/js/flyout` | Trigger → panel surface: positioning, open/close, sheet mode (token `flyout`) |
80
- | `actual-css/js/context-menu` | Context menus on `data-context-menu` |
81
- | `actual-css/js/focus-group` | Reusable roving-focus controller; no automatic discovery |
82
- | `actual-css/js/dialog` | Native `<dialog>` behavior, focus management, dismissal |
83
- | `actual-css/js/dismiss` | The generic `--dismiss` command |
84
- | `actual-css/js/tab` | Tab panels and arrow-key navigation (token `tabs`) |
85
- | `actual-css/js/tooltip` | Tooltips on `data-tooltip` |
86
- | `actual-css/js/scrollspy` | Scroll-driven nav highlighting (token `scrollspy`) |
87
- | `actual-css/js/filter` | Input value filtering on `data-filter` |
88
- | `actual-css/js/mask` | Input masks on `data-mask` |
89
- | `actual-css/js/password` | Password reveal toggle |
90
- | `actual-css/js/validation` | Form validation (token `validation`) |
91
- | `actual-css/js/status` | Singleton status bar on `[data-status][role="status"]` |
92
- | `actual-css/js/enhancement-loader` | Declared enhancement manifests (`data-enhance-modules`, `Enhance-Modules`) |
77
+ | Module | Behavior |
78
+ | ---------------------------------- | ----------------------------------------------------------- |
79
+ | `actual-css/js/flyout` | Trigger → panel positioning and open/close (token `flyout`) |
80
+ | `actual-css/js/context-menu` | Context menus on `data-context-menu` |
81
+ | `actual-css/js/focus-group` | Reusable roving-focus controller; no automatic discovery |
82
+ | `actual-css/js/dialog` | Native `<dialog>` behavior, focus management, dismissal |
83
+ | `actual-css/js/dismiss` | The generic `--dismiss` command |
84
+ | `actual-css/js/tab` | Tab panels and arrow-key navigation (token `tabs`) |
85
+ | `actual-css/js/tooltip` | Tooltips on `data-tooltip` |
86
+ | `actual-css/js/scrollspy` | Scroll-driven nav highlighting (token `scrollspy`) |
87
+ | `actual-css/js/filter` | Input value filtering on `data-filter` |
88
+ | `actual-css/js/mask` | Input masks on `data-mask` |
89
+ | `actual-css/js/password` | Password reveal toggle |
90
+ | `actual-css/js/validation` | Form validation (token `validation`) |
91
+ | `actual-css/js/status` | Singleton status bar on `[data-status][role="status"]` |
92
+ | `actual-css/js/enhancement-loader` | Declared enhancement manifests |
93
+
94
+ The enhancement loader reads its manifests from `data-enhance-modules` or the
95
+ `Enhance-Modules` header.
93
96
 
94
97
  Use `actual-css/js/full` for demos, playgrounds, and smoke tests where one import
95
98
  enables every built-in behavior. Production apps can import individual modules
@@ -121,19 +124,18 @@ The JS is designed to run on its own, without Actual's stylesheet.
121
124
  ## The runtime as a primitive kit
122
125
 
123
126
  For building custom widgets (select, tags, date picker) on Actual's primitives,
124
- see the widget-primitives design note. Every primitive subpath is published in
125
- `package.json#exports`:
126
-
127
- | Subpath | Purpose |
128
- |--------------------------|------------------------------------------------------------------|
129
- | `actual-css/js/enhance` | DOM lifecycle engine: `enhance()`, `registerEnhancement`, tokens |
130
- | `actual-css/js/escape` | Per-document LIFO Escape dismissal stack |
131
- | `actual-css/js/events` | The `actual:*` event name constants |
132
- | `actual-css/js/floating` | Positioning engine (`reposition`, `repositionAt`, `autoUpdate`) |
133
- | `actual-css/js/focus` | Focusable-item lookup and helpers |
134
- | `actual-css/js/keys` | Roving-focus item navigation helpers |
135
- | `actual-css/js/menu` | Menu keyboard/click wiring, item vocabulary |
136
- | `actual-css/js/surface` | Surface lifecycle (`openSurface`, `closeSurface`, …) |
127
+ see the widget-primitives design note. Every Actual runtime primitive subpath is
128
+ published in `package.json#exports`:
129
+
130
+ | Subpath | Purpose |
131
+ | ----------------------- | ---------------------------------------------------------------- |
132
+ | `actual-css/js/enhance` | DOM lifecycle engine: `enhance()`, `registerEnhancement`, tokens |
133
+ | `actual-css/js/escape` | Per-document LIFO Escape dismissal stack |
134
+ | `actual-css/js/events` | The `actual:*` event name constants |
135
+ | `actual-css/js/focus` | Focusable-item lookup and helpers |
136
+ | `actual-css/js/keys` | Roving-focus item navigation helpers |
137
+ | `actual-css/js/menu` | Menu keyboard/click wiring, item vocabulary |
138
+ | `actual-css/js/surface` | Surface lifecycle (`openSurface`, `closeSurface`, …) |
137
139
 
138
140
  The exports map is explicit — it *is* the statement of what is public.
139
141
 
@@ -146,31 +148,36 @@ computes and writes inline `left`/`top`, `data-placement`,
146
148
  caller owns the floating element's presentation entirely.
147
149
 
148
150
  ```js
149
- import { autoUpdate, reposition, repositionAt } from "actual-css/js/floating";
151
+ import { autoUpdate, reposition, repositionAt } from "@lekoala/floating";
150
152
 
151
- const stop = autoUpdate(float, () => {
153
+ const stop = autoUpdate(trigger, float, () => {
152
154
  reposition(trigger, float, { placement: "bottom-start", distance: 4 });
153
155
  });
154
156
  ```
155
157
 
156
158
  Options passed to `reposition()`:
157
159
 
158
- | Option | Default | Contract |
159
- |----------------|------------------|------------------------------------------------------------------|
160
- | `placement` | `"bottom-start"` | Preferred side and alignment (`-start` / `-end`) |
161
- | `distance` | `0` | Gap between the reference and the floating element |
162
- | `flip` | `true` | Flip to the opposite side when the preferred side is out of view |
163
- | `shift` | `true` | Shift along the main axis to stay within the boundary |
164
- | `shiftPadding` | `4` | Minimum space kept from the boundary |
165
- | `scope` | viewport | Boundary element for overflow decisions |
166
-
167
- `autoUpdate(element, callback)` batches scroll, resize, and element-resize
168
- callbacks per document and returns a stop handle; it does not keep a closed or
160
+ | Option | Default | Contract |
161
+ | -------------- | ---------------- | -------------------------------------------- |
162
+ | `placement` | `"bottom-start"` | Preferred side and alignment |
163
+ | `distance` | `0` | Gap from the reference element |
164
+ | `flip` | `true` | Flip when the preferred side is out of view |
165
+ | `shift` | `true` | Shift along the cross axis to stay in bounds |
166
+ | `shiftPadding` | `4` | Minimum space kept from the boundary |
167
+ | `scope` | viewport | Boundary element for overflow decisions |
168
+
169
+ `placement` takes a `-start` or `-end` alignment suffix.
170
+
171
+ `@lekoala/floating` is the standalone positioning dependency used by the
172
+ runtime. `autoUpdate(reference, float, callback)` batches scroll, resize, and
173
+ element-resize callbacks per document and returns a stop handle; it observes
174
+ both the reference and floating element while the surface is open. Pass `null`
175
+ as the reference for point-positioned surfaces. It does not keep a closed or
169
176
  hidden element positioned. `repositionAt(x, y, float, opts)` positions relative
170
177
  to a fixed point — used by context menus.
171
178
 
172
- A third-party widget importing only `floating` with no Actual stylesheet must be
173
- able to position a listbox under an input — that is the test.
179
+ A third-party widget importing only `@lekoala/floating` with no Actual stylesheet
180
+ must be able to position a listbox under an input — that is the test.
174
181
 
175
182
  ## Surface contract
176
183
 
@@ -206,22 +213,33 @@ visible dismissable UI to the shared per-document Escape stack.
206
213
  widgets can veto or decorate opens, and context menus inject their own
207
214
  `source`/`restoreFocusTo` through it.
208
215
 
209
- | Option | Default | Contract |
210
- |-------------------|-----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
211
- | `trigger` | — | Anchoring element; also the focus-restore target by default |
212
- | `source` | — | Alternate anchor when there is no trigger |
213
- | `x`, `y` | — | Position at a fixed viewport point instead of an anchor (context menus) |
214
- | `placement` | `"bottom-start"` | Preferred placement |
215
- | `distance` | `4` | Gap between anchor and surface |
216
- | `flip` | `true` | Flip when the preferred side is out of view |
217
- | `shift` | `true` | Shift to stay within the boundary |
218
- | `shiftPadding` | `4` | Minimum space kept from the boundary |
219
- | `scope` | viewport | Boundary element |
220
- | `mobile` | `"auto"` | `"auto"`, `"sheet"`, `"none"`, or `"anchored"` sheet behavior |
221
- | `breakpoint` | `768` | Max viewport width for an automatic sheet |
222
- | `autoClose` | `"outside"` | `"true"` closes for inside and outside clicks; `"inside"` and `"outside"` limit the side; `"false"` disables automatic click closing. Invalid values use `"true"` |
223
- | `dismissOnScroll` | `false` | Close when scrolling outside the surface follows a new user input; opening/focus scroll is ignored |
224
- | `restoreFocusTo` | `trigger` or `source` | Element focused on close |
216
+ | Option | Default | Contract |
217
+ | ----------------- | ---------------- | ------------------------------------------- |
218
+ | `trigger` | — | Anchoring element, and focus-restore target |
219
+ | `source` | — | Alternate anchor when there is no trigger |
220
+ | `x`, `y` | — | Position at a fixed viewport point |
221
+ | `placement` | `"bottom-start"` | Preferred placement |
222
+ | `distance` | `4` | Gap between anchor and surface |
223
+ | `flip` | `true` | Flip when the preferred side is hidden |
224
+ | `shift` | `true` | Shift to stay within the boundary |
225
+ | `shiftPadding` | `4` | Minimum space kept from the boundary |
226
+ | `scope` | viewport | Boundary element |
227
+ | `mobile` | `"auto"` | Sheet behavior |
228
+ | `breakpoint` | `768` | Max viewport width for an automatic sheet |
229
+ | `autoClose` | `"outside"` | Which clicks close the surface |
230
+ | `dismissOnScroll` | `false` | Close on a scroll the user just started |
231
+ | `restoreFocusTo` | `trigger` | Element focused on close |
232
+
233
+ `x`, `y` replace the anchor entirely, which is what a context menu needs.
234
+ `mobile` takes `"auto"`, `"sheet"`, `"none"` or `"anchored"`.
235
+
236
+ `autoClose` takes `"true"` to close on inside and outside clicks, `"inside"` or
237
+ `"outside"` to limit it to one side, and `"false"` to disable automatic click
238
+ closing; an invalid value reads as `"true"`.
239
+
240
+ `dismissOnScroll` only fires when the scroll follows a new user input — the
241
+ scroll that opening or focusing causes is ignored. `restoreFocusTo` falls back
242
+ to `source` when there is no `trigger`.
225
243
 
226
244
  The click policy belongs to the surface rather than to a particular menu
227
245
  anatomy. The generic primitive defaults to outside-click dismissal; flyout and
@@ -242,14 +260,18 @@ The runtime dispatches a small set of public `actual:*` events. All are
242
260
  listenable on the document; cancelable events veto the associated action when
243
261
  `preventDefault()` is called.
244
262
 
245
- | Event | Dispatch | Contract |
246
- |------------------------|--------------------------------------------|------------------------------------------------------------------------------------------------|
247
- | `actual:surface-open` | `openSurface()`, before a surface opens | Cancelable. `detail: { surface, options }` |
248
- | `actual:context-menu` | context-menu, before its menu opens | Cancelable. `detail: { menu, context, origin, trigger }` |
249
- | `actual:status` | status module, or any code | Show or clear the status bar. `detail: { message, intent, duration }`; omit `message` to clear |
250
- | `actual:invalid` | validation, after a submit was blocked | `detail: { form, firstInvalid, message }` |
251
- | `actual:dialog-cancel` | dialog, before native cancel close | Cancelable. `detail: { dialog, sourceEvent }` |
252
- | `actual:dismiss` | `--dismiss` command, after hiding a target | `detail: { trigger }` |
263
+ | Event | Dispatch | `detail` |
264
+ | ---------------------- | ------------------------------ | ------------------------------------ |
265
+ | `actual:surface-open` | before a surface opens | `{ surface, options }` |
266
+ | `actual:context-menu` | before a context menu opens | `{ menu, context, origin, trigger }` |
267
+ | `actual:status` | status module, or any code | `{ message, intent, duration }` |
268
+ | `actual:invalid` | after a submit was blocked | `{ form, firstInvalid, message }` |
269
+ | `actual:dialog-cancel` | before a native cancel close | `{ dialog, sourceEvent }` |
270
+ | `actual:dismiss` | after `--dismiss` hid a target | `{ trigger }` |
271
+
272
+ `actual:surface-open`, `actual:context-menu` and `actual:dialog-cancel` are
273
+ cancelable. `actual:status` both shows and clears the status bar — omit
274
+ `message` to clear it.
253
275
 
254
276
  ## Extending the runtime
255
277
 
@@ -388,7 +410,8 @@ import { loadEnhancement, loadEnhancements, loadResponse } from "actual-css/js/e
388
410
 
389
411
  await loadEnhancements(); // every manifest block in the document
390
412
  await loadEnhancement("autosubmit", "/js/autosubmit.js");
391
- await loadResponse(fetch("/...").then((r) => r)); // Enhance-Modules header
413
+ const response = await fetch("/...");
414
+ await loadResponse(response); // Enhance-Modules header
392
415
  ```
393
416
 
394
417
  The `Enhance-Modules` HTTP header carries the same JSON object. Loaded modules
@@ -638,7 +661,7 @@ enhance({
638
661
 
639
662
  ## Form validation
640
663
 
641
- `actual-css/js/validation` is part of the default runtime and also importable on
664
+ `actual-css/js/validation` is part of the full runtime and also importable on
642
665
  its own — it is an enhancer, not a validation framework. Forms opt in with the
643
666
  `data-enhance="validation"` token (`.needs-validation` is a presentation class
644
667
  for CSS-only `:user-invalid` feedback and does not by itself register the
@@ -205,7 +205,7 @@ Actual does not prohibit media queries. It simply does not encode every media qu
205
205
  ## Utility translation guide
206
206
 
207
207
  | Tailwind usage | Actual approach |
208
- |--------------------------------------|---------------------------------------------------|
208
+ | ------------------------------------ | ------------------------------------------------- |
209
209
  | `flex flex-col gap-*` | `.stack` |
210
210
  | `flex flex-wrap items-center gap-*` | `.cluster` |
211
211
  | `grid grid-cols-*` | `.grid`, `.grid-2`, `.grid-3`, etc. |
@@ -407,7 +407,7 @@ Do not remove Tailwind from the build until migrated screens no longer depend on
407
407
  ## Where migration is genuinely harder
408
408
 
409
409
  | Existing Tailwind usage | Migration cost |
410
- |----------------------------------------------------|----------------|
410
+ | -------------------------------------------------- | -------------- |
411
411
  | buttons, badges, alerts, forms | low |
412
412
  | repeated card/panel patterns | low |
413
413
  | basic flex/grid composition | low to medium |
@@ -1,11 +1,11 @@
1
1
  # App Shell
2
2
 
3
- Full-height, single-column document flow. Despite its historical name, this is
4
- the general shell for ordinary pages as well as simple applications.
3
+ Full-height, single-column document flow. Use it as the outer shell for ordinary pages,
4
+ simple applications, and other layouts that need a header / main / footer structure spanning the viewport.
5
5
 
6
6
  Header and footer are document landmarks, not required layout classes.
7
- Use semantic elements by default. `.app-shell` already supplies the outer
8
- column, so do not add a `.stack` solely to arrange the page landmarks.
7
+ Use semantic elements by default. .app-shell already supplies the outer column,
8
+ so do not add a .stack solely to arrange the page landmarks.
9
9
 
10
10
  ```html demo
11
11
  <body class="app-shell">
@@ -5,10 +5,14 @@ number of children visible in one mockup.
5
5
 
6
6
  ## Page and application shells
7
7
 
8
- | Situation | Recipe |
9
- |---|---|
10
- | Public, marketing, editorial, or normally scrolling page | Semantic landmarks; optionally `.app-shell`, with `.navbar` for site navigation |
11
- | Persistent topbar + independently scrolling main + bottom-to-side primary navigation | `.app-layout` with its exact direct-child contract |
8
+ | Situation | Recipe |
9
+ | -------------------------------------- | ------------------------------------------- |
10
+ | A normally scrolling page | Semantic landmarks, optionally `.app-shell` |
11
+ | Topbar + scrolling main + adaptive nav | `.app-layout` |
12
+
13
+ The first covers public, marketing and editorial pages; add `.navbar` for site
14
+ navigation. The second is `.app-layout` with its exact direct-child contract,
15
+ where the primary navigation moves from bottom to side.
12
16
 
13
17
  Do not choose `.app-layout` from the word "app" or from the presence of a
14
18
  header. Its viewport-sized grid, hidden shell overflow, internal main scroll,
@@ -19,11 +23,11 @@ below.
19
23
  ## Content relationships
20
24
 
21
25
  | Situation | Primitive |
22
- |--------------------------------------------------------------|-------------------|
26
+ | ------------------------------------------------------------ | ----------------- |
23
27
  | Vertical flow | `.stack` |
24
28
  | Inline actions, tags, or navigation that may wrap | `.cluster` |
25
29
  | Responsive collection; an incomplete final row is acceptable | `.grid` |
26
- | Known structural density, at most N columns | `.grid-N` |
30
+ | Known structural density, at most N columns | `.grid-N` |
27
31
  | Peer regions that must switch together | `.switcher` |
28
32
  | Main content followed by a secondary region | `.sidebar-layout` |
29
33
  | Fixed media followed by flexible content | `.media` |
@@ -12,7 +12,7 @@ column count.
12
12
  `.grid` fits as many columns as the available inline space permits. Incomplete
13
13
  final rows are part of the contract.
14
14
 
15
- ```html demo
15
+ ```html demo resize
16
16
  <section class="grid">
17
17
  <article class="card"><h3>Starter</h3><p>For small projects.</p></article>
18
18
  <article class="card"><h3>Team</h3><p>For shared products.</p></article>
@@ -34,7 +34,7 @@ Tune the item minimum with `--grid-min`.
34
34
  own: it never exceeds N columns, never overflows, and every item keeps the same
35
35
  width.
36
36
 
37
- ```html demo bare
37
+ ```html demo resize
38
38
  <div class="grid-4">
39
39
  <div class="card">Exercitation</div>
40
40
  <div class="card">Amet mollit</div>
@@ -47,7 +47,7 @@ width.
47
47
  density is `.grid-N`'s. Choose the preset that suits your item size:
48
48
 
49
49
  | Item | Preset |
50
- |-----------------------------------|----------------------|
50
+ | --------------------------------- | -------------------- |
51
51
  | large card | `.grid-2` |
52
52
  | card with a heading and a summary | `.grid-3`, `.grid-4` |
53
53
  | compact tile, stat, avatar | `.grid-6` |
@@ -56,9 +56,9 @@ density is `.grid-N`'s. Choose the preset that suits your item size:
56
56
 
57
57
  Left alone, a preset collapses one column at a time, so a six-item `.grid-6`
58
58
  can pass through five columns — five items and a lone sixth. The example above
59
- is that bare version. Placed inside a container named **`actual-grid`** — the
59
+ is that bare version. Placed inside a container named **`actual-container`** — the
60
60
  `.container-query` helper, or a region of your own that declares
61
- `container: actual-grid / inline-size` — it only ever enters a **divisor of N**:
61
+ `container: actual-container / inline-size` — it only ever enters a **divisor of N**:
62
62
 
63
63
  ```text
64
64
  .grid-2 2 → 1
@@ -69,7 +69,7 @@ is that bare version. Placed inside a container named **`actual-grid`** — the
69
69
 
70
70
  Every state splits the collection evenly, and all items keep the same width.
71
71
 
72
- ```html demo
72
+ ```html demo resize
73
73
  <div class="container-query">
74
74
  <div class="grid-6">
75
75
  <div class="card">1</div>
@@ -89,7 +89,7 @@ not the grid's own width. Padding and borders on the container come off before
89
89
  the query resolves.
90
90
 
91
91
  | Container content box | `.grid-2` | `.grid-3` | `.grid-4` | `.grid-6` |
92
- |-----------------------|-----------|-----------|-----------|-----------|
92
+ | --------------------- | --------- | --------- | --------- | --------- |
93
93
  | under `28rem` | 1 | 1 | 1 | 1 |
94
94
  | `28rem` to `48rem` | 2 | 1 | 2 | 2 |
95
95
  | `48rem` to `64rem` | 2 | 3 | 2 | 3 |
@@ -113,9 +113,10 @@ change cannot drop the region a state.
113
113
 
114
114
  Balanced subdivision is precision, never a prerequisite for responsive
115
115
  behavior — forgetting the container costs you the exact chain, nothing else.
116
- The grid responds only to a container named `actual-grid`, never to an
117
- incidental query container, so a region that sets `container-type: inline-size`
118
- for its own reasons leaves the grid untouched. The container has to be an
116
+ `actual-container` is the framework's shared name for size-aware components,
117
+ so one region can serve a grid and a step flow at once. The grid responds only
118
+ to that name, never to an incidental query container, so a region that sets
119
+ `container-type: inline-size` for its own reasons leaves the grid untouched. The container has to be an
119
120
  ancestor: an element cannot query its own size without taking inline-size
120
121
  containment, which would collapse the grid inside a `.cluster`, a float, or any
121
122
  shrink-to-fit box. Put it on a normal block-level wrapper for the same reason.
@@ -44,12 +44,16 @@ not as the wrapper that lays out independent full-width regions of a page.
44
44
  `--gap` is the primitive's channel, and the density variants set it at the point
45
45
  of use. Pick the one that matches how tightly the children belong together:
46
46
 
47
- | Markup | Gap | Use for |
48
- |--------------------|------|--------------------------------------------------------|
49
- | `.stack gap-none` | 0 | Lines that form one typographic unit — a name and a job title, a figure and its caption. |
50
- | `.stack sm` | 8px | A homogeneous series of distinct controls — a radio list, a checkbox list, a compact vertical menu. |
51
- | `.stack` | 12px | Normal flow between distinct elements. |
52
- | `.stack lg` | 24px | Sections, or blocks that should read as separated. |
47
+ | Markup | Gap | Use for |
48
+ | ----------------- | ---- | ------------------------------------------ |
49
+ | `.stack gap-none` | 0 | Lines forming one typographic unit |
50
+ | `.stack sm` | 8px | A homogeneous series of controls |
51
+ | `.stack` | 12px | Normal flow between distinct elements |
52
+ | `.stack lg` | 24px | Sections, or blocks that read as separated |
53
+
54
+ One typographic unit means a name and a job title, or a figure and its caption.
55
+ A homogeneous series means a radio list, a checkbox list, or a compact vertical
56
+ menu.
53
57
 
54
58
  The distinction between the first two matters. `42` above `Open issues` is
55
59
  almost a single block of text, so it takes `gap-none`. Three `.choice` labels
@@ -3,13 +3,13 @@
3
3
  Choose list markup from the content semantics, then add only the layout or
4
4
  component contract the collection needs.
5
5
 
6
- | Need | Use |
7
- | --- | --- |
8
- | Bullets or order carry meaning | Native `<ul>` or `<ol>` |
9
- | One leading element and one flexible content region | [`.media`](../layout/media.md) |
10
- | Repeated application rows with leading, content, and trailing regions | [`.list`](../components/list.md) |
11
- | A list of navigation links | [`.nav-list`](./navigation-list.md) |
12
- | A richer collection with its own item structure | Native list plus layout primitives and components |
6
+ | Need | Use |
7
+ | ----------------------------------------------- | ----------------------------------- |
8
+ | Bullets or order carry meaning | Native `<ul>` or `<ol>` |
9
+ | Leading element plus flexible content | [`.media`](../layout/media.md) |
10
+ | Repeated rows: leading, content, trailing | [`.list`](../components/list.md) |
11
+ | A list of navigation links | [`.nav-list`](./navigation-list.md) |
12
+ | A richer collection with its own item structure | Native list plus primitives |
13
13
 
14
14
  `.media` and `.list` are not interchangeable. `.media` is geometry for one
15
15
  two-part composition and requires exactly two direct children. `.list` owns the
@@ -5,7 +5,7 @@ Text hidden visually but still available to assistive technology.
5
5
  ## Class reference
6
6
 
7
7
  | Class | Kind | Description |
8
- |------------|---------|-----------------------------------------------------------------|
8
+ | ---------- | ------- | --------------------------------------------------------------- |
9
9
  | `.sr-only` | Utility | Visually hides text while keeping it in the accessibility tree. |
10
10
 
11
11
  ## Screen reader only
@@ -4,19 +4,26 @@ Small flex helpers for grow behavior and other one-line needs.
4
4
 
5
5
  ## Class reference
6
6
 
7
- | Class | Kind | Description |
8
- |----------------------------------|---------|---------------------------------------------------------------------------|
9
- | `.grow` | Utility | Makes an item take available flex space without overflowing. |
10
- | `.items-start` | Utility | Aligns children to the block-start edge; sets `--items-align`. |
11
- | `.items-center` | Utility | Centers children on the cross axis; sets `--items-align`. |
12
- | `.items-end` | Utility | Aligns children to the block-end edge; sets `--items-align`. |
13
- | `.dot` | Utility | Inline separator dot for metadata rows. |
14
- | `.justify-content-start` | Utility | `justify-content: flex-start` and `--cluster-justify`. Optional layer. |
15
- | `.justify-content-center` | Utility | `justify-content: center` and `--cluster-justify`. Optional layer. |
16
- | `.justify-content-end` | Utility | `justify-content: flex-end` and `--cluster-justify`. Optional layer. |
17
- | `.justify-content-space-between` | Utility | `justify-content: space-between` and `--cluster-justify`. Optional layer. |
18
- | `.flex-wrap` | Utility | `flex-wrap: wrap` on any flex container. Optional layer. |
19
- | `.flex-nowrap` | Utility | `flex-wrap: nowrap` on any flex container. Optional layer. |
7
+ Base utilities:
8
+
9
+ | Class | Description |
10
+ | --------------- | -------------------------------------------------------------- |
11
+ | `.grow` | Makes an item take available flex space without overflowing. |
12
+ | `.items-start` | Aligns children to the block-start edge; sets `--items-align`. |
13
+ | `.items-center` | Centers children on the cross axis; sets `--items-align`. |
14
+ | `.items-end` | Aligns children to the block-end edge; sets `--items-align`. |
15
+ | `.dot` | Inline separator dot for metadata rows. |
16
+
17
+ Extra utilities:
18
+
19
+ | Class | Description |
20
+ | -------------------------------- | --------------------------------------------------------- |
21
+ | `.justify-content-start` | `justify-content: flex-start` and `--cluster-justify`. |
22
+ | `.justify-content-center` | `justify-content: center` and `--cluster-justify`. |
23
+ | `.justify-content-end` | `justify-content: flex-end` and `--cluster-justify`. |
24
+ | `.justify-content-space-between` | `justify-content: space-between` and `--cluster-justify`. |
25
+ | `.flex-wrap` | `flex-wrap: wrap` on any flex container. |
26
+ | `.flex-nowrap` | `flex-wrap: nowrap` on any flex container. |
20
27
 
21
28
  ## Grow
22
29
 
@@ -5,7 +5,7 @@ Link styling for chrome that is conceptually a link but should not look like pro
5
5
  ## Class reference
6
6
 
7
7
  | Class | Kind | Description |
8
- |---------------|---------|-----------------------------------------------------------|
8
+ | ------------- | ------- | --------------------------------------------------------- |
9
9
  | `.link-plain` | Utility | Removes the underline and inherits the surrounding color. |
10
10
  | `.link-muted` | Utility | Muted link that shifts to the full text color on hover. |
11
11
 
@@ -5,7 +5,7 @@ Utilities for list chrome reset, readable measure, and editorial kicker labels.
5
5
  ## Class reference
6
6
 
7
7
  | Class | Kind | Description |
8
- |---------------|-----------|---------------------------------------------------------------|
8
+ | ------------- | --------- | ------------------------------------------------------------- |
9
9
  | `.list-reset` | Utility | Removes native list margin, padding, and markers. |
10
10
  | `.measure` | Utility | Caps a block at a readable width via `--measure`. |
11
11
  | `.overline` | Component | Small editorial kicker label: muted, uppercase, letterspaced. |