actual-css 0.12.0 → 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 +49 -0
- package/README.md +7 -8
- package/components.json +8 -2
- package/dist/actual.full.css +505 -233
- package/dist/actual.full.js +1 -1
- package/dist/actual.full.min.css +1 -1
- package/docs/design-notes/architecture.md +67 -0
- package/docs/design-notes/steps.md +45 -28
- package/docs/pages/components/avatar.md +17 -11
- package/docs/pages/components/breadcrumb.md +16 -2
- package/docs/pages/components/list.md +9 -13
- package/docs/pages/components/navbar.md +42 -22
- package/docs/pages/components/pagination.md +19 -0
- package/docs/pages/components/steps.md +24 -20
- package/docs/pages/enhancements/scrollspy.md +6 -6
- package/docs/pages/enhancements/tabs.md +74 -3
- package/docs/pages/forms/floating-field.md +21 -7
- package/docs/pages/forms/form-actions.md +3 -6
- package/docs/pages/forms/states-and-sizes.md +15 -15
- package/docs/pages/foundations/philosophy.md +97 -1
- package/docs/pages/foundations/tokens.md +40 -4
- package/docs/pages/guides/design-tools.md +1 -1
- package/docs/pages/guides/integrating-actual-css.md +74 -8
- package/docs/pages/guides/introduction.md +3 -2
- package/docs/pages/guides/modular-import.md +1 -1
- package/docs/pages/guides/progressive-enhancement.md +25 -7
- package/docs/pages/guides/upgrading.md +86 -9
- package/docs/pages/layout/center.md +2 -1
- package/docs/pages/layout/cluster.md +11 -4
- package/docs/pages/layout/grid.md +2 -0
- package/docs/pages/layout/sidebar-layout.md +3 -0
- package/docs/pages/layout/switcher.md +2 -0
- package/docs/pages/layout/topbar.md +6 -4
- package/docs/pages/patterns/icon-slot.md +17 -1
- package/docs/pages/utilities/flex.md +1 -1
- package/docs/pages/utilities/sizing-wrapping.md +51 -6
- package/package.json +5 -5
- package/src/cli/actual-css.js +1 -1
- package/src/css/components/alert.css +34 -34
- package/src/css/components/avatar.css +2 -18
- package/src/css/components/badge.css +0 -1
- package/src/css/components/breadcrumb.css +74 -8
- package/src/css/components/drawer.css +23 -42
- package/src/css/components/flyout.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 +17 -10
- package/src/css/components/navbar.css +10 -8
- 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/focus.css +8 -6
- package/src/css/core/theme.css +6 -1
- package/src/css/core/tokens.css +4 -2
- 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 +5 -8
- 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 +14 -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/utilities/extra.css +3 -3
- 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/design-export.js +1 -1
- package/src/tooling/design-tokens.js +44 -33
- package/src/tooling/theme-contrast.js +32 -24
|
@@ -63,11 +63,30 @@ handle, and cleanup happens per element when an element leaves the DOM.
|
|
|
63
63
|
|
|
64
64
|
## The full runtime
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
66
|
+
Import `actual-css/js/full` to enable the full runtime:
|
|
67
|
+
|
|
68
|
+
```js
|
|
69
|
+
import "actual-css/js/full";
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The same entrypoint exposes the public enhancement API from the same runtime
|
|
73
|
+
instance, for adopters that extend the runtime they already run:
|
|
74
|
+
|
|
75
|
+
```js
|
|
76
|
+
import { applyEnhancement, enhance, registerEnhancement } from "actual-css/js/full";
|
|
77
|
+
|
|
78
|
+
registerEnhancement("autosubmit", (form) => {
|
|
79
|
+
// ...
|
|
80
|
+
});
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
For anything beyond that extension API, keep using `actual-css/js/*`.
|
|
84
|
+
|
|
85
|
+
The same entrypoint produces the `dist/actual.full.js` standalone for a
|
|
86
|
+
classic `<script>`, where no global API is exposed. Static HTML that needs to
|
|
87
|
+
trigger something from its own inline `<script>` dispatches the module's
|
|
88
|
+
public event instead of calling into a global — `actual:status` for the
|
|
89
|
+
status bar, for example:
|
|
71
90
|
|
|
72
91
|
```html
|
|
73
92
|
<script src="actual.full.js"></script>
|
|
@@ -110,8 +129,7 @@ needed.
|
|
|
110
129
|
The JS is designed to run on its own, without Actual's stylesheet.
|
|
111
130
|
|
|
112
131
|
- **`data-enhance` tokens** register named behaviors. The runtime discovers
|
|
113
|
-
components through `data-enhance="tabs"`, `data-enhance="flyout"`,
|
|
114
|
-
`data-enhance="range"`, `data-enhance="scrollspy"`, and
|
|
132
|
+
components through `data-enhance="tabs"`, `data-enhance="flyout"`, `data-enhance="range"`, `data-enhance="scrollspy"`, and
|
|
115
133
|
`data-enhance="validation"` — no Actual presentation class needed.
|
|
116
134
|
Self-describing attributes (`data-mask`, `data-tooltip`,
|
|
117
135
|
`data-context-menu`) stay framework-neutral by construction.
|
|
@@ -1,12 +1,90 @@
|
|
|
1
|
-
# Upgrading
|
|
1
|
+
# Upgrading
|
|
2
2
|
|
|
3
3
|
Each step below is a search for a removed class or hook and its replacement.
|
|
4
4
|
The [changelog](https://github.com/lekoala/actual-css/blob/master/CHANGELOG.md)
|
|
5
|
-
lists every change; this page keeps the ones that need an edit.
|
|
5
|
+
lists every change; this page keeps the ones that need an edit. Apply the
|
|
6
|
+
sections in order when skipping a release.
|
|
6
7
|
|
|
7
8
|
**Related terms:** migration, breaking changes, update, version.
|
|
8
9
|
|
|
9
|
-
##
|
|
10
|
+
## 0.12 to 0.13
|
|
11
|
+
|
|
12
|
+
### Layout hooks stop at each layout
|
|
13
|
+
|
|
14
|
+
`--cluster-justify`, `--cluster-align` and `--cluster-wrap` are reset on every
|
|
15
|
+
`.cluster`, and `--grid-columns` and `--grid-min` on every `.grid`. A value set
|
|
16
|
+
on an ancestor, including an outer cluster or grid, no longer reaches the
|
|
17
|
+
layout inside it. Search application CSS and inline styles for these hooks on
|
|
18
|
+
anything but the layout itself, then set them on the row or grid, or select it:
|
|
19
|
+
|
|
20
|
+
```css
|
|
21
|
+
.toolbar > .cluster {
|
|
22
|
+
--cluster-justify: space-between;
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`--gap` still inherits, so a density context keeps reaching every nested
|
|
27
|
+
layout.
|
|
28
|
+
|
|
29
|
+
### Avatar stacks
|
|
30
|
+
|
|
31
|
+
`.avatar-stack` no longer takes its size from a child `.avatar.sm` or
|
|
32
|
+
`.avatar.lg`. Move the size class to the stack and drop it from its avatars:
|
|
33
|
+
|
|
34
|
+
```html
|
|
35
|
+
<div class="avatar-stack sm" role="group" aria-label="Team members">
|
|
36
|
+
<div class="avatar" role="img" aria-label="John Doe">…</div>
|
|
37
|
+
</div>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Focus outline
|
|
41
|
+
|
|
42
|
+
`--focus-outline` has no default value any more. Search application CSS for
|
|
43
|
+
`var(--focus-outline)` and write the generic line instead:
|
|
44
|
+
|
|
45
|
+
```css
|
|
46
|
+
outline: var(--focus-ring-width) solid var(--focus-outline-color);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Setting `--focus-outline` still replaces the generic line.
|
|
50
|
+
|
|
51
|
+
### List rows
|
|
52
|
+
|
|
53
|
+
`.list-item` regions center on the row. For rows with long supporting text,
|
|
54
|
+
add `.items-start` to the row or to the `.list` to keep them top-aligned.
|
|
55
|
+
|
|
56
|
+
### Step rows
|
|
57
|
+
|
|
58
|
+
`.steps-horizontal` budgets each step from its marker instead of `7rem`, so a
|
|
59
|
+
row fits narrower widths before it scrolls. To keep the previous budget on a
|
|
60
|
+
row, set `--step-min: 7rem` on it.
|
|
61
|
+
|
|
62
|
+
### Current links and rows
|
|
63
|
+
|
|
64
|
+
`.nav-link` shows its current state only for `aria-current="page"` or
|
|
65
|
+
`aria-current="location"`, and `a.list-item` only for `aria-current="page"` or
|
|
66
|
+
`aria-current="true"`. Search markup for other values on these classes and
|
|
67
|
+
use the matching one.
|
|
68
|
+
|
|
69
|
+
### Tabs
|
|
70
|
+
|
|
71
|
+
`data-enhance="tabs"` only wires an element that also carries
|
|
72
|
+
`role="tablist"`. Search markup for the token and add the role where it is
|
|
73
|
+
missing; the console names each list it skipped.
|
|
74
|
+
|
|
75
|
+
### Rendering changes without an edit
|
|
76
|
+
|
|
77
|
+
- A horizontal `.tabs` strip never wraps: a strip that does not fit scrolls
|
|
78
|
+
horizontally, with no scrollbar and faded edges.
|
|
79
|
+
- `.breadcrumb` never wraps either: a trail that does not fit truncates its
|
|
80
|
+
labels with an ellipsis, ancestors first. Ancestor labels need an `<a>` or
|
|
81
|
+
`<span>`.
|
|
82
|
+
- The focus reserve of a scrolling dialog or drawer body no longer grows with
|
|
83
|
+
`--border-width`: 1px narrower under `prefers-contrast: more`.
|
|
84
|
+
|
|
85
|
+
## 0.11 to 0.12
|
|
86
|
+
|
|
87
|
+
### Action rows
|
|
10
88
|
|
|
11
89
|
`.actions`, `.navbar-nav` and the layout of `.form-actions` are gone. A row of
|
|
12
90
|
actions is a `.cluster`; a vertical list is `stack list-reset`. Replace
|
|
@@ -27,12 +105,11 @@ actions is a `.cluster`; a vertical list is `stack list-reset`. Replace
|
|
|
27
105
|
`gap: var(--space-10)` on that row in application CSS.
|
|
28
106
|
- `.form-actions` has no top margin and no `--form-actions-margin-block-start`:
|
|
29
107
|
put `.stack` on the form. `--form-actions-justify` and `--form-actions-align`
|
|
30
|
-
still apply. In a modular build, import `layout/cluster
|
|
31
|
-
`forms/form-actions`.
|
|
108
|
+
still apply. In a modular build, also import `layout/cluster`.
|
|
32
109
|
- `.justify-content-*` aligns only its own element and no longer reaches a
|
|
33
110
|
nested `.cluster`. Put the utility on the row it should align.
|
|
34
111
|
|
|
35
|
-
|
|
112
|
+
### Dialogs
|
|
36
113
|
|
|
37
114
|
- `.dialog-confirmation` is removed. Compose `.media` with `.dialog-icon`, then
|
|
38
115
|
a `<footer class="bleed background-subtle cluster justify-content-space-between">`;
|
|
@@ -46,7 +123,7 @@ actions is a `.cluster`; a vertical list is `stack list-reset`. Replace
|
|
|
46
123
|
`.dialog-confirmation` used 1.5rem. Set `--modal-pad: var(--space-50)` on
|
|
47
124
|
the dialog to keep the roomier treatment.
|
|
48
125
|
|
|
49
|
-
|
|
126
|
+
### Cards
|
|
50
127
|
|
|
51
128
|
The layout of a `.card` header or footer row is a zero-specificity default: any
|
|
52
129
|
author rule that targets the slot replaces it, not only a `.media`, `.cluster`,
|
|
@@ -54,7 +131,7 @@ author rule that targets the slot replaces it, not only a `.media`, `.cluster`,
|
|
|
54
131
|
element rules such as `header { … }` or `footer { … }`, which now win over the
|
|
55
132
|
card's slot row.
|
|
56
133
|
|
|
57
|
-
|
|
134
|
+
### Themes and density
|
|
58
135
|
|
|
59
136
|
- A theme sets `--control-pad-x-sm`, `--control-pad-x-md` and
|
|
60
137
|
`--control-pad-x-lg` instead of `--control-pad-x`. Used as a nested island,
|
|
@@ -63,7 +140,7 @@ card's slot row.
|
|
|
63
140
|
- `--font-width-dense` is removed, and `.compact` no longer condenses type: set
|
|
64
141
|
`font-stretch` on the element that should render condensed.
|
|
65
142
|
|
|
66
|
-
|
|
143
|
+
### Rendering changes without an edit
|
|
67
144
|
|
|
68
145
|
These need no markup change; compare the affected screens.
|
|
69
146
|
|
|
@@ -15,7 +15,8 @@ Constrain readable content and center it in the viewport, with width and padding
|
|
|
15
15
|
</main>
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
Tune width and side padding with
|
|
18
|
+
Tune width and side padding with `--center-size` and `--center-pad`. Both
|
|
19
|
+
inherit: set them on `:root` for the site's content width, or on one region.
|
|
19
20
|
|
|
20
21
|
```css
|
|
21
22
|
.docs-page {
|
|
@@ -61,11 +61,15 @@ separate `.split` or `.spread` primitive; this is the same relationship.
|
|
|
61
61
|
</div>
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
+
Once the row wraps, `space-between` puts an item alone on its line at the
|
|
65
|
+
start. To keep the end item on the end edge when it wraps, add
|
|
66
|
+
`.margin-inline-start-auto` to it.
|
|
67
|
+
|
|
64
68
|
To align a row to its top edge instead of centering it — useful when one item
|
|
65
|
-
wraps to several lines — set `--cluster-align
|
|
69
|
+
wraps to several lines — set `--cluster-align` on the cluster itself.
|
|
66
70
|
|
|
67
71
|
```css
|
|
68
|
-
.filters {
|
|
72
|
+
.cluster.filters {
|
|
69
73
|
--cluster-align: start;
|
|
70
74
|
--cluster-justify: space-between;
|
|
71
75
|
}
|
|
@@ -74,8 +78,11 @@ wraps to several lines — set `--cluster-align`.
|
|
|
74
78
|
The optional utility layer ships `.justify-content-start`, `.justify-content-center`,
|
|
75
79
|
`.justify-content-end` and `.justify-content-space-between`. They set
|
|
76
80
|
`justify-content` on that one row only; a nested `.cluster` keeps its own
|
|
77
|
-
alignment. `--cluster
|
|
78
|
-
|
|
81
|
+
alignment. The `--cluster-*` hooks behave the same way: each cluster resets
|
|
82
|
+
them, so a value applies to the cluster it is set on and never to a nested
|
|
83
|
+
one. To align nested rows, select them (`.toolbar > .cluster`). `--gap` keeps
|
|
84
|
+
inheriting, so a density context still reaches every nested cluster. See the
|
|
85
|
+
utilities page.
|
|
79
86
|
|
|
80
87
|
## Controls inside a wrapping cluster
|
|
81
88
|
|
|
@@ -172,3 +172,5 @@ stacked, prefer `.switcher`.
|
|
|
172
172
|
- `--grid-min` tunes the minimum item width of the intrinsic `.grid` recipe.
|
|
173
173
|
It does not apply to `.grid-N`.
|
|
174
174
|
- `--grid-columns` replaces that recipe with an author-owned template.
|
|
175
|
+
|
|
176
|
+
Both stop at a nested `.grid`: set them on the grid itself.
|
|
@@ -47,3 +47,6 @@ When the layout stacks (narrow space), the aside stays on top.
|
|
|
47
47
|
|
|
48
48
|
- `--sidebar-layout-size` sets the aside's preferred width.
|
|
49
49
|
- `--sidebar-content-min` sets the main region's minimum viable width.
|
|
50
|
+
|
|
51
|
+
The regions read both, so they also reach the regions of a nested
|
|
52
|
+
`.sidebar-layout`; set them on the nested layout to give it its own sizes.
|
|
@@ -11,10 +11,12 @@ Use `.topbar` for the structural shell of an app-shell header: sticky positionin
|
|
|
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>
|
|
@@ -80,7 +80,7 @@ These helpers work by setting a custom property that participating components re
|
|
|
80
80
|
so they also apply inside a component's own grid anatomy rather than only on plain
|
|
81
81
|
flex containers:
|
|
82
82
|
|
|
83
|
-
- `.items-start` / `.items-center` / `.items-end` / `.items-baseline` 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`.
|
|
84
84
|
- `.text-start` / `.text-center` / `.text-end` set `--text-align`, read by `.table` cells.
|
|
85
85
|
|
|
86
86
|
`.justify-content-*` and `.flex-wrap` / `.flex-nowrap` (utilities/extra) set the property
|
|
@@ -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.
|
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",
|
|
@@ -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/src/cli/actual-css.js
CHANGED
|
@@ -12,7 +12,7 @@ function usage() {
|
|
|
12
12
|
"",
|
|
13
13
|
" -o, --out FILE write the bundle to FILE / the export to DIR (required)",
|
|
14
14
|
" --minify collapse comments and whitespace",
|
|
15
|
-
" --theme FILE read this [data-theme]
|
|
15
|
+
" --theme FILE read this theme file ([data-theme] or :root) over the default",
|
|
16
16
|
" --name NAME the data-theme name, when the file declares several",
|
|
17
17
|
" -h, --help show this message",
|
|
18
18
|
" --version print the actual-css version",
|
|
@@ -107,10 +107,11 @@
|
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
/* Decorative leading icon — use .alert-icon on the icon element.
|
|
110
|
+
/* Decorative leading icon — use .alert-icon on the icon element. display and
|
|
111
|
+
vertical-align are the no-:has() layout (Degraded tier: the icon sits inline
|
|
112
|
+
before the text); the grid anatomy below replaces them. */
|
|
111
113
|
.alert > .alert-icon {
|
|
112
114
|
display: inline-block;
|
|
113
|
-
flex: none;
|
|
114
115
|
inline-size: var(--alert-icon-size);
|
|
115
116
|
block-size: var(--alert-icon-size);
|
|
116
117
|
font-size: var(--alert-icon-size);
|
|
@@ -142,45 +143,44 @@
|
|
|
142
143
|
|
|
143
144
|
/* Grid anatomy — activated by a leading icon, a trailing dismiss button, or
|
|
144
145
|
both. Icon and dismiss are pinned to the outer columns; anything else (the
|
|
145
|
-
message content) flows into the remaining text column.
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
.alert:has(> .alert-icon) {
|
|
155
|
-
grid-template-columns: auto minmax(0, 1fr);
|
|
156
|
-
}
|
|
146
|
+
message content) flows into the remaining text column. Without :has(), the
|
|
147
|
+
grid rules drop together and the alert keeps ordinary block flow. */
|
|
148
|
+
.alert:has(> .alert-icon, > .close) {
|
|
149
|
+
display: grid;
|
|
150
|
+
/* No grid-template-columns: the icon and close branches below always set
|
|
151
|
+
it, since one of them is what matched. */
|
|
152
|
+
align-items: var(--items-align, start);
|
|
153
|
+
column-gap: var(--space-30);
|
|
154
|
+
}
|
|
157
155
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
display: inline-grid;
|
|
162
|
-
place-items: center;
|
|
163
|
-
margin-block-start: 0.125em;
|
|
164
|
-
}
|
|
156
|
+
.alert:has(> .alert-icon) {
|
|
157
|
+
grid-template-columns: auto minmax(0, 1fr);
|
|
158
|
+
}
|
|
165
159
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
160
|
+
.alert:has(> .alert-icon) > .alert-icon {
|
|
161
|
+
grid-column: 1;
|
|
162
|
+
grid-row: 1 / -1;
|
|
163
|
+
display: inline-grid;
|
|
164
|
+
place-items: center;
|
|
165
|
+
margin-block-start: 0.125em;
|
|
166
|
+
}
|
|
169
167
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
168
|
+
.alert:has(> .alert-icon) > :not(.alert-icon, .close) {
|
|
169
|
+
grid-column: 2;
|
|
170
|
+
}
|
|
173
171
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
172
|
+
.alert:has(> .close) {
|
|
173
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
174
|
+
}
|
|
177
175
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
grid-row: 1;
|
|
181
|
-
}
|
|
176
|
+
.alert:has(> .alert-icon):has(> .close) {
|
|
177
|
+
grid-template-columns: auto minmax(0, 1fr) auto;
|
|
182
178
|
}
|
|
183
179
|
|
|
180
|
+
.alert:has(> .close) > .close {
|
|
181
|
+
grid-column: -2 / -1;
|
|
182
|
+
grid-row: 1;
|
|
183
|
+
}
|
|
184
184
|
/* Links */
|
|
185
185
|
.alert :where(a:not(.btn)) {
|
|
186
186
|
color: inherit;
|
|
@@ -11,13 +11,13 @@
|
|
|
11
11
|
* --avatar-size
|
|
12
12
|
* --avatar-radius
|
|
13
13
|
* --avatar-font-size
|
|
14
|
+
* --avatar-bg
|
|
14
15
|
* --avatar-stack-size
|
|
15
16
|
* --avatar-stack-font-size
|
|
16
17
|
* --avatar-stack-overlap
|
|
17
18
|
* --avatar-stack-ring
|
|
18
19
|
*
|
|
19
20
|
* Internal:
|
|
20
|
-
* --avatar-bg
|
|
21
21
|
* --avatar-fg
|
|
22
22
|
* --avatar-status-translate-x
|
|
23
23
|
*/
|
|
@@ -95,16 +95,13 @@
|
|
|
95
95
|
|
|
96
96
|
.avatar > img,
|
|
97
97
|
.avatar > picture > img {
|
|
98
|
+
display: block;
|
|
98
99
|
inline-size: 100%;
|
|
99
100
|
block-size: 100%;
|
|
100
101
|
object-fit: cover;
|
|
101
102
|
border-radius: inherit;
|
|
102
103
|
}
|
|
103
104
|
|
|
104
|
-
.avatar > picture > img {
|
|
105
|
-
display: block;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
105
|
button.avatar {
|
|
109
106
|
appearance: none;
|
|
110
107
|
cursor: pointer;
|
|
@@ -198,19 +195,6 @@ a.avatar[aria-disabled="true"] {
|
|
|
198
195
|
--avatar-stack-font-size: var(--font-size-lg);
|
|
199
196
|
}
|
|
200
197
|
|
|
201
|
-
/* Infer the stack scale from its avatars. Progressive: without :has() the
|
|
202
|
-
explicit .avatar-stack.sm/.lg classes and the default size still size the
|
|
203
|
-
group, only the inference is lost. */
|
|
204
|
-
.avatar-stack:has(> .avatar.sm) {
|
|
205
|
-
--avatar-stack-size: 1.75rem;
|
|
206
|
-
--avatar-stack-font-size: var(--font-size-xs);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
.avatar-stack:has(> .avatar.lg) {
|
|
210
|
-
--avatar-stack-size: 3rem;
|
|
211
|
-
--avatar-stack-font-size: var(--font-size-lg);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
198
|
/* Overlapping avatars hide their neighbour: a translucent fill (--surface-subtle
|
|
215
199
|
on a glass palette) would show the next avatar's edge through it, most of all
|
|
216
200
|
when hover raises one above the other. The fill is layered over the opaque
|