actual-css 0.11.1 → 0.13.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 +96 -0
- package/README.md +25 -6
- package/components.json +12 -18
- package/dist/actual.full.css +780 -479
- package/dist/actual.full.js +1 -1
- package/dist/actual.full.min.css +1 -1
- package/docs/brand/favicon.svg +5 -0
- package/docs/brand/lockup.svg +12 -0
- package/docs/brand/logo-dark.svg +9 -0
- package/docs/brand/logo-light.svg +9 -0
- package/docs/brand/logo.svg +11 -0
- package/docs/brand/mark.svg +11 -0
- package/docs/design-notes/architecture.md +67 -0
- package/docs/design-notes/steps.md +45 -28
- package/docs/navigation.json +3 -2
- package/docs/pages/components/alert.md +2 -10
- package/docs/pages/components/avatar.md +17 -11
- package/docs/pages/components/badge.md +3 -9
- package/docs/pages/components/breadcrumb.md +16 -2
- package/docs/pages/components/card.md +31 -2
- package/docs/pages/components/dialog.md +121 -33
- package/docs/pages/components/drawer.md +2 -2
- package/docs/pages/components/list.md +9 -13
- package/docs/pages/components/navbar.md +49 -30
- package/docs/pages/components/pagination.md +19 -0
- package/docs/pages/components/steps.md +24 -20
- package/docs/pages/components/table.md +3 -3
- package/docs/pages/enhancements/flyout.md +2 -2
- package/docs/pages/enhancements/scrollspy.md +7 -7
- package/docs/pages/enhancements/status-bar.md +2 -2
- package/docs/pages/enhancements/tabs.md +74 -3
- package/docs/pages/examples/overview.md +2 -1
- package/docs/pages/forms/date-picker.md +90 -0
- package/docs/pages/forms/detached-actions.md +37 -30
- package/docs/pages/forms/floating-field.md +21 -7
- package/docs/pages/forms/form-actions.md +58 -28
- package/docs/pages/forms/input-policy.md +1 -1
- package/docs/pages/forms/overview.md +6 -5
- package/docs/pages/forms/states-and-sizes.md +15 -15
- package/docs/pages/forms/sticky-actions.md +85 -83
- package/docs/pages/forms/validation.md +5 -5
- package/docs/pages/foundations/philosophy.md +102 -4
- package/docs/pages/foundations/theming.md +15 -4
- package/docs/pages/foundations/tokens.md +89 -36
- package/docs/pages/foundations/typography.md +4 -7
- package/docs/pages/guides/bootstrap.md +2 -2
- package/docs/pages/guides/design-tools.md +2 -2
- package/docs/pages/guides/integrating-actual-css.md +79 -9
- package/docs/pages/guides/introduction.md +5 -5
- package/docs/pages/guides/modular-import.md +3 -0
- package/docs/pages/guides/progressive-enhancement.md +27 -9
- package/docs/pages/guides/tailwind.md +70 -0
- package/docs/pages/guides/upgrading.md +151 -0
- package/docs/pages/layout/center.md +2 -1
- package/docs/pages/layout/cluster.md +37 -4
- package/docs/pages/layout/grid.md +2 -0
- package/docs/pages/layout/overview.md +1 -1
- package/docs/pages/layout/sidebar-layout.md +3 -0
- package/docs/pages/layout/stack.md +21 -16
- package/docs/pages/layout/switcher.md +2 -0
- package/docs/pages/layout/topbar.md +7 -5
- package/docs/pages/patterns/icon-slot.md +17 -1
- package/docs/pages/patterns/navigation-list.md +16 -46
- package/docs/pages/patterns/overview.md +3 -4
- package/docs/pages/utilities/flex.md +30 -20
- package/docs/pages/utilities/sizing-wrapping.md +52 -7
- package/docs/pages/utilities/spacing.md +4 -3
- package/package.json +6 -6
- package/reserved-classes.json +3 -3
- package/skills/actual-css/references/enhancements.md +10 -7
- package/src/cli/actual-css.js +39 -13
- package/src/css/components/alert.css +34 -34
- package/src/css/components/avatar.css +8 -17
- package/src/css/components/badge.css +1 -6
- package/src/css/components/breadcrumb.css +74 -8
- package/src/css/components/button.css +3 -9
- package/src/css/components/card.css +18 -10
- package/src/css/components/chat.css +4 -5
- package/src/css/components/drawer.css +42 -45
- package/src/css/components/flyout.css +3 -1
- package/src/css/components/index.css +0 -1
- package/src/css/components/join.css +2 -2
- package/src/css/components/list.css +10 -10
- package/src/css/components/modal.css +113 -134
- package/src/css/components/navbar.css +22 -31
- package/src/css/components/pagination.css +5 -0
- package/src/css/components/scrollspy.css +1 -1
- package/src/css/components/steps.css +66 -12
- package/src/css/components/tab.css +134 -4
- package/src/css/core/base.css +1 -1
- package/src/css/core/focus.css +8 -6
- package/src/css/core/reset.css +2 -1
- package/src/css/core/theme.css +10 -1
- package/src/css/core/tokens.css +32 -12
- package/src/css/core/variants.css +41 -14
- package/src/css/forms/choice-card.css +1 -1
- package/src/css/forms/choice.css +1 -1
- package/src/css/forms/control.css +1 -1
- package/src/css/forms/floating-field.css +20 -18
- package/src/css/forms/form-actions.css +14 -12
- package/src/css/forms/native.css +2 -2
- package/src/css/forms/otp.css +4 -5
- package/src/css/forms/switch.css +1 -1
- package/src/css/forms/validation.css +23 -30
- package/src/css/layout/center.css +2 -0
- package/src/css/layout/cluster.css +25 -0
- package/src/css/layout/grid.css +7 -0
- package/src/css/layout/scroller.css +19 -3
- package/src/css/layout/sidebar-layout.css +3 -0
- package/src/css/layout/switcher.css +3 -0
- package/src/css/layout/topbar.css +12 -6
- package/src/css/utilities/base.css +5 -0
- package/src/css/utilities/extra.css +3 -7
- package/src/js/full.js +4 -0
- package/src/js/inline-visible.js +54 -0
- package/src/js/parsed.js +21 -0
- package/src/js/tab.js +33 -7
- package/src/tooling/color.js +65 -0
- package/src/tooling/design-export.js +1 -1
- package/src/tooling/design-tokens.js +53 -34
- package/src/tooling/theme-contrast.js +217 -0
- package/docs/pages/patterns/actions.md +0 -52
- package/src/css/components/actions.css +0 -27
|
@@ -39,19 +39,24 @@ content, keep them in normal block flow instead:
|
|
|
39
39
|
Use `.stack` for the vertical rhythm *between* related items inside one region,
|
|
40
40
|
not as the wrapper that lays out independent full-width regions of a page.
|
|
41
41
|
|
|
42
|
-
## Choosing a
|
|
42
|
+
## Choosing a rhythm
|
|
43
43
|
|
|
44
|
-
`--gap` is the primitive's channel
|
|
45
|
-
the
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
`--gap` is the primitive's channel. `.tight` and `.loose` set it and nothing
|
|
45
|
+
else; apply one on the stack to space one instance, or on an ancestor to reach
|
|
46
|
+
nested layouts. Pick the one that matches how tightly the children belong
|
|
47
|
+
together:
|
|
48
48
|
|
|
49
49
|
| Markup | Gap | Use for |
|
|
50
50
|
| ----------------- | ---- | ------------------------------------------ |
|
|
51
51
|
| `.stack gap-none` | 0 | Lines forming one typographic unit |
|
|
52
|
-
| `.stack
|
|
52
|
+
| `.stack tight` | 8px | A homogeneous series of controls |
|
|
53
53
|
| `.stack` | 12px | Normal flow between distinct elements |
|
|
54
|
-
| `.stack
|
|
54
|
+
| `.stack loose` | 24px | Sections, or blocks that read as separated |
|
|
55
|
+
|
|
56
|
+
**Size** changes a component's scale. **Density** (`.compact`, `.spacious`)
|
|
57
|
+
changes UI geometry and rhythm together: gap, padding, control size. **Rhythm**
|
|
58
|
+
(`.tight`, `.loose`) changes the gap only — closer or farther items, tighter
|
|
59
|
+
spacing without smaller buttons. Use one rhythm class per element.
|
|
55
60
|
|
|
56
61
|
One typographic unit means a name and a job title, or a figure and its caption.
|
|
57
62
|
A homogeneous series means a radio list, a checkbox list, or a compact vertical
|
|
@@ -60,13 +65,13 @@ menu.
|
|
|
60
65
|
The distinction between the first two matters. `42` above `Open issues` is
|
|
61
66
|
almost a single block of text, so it takes `gap-none`. Three `.choice` labels
|
|
62
67
|
stay three separate controls that happen to form one group, so they take
|
|
63
|
-
`
|
|
68
|
+
`tight` — tighter than the default, but still spaced.
|
|
64
69
|
|
|
65
|
-
`.
|
|
66
|
-
Because the token is inherited,
|
|
67
|
-
of any nested stack, cluster, and grid. For a one-off gap
|
|
68
|
-
|
|
69
|
-
explains why).
|
|
70
|
+
`.tight` and `.loose` rebind `--gap` to `--space-20` and `--space-50`, the same
|
|
71
|
+
steps `.compact` and `.spacious` use. Because the token is inherited, they also
|
|
72
|
+
tighten the inner gap of any nested stack, cluster, and grid. For a one-off gap
|
|
73
|
+
that must *not* reach nested layouts, set the `gap` property directly on the
|
|
74
|
+
instance (the next section explains why).
|
|
70
75
|
|
|
71
76
|
A stack that mixes kinds keeps the default: five `.field` wrappers and one lone
|
|
72
77
|
`.choice` is a form that contains a checkbox, not a list of options, and
|
|
@@ -92,7 +97,7 @@ depth:
|
|
|
92
97
|
```
|
|
93
98
|
|
|
94
99
|
Both give the region the same spacing; only the second stops there. This is what
|
|
95
|
-
makes a nested `.stack
|
|
100
|
+
makes a nested `.stack tight` a real rhythm choice — 12px down to 8px — rather
|
|
96
101
|
than a patch cancelling a rhythm inherited from three levels up.
|
|
97
102
|
|
|
98
103
|
Setting `--gap` is still the right move on the element that *consumes* it: a
|
|
@@ -100,8 +105,8 @@ one-off `--gap` on a card body or an actions row tunes that primitive and
|
|
|
100
105
|
nothing below it, because the setter is the consumer. The leak only appears when
|
|
101
106
|
a container sets the token and its children read it.
|
|
102
107
|
|
|
103
|
-
|
|
104
|
-
precisely so
|
|
108
|
+
The rhythm and density classes are the deliberate exception: they set `--gap`
|
|
109
|
+
precisely so the context reaches nested layouts.
|
|
105
110
|
|
|
106
111
|
## Grouping items tightly
|
|
107
112
|
|
|
@@ -4,17 +4,19 @@ Sticky, frosted top bar shell for app/dashboard layouts with a persistent sideba
|
|
|
4
4
|
|
|
5
5
|
> **Module** — import `actual-css/css/layout/topbar` or `actual-css/css/layout`.
|
|
6
6
|
|
|
7
|
-
Use `.topbar` for the structural shell of an app-shell header: sticky positioning, stacking, and a frosted background. Row content — search, breadcrumb, actions — stays local to the page.
|
|
7
|
+
Use `.topbar` for the structural shell of an app-shell header: sticky positioning, stacking, and a frosted background. Its children sit in a centered row by default; a layout primitive on the same element, such as `topbar cluster`, replaces that row. Row content — search, breadcrumb, actions — stays local to the page.
|
|
8
8
|
|
|
9
9
|
```html demo
|
|
10
10
|
<header class="topbar">
|
|
11
11
|
<button class="btn neutral ghost" type="button" aria-label="Open navigation">
|
|
12
12
|
<i class="ti ti-menu-2" aria-hidden="true"></i>
|
|
13
13
|
</button>
|
|
14
|
-
<
|
|
15
|
-
<
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
<nav aria-label="Breadcrumb">
|
|
15
|
+
<ol class="breadcrumb">
|
|
16
|
+
<li><a href="#">Overview</a></li>
|
|
17
|
+
<li aria-current="page">Accounts</li>
|
|
18
|
+
</ol>
|
|
19
|
+
</nav>
|
|
18
20
|
<div class="grow"></div>
|
|
19
21
|
<span class="avatar sm"><abbr>LW</abbr></span>
|
|
20
22
|
</header>
|
|
@@ -42,6 +42,22 @@ For a round disc, add the `.circle` utility — it supplies the `border-radius`:
|
|
|
42
42
|
}
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
+
## Webfont glyphs
|
|
46
|
+
|
|
47
|
+
An icon font draws nothing measurable until it loads, so a button or nav link
|
|
48
|
+
shifts when the glyph arrives. Reserve a `1em` square on the icon library's
|
|
49
|
+
class in application CSS; it follows the surrounding font size:
|
|
50
|
+
|
|
51
|
+
```css
|
|
52
|
+
.ti {
|
|
53
|
+
display: inline-grid;
|
|
54
|
+
flex: none;
|
|
55
|
+
place-items: center;
|
|
56
|
+
inline-size: 1em;
|
|
57
|
+
block-size: 1em;
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
45
61
|
## Reuse the existing icon slots
|
|
46
62
|
|
|
47
63
|
Several components already embody this slot — reach for them before composing
|
|
@@ -55,7 +71,7 @@ your own:
|
|
|
55
71
|
```html demo
|
|
56
72
|
<div class="media">
|
|
57
73
|
<span class="avatar primary"><abbr>AM</abbr></span>
|
|
58
|
-
<div class="stack">
|
|
74
|
+
<div class="stack gap-none">
|
|
59
75
|
<strong>Ada Meridian</strong>
|
|
60
76
|
<span class="muted">Senior designer.</span>
|
|
61
77
|
</div>
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
# Navigation List
|
|
2
2
|
|
|
3
|
-
Use `.nav-list` for a
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Use `.nav-list` for a vertical list of navigation links: it removes native list
|
|
4
|
+
chrome, stacks the rows and stretches each `.nav-link` across the row. For a
|
|
5
|
+
horizontal row of links, use `.cluster` on the list, which removes the list
|
|
6
|
+
chrome too.
|
|
6
7
|
|
|
7
8
|
```html demo
|
|
8
9
|
<div class="stack">
|
|
9
10
|
<h2>Navigation</h2>
|
|
10
11
|
<nav aria-label="Main navigation">
|
|
11
|
-
<ul class="
|
|
12
|
+
<ul class="cluster">
|
|
12
13
|
<li><a href="/docs">Docs</a></li>
|
|
13
14
|
<li><a href="/components">Components</a></li>
|
|
14
15
|
<li><a href="/examples">Examples</a></li>
|
|
@@ -16,7 +17,7 @@ It removes native list chrome but does not force a direction. Combine it with la
|
|
|
16
17
|
</nav>
|
|
17
18
|
<h2>Documentation</h2>
|
|
18
19
|
<nav aria-label="Documentation">
|
|
19
|
-
<ul class="nav-list
|
|
20
|
+
<ul class="nav-list">
|
|
20
21
|
<li><a href="/docs/getting-started" aria-current="page">Getting started</a></li>
|
|
21
22
|
<li><a href="/docs/tokens">Tokens</a></li>
|
|
22
23
|
<li><a href="/docs/layout">Layout</a></li>
|
|
@@ -26,14 +27,6 @@ It removes native list chrome but does not force a direction. Combine it with la
|
|
|
26
27
|
</div>
|
|
27
28
|
```
|
|
28
29
|
|
|
29
|
-
Use `.nav-list` for:
|
|
30
|
-
|
|
31
|
-
- header navigation
|
|
32
|
-
- side navigation
|
|
33
|
-
- footer navigation
|
|
34
|
-
- tab-like navigation lists
|
|
35
|
-
- documentation navigation
|
|
36
|
-
|
|
37
30
|
Do not reset every list inside `nav`.
|
|
38
31
|
|
|
39
32
|
```css
|
|
@@ -51,7 +44,7 @@ Prefer an explicit pattern class.
|
|
|
51
44
|
|
|
52
45
|
```html demo
|
|
53
46
|
<nav aria-label="Footer">
|
|
54
|
-
<ul class="
|
|
47
|
+
<ul class="cluster">
|
|
55
48
|
<li><a href="/privacy">Privacy</a></li>
|
|
56
49
|
<li><a href="/terms">Terms</a></li>
|
|
57
50
|
<li><a href="/contact">Contact</a></li>
|
|
@@ -69,7 +62,7 @@ Header navigation is usually a composition of landmarks, layout primitives, and
|
|
|
69
62
|
<a class="brand" href="/">Actual CSS</a>
|
|
70
63
|
|
|
71
64
|
<nav aria-label="Main navigation">
|
|
72
|
-
<ul class="
|
|
65
|
+
<ul class="cluster">
|
|
73
66
|
<li><a href="/docs">Docs</a></li>
|
|
74
67
|
<li><a href="/components">Components</a></li>
|
|
75
68
|
<li><a href="/examples">Examples</a></li>
|
|
@@ -85,8 +78,7 @@ In this example:
|
|
|
85
78
|
- `.center` constrains the content.
|
|
86
79
|
- `.cluster` arranges the brand and navigation.
|
|
87
80
|
- `nav` provides navigation semantics.
|
|
88
|
-
- `.
|
|
89
|
-
- the inner `.cluster` arranges navigation items horizontally.
|
|
81
|
+
- the inner `.cluster` removes the list chrome and arranges the links horizontally.
|
|
90
82
|
|
|
91
83
|
A project may add `.site-header` when it needs a visual shell.
|
|
92
84
|
|
|
@@ -106,7 +98,7 @@ A project may add `.site-header` when it needs a visual shell.
|
|
|
106
98
|
<aside class="shell-sidebar-nav" aria-label="Primary">
|
|
107
99
|
<a class="navbar-brand" href="#"><span class="avatar primary"><abbr>AC</abbr></span> Product</a>
|
|
108
100
|
<nav aria-label="Primary">
|
|
109
|
-
<ul class="nav-list
|
|
101
|
+
<ul class="nav-list">
|
|
110
102
|
<li><a class="nav-link" href="#" aria-current="page">Overview</a></li>
|
|
111
103
|
<li><a class="nav-link" href="#">Settings</a></li>
|
|
112
104
|
</ul>
|
|
@@ -167,7 +159,7 @@ Side navigation is usually a `.nav-list` composed with `.stack`.
|
|
|
167
159
|
```html demo
|
|
168
160
|
<aside>
|
|
169
161
|
<nav aria-label="Documentation">
|
|
170
|
-
<ul class="nav-list
|
|
162
|
+
<ul class="nav-list">
|
|
171
163
|
<li><a href="/docs/getting-started" aria-current="page">Getting started</a></li>
|
|
172
164
|
<li><a href="/docs/tokens">Tokens</a></li>
|
|
173
165
|
<li><a href="/docs/layout">Layout</a></li>
|
|
@@ -182,7 +174,7 @@ A project may add `.side-nav` only when it needs specific visual behavior such a
|
|
|
182
174
|
```html demo
|
|
183
175
|
<aside class="side-nav">
|
|
184
176
|
<nav aria-label="Documentation">
|
|
185
|
-
<ul class="nav-list
|
|
177
|
+
<ul class="nav-list">
|
|
186
178
|
<li><a href="/docs/getting-started" aria-current="page">Getting started</a></li>
|
|
187
179
|
<li><a href="/docs/tokens">Tokens</a></li>
|
|
188
180
|
<li><a href="/docs/layout">Layout</a></li>
|
|
@@ -206,30 +198,8 @@ A project may add `.side-nav` only when it needs specific visual behavior such a
|
|
|
206
198
|
}
|
|
207
199
|
```
|
|
208
200
|
|
|
209
|
-
###
|
|
210
|
-
|
|
211
|
-
`.nav-list` can stay purely structural. If the framework wants navigation links to have a default hit area and active state, this can be added as a lightweight visual pattern.
|
|
212
|
-
|
|
213
|
-
```css
|
|
214
|
-
.nav-list a {
|
|
215
|
-
display: flex;
|
|
216
|
-
align-items: center;
|
|
217
|
-
gap: var(--space-20);
|
|
218
|
-
min-block-size: 2rem;
|
|
219
|
-
padding-inline: var(--space-20);
|
|
220
|
-
border-radius: var(--radius-sm);
|
|
221
|
-
color: inherit;
|
|
222
|
-
text-decoration: none;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
.nav-list a:hover {
|
|
226
|
-
background: var(--surface-subtle);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
.nav-list a[aria-current="page"] {
|
|
230
|
-
background: var(--surface-subtle);
|
|
231
|
-
font-weight: 600;
|
|
232
|
-
}
|
|
233
|
-
```
|
|
201
|
+
### Link Styling
|
|
234
202
|
|
|
235
|
-
|
|
203
|
+
`.nav-link` gives a link its hit area, hover fill and `aria-current` state, in a
|
|
204
|
+
`.cluster` row or a `.nav-list` (see [Navbar](../components/navbar.md)). Set
|
|
205
|
+
`--gap` on a `.nav-list` to space its rows differently.
|
|
@@ -22,9 +22,8 @@ Use patterns when a semantic element needs a small amount of normalization befor
|
|
|
22
22
|
Patterns often compose with layout primitives.
|
|
23
23
|
|
|
24
24
|
```html
|
|
25
|
-
<menu class="
|
|
26
|
-
<ul class="nav-list
|
|
27
|
-
<ul class="nav-list stack">...</ul>
|
|
25
|
+
<menu class="cluster">...</menu>
|
|
26
|
+
<ul class="nav-list">...</ul>
|
|
28
27
|
<section class="grid">...</section>
|
|
29
28
|
```
|
|
30
29
|
|
|
@@ -51,7 +50,7 @@ Avoid putting semantic resets into layout primitives.
|
|
|
51
50
|
If list chrome should be removed, use an explicit pattern.
|
|
52
51
|
|
|
53
52
|
```html demo
|
|
54
|
-
<ul class="nav-list
|
|
53
|
+
<ul class="nav-list">
|
|
55
54
|
<li><a href="/docs">Docs</a></li>
|
|
56
55
|
<li><a href="/components">Components</a></li>
|
|
57
56
|
</ul>
|
|
@@ -6,24 +6,25 @@ Small flex helpers for grow behavior and other one-line needs.
|
|
|
6
6
|
|
|
7
7
|
Base utilities:
|
|
8
8
|
|
|
9
|
-
| Class
|
|
10
|
-
|
|
|
11
|
-
| `.grow`
|
|
12
|
-
| `.items-start`
|
|
13
|
-
| `.items-center`
|
|
14
|
-
| `.items-end`
|
|
15
|
-
| `.
|
|
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
|
+
| `.items-baseline` | Aligns children on their first text baseline; sets `--items-align`. |
|
|
16
|
+
| `.dot` | Inline separator dot for metadata rows. |
|
|
16
17
|
|
|
17
18
|
Extra utilities:
|
|
18
19
|
|
|
19
|
-
| Class | Description
|
|
20
|
-
| -------------------------------- |
|
|
21
|
-
| `.justify-content-start` | `justify-content: flex-start`
|
|
22
|
-
| `.justify-content-center` | `justify-content: center`
|
|
23
|
-
| `.justify-content-end` | `justify-content: flex-end`
|
|
24
|
-
| `.justify-content-space-between` | `justify-content: space-between`
|
|
25
|
-
| `.flex-wrap` | `flex-wrap: wrap` on any flex container.
|
|
26
|
-
| `.flex-nowrap` | `flex-wrap: nowrap` on any flex container.
|
|
20
|
+
| Class | Description |
|
|
21
|
+
| -------------------------------- | ------------------------------------------------------- |
|
|
22
|
+
| `.justify-content-start` | `justify-content: flex-start` on the element itself. |
|
|
23
|
+
| `.justify-content-center` | `justify-content: center` on the element itself. |
|
|
24
|
+
| `.justify-content-end` | `justify-content: flex-end` on the element itself. |
|
|
25
|
+
| `.justify-content-space-between` | `justify-content: space-between` on the element itself. |
|
|
26
|
+
| `.flex-wrap` | `flex-wrap: wrap` on any flex container. |
|
|
27
|
+
| `.flex-nowrap` | `flex-wrap: nowrap` on any flex container. |
|
|
27
28
|
|
|
28
29
|
## Grow
|
|
29
30
|
|
|
@@ -66,14 +67,24 @@ Use `.items-start` on flex or grid layouts when children should keep their natur
|
|
|
66
67
|
|
|
67
68
|
Use `.items-center` when a flex or grid layout should center its children on the cross axis. Use `.items-end` when children should align to the block-end edge.
|
|
68
69
|
|
|
70
|
+
Use `.items-baseline` when a row mixes text sizes — a price and its period, a name and a timestamp — so the words share one line instead of their boxes sharing a center.
|
|
71
|
+
|
|
72
|
+
```html demo
|
|
73
|
+
<p class="cluster items-baseline">
|
|
74
|
+
<strong style="font-size: 2rem">$29</strong>
|
|
75
|
+
<span class="muted">/ month</span>
|
|
76
|
+
</p>
|
|
77
|
+
```
|
|
78
|
+
|
|
69
79
|
These helpers work by setting a custom property that participating components read,
|
|
70
80
|
so they also apply inside a component's own grid anatomy rather than only on plain
|
|
71
81
|
flex containers:
|
|
72
82
|
|
|
73
|
-
- `.items-start` / `.items-center` / `.items-end` set `--items-align`, read by `.alert` and `.
|
|
83
|
+
- `.items-start` / `.items-center` / `.items-end` / `.items-baseline` set `--items-align`, read by `.alert`, `.card` and `.list-item`.
|
|
74
84
|
- `.text-start` / `.text-center` / `.text-end` set `--text-align`, read by `.table` cells.
|
|
75
|
-
|
|
76
|
-
- `.flex-wrap` / `.flex-nowrap` (utilities/extra) set
|
|
85
|
+
|
|
86
|
+
`.justify-content-*` and `.flex-wrap` / `.flex-nowrap` (utilities/extra) set the property
|
|
87
|
+
directly, so they never reach a nested `.cluster`.
|
|
77
88
|
|
|
78
89
|
Set the property directly when you need a value the helpers do not ship.
|
|
79
90
|
|
|
@@ -107,6 +118,5 @@ Always mark it `aria-hidden="true"` — it is a visual separator, not content.
|
|
|
107
118
|
|
|
108
119
|
## CSS hooks
|
|
109
120
|
|
|
110
|
-
- `--items-align` — cross-axis alignment, set by
|
|
121
|
+
- `--items-align` — cross-axis alignment, set by the `.items-*` helpers.
|
|
111
122
|
- `--text-align` — text alignment, set by `.text-start` / `.text-center` / `.text-end`.
|
|
112
|
-
- `--cluster-justify` — main-axis distribution, set by the optional `.justify-content-*` helpers and read by `.cluster`.
|
|
@@ -29,7 +29,7 @@ one line (`.badge`). To stop a layout primitive from wrapping — for example to
|
|
|
29
29
|
force a `.cluster` onto a single row — set `--cluster-wrap: nowrap`.
|
|
30
30
|
|
|
31
31
|
```html demo
|
|
32
|
-
<div class="cluster
|
|
32
|
+
<div class="cluster tight" style="--cluster-wrap: nowrap;">
|
|
33
33
|
<select class="select sm fit" aria-label="Segment">
|
|
34
34
|
<option>All segments</option>
|
|
35
35
|
</select>
|
|
@@ -66,11 +66,10 @@ Use `.truncate` on the flexible item that should ellipsize inside a constrained
|
|
|
66
66
|
|
|
67
67
|
## Scroller
|
|
68
68
|
|
|
69
|
-
Use `.scroller` to apply optional framework
|
|
69
|
+
Use `.scroller` to apply optional framework overflow treatment to a scroll container: a quieter scrollbar. It does not create overflow; pair it with `.overflow-auto` or a component that already creates overflow.
|
|
70
70
|
|
|
71
|
-
The
|
|
72
|
-
|
|
73
|
-
follow the theme. There is no `::-webkit-scrollbar` chrome: rebuilding a thumb
|
|
71
|
+
The engine keeps drawing the scrollbar; `.scroller` only hands it a density
|
|
72
|
+
and a colour that follow the theme. There is no `::-webkit-scrollbar` chrome: rebuilding a thumb
|
|
74
73
|
by hand means re-implementing the hover, the corner and the light/dark
|
|
75
74
|
adaptation that `color-scheme` already provides, and the hand-built version
|
|
76
75
|
never quite matches the native one anyway.
|
|
@@ -80,6 +79,9 @@ above the capability floor. An engine that knows neither ignores both
|
|
|
80
79
|
declarations and draws its native scrollbar — the intended fallback, not a
|
|
81
80
|
broken state.
|
|
82
81
|
|
|
82
|
+
`.scroller` does not apply to touch screens, where the native overlay scrollbar
|
|
83
|
+
stays: it hides at rest, where a styled bar would stay visible.
|
|
84
|
+
|
|
83
85
|
`.scroller` is a layout primitive, so it comes with `actual.full.css` and with
|
|
84
86
|
`actual-css/css/layout` like `.stack` or `.cluster`. A project importing module
|
|
85
87
|
by module reaches it directly:
|
|
@@ -102,9 +104,13 @@ by module reaches it directly:
|
|
|
102
104
|
.scroller {
|
|
103
105
|
--scroller-track: transparent;
|
|
104
106
|
--scroller-thumb: var(--border);
|
|
107
|
+
}
|
|
105
108
|
|
|
106
|
-
|
|
107
|
-
|
|
109
|
+
@media not all and (pointer: coarse) {
|
|
110
|
+
.scroller {
|
|
111
|
+
scrollbar-color: var(--scroller-thumb) var(--scroller-track);
|
|
112
|
+
scrollbar-width: thin;
|
|
113
|
+
}
|
|
108
114
|
}
|
|
109
115
|
```
|
|
110
116
|
|
|
@@ -120,6 +126,45 @@ Thickness is not a hook: `scrollbar-width` takes `thin` or `auto`, not a length.
|
|
|
120
126
|
Hover is left to the engine — it varies by platform, and matching it by hand was
|
|
121
127
|
the part of a custom scrollbar that never held up.
|
|
122
128
|
|
|
129
|
+
### One-row strips
|
|
130
|
+
|
|
131
|
+
Components that never wrap scroll horizontally when they do not fit: `.tabs`,
|
|
132
|
+
`.steps-horizontal`, and `.table-wrap`. (`.breadcrumb` truncates its labels
|
|
133
|
+
instead; see [Breadcrumb](../components/breadcrumb.md). `.pagination` wraps.)
|
|
134
|
+
In supporting browsers, a strip that loads on a current link tab or step starts
|
|
135
|
+
scrolled to it; elsewhere it starts at its first item.
|
|
136
|
+
|
|
137
|
+
`.tabs` hides its scrollbar and fades its edges instead: selecting the clipped
|
|
138
|
+
tab scrolls it into view. The others leave the scrollbar to the engine, so an
|
|
139
|
+
OS-default horizontal scrollbar can sit under a short strip, and on touch
|
|
140
|
+
screens it overlays the strip and hides at rest, leaving a clipped item as the
|
|
141
|
+
cue that the strip continues. Put `.scroller` on the strip itself — the element
|
|
142
|
+
that scrolls — for a thin, theme-coloured bar under a mouse; touch keeps the
|
|
143
|
+
overlay. These strips have no edge fade (overflow shadow, scroll hint): the
|
|
144
|
+
clipped item and the scrollbar already say there is more. Keyboard focus stops
|
|
145
|
+
an item with its focus line inside the strip.
|
|
146
|
+
|
|
147
|
+
```html
|
|
148
|
+
<ol class="steps steps-horizontal scroller">
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
There is no class that hides the scrollbar: on a strip whose items do not
|
|
152
|
+
scroll it themselves, it is the only visible scroll control for a mouse without
|
|
153
|
+
a horizontal wheel. Apply `.scroller` to every such strip of a page, or to
|
|
154
|
+
none, so the bars stay consistent.
|
|
155
|
+
|
|
156
|
+
A strip keeps scrolling inside a flex or grid row, such as a label and link
|
|
157
|
+
tabs on one `.cluster`: a `<nav>` directly around `.tabs` shrinks with the row
|
|
158
|
+
(and around `.breadcrumb`, which then truncates). Any other wrapper needs
|
|
159
|
+
`min-inline-size: 0`, or the row pushes the whole page into scrolling.
|
|
160
|
+
|
|
161
|
+
```html
|
|
162
|
+
<div class="cluster">
|
|
163
|
+
<span>Sections</span>
|
|
164
|
+
<nav aria-label="Account sections"><ul class="tabs">…</ul></nav>
|
|
165
|
+
</div>
|
|
166
|
+
```
|
|
167
|
+
|
|
123
168
|
## CSS hooks
|
|
124
169
|
|
|
125
170
|
- `--scroller-track` — scrollbar track color.
|
|
@@ -48,9 +48,10 @@ Override the default gap from layout primitives (`.stack`, `.cluster`, `.grid`):
|
|
|
48
48
|
- `.gap-none` → `gap: 0`
|
|
49
49
|
|
|
50
50
|
`.gap-none` sets the element's own gap directly and does not change `--gap`
|
|
51
|
-
for nested layouts. For a
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
for nested layouts. For a tighter or looser rhythm alone — closer items, without
|
|
52
|
+
smaller controls — use `.tight` / `.loose`; `.compact` / `.spacious` also change
|
|
53
|
+
padding and control size. Set the `gap` property on the instance when the change
|
|
54
|
+
must stop there.
|
|
54
55
|
|
|
55
56
|
`--gap` defines the contextual rhythm; `.gap-context` applies that rhythm to a
|
|
56
57
|
container that does not already consume `--gap`. The layout primitives
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "actual-css",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "Plain CSS component framework with semantic classes, universal variants, small tokens, theme hooks, and progressive enhancements.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "bun@1.4.2",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"type": "git",
|
|
11
11
|
"url": "https://github.com/lekoala/actual-css.git"
|
|
12
12
|
},
|
|
13
|
-
"homepage": "https://github.
|
|
13
|
+
"homepage": "https://lekoala.github.io/actual-css/",
|
|
14
14
|
"bugs": {
|
|
15
15
|
"url": "https://github.com/lekoala/actual-css/issues"
|
|
16
16
|
},
|
|
@@ -112,7 +112,8 @@
|
|
|
112
112
|
"node": ">=18"
|
|
113
113
|
},
|
|
114
114
|
"scripts": {
|
|
115
|
-
"
|
|
115
|
+
"hooks:install": "bun scripts/install-hooks.js",
|
|
116
|
+
"lint": "biome check --reporter concise",
|
|
116
117
|
"lint:fix": "biome check --write",
|
|
117
118
|
"build:docs": "bun run build:themes && bun scripts/build-docs.js",
|
|
118
119
|
"watch:docs": "bun run build:themes && bun scripts/build-docs.js --watch",
|
|
@@ -139,7 +140,6 @@
|
|
|
139
140
|
"check:catalog": "bun scripts/check-catalog.js",
|
|
140
141
|
"check:links": "bun scripts/check-doc-links.js",
|
|
141
142
|
"check:templates": "bun scripts/check-templates.js",
|
|
142
|
-
"check:markup": "bun scripts/check-markup.js",
|
|
143
143
|
"shot:crop": "bun scripts/shot-crop.js",
|
|
144
144
|
"shot:forced": "bun scripts/forced-colors-shot.js",
|
|
145
145
|
"shot:multi": "bun scripts/multi-shot.js",
|
|
@@ -152,11 +152,11 @@
|
|
|
152
152
|
"release:notes": "bun scripts/release-notes.js",
|
|
153
153
|
"test": "bun test",
|
|
154
154
|
"test:changed": "bun test --changed=master",
|
|
155
|
-
"build:all": "bun run lint && bun run build:dist && bun run build:js && bun run build:size && bun run format:docs && bun run build:docs && bun run check:docs && bun run check:doc-classes && bun run check:compat && bun run check:css-api && bun run check:color-space && bun run check:architecture && bun run check:enhance && bun run generate:reserved && bun run check:reserved && bun run generate:catalog && bun run check:catalog && bun run check:sync && bun run check:links && bun run check:templates && bun run
|
|
155
|
+
"build:all": "bun run lint && bun run build:dist && bun run build:js && bun run build:size && bun run format:docs && bun run build:docs && bun run check:docs && bun run check:doc-classes && bun run check:compat && bun run check:css-api && bun run check:color-space && bun run check:architecture && bun run check:enhance && bun run generate:reserved && bun run check:reserved && bun run generate:catalog && bun run check:catalog && bun run check:sync && bun run check:links && bun run check:templates && bun run test",
|
|
156
156
|
"prepublishOnly": "bun run build:all"
|
|
157
157
|
},
|
|
158
158
|
"devDependencies": {
|
|
159
|
-
"@biomejs/biome": "^2.5.
|
|
159
|
+
"@biomejs/biome": "^2.5.15",
|
|
160
160
|
"happy-dom": "^20.14.0"
|
|
161
161
|
},
|
|
162
162
|
"dependencies": {
|
package/reserved-classes.json
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
[
|
|
2
2
|
"accordion",
|
|
3
|
-
"actions",
|
|
4
3
|
"admonition",
|
|
5
4
|
"alert",
|
|
6
5
|
"alert-body",
|
|
@@ -56,7 +55,6 @@
|
|
|
56
55
|
"cursor-pointer",
|
|
57
56
|
"danger",
|
|
58
57
|
"data-list",
|
|
59
|
-
"dialog-confirmation",
|
|
60
58
|
"dialog-icon",
|
|
61
59
|
"display-block",
|
|
62
60
|
"display-flex",
|
|
@@ -110,6 +108,7 @@
|
|
|
110
108
|
"intent-color",
|
|
111
109
|
"is-open",
|
|
112
110
|
"is-static",
|
|
111
|
+
"items-baseline",
|
|
113
112
|
"items-center",
|
|
114
113
|
"items-end",
|
|
115
114
|
"items-start",
|
|
@@ -132,6 +131,7 @@
|
|
|
132
131
|
"list-item-title",
|
|
133
132
|
"list-item-trailing",
|
|
134
133
|
"list-reset",
|
|
134
|
+
"loose",
|
|
135
135
|
"margin-block-end-auto",
|
|
136
136
|
"margin-block-start-auto",
|
|
137
137
|
"margin-inline-auto",
|
|
@@ -159,7 +159,6 @@
|
|
|
159
159
|
"nav-list",
|
|
160
160
|
"navbar",
|
|
161
161
|
"navbar-brand",
|
|
162
|
-
"navbar-nav",
|
|
163
162
|
"needs-validation",
|
|
164
163
|
"neutral",
|
|
165
164
|
"otp",
|
|
@@ -248,6 +247,7 @@
|
|
|
248
247
|
"text-uppercase",
|
|
249
248
|
"text-wrap",
|
|
250
249
|
"textarea",
|
|
250
|
+
"tight",
|
|
251
251
|
"tooltip",
|
|
252
252
|
"topbar",
|
|
253
253
|
"touch-target",
|
|
@@ -40,16 +40,19 @@ the title in the content wrapper's direct `<header>`. The close button is then
|
|
|
40
40
|
anchored to the surface, and the header reserves room so the title cannot run
|
|
41
41
|
under it. A `.close` that is a direct child of the chrome header is that same
|
|
42
42
|
corner overlay, and that header reserves room for it too. Put actions in the
|
|
43
|
-
wrapper's `<footer
|
|
43
|
+
wrapper's `<footer>` and compose its row in markup
|
|
44
|
+
(`<footer class="cluster justify-content-end">`); the modal and drawer footers
|
|
45
|
+
have no layout of their own.
|
|
44
46
|
|
|
45
47
|
Use `.bleed` on that direct header when it needs a contrasting full-width band;
|
|
46
48
|
the wrapper relays the modal padding so the band reaches the surface edges while
|
|
47
|
-
its contents keep the normal inset.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
its contents keep the normal inset. A confirmation is composition, not a
|
|
50
|
+
variant: a `.media` row with a leading `.dialog-icon` and the text column (its
|
|
51
|
+
first heading centers on the icon, following copy stays in that column), then a
|
|
52
|
+
`<footer class="bleed background-subtle cluster justify-content-space-between">` action
|
|
53
|
+
band with the cancel-style action first. For a trailing icon, use the wrapper's
|
|
54
|
+
direct header as a non-wrapping split `.cluster`, with `.grow` on the text
|
|
55
|
+
group. Do not compensate heading alignment with a literal margin.
|
|
53
56
|
|
|
54
57
|
Do not turn the dialog heading into an `.alert` to obtain icon or surface
|
|
55
58
|
styling. Compose `.dialog-icon` with `.media` for a leading title icon; reserve
|