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.
- package/CHANGELOG.md +38 -1
- package/README.md +24 -9
- package/dist/actual-themes.min.css +1 -0
- package/dist/actual.css +1244 -915
- package/dist/actual.js +1 -3
- package/dist/actual.min.css +1 -1
- package/dist/optional.css +1048 -0
- package/dist/optional.min.css +1 -0
- package/docs/design-notes/browser-support.md +94 -14
- package/docs/design-notes/cascade-layer.md +1 -1
- package/docs/design-notes/enhancement-contract.md +11 -14
- package/docs/design-notes/forced-colors.md +105 -0
- package/docs/design-notes/naming.md +2 -1
- package/docs/design-notes/platform-alignment.md +492 -0
- package/docs/design-notes/references.md +8 -0
- package/docs/design-notes/widget-primitives.md +37 -1
- package/docs/navigation.json +135 -0
- package/docs/pages/components/accordion.md +80 -0
- package/docs/pages/components/alert.md +203 -0
- package/docs/pages/components/aura.md +35 -0
- package/docs/pages/components/avatar.md +95 -0
- package/docs/pages/components/badge.md +102 -0
- package/docs/pages/components/breadcrumb.md +19 -0
- package/docs/pages/components/button.md +205 -0
- package/docs/pages/components/card.md +183 -0
- package/docs/pages/components/chat.md +50 -0
- package/docs/pages/components/dialog.md +367 -0
- package/docs/pages/components/drawer.md +113 -0
- package/docs/pages/components/fab.md +118 -0
- package/docs/pages/components/key.md +33 -0
- package/docs/pages/components/meter.md +23 -0
- package/docs/pages/components/navbar.md +92 -0
- package/docs/pages/components/pagination.md +55 -0
- package/docs/pages/components/progress.md +29 -0
- package/docs/pages/components/skeleton.md +38 -0
- package/docs/pages/components/spinner.md +93 -0
- package/docs/pages/components/table.md +102 -0
- package/docs/pages/enhancements/flyout.md +391 -0
- package/docs/pages/enhancements/overview.md +36 -0
- package/docs/pages/enhancements/scrollspy.md +71 -0
- package/docs/pages/enhancements/status-bar.md +72 -0
- package/docs/pages/enhancements/tabs.md +80 -0
- package/docs/pages/enhancements/tooltip.md +130 -0
- package/docs/pages/examples/overview.md +41 -0
- package/docs/pages/forms/choice-cards.md +102 -0
- package/docs/pages/forms/controls.md +32 -0
- package/docs/pages/forms/detached-actions.md +59 -0
- package/docs/pages/forms/floating-field.md +88 -0
- package/docs/pages/forms/form-actions.md +56 -0
- package/docs/pages/forms/input-policy.md +91 -0
- package/docs/pages/forms/joined-controls.md +37 -0
- package/docs/pages/forms/labels.md +42 -0
- package/docs/pages/forms/otp.md +50 -0
- package/docs/pages/forms/overview.md +188 -0
- package/docs/pages/forms/password.md +40 -0
- package/docs/pages/forms/range.md +17 -0
- package/docs/pages/forms/states-and-sizes.md +321 -0
- package/docs/pages/forms/sticky-actions.md +187 -0
- package/docs/pages/forms/switch.md +31 -0
- package/docs/pages/forms/validation.md +241 -0
- package/docs/{mental-model.md → pages/foundations/philosophy.md} +33 -18
- package/docs/pages/foundations/theming.md +92 -0
- package/docs/pages/foundations/tokens.md +421 -0
- package/docs/{typography.md → pages/foundations/typography.md} +27 -9
- package/docs/pages/guides/bootstrap.md +438 -0
- package/docs/pages/guides/introduction.md +157 -0
- package/docs/pages/guides/optional-components.md +33 -0
- package/docs/pages/guides/progressive-enhancement.md +686 -0
- package/docs/pages/guides/tailwind.md +455 -0
- package/docs/pages/layout/app-shell.md +25 -0
- package/docs/pages/layout/center.md +29 -0
- package/docs/pages/layout/cluster.md +57 -0
- package/docs/pages/layout/frame.md +30 -0
- package/docs/pages/layout/grid.md +142 -0
- package/docs/pages/layout/list.md +41 -0
- package/docs/pages/layout/media.md +21 -0
- package/docs/pages/layout/overview.md +37 -0
- package/docs/pages/layout/scroll-snap.md +54 -0
- package/docs/pages/layout/sidebar-layout.md +27 -0
- package/docs/pages/layout/stack.md +18 -0
- package/docs/pages/layout/switcher.md +36 -0
- package/docs/pages/layout/topbar.md +23 -0
- package/docs/pages/patterns/actions.md +52 -0
- package/docs/pages/patterns/code-block.md +36 -0
- package/docs/pages/patterns/exclusive-accordion.md +16 -0
- package/docs/pages/patterns/hierarchical-nav.md +26 -0
- package/docs/pages/patterns/icon-input.md +25 -0
- package/docs/pages/patterns/intent-nesting.md +3 -0
- package/docs/pages/patterns/navigation-list.md +235 -0
- package/docs/pages/patterns/overview.md +58 -0
- package/docs/pages/patterns/structured-lists.md +47 -0
- package/docs/pages/utilities/accessibility.md +34 -0
- package/docs/pages/utilities/flex.md +105 -0
- package/docs/pages/utilities/links.md +18 -0
- package/docs/pages/utilities/list.md +31 -0
- package/docs/pages/utilities/overflow.md +43 -0
- package/docs/pages/utilities/overview.md +18 -0
- package/docs/pages/utilities/shape.md +25 -0
- package/docs/pages/utilities/sizing-wrapping.md +115 -0
- package/docs/pages/utilities/spacing.md +79 -0
- package/docs/pages/utilities/text.md +43 -0
- package/llms.txt +4 -4
- package/package.json +20 -12
- package/src/css/actual.css +12 -1
- package/src/css/base.css +3 -5
- package/src/css/components/accordion.css +18 -30
- package/src/css/components/actions.css +4 -1
- package/src/css/components/alert.css +126 -99
- package/src/css/components/avatar.css +16 -10
- package/src/css/components/badge.css +55 -35
- package/src/css/components/breadcrumb.css +7 -15
- package/src/css/components/busy.css +6 -0
- package/src/css/components/button.css +78 -32
- package/src/css/components/card.css +17 -37
- package/src/css/components/drawer.css +30 -13
- package/src/css/components/flyout.css +39 -109
- package/src/css/components/index.css +1 -0
- package/src/css/components/join.css +14 -2
- package/src/css/components/key.css +2 -0
- package/src/css/components/menu.css +125 -0
- package/src/css/components/meter.css +0 -23
- package/src/css/components/modal.css +162 -7
- package/src/css/components/navbar.css +17 -18
- package/src/css/components/overline.css +0 -7
- package/src/css/components/pagination.css +1 -1
- package/src/css/components/progress.css +8 -26
- package/src/css/components/skeleton.css +7 -0
- package/src/css/components/spinner.css +6 -7
- package/src/css/components/status-bar.css +15 -24
- package/src/css/components/surface.css +2 -8
- package/src/css/components/tab.css +19 -48
- package/src/css/components/table.css +7 -5
- package/src/css/components/tooltip.css +14 -7
- package/src/css/focus.css +14 -38
- package/src/css/forms/choice-card.css +13 -14
- package/src/css/forms/choice.css +21 -27
- package/src/css/forms/control.css +16 -17
- package/src/css/forms/custom-select.css +9 -11
- package/src/css/forms/form-actions.css +14 -3
- package/src/css/forms/form.css +7 -4
- package/src/css/forms/index.css +4 -4
- package/src/css/forms/input-icon.css +30 -12
- package/src/css/forms/native.css +50 -11
- package/src/css/forms/range.css +17 -9
- package/src/css/forms/select.css +8 -8
- package/src/css/forms/switch.css +14 -12
- package/src/css/forms/validation.css +32 -5
- package/src/css/grid.css +19 -18
- package/src/css/intents.css +2 -2
- package/src/css/layout.css +29 -1
- package/src/css/optional/aura.css +93 -0
- package/src/css/optional/chat.css +105 -0
- package/src/css/optional/fab.css +104 -0
- package/src/css/optional/floating-field.css +87 -0
- package/src/css/optional/index.css +5 -0
- package/src/css/optional/layout-extra.css +7 -4
- package/src/css/optional/otp.css +115 -0
- package/src/css/optional/scroll-snap.css +6 -0
- package/src/css/optional/scroller.css +13 -7
- package/src/css/optional/typography-fluid.css +5 -0
- package/src/css/optional/utilities-extra.css +17 -2
- package/src/css/prose.css +18 -8
- package/src/css/reset.css +0 -10
- package/src/css/theme.css +21 -5
- package/src/css/themes/cyberpunk.css +1 -1
- package/src/css/themes/dim.css +3 -3
- package/src/css/themes/edge.css +8 -10
- package/src/css/themes/index.css +3 -3
- package/src/css/themes/{dark.css → indigo.css} +5 -4
- package/src/css/themes/neon.css +5 -5
- package/src/css/themes/square.css +0 -3
- package/src/css/tokens.css +74 -20
- package/src/css/utilities.css +8 -10
- package/src/css/variants.css +37 -65
- package/src/js/command.js +1 -3
- package/src/js/context-menu.js +67 -35
- package/src/js/dialog.js +68 -79
- package/src/js/dismiss.js +15 -0
- package/src/js/enhance.js +54 -23
- package/src/js/enhancement-loader.js +301 -0
- package/src/js/events.js +3 -0
- package/src/js/filter.js +3 -3
- package/src/js/floating.js +101 -131
- package/src/js/flyout.js +104 -87
- package/src/js/focus-group.js +116 -0
- package/src/js/focus.js +6 -1
- package/src/js/index.js +4 -2
- package/src/js/input.js +1 -1
- package/src/js/keys.js +27 -0
- package/src/js/mask.js +7 -6
- package/src/js/menu.js +87 -34
- package/src/js/parse-config.js +47 -0
- package/src/js/password.js +9 -1
- package/src/js/scrollspy.js +12 -4
- package/src/js/selectors.js +0 -7
- package/src/js/status.js +3 -1
- package/src/js/surface.js +185 -136
- package/src/js/tab.js +36 -53
- package/src/js/tooltip.js +53 -31
- package/src/js/validation.js +34 -8
- package/dist/actual.js.map +0 -31
- package/docs/README.md +0 -28
- package/docs/components.md +0 -860
- package/docs/design-notes/previous-work.md +0 -5
- package/docs/forms.md +0 -1265
- package/docs/javascript.md +0 -496
- package/docs/layout.md +0 -480
- package/docs/patterns.md +0 -504
- package/docs/reserved.md +0 -7
- package/docs/tokens.md +0 -455
- package/docs/ui.md +0 -929
- package/docs/utilities.md +0 -384
- package/src/css/dialog-fallback.css +0 -56
- 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
|
-
|
|
|
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
|
+
}
|