actual-css 0.2.0 → 0.3.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 (214) hide show
  1. package/CHANGELOG.md +38 -1
  2. package/README.md +24 -9
  3. package/dist/actual-themes.min.css +1 -0
  4. package/dist/actual.css +1244 -915
  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 +1 -1
  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 +205 -0
  25. package/docs/pages/components/card.md +183 -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 +41 -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 +92 -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 +57 -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 +21 -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 +18 -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 +31 -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 +20 -12
  104. package/src/css/actual.css +12 -1
  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 +126 -99
  109. package/src/css/components/avatar.css +16 -10
  110. package/src/css/components/badge.css +55 -35
  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 +78 -32
  114. package/src/css/components/card.css +17 -37
  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 +17 -18
  124. package/src/css/components/overline.css +0 -7
  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 +16 -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 +19 -18
  149. package/src/css/intents.css +2 -2
  150. package/src/css/layout.css +29 -1
  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 +3 -3
  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 +37 -65
  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 +185 -136
  198. package/src/js/tab.js +36 -53
  199. package/src/js/tooltip.js +53 -31
  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,492 @@
1
+ # Platform alignment
2
+
3
+ Actual CSS should stay close to the direction of the web platform.
4
+
5
+ HTML, CSS, ARIA, and browser APIs continue to absorb behaviors that historically required framework components or JavaScript widgets. Open UI is a particularly useful signal because it studies common design-system patterns and explores how they can become native platform capabilities.
6
+
7
+ This note does not define a browser support policy and is not a commitment to implement experimental proposals.
8
+
9
+ Its purpose is architectural:
10
+
11
+ > When the platform eventually provides a capability natively, Actual should be able to adopt it by removing code rather than redesigning its public API.
12
+
13
+ ## Core principle
14
+
15
+ Actual should prefer this progression:
16
+
17
+ ```text
18
+ native HTML
19
+ ↓
20
+ native HTML + CSS
21
+ ↓
22
+ native HTML + progressive enhancement
23
+ ↓
24
+ small reusable behavior primitive
25
+ ↓
26
+ Actual component
27
+ ↓
28
+ application-specific widget
29
+ ```
30
+
31
+ The further down this list a feature sits, the stronger the justification should be.
32
+
33
+ A framework component should not exist merely because the platform does not provide a convenient primitive today.
34
+
35
+ ## Design for deletion
36
+
37
+ Progressive enhancement is not only about supporting older browsers.
38
+
39
+ It should also make framework code temporary.
40
+
41
+ When Actual implements behavior that browsers may eventually provide, the implementation should be structured so that native support can replace one responsibility at a time.
42
+
43
+ For example, a floating interactive surface can involve several independent concerns:
44
+
45
+ ```text
46
+ surface
47
+ positioning
48
+ open / close lifecycle
49
+ light dismiss
50
+ focus management
51
+ keyboard navigation
52
+ command invocation
53
+ ```
54
+
55
+ These should not unnecessarily become one monolithic widget.
56
+
57
+ The platform is evolving these responsibilities independently. Actual should do the same.
58
+
59
+ This is the motivation behind reusable primitives such as `surface`, `floating`, `menu`, `keys`, and `command`.
60
+
61
+ A future native primitive should ideally replace one of these pieces without forcing unrelated behavior or styling to change.
62
+
63
+ ## Follow semantics, not proposal syntax
64
+
65
+ Open UI proposals are useful directional signals, but experimental syntax is not an Actual API.
66
+
67
+ Actual should not prematurely reproduce proposed HTML attributes or elements as `data-*` APIs.
68
+
69
+ For example, if the platform is exploring:
70
+
71
+ ```html
72
+ <div focusgroup="toolbar">
73
+ ```
74
+
75
+ Actual should not automatically introduce:
76
+
77
+ ```html
78
+ <div data-focusgroup="toolbar">
79
+ ```
80
+
81
+ Instead, the underlying behavior can influence the design of a reusable JavaScript primitive.
82
+
83
+ If native `focusgroup` later becomes broadly available, the JavaScript implementation can become a fallback or disappear.
84
+
85
+ The important thing to copy early is the **responsibility boundary**, not necessarily the proposed syntax.
86
+
87
+ ## Preserve native-shaped markup
88
+
89
+ When a useful platform feature can be added without harming unsupported browsers, documentation should prefer markup that remains compatible with that future.
90
+
91
+ For example, Actual's switch is intentionally based on a real checkbox:
92
+
93
+ ```html
94
+ <input type="checkbox" class="switch">
95
+ ```
96
+
97
+ If a native switch attribute becomes appropriate for the supported browser contract, the same component can evolve toward:
98
+
99
+ ```html
100
+ <input type="checkbox" class="switch" switch>
101
+ ```
102
+
103
+ without replacing the element or changing the styling API.
104
+
105
+ The class remains responsible for appearance.
106
+
107
+ The platform remains responsible for semantics and behavior.
108
+
109
+ This separation is desirable.
110
+
111
+ ## Public classes should survive platform evolution
112
+
113
+ Actual classes should generally describe visual or compositional concepts rather than reimplement browser mechanics.
114
+
115
+ For example:
116
+
117
+ ```text
118
+ .switch
119
+ .modal
120
+ .drawer
121
+ .tooltip
122
+ .toolbar
123
+ ```
124
+
125
+ may remain useful styling hooks even if more of their semantics and behavior eventually become native.
126
+
127
+ This means platform adoption should not require unnecessary class churn.
128
+
129
+ A successful transition may look like:
130
+
131
+ ```text
132
+ Actual class + Actual JavaScript
133
+ ↓
134
+ Actual class + small fallback
135
+ ↓
136
+ Actual class + native HTML
137
+ ```
138
+
139
+ rather than replacing one framework API with another.
140
+
141
+ ## Prefer capabilities over browser generations
142
+
143
+ New platform features should not automatically raise Actual's Minimal browser floor.
144
+
145
+ When a modern capability has a cheap functional fallback, it should normally be used as progressive enhancement.
146
+
147
+ This applies especially to features concerned with:
148
+
149
+ * presentation;
150
+ * positioning;
151
+ * animation;
152
+ * interaction convenience;
153
+ * declarative invocation;
154
+ * richer native controls.
155
+
156
+ The Minimal tier should move when the framework genuinely needs a capability for its supported contract, not simply because a newer API produces a nicer implementation.
157
+
158
+ ## Current platform directions
159
+
160
+ The following areas are particularly relevant to Actual's architecture.
161
+
162
+ Their specifications and exact syntax may change. The important part is the direction they indicate.
163
+
164
+ ### Focus groups
165
+
166
+ Focus-group proposals aim to provide common keyboard and focus behavior for collections of related controls.
167
+
168
+ This overlaps with behavior currently implemented through keyboard helpers such as next-item, previous-item, first-item, and last-item navigation.
169
+
170
+ **Influence on Actual:**
171
+
172
+ * keep keyboard navigation reusable rather than widget-specific;
173
+ * consider a reusable focus-group primitive internally;
174
+ * let tabs, menus, toolbars, and similar patterns share it;
175
+ * avoid exposing speculative `focusgroup`-like HTML syntax prematurely.
176
+
177
+ This is a strong candidate for code that could eventually shrink when native focus-group behavior becomes available.
178
+
179
+ ### Toolbar
180
+
181
+ Toolbar proposals combine a semantic group of controls with conventional keyboard navigation.
182
+
183
+ Actual already has most of the visual building blocks through buttons, actions, clusters, and keyboard helpers.
184
+
185
+ **Influence on Actual:**
186
+
187
+ A toolbar may be a useful small pattern, but its keyboard contract should preferably be built on a shared focus primitive rather than implemented independently.
188
+
189
+ Do not add `.toolbar` merely as another horizontal flex utility.
190
+
191
+ ### Menu elements
192
+
193
+ The platform is exploring native menu structures with menu items, submenus, popover behavior, anchor positioning, commands, focus management, and keyboard navigation.
194
+
195
+ This strongly validates keeping these responsibilities separate in Actual.
196
+
197
+ **Influence on Actual:**
198
+
199
+ * `surface` should not own menu semantics;
200
+ * `floating` should not own menu lifecycle;
201
+ * `menu` should not unnecessarily own positioning;
202
+ * keyboard behavior should remain reusable;
203
+ * command invocation should remain independent.
204
+
205
+ Actual should not attempt to reproduce a future native menu element API.
206
+
207
+ Instead, its current primitives should make eventual native menus easy to adopt.
208
+
209
+ ### Interest invokers and hint popovers
210
+
211
+ The platform is moving toward declarative ways to express that focus, hover, or other user interest should reveal contextual content.
212
+
213
+ This overlaps substantially with tooltip and hover-card behavior.
214
+
215
+ **Influence on Actual:**
216
+
217
+ * keep tooltip appearance separate from invocation mechanics;
218
+ * avoid making hover timers or pointer handling part of the visual component contract;
219
+ * prefer native popover lifecycle where possible;
220
+ * structure tooltip enhancement so future native interest invocation can remove JavaScript.
221
+
222
+ Tooltip is a good example of a component whose implementation should become smaller over time.
223
+
224
+ ### Openable content
225
+
226
+ A generic openable primitive is being explored for content that can be shown and hidden without imposing a new semantic element.
227
+
228
+ This overlaps with the territory traditionally occupied by generic framework `collapse` widgets.
229
+
230
+ **Influence on Actual:**
231
+
232
+ Do not add a generic Collapse component simply to match other frameworks.
233
+
234
+ Use semantic platform elements where they already exist:
235
+
236
+ * `<details>` for disclosure;
237
+ * `<dialog>` for modal or dialog-like surfaces;
238
+ * popovers for transient surfaces.
239
+
240
+ Application-specific show/hide behavior can remain application code.
241
+
242
+ If the platform eventually gains a generic openable mechanism, this gap may disappear naturally.
243
+
244
+ ### Customizable and filterable select
245
+
246
+ Native `<select>` is becoming substantially more customizable, and further work is exploring filtering and richer option behavior.
247
+
248
+ **Influence on Actual:**
249
+
250
+ Actual should continue to improve native select progressively rather than introducing a replacement select widget into core.
251
+
252
+ Avoid owning:
253
+
254
+ * option synchronization;
255
+ * keyboard selection models;
256
+ * popup lifecycle;
257
+ * active-option state;
258
+ * form integration;
259
+
260
+ when the platform is actively moving toward providing those capabilities.
261
+
262
+ A third-party autocomplete or advanced combobox can still compose Actual primitives when needed.
263
+
264
+ Repeated low-level needs discovered there may justify reusable primitives, but not necessarily a core widget.
265
+
266
+ ### Link area delegation
267
+
268
+ The platform is exploring safer ways to make larger content areas delegate activation to a link while preserving nested interactions and text selection.
269
+
270
+ This overlaps with patterns such as Bootstrap's stretched links and pseudo-element link overlays.
271
+
272
+ **Influence on Actual:**
273
+
274
+ Do not introduce a generic `.stretched-link` workaround.
275
+
276
+ Prefer an explicit primary link today.
277
+
278
+ Wait for a native solution to the more general clickable-card problem.
279
+
280
+ ### Enhanced range controls
281
+
282
+ Work on richer native range controls may eventually expose more consistent styling parts and more advanced range interactions.
283
+
284
+ **Influence on Actual:**
285
+
286
+ Avoid building a large custom range abstraction around browser-specific pseudo-elements unless a concrete project requirement justifies it.
287
+
288
+ Prefer native controls and progressive styling.
289
+
290
+ ### Navigation
291
+
292
+ Native navigation proposals may eventually provide richer semantics and interaction behavior for complex navigation structures.
293
+
294
+ **Influence on Actual:**
295
+
296
+ Keep `.navbar` a small layout/presentation pattern.
297
+
298
+ Compose complex behaviors from existing primitives such as flyouts, drawers, commands, and menus rather than turning Navbar into a large JavaScript widget.
299
+
300
+ ### Invoker commands
301
+
302
+ Declarative command invocation is an important platform direction because it separates the element requesting an action from the element implementing it.
303
+
304
+ This maps well to Actual's preference for semantic HTML and small behavior primitives.
305
+
306
+ **Influence on Actual:**
307
+
308
+ Prefer native commands where available and appropriate.
309
+
310
+ When fallback behavior is needed, keep it generic rather than implementing separate invocation systems inside Modal, Drawer, Popover, and other widgets.
311
+
312
+ ## Decision framework
313
+
314
+ Before adding a new Actual component or JavaScript behavior, ask these questions in order.
315
+
316
+ ### 1. Does semantic HTML already solve it?
317
+
318
+ Prefer native elements such as:
319
+
320
+ ```text
321
+ button
322
+ details
323
+ dialog
324
+ select
325
+ input
326
+ progress
327
+ meter
328
+ ```
329
+
330
+ when their semantics match the requirement.
331
+
332
+ ### 2. Is the missing part mainly styling?
333
+
334
+ If so, add CSS rather than JavaScript.
335
+
336
+ ### 3. Can a modern platform capability solve it progressively?
337
+
338
+ Use the capability when unsupported browsers retain an acceptable functional result.
339
+
340
+ Do not raise the Minimal floor unnecessarily.
341
+
342
+ ### 4. Is the platform actively moving toward this capability?
343
+
344
+ Check HTML, CSS, ARIA, and Open UI direction before inventing a framework abstraction.
345
+
346
+ A proposal is not a reason to wait indefinitely, but it is a reason to avoid designing an API directly against a temporary platform limitation.
347
+
348
+ ### 5. Is there a smaller reusable behavior underneath the requested widget?
349
+
350
+ Prefer:
351
+
352
+ ```text
353
+ focus navigation
354
+ floating positioning
355
+ surface lifecycle
356
+ command invocation
357
+ selection state
358
+ ```
359
+
360
+ over a monolithic component when several widgets share the same responsibility.
361
+
362
+ ### 6. Is the behavior actually framework-level?
363
+
364
+ If it is highly application-specific, leave it to project code.
365
+
366
+ Actual does not need to provide every interaction pattern found in application UI.
367
+
368
+ ## Adoption levels
369
+
370
+ Platform developments can influence Actual at different stages.
371
+
372
+ ### Adopt
373
+
374
+ Use the native feature directly when it is part of the supported contract or has a safe fallback.
375
+
376
+ Examples include mature semantic HTML and suitable progressive enhancements.
377
+
378
+ ### Align
379
+
380
+ The native feature is not ready to depend on, but its architecture is sufficiently useful to influence Actual's internal boundaries.
381
+
382
+ Focus-group behavior is a good example.
383
+
384
+ ### Watch
385
+
386
+ The proposal solves a relevant problem but is too early, uncertain, or specialized to affect code today.
387
+
388
+ Document the direction and avoid unnecessary competing abstractions.
389
+
390
+ ### Ignore
391
+
392
+ Not every platform proposal belongs in Actual.
393
+
394
+ A capability may be useful for applications without being appropriate for a small CSS framework.
395
+
396
+ ## What Open UI should not become for Actual
397
+
398
+ Open UI is not a backlog of components to implement.
399
+
400
+ Actual should not:
401
+
402
+ * mirror every Open UI component;
403
+ * polyfill every proposal;
404
+ * expose experimental syntax under `data-*` names;
405
+ * add components solely because another framework has them;
406
+ * maintain custom widgets that duplicate improving native controls;
407
+ * raise browser requirements just to adopt newer syntax;
408
+ * freeze an experimental proposal into the public Actual API.
409
+
410
+ The objective is compatibility of **architecture**, not API imitation.
411
+
412
+ ## Near-term implications
413
+
414
+ The current direction suggests a few concrete actions.
415
+
416
+ ### Focus navigation
417
+
418
+ Audit `keys` around the responsibilities described by focus groups.
419
+
420
+ If several widgets need the same roving-focus behavior, extract one reusable primitive rather than adding separate implementations.
421
+
422
+ ### Toolbar
423
+
424
+ Consider a small Toolbar pattern only after the shared focus behavior is clear.
425
+
426
+ Its value should come from semantics and interaction, not from duplicating `.cluster`.
427
+
428
+ ### Switch
429
+
430
+ Keep the checkbox-based implementation.
431
+
432
+ Track native switch semantics and adopt forward-compatible markup when it becomes appropriate for the browser contract.
433
+
434
+ ### Menu
435
+
436
+ Keep menu styling, surface lifecycle, floating positioning, commands, and keyboard behavior decomposed.
437
+
438
+ Do not add a second menu architecture that mimics experimental elements.
439
+
440
+ ### Tooltip
441
+
442
+ Continue treating Tooltip as progressive enhancement over native-shaped markup.
443
+
444
+ Interest invocation and hint popovers should eventually be able to replace parts of its JavaScript.
445
+
446
+ ### Select and combobox
447
+
448
+ Keep native `<select>` as the core path.
449
+
450
+ Do not add a custom select or autocomplete widget merely to fill today's browser gaps.
451
+
452
+ ### Collapse
453
+
454
+ Do not add a generic Collapse widget while native disclosure, popover, dialog, and possible future openable primitives cover or may cover the relevant use cases.
455
+
456
+ ### Clickable cards
457
+
458
+ Do not add a stretched-link utility as a framework workaround.
459
+
460
+ Use explicit links until the platform provides a robust delegation mechanism.
461
+
462
+ ## Review trigger
463
+
464
+ This note should be revisited when:
465
+
466
+ * Actual considers adding a complex interactive component;
467
+ * a relevant Open UI proposal graduates or materially changes direction;
468
+ * an HTML or CSS primitive becomes broadly available;
469
+ * browser support tiers are revised;
470
+ * several existing widgets duplicate the same interaction logic.
471
+
472
+ The useful question is not:
473
+
474
+ > "Can browsers do this natively yet?"
475
+
476
+ It is:
477
+
478
+ > "If browsers can do this natively in two years, will today's Actual design make that transition easy?"
479
+
480
+ ## Goal
481
+
482
+ Actual should progressively become **less responsible for browser behavior**, not more.
483
+
484
+ CSS should provide the visual system.
485
+
486
+ Small primitives should bridge genuine platform gaps.
487
+
488
+ JavaScript enhancements should remain replaceable.
489
+
490
+ HTML should carry as much semantics and behavior as the platform can reasonably provide.
491
+
492
+ The ideal long-term outcome is that improvements to HTML and CSS allow Actual to delete implementation code while applications keep essentially the same markup and styling vocabulary.
@@ -13,6 +13,14 @@ It claims a small public grammar: `.component [intent] [variant] [size] [modifie
13
13
  - No compatibility build that rewrites the product.
14
14
  - No complex widgets.
15
15
 
16
+ ## Previous work
17
+
18
+ Prior Actual CSS libraries:
19
+
20
+ - https://github.com/lekoala/liveinit
21
+ - https://github.com/lekoala/modern-now
22
+ - unpublished css library
23
+
16
24
  ## Research links
17
25
 
18
26
  ### Forms
@@ -9,15 +9,51 @@ The JS runtime doubles as a primitive kit for building custom widgets.
9
9
  | Opt-in discovery + lifecycle + cleanup | `enhance`, `registerEnhancement` | `actual-css/js/enhance` |
10
10
  | Positioning, flip/shift, `--available-height`, `data-placement` | `floating` (`track`, `reposition`, `repositionAt`) | `actual-css/js/floating` |
11
11
  | Open/close, sheet on mobile, backdrop, outside-click, Escape, focus restore | `surface` | `actual-css/js/surface` |
12
- | Roving focus over a list | `keys` (`firstItem`, `lastItem`, `nextItem`) | `actual-css/js/keys` |
12
+ | Directional item lookup, edges, wrapping, RTL | `keys` (`itemForKey`, `firstItem`, `lastItem`, `nextItem`) | `actual-css/js/keys` |
13
13
  | Menu-item vocabulary, usable-item filtering | `menu` | `actual-css/js/menu` |
14
14
  | Focusable lookup, visibility | `focus` | `actual-css/js/focus` |
15
+ | One remembered tab stop with directional navigation | `focus-group` (`connectFocusGroup`) | `actual-css/js/focus-group` |
15
16
  | Caret-safe value rewriting | `input` (`onTextInput`, `setCaret`, `dispatchInput`) | `actual-css/js/input` |
16
17
  | Character policies | `filter` | `actual-css/js/filter` |
17
18
  | Event namespace | `events` (`EVENTS`, `ACTUAL_EVENT_PREFIX`) | `actual-css/js/events` |
18
19
  | Declarative triggers | `command` (`registerCommands`) | `actual-css/js/command` |
19
20
  | State classes the runtime writes | `selectors` (`CLASSES`) | `actual-css/js/selectors` |
20
21
 
22
+ ## Focus group
23
+
24
+ `connectFocusGroup(root, options)` gives a composite one remembered tab stop and
25
+ Arrow/Home/End navigation. The consumer supplies `getItems()` because candidate
26
+ discovery and disabled semantics belong to the widget, not to the controller.
27
+ The controller updates only `tabindex` and focus; it does not activate controls
28
+ or write ARIA and application state.
29
+
30
+ ```js
31
+ import { connectFocusGroup } from "actual-css/js/focus-group";
32
+
33
+ const focusGroup = connectFocusGroup(toolbar, {
34
+ getItems: () => toolbar.querySelectorAll(":scope > button:not(:disabled)"),
35
+ orientation: "horizontal",
36
+ wrap: false,
37
+ signal,
38
+ });
39
+
40
+ // Call this after changing which controls belong to the group.
41
+ focusGroup.sync();
42
+ ```
43
+
44
+ Candidates are re-read when focus or keyboard input occurs. A consumer that
45
+ changes the candidate list calls `focusGroup.sync()` explicitly; the primitive
46
+ does not observe the subtree. A plain `sync()` preserves the remembered item
47
+ when possible; `sync(item)` explicitly makes an item the group's tab stop.
48
+ Horizontal navigation follows the root's effective text direction.
49
+ `focusGroup.disconnect()` removes its listeners and restores authored
50
+ `tabindex` values. This is a JavaScript responsibility primitive, not a
51
+ `focusgroup` attribute or enhancement token.
52
+
53
+ `menu` consumes this primitive only for `[role="menu"]`. Plain `.menu` action
54
+ lists retain normal tab stops and use the menu layer's lighter directional
55
+ focus behavior.
56
+
21
57
  ## Compositions
22
58
 
23
59
  ### Custom select — A. Owns its popup
@@ -0,0 +1,135 @@
1
+ {
2
+ "groups": [
3
+ {
4
+ "title": "Guides",
5
+ "slug": "guides",
6
+ "pages": [
7
+ "introduction",
8
+ "optional-components",
9
+ "progressive-enhancement",
10
+ "bootstrap",
11
+ "tailwind"
12
+ ]
13
+ },
14
+ {
15
+ "title": "Foundations",
16
+ "slug": "foundations",
17
+ "pages": ["philosophy", "typography", "tokens", "theming"]
18
+ },
19
+ {
20
+ "title": "Layout",
21
+ "slug": "layout",
22
+ "pages": [
23
+ "overview",
24
+ "stack",
25
+ "cluster",
26
+ "grid",
27
+ "center",
28
+ "sidebar-layout",
29
+ "media",
30
+ "switcher",
31
+ "topbar",
32
+ "scroll-snap",
33
+ "frame",
34
+ "app-shell",
35
+ "list"
36
+ ]
37
+ },
38
+ {
39
+ "title": "Components",
40
+ "slug": "components",
41
+ "pages": [
42
+ "accordion",
43
+ "alert",
44
+ "aura",
45
+ "avatar",
46
+ "badge",
47
+ "breadcrumb",
48
+ "button",
49
+ "card",
50
+ "chat",
51
+ "dialog",
52
+ "drawer",
53
+ "fab",
54
+ "key",
55
+ "meter",
56
+ "navbar",
57
+ "pagination",
58
+ "progress",
59
+ "skeleton",
60
+ "spinner",
61
+ "table"
62
+ ]
63
+ },
64
+ {
65
+ "title": "Forms",
66
+ "slug": "forms",
67
+ "pages": [
68
+ "overview",
69
+ "controls",
70
+ "labels",
71
+ "floating-field",
72
+ "states-and-sizes",
73
+ "form-actions",
74
+ "joined-controls",
75
+ "choice-cards",
76
+ "switch",
77
+ "range",
78
+ "otp",
79
+ "password",
80
+ "input-policy",
81
+ "validation",
82
+ "detached-actions",
83
+ "sticky-actions"
84
+ ]
85
+ },
86
+ {
87
+ "title": "Patterns",
88
+ "slug": "patterns",
89
+ "pages": [
90
+ "overview",
91
+ "actions",
92
+ "navigation-list",
93
+ "icon-input",
94
+ "structured-lists",
95
+ "hierarchical-nav",
96
+ "code-block",
97
+ "exclusive-accordion",
98
+ "intent-nesting"
99
+ ]
100
+ },
101
+ {
102
+ "title": "Utilities",
103
+ "slug": "utilities",
104
+ "pages": [
105
+ "overview",
106
+ "accessibility",
107
+ "overflow",
108
+ "sizing-wrapping",
109
+ "flex",
110
+ "spacing",
111
+ "text",
112
+ "shape",
113
+ "list",
114
+ "links"
115
+ ]
116
+ },
117
+ {
118
+ "title": "Enhancements",
119
+ "slug": "enhancements",
120
+ "pages": [
121
+ "overview",
122
+ "flyout",
123
+ "tooltip",
124
+ "tabs",
125
+ "scrollspy",
126
+ "status-bar"
127
+ ]
128
+ },
129
+ {
130
+ "title": "Examples",
131
+ "slug": "examples",
132
+ "pages": ["overview"]
133
+ }
134
+ ]
135
+ }