actual-css 0.9.2 → 0.11.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 +169 -1
- package/README.md +65 -44
- package/components.json +35 -14
- package/dist/actual.full.css +877 -583
- package/dist/actual.full.js +1 -1
- package/dist/actual.full.min.css +1 -1
- package/docs/design-notes/app-ui.md +1 -1
- package/docs/design-notes/column-layout.md +103 -520
- package/docs/design-notes/enhancement-contract.md +16 -7
- package/docs/design-notes/forced-colors.md +12 -1
- package/docs/design-notes/naming.md +1 -1
- package/docs/design-notes/platform-alignment.md +8 -4
- package/docs/design-notes/rich-text.md +61 -0
- package/docs/design-notes/steps.md +2 -2
- package/docs/design-notes/surface-reparenting.md +8 -9
- package/docs/navigation.json +4 -0
- package/docs/pages/components/accordion.md +55 -1
- package/docs/pages/components/alert.md +9 -15
- package/docs/pages/components/aura.md +12 -13
- package/docs/pages/components/badge.md +16 -7
- package/docs/pages/components/bleed.md +42 -0
- package/docs/pages/components/button.md +30 -4
- package/docs/pages/components/card.md +21 -86
- package/docs/pages/components/chat.md +5 -0
- package/docs/pages/components/close.md +48 -0
- package/docs/pages/components/data-list.md +26 -1
- package/docs/pages/components/dialog.md +21 -18
- package/docs/pages/components/drawer.md +9 -9
- package/docs/pages/components/navbar.md +5 -5
- package/docs/pages/components/pagination.md +15 -15
- package/docs/pages/components/shimmer.md +57 -0
- package/docs/pages/components/skeleton.md +2 -1
- package/docs/pages/components/spinner.md +14 -9
- package/docs/pages/components/table.md +13 -0
- package/docs/pages/enhancements/flyout.md +2 -0
- package/docs/pages/enhancements/overview.md +5 -0
- package/docs/pages/enhancements/tabs.md +4 -0
- package/docs/pages/enhancements/tooltip.md +3 -1
- package/docs/pages/examples/overview.md +2 -1
- package/docs/pages/forms/choice-cards.md +116 -4
- package/docs/pages/forms/combobox.md +39 -12
- package/docs/pages/forms/joined-controls.md +2 -5
- package/docs/pages/forms/overview.md +10 -1
- package/docs/pages/forms/range.md +110 -5
- package/docs/pages/forms/rich-text.md +110 -0
- package/docs/pages/forms/validation.md +5 -1
- package/docs/pages/foundations/theming.md +110 -18
- package/docs/pages/foundations/tokens.md +41 -13
- package/docs/pages/guides/bootstrap.md +2 -1
- package/docs/pages/guides/introduction.md +15 -23
- package/docs/pages/guides/modular-import.md +54 -7
- package/docs/pages/guides/progressive-enhancement.md +19 -17
- package/docs/pages/guides/tailwind.md +21 -7
- package/docs/pages/layout/column-layout.md +92 -54
- package/docs/pages/layout/media.md +1 -1
- package/docs/pages/layout/overview.md +1 -1
- package/docs/pages/utilities/overview.md +1 -1
- package/docs/pages/utilities/sizing-wrapping.md +5 -3
- package/llms.txt +25 -4
- package/package.json +10 -6
- package/reserved-classes.json +6 -30
- package/skills/actual-css/PROJECT.md.example +65 -0
- package/skills/actual-css/README.md +64 -0
- package/skills/actual-css/SKILL.md +234 -0
- package/skills/actual-css/references/accessibility.md +44 -0
- package/skills/actual-css/references/api-and-vocabulary.md +94 -0
- package/skills/actual-css/references/enhancements.md +59 -0
- package/skills/actual-css/references/forms.md +49 -0
- package/skills/actual-css/references/layout-and-theming.md +82 -0
- package/skills/actual-css/references/review-checklist.md +51 -0
- package/skills/actual-css/scripts/inspect-actual-css.mjs +171 -0
- package/src/css/components/accordion.css +44 -7
- package/src/css/components/alert.css +23 -43
- package/src/css/components/app-nav.css +9 -0
- package/src/css/components/avatar.css +1 -1
- package/src/css/components/badge.css +11 -39
- package/src/css/components/bleed.css +79 -0
- package/src/css/components/button.css +6 -17
- package/src/css/components/card.css +7 -40
- package/src/css/components/close.css +91 -0
- package/src/css/components/data-list.css +18 -0
- package/src/css/components/drawer.css +15 -56
- package/src/css/components/fab.css +10 -0
- package/src/css/components/flyout.css +5 -1
- package/src/css/components/index.css +2 -0
- package/src/css/components/join.css +36 -20
- package/src/css/components/menu.css +12 -0
- package/src/css/components/meter.css +1 -1
- package/src/css/components/modal.css +10 -57
- package/src/css/components/navbar.css +27 -0
- package/src/css/components/pagination.css +3 -2
- package/src/css/components/rating.css +1 -1
- package/src/css/components/status-bar.css +2 -2
- package/src/css/components/steps.css +3 -3
- package/src/css/components/tab.css +3 -3
- package/src/css/components/table.css +6 -0
- package/src/css/components/tooltip.css +1 -1
- package/src/css/core/focus.css +19 -3
- package/src/css/core/theme.css +33 -43
- package/src/css/core/tokens.css +9 -5
- package/src/css/core/variants.css +5 -34
- package/src/css/effects/aura.css +51 -33
- package/src/css/effects/index.css +1 -0
- package/src/css/effects/shimmer.css +57 -0
- package/src/css/forms/choice-card.css +142 -24
- package/src/css/forms/choice.css +2 -3
- package/src/css/forms/control.css +17 -10
- package/src/css/forms/custom-select.css +4 -4
- package/src/css/forms/native.css +4 -4
- package/src/css/forms/otp.css +9 -1
- package/src/css/forms/range.css +72 -14
- package/src/css/forms/switch.css +2 -3
- package/src/css/layout/app-layout.css +1 -1
- package/src/css/layout/column-layout.css +26 -111
- package/src/css/utilities/extra.css +7 -6
- package/src/js/command.js +61 -32
- package/src/js/dialog.js +103 -47
- package/src/js/dismiss.js +1 -2
- package/src/js/enhance.js +91 -126
- package/src/js/escape.js +1 -0
- package/src/js/flyout.js +10 -1
- package/src/js/focus-group.js +2 -1
- package/src/js/full.js +1 -0
- package/src/js/keys.js +14 -0
- package/src/js/menu.js +2 -1
- package/src/js/password.js +1 -8
- package/src/js/range.js +151 -0
- package/src/js/scrollspy.js +4 -5
- package/src/js/status.js +21 -10
- package/src/js/surface.js +12 -8
- package/src/js/tab.js +2 -1
- package/src/js/tooltip.js +29 -2
- package/src/js/validation.js +8 -15
- package/dist/actual.css +0 -876
- package/dist/actual.js +0 -1
- package/dist/actual.min.css +0 -1
|
@@ -1,24 +1,20 @@
|
|
|
1
1
|
# Card
|
|
2
2
|
|
|
3
|
-
Flexible content container with optional header, body, and footer regions
|
|
3
|
+
Flexible content container with optional header, body, and footer regions.
|
|
4
4
|
|
|
5
5
|
## Class reference
|
|
6
6
|
|
|
7
|
-
| Class
|
|
8
|
-
|
|
|
9
|
-
| `.card`
|
|
10
|
-
| `.raised`
|
|
11
|
-
| `.subtle`
|
|
12
|
-
| `.surface`
|
|
13
|
-
| `.
|
|
14
|
-
| `.compact` | Density | Tighter padding and compact descendant context. |
|
|
7
|
+
| Class | Kind | Description |
|
|
8
|
+
| ---------- | --------- | ----------------------------------------------- |
|
|
9
|
+
| `.card` | Component | Neutral raised surface for grouped content. |
|
|
10
|
+
| `.raised` | Variant | Elevated surface with a soft shadow. |
|
|
11
|
+
| `.subtle` | Variant | Lower contrast against the page surface. |
|
|
12
|
+
| `.surface` | Variant | The page surface; intent in the text only. |
|
|
13
|
+
| `.compact` | Density | Tighter padding and compact descendant context. |
|
|
15
14
|
|
|
16
15
|
`.surface` is a shared variant: it paints the page surface instead of
|
|
17
|
-
`--surface-raised` and leaves the intent to the text.
|
|
18
|
-
|
|
19
|
-
`.inverted` paints `--surface-solid` and swaps the foreground to `--surface`,
|
|
20
|
-
so it inverts in dark themes instead of always reading as dark. Write it as
|
|
21
|
-
`class="card inverted"`, or on any block.
|
|
16
|
+
`--surface-raised` and leaves the intent to the text. For a dark card on a
|
|
17
|
+
light page (or the reverse), put `data-theme="dark"` on the card.
|
|
22
18
|
|
|
23
19
|
## Basic usage
|
|
24
20
|
|
|
@@ -59,52 +55,8 @@ gap.
|
|
|
59
55
|
|
|
60
56
|
## Bleed
|
|
61
57
|
|
|
62
|
-
Use `.bleed` on a direct child to
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
```html demo
|
|
66
|
-
<div style="max-inline-size: 32rem">
|
|
67
|
-
<article class="card stack">
|
|
68
|
-
<img class="bleed" src="https://picsum.photos/seed/actual-css-card/600/300" alt="Coastal cliffs at dusk" />
|
|
69
|
-
<header>
|
|
70
|
-
<h3>Coastal cliffs at dusk</h3>
|
|
71
|
-
</header>
|
|
72
|
-
<section class="stack" aria-label="Summary">
|
|
73
|
-
<p>A short caption that wraps across a few lines. The image bleeds to the card edges.</p>
|
|
74
|
-
</section>
|
|
75
|
-
<footer>
|
|
76
|
-
<span class="badge primary soft">Photo</span>
|
|
77
|
-
<button type="button" class="btn outline">View</button>
|
|
78
|
-
</footer>
|
|
79
|
-
</article>
|
|
80
|
-
</div>
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
```html demo
|
|
84
|
-
<article class="card stack" style="--card-max-inline-size: 24rem">
|
|
85
|
-
<header class="bleed stack items-center text-center" style="background: var(--surface-subtle)">
|
|
86
|
-
<hgroup>
|
|
87
|
-
<h3>Team</h3>
|
|
88
|
-
<p class="muted">For growing products</p>
|
|
89
|
-
</hgroup>
|
|
90
|
-
<p>
|
|
91
|
-
<span style="font-size: 2rem; font-weight: var(--font-weight-semibold); line-height: 1">$24</span>
|
|
92
|
-
<span class="muted">/ user / month</span>
|
|
93
|
-
</p>
|
|
94
|
-
</header>
|
|
95
|
-
|
|
96
|
-
<ul class="stack items-center" style="list-style: none; padding: 0">
|
|
97
|
-
<li>Unlimited projects</li>
|
|
98
|
-
<li>Up to 25 seats</li>
|
|
99
|
-
<li>Shared workspaces</li>
|
|
100
|
-
<li>Priority support</li>
|
|
101
|
-
</ul>
|
|
102
|
-
|
|
103
|
-
<footer class="bleed" style="background: var(--surface-subtle); justify-content: center">
|
|
104
|
-
<a class="btn primary" href="#">Upgrade</a>
|
|
105
|
-
</footer>
|
|
106
|
-
</article>
|
|
107
|
-
```
|
|
58
|
+
Use `.bleed` on a direct child to bring an image or band to the card edge. See
|
|
59
|
+
[Bleed](bleed.md) for the shared surface contract and its modular import.
|
|
108
60
|
|
|
109
61
|
## In grids
|
|
110
62
|
|
|
@@ -148,27 +100,10 @@ all footers in the row line up regardless of body length.
|
|
|
148
100
|
|
|
149
101
|
## Surfaces
|
|
150
102
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
Apply it directly to a component that consumes the shared `--ui-*` surface
|
|
157
|
-
contract (`.card`, `.navbar`, `.alert`, `.badge`) to treat that component as the
|
|
158
|
-
contrasting surface. A surface-owning component nested inside an inverted block
|
|
159
|
-
keeps its own surface and establishes a new context for its descendants. Use a
|
|
160
|
-
`data-theme` island when every component and form control in a subtree must use
|
|
161
|
-
another theme.
|
|
162
|
-
|
|
163
|
-
More specific component states or explicit surface variants still take
|
|
164
|
-
precedence: `.card.inverted.subtle` keeps the `.subtle` background while the
|
|
165
|
-
foreground stays inverted.
|
|
166
|
-
|
|
167
|
-
`.inverted` and `.subtle` are competing surface treatments — do not combine
|
|
168
|
-
them. `.subtle` paints the card's background directly while `.inverted` swaps
|
|
169
|
-
the surface tokens, so `.card.subtle.inverted` renders a subtle background with
|
|
170
|
-
inverted foreground. Treat them as mutually exclusive, like two competing
|
|
171
|
-
variants.
|
|
103
|
+
A card is a surface-owning component: inside a painted band it keeps its own
|
|
104
|
+
surface and resets the context for its content. A card with
|
|
105
|
+
`data-theme="dark"` is a complete dark island — its fields, intents and states
|
|
106
|
+
all follow.
|
|
172
107
|
|
|
173
108
|
`.surface` is the shared variant on a card: it drops the card to the page
|
|
174
109
|
surface instead of `--surface-raised`, keeps the theme border, and lets an
|
|
@@ -198,12 +133,12 @@ treatments on either side of it.
|
|
|
198
133
|
</hgroup>
|
|
199
134
|
</article>
|
|
200
135
|
|
|
201
|
-
<article class="card
|
|
136
|
+
<article class="card stack" data-theme="dark">
|
|
202
137
|
<hgroup>
|
|
203
|
-
<h3>
|
|
204
|
-
<p>
|
|
138
|
+
<h3>Dark island</h3>
|
|
139
|
+
<p class="muted">A complete dark theme on one card.</p>
|
|
205
140
|
</hgroup>
|
|
206
|
-
<button type="button" class="btn">Action</button>
|
|
141
|
+
<button type="button" class="btn primary outline">Action</button>
|
|
207
142
|
</article>
|
|
208
143
|
|
|
209
144
|
<article class="card compact">
|
|
@@ -219,5 +154,5 @@ treatments on either side of it.
|
|
|
219
154
|
|
|
220
155
|
- `--card-radius` — corner radius.
|
|
221
156
|
- `--card-max-inline-size` — maximum width.
|
|
222
|
-
- `--card-pad` — inner padding
|
|
157
|
+
- `--card-pad` — inner padding, relayed to direct children for `.bleed`. `.compact` lowers it.
|
|
223
158
|
- `--card-gap` — space between direct children of a bare card. A composed layout primitive owns its own gap instead.
|
|
@@ -34,6 +34,11 @@ For a live conversation, put an appropriate live-region or `role="log"` on the
|
|
|
34
34
|
conversation container according to the product's announcement needs. Do not
|
|
35
35
|
put `role="log"` on individual messages.
|
|
36
36
|
|
|
37
|
+
For the message input itself, keep a native `<textarea>` inside a surface with
|
|
38
|
+
an actions row — see the [composer template](../../demo/templates/composer.html).
|
|
39
|
+
Formatting needs a hosted editor instead — see the
|
|
40
|
+
[rich-text template](../../demo/templates/rich-text.html).
|
|
41
|
+
|
|
37
42
|
## Class reference
|
|
38
43
|
|
|
39
44
|
| Class | Description |
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Close
|
|
2
|
+
|
|
3
|
+
> Icon-only X button that closes a dialog, dismisses an alert, or removes a tag.
|
|
4
|
+
|
|
5
|
+
**Related terms:** close button, dismiss button, remove button, clear, X.
|
|
6
|
+
|
|
7
|
+
- Use an empty `<button class="close" aria-label="…">`: it paints its own X from `--icon-close`, so it needs no icon font and no text glyph.
|
|
8
|
+
- `.close` is always the X. A button with another pictogram is a `.btn.icon-only`.
|
|
9
|
+
- The class names the look, not the mechanism. Close with the container's own action: `command="request-close"` or `method="dialog"` in a dialog, `command="--dismiss"` on an alert, application logic on a tag.
|
|
10
|
+
- The container sets the size and place: the top inline-end corner of a `.modal` or a `.drawer`, the last column of an `.alert`, the end of a `.badge`.
|
|
11
|
+
- A modular build imports `actual-css/css/components/close` next to the component that hosts it.
|
|
12
|
+
|
|
13
|
+
## Basic usage
|
|
14
|
+
|
|
15
|
+
```html demo
|
|
16
|
+
<div class="cluster">
|
|
17
|
+
<button class="close" type="button" aria-label="Close"></button>
|
|
18
|
+
|
|
19
|
+
<span class="badge primary soft">
|
|
20
|
+
Design
|
|
21
|
+
<button class="close" type="button" aria-label="Remove Design"></button>
|
|
22
|
+
</span>
|
|
23
|
+
</div>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## In a dialog
|
|
27
|
+
|
|
28
|
+
In a `.modal` or a `.drawer`, the close sits out of the content flow at the
|
|
29
|
+
panel's top inline-end corner. Place it as a direct child of the dialog, of its
|
|
30
|
+
top-level `form` or `header`, or of a `form` inside that header; a `.close`
|
|
31
|
+
deeper in the content keeps its own place. See [Dialog](dialog.md) and
|
|
32
|
+
[Drawer](drawer.md).
|
|
33
|
+
|
|
34
|
+
```html
|
|
35
|
+
<dialog class="modal" id="details">
|
|
36
|
+
<button class="close" type="button" commandfor="details" command="request-close"
|
|
37
|
+
aria-label="Close dialog"></button>
|
|
38
|
+
…
|
|
39
|
+
</dialog>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## CSS hooks
|
|
43
|
+
|
|
44
|
+
- `--close-size` — inline and block size of the button; `--control-size` unless the container sets it.
|
|
45
|
+
- `--close-icon-size` — size of the X.
|
|
46
|
+
|
|
47
|
+
Alerts and badges declare both hooks on themselves, so set them on the container
|
|
48
|
+
or on the button.
|
|
@@ -61,6 +61,24 @@ metadata.
|
|
|
61
61
|
</article>
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
+
## Stacked
|
|
65
|
+
|
|
66
|
+
`.stacked` puts each value under its term instead of beside it, for a narrow
|
|
67
|
+
column or for values too long to share a row.
|
|
68
|
+
|
|
69
|
+
```html demo
|
|
70
|
+
<dl class="data-list stacked" style="max-inline-size: 16rem">
|
|
71
|
+
<dt>Billing contact</dt>
|
|
72
|
+
<dd>alice@example.com</dd>
|
|
73
|
+
|
|
74
|
+
<dt>Registered address</dt>
|
|
75
|
+
<dd>42 Rue des Fleurs, 1000 Brussels, Belgium</dd>
|
|
76
|
+
|
|
77
|
+
<dt>Renewal</dt>
|
|
78
|
+
<dd><time datetime="2026-09-14">14 Sep 2026</time></dd>
|
|
79
|
+
</dl>
|
|
80
|
+
```
|
|
81
|
+
|
|
64
82
|
## Contract
|
|
65
83
|
|
|
66
84
|
`.data-list` styles one `<dt>` followed by one `<dd>` per property. A valid
|
|
@@ -69,4 +87,11 @@ markup does not belong in `.data-list` — use a plain description list instead,
|
|
|
69
87
|
where `.prose` already covers the editorial cases.
|
|
70
88
|
|
|
71
89
|
Use `.data-list` for the properties of a single object. Use a `<table>` when
|
|
72
|
-
comparing the same properties across multiple objects.
|
|
90
|
+
comparing the same properties across multiple objects.
|
|
91
|
+
|
|
92
|
+
A per-property icon goes inside the `<dt>`, next to the term. There is no
|
|
93
|
+
gutter slot spanning a term and its value: a `<dl>` admits only `<dt>` and
|
|
94
|
+
`<dd>` per pair — directly or inside a `<div>` wrapper — so no third element
|
|
95
|
+
can hold it. When the icon is the point and the term/value relation is not,
|
|
96
|
+
the content is not a description list: reach for `.media` with an `.overline`
|
|
97
|
+
label instead.
|
|
@@ -6,22 +6,24 @@
|
|
|
6
6
|
|
|
7
7
|
## Class reference
|
|
8
8
|
|
|
9
|
-
| Class | Kind
|
|
10
|
-
| ---------------------- |
|
|
11
|
-
| `.modal` | Component
|
|
12
|
-
| `.scrollable` | Variant
|
|
13
|
-
| `.dialog-confirmation` | Variant
|
|
14
|
-
| `.dialog-icon` | Component
|
|
15
|
-
| `.
|
|
16
|
-
|
|
17
|
-
`.
|
|
18
|
-
dialog's own
|
|
9
|
+
| Class | Kind | Description |
|
|
10
|
+
| ---------------------- | ----------- | ---------------------------------------------- |
|
|
11
|
+
| `.modal` | Component | Centered surface on the native `<dialog>`. |
|
|
12
|
+
| `.scrollable` | Variant | Header and footer stay while the body scrolls. |
|
|
13
|
+
| `.dialog-confirmation` | Variant | Message above a full-width action band. |
|
|
14
|
+
| `.dialog-icon` | Component | Circular intent-aware icon well. |
|
|
15
|
+
| `.close` | Composition | Icon-only close button, at the top end. |
|
|
16
|
+
|
|
17
|
+
A [`.close`](close.md) placed as a direct child of the dialog or of its form
|
|
18
|
+
sits outside the content flow, so it does not take part in the dialog's own
|
|
19
|
+
layout.
|
|
19
20
|
|
|
20
21
|
## Usage
|
|
21
22
|
|
|
22
23
|
Modals use the platform-native `<dialog class="modal">` element with `commandfor` and `command` buttons.
|
|
23
24
|
|
|
24
|
-
Use `command="show-modal"` to open a modal dialog
|
|
25
|
+
Use `command="show-modal"` to open a modal dialog, or `command="--show"` to open
|
|
26
|
+
it non-modally.
|
|
25
27
|
|
|
26
28
|
Add `aria-haspopup="dialog"` and `aria-controls="<id>"` to opening buttons so
|
|
27
29
|
their semantics are present before either native or framework JavaScript runs.
|
|
@@ -138,7 +140,7 @@ has no action button; the header close button dismisses the dialog.
|
|
|
138
140
|
id="details-dialog"
|
|
139
141
|
closedby="any"
|
|
140
142
|
data-dialog-dismissible>
|
|
141
|
-
<button class="
|
|
143
|
+
<button class="close"
|
|
142
144
|
type="button"
|
|
143
145
|
commandfor="details-dialog"
|
|
144
146
|
command="request-close"
|
|
@@ -243,7 +245,7 @@ promoted above it and still unclickable.
|
|
|
243
245
|
id="overlay-dialog"
|
|
244
246
|
closedby="any"
|
|
245
247
|
data-dialog-dismissible>
|
|
246
|
-
<button class="
|
|
248
|
+
<button class="close"
|
|
247
249
|
type="button"
|
|
248
250
|
commandfor="overlay-dialog"
|
|
249
251
|
command="request-close"
|
|
@@ -296,7 +298,9 @@ Available options:
|
|
|
296
298
|
light dismiss and closes the dialog (or rewrites `closedby="any"` to
|
|
297
299
|
`closedby="closerequest"` so the native dialog does not double-handle).
|
|
298
300
|
It never affects Escape or explicit close requests.
|
|
299
|
-
* `data-dialog-modal="false"`
|
|
301
|
+
* `data-dialog-modal="false"` makes direct `openDialog()` calls use `show()`
|
|
302
|
+
instead of `showModal()`. The `show-modal` and `--show` commands override
|
|
303
|
+
this default.
|
|
300
304
|
* `data-dialog-view-transition` enables a view transition that morphs the dialog to/from its trigger. Only active when the browser supports `document.startViewTransition` and the user allows motion.
|
|
301
305
|
* `closedby` keeps its native meaning: `"any"` closes on backdrop click and
|
|
302
306
|
Escape, `"closerequest"` closes on Escape only, `"none"` disables both. The
|
|
@@ -381,7 +385,6 @@ Keep the button a direct child of `dialog.modal` so the scrolling content
|
|
|
381
385
|
- `--dialog-viewport-gap` — distance kept between the dialog and the viewport edges.
|
|
382
386
|
- `--dialog-icon-size` — diameter of the `.dialog-icon` circle.
|
|
383
387
|
- `--dialog-icon-glyph-size` — size of the glyph centered inside `.dialog-icon`.
|
|
384
|
-
- `--
|
|
385
|
-
header reserves
|
|
386
|
-
|
|
387
|
-
- `--dialog-close-icon-size` — size of the close glyph.
|
|
388
|
+
- `--close-size` / `--close-icon-size` — size of the corner `.close` and of its
|
|
389
|
+
X. The header reserves the close size plus `--space-30` on its inline end so
|
|
390
|
+
the title never runs under it.
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
|
|
7
7
|
## Class reference
|
|
8
8
|
|
|
9
|
-
| Class
|
|
10
|
-
|
|
|
11
|
-
| `.drawer`
|
|
12
|
-
| `.
|
|
9
|
+
| Class | Kind | Description |
|
|
10
|
+
| --------- | ----------- | -------------------------------------------------------- |
|
|
11
|
+
| `.drawer` | Component | Modal side-sheet built on the native `<dialog>` element. |
|
|
12
|
+
| `.close` | Composition | Icon-only close button, at the top end. |
|
|
13
13
|
|
|
14
14
|
## Usage
|
|
15
15
|
|
|
@@ -56,7 +56,7 @@ your intended target `autofocus`; otherwise the body claims initial focus.
|
|
|
56
56
|
<strong>Menu</strong>
|
|
57
57
|
|
|
58
58
|
<form method="dialog">
|
|
59
|
-
<button class="
|
|
59
|
+
<button class="close" type="submit" aria-label="Close navigation"></button>
|
|
60
60
|
</form>
|
|
61
61
|
</header>
|
|
62
62
|
|
|
@@ -96,7 +96,7 @@ actions and the close button can close the drawer.
|
|
|
96
96
|
<form method="dialog">
|
|
97
97
|
<header>
|
|
98
98
|
<strong>Settings</strong>
|
|
99
|
-
<button class="
|
|
99
|
+
<button class="close" type="submit" aria-label="Close settings"></button>
|
|
100
100
|
</header>
|
|
101
101
|
|
|
102
102
|
<div class="stack">
|
|
@@ -123,6 +123,6 @@ useful for drawers that should not be dismissed accidentally.
|
|
|
123
123
|
|
|
124
124
|
- `--drawer-size` — panel width.
|
|
125
125
|
- `--drawer-pad` — panel padding.
|
|
126
|
-
- `--
|
|
127
|
-
reserves
|
|
128
|
-
the title never runs under
|
|
126
|
+
- `--close-size` / `--close-icon-size` — size of the corner [`.close`](close.md)
|
|
127
|
+
and of its X. The header reserves the close size plus `--space-30` on its
|
|
128
|
+
inline end so the title never runs under it.
|
|
@@ -51,7 +51,7 @@ icons. See [App Navigation](app-navigation.md).
|
|
|
51
51
|
|
|
52
52
|
For a vertical sidebar nav, use `.nav-list` inside the drawer or sidebar.
|
|
53
53
|
Links inside `.nav-list` stretch to the available inline size, providing a
|
|
54
|
-
full-row hit target for vertical navigation. The [Workspaces example](../examples/overview.md)
|
|
54
|
+
full-row hit target for vertical navigation. The [Workspaces example](../examples/overview.md#page-shapes)
|
|
55
55
|
shows the sectioned-sidebar composition: grouped `.nav-list` blocks with
|
|
56
56
|
section titles, a pinned account footer, and the native current state.
|
|
57
57
|
|
|
@@ -94,15 +94,15 @@ accessible name.
|
|
|
94
94
|
<header>
|
|
95
95
|
<strong>Menu</strong>
|
|
96
96
|
<form method="dialog">
|
|
97
|
-
<button class="
|
|
97
|
+
<button class="close" type="submit" aria-label="Close navigation"></button>
|
|
98
98
|
</form>
|
|
99
99
|
</header>
|
|
100
100
|
|
|
101
101
|
<nav>
|
|
102
102
|
<ul class="nav-list stack">
|
|
103
|
-
<li><a href="#" aria-current="page">Home</a></li>
|
|
104
|
-
<li><a href="#">Docs</a></li>
|
|
105
|
-
<li><a href="#">Components</a></li>
|
|
103
|
+
<li><a class="nav-link" href="#" aria-current="page">Home</a></li>
|
|
104
|
+
<li><a class="nav-link" href="#">Docs</a></li>
|
|
105
|
+
<li><a class="nav-link" href="#">Components</a></li>
|
|
106
106
|
</ul>
|
|
107
107
|
</nav>
|
|
108
108
|
</dialog>
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
- Use `aria-current="page"` for the current page.
|
|
8
8
|
- Put `.sm` or `.lg` on `.pagination` to scale its controls.
|
|
9
9
|
- Numeric links may use `aria-label="Page N"` for clearer screen reader output.
|
|
10
|
-
- Prefer text labels for Previous and Next. Icon-only controls need an accessible name.
|
|
11
|
-
-
|
|
10
|
+
- Prefer text labels for Previous and Next; a chevron icon may accompany them. Icon-only controls need an accessible name.
|
|
11
|
+
- Compose page links with `.btn.ghost`; `aria-current="page"` fills the current one, so it is the only boxed item.
|
|
12
12
|
- Arrows, page numbers, and truncation ellipses share one geometric system: every item gets the same minimum footprint, and wider content (100, 1000, text labels) grows past it naturally.
|
|
13
13
|
- Truncated ranges are plain text with `.muted` and `aria-hidden="true"`, not `.btn` — they are decorative, not actionable.
|
|
14
14
|
|
|
@@ -24,12 +24,12 @@
|
|
|
24
24
|
```html demo
|
|
25
25
|
<nav aria-label="Pagination">
|
|
26
26
|
<ol class="pagination sm">
|
|
27
|
-
<li><a href="?page=2" class="btn
|
|
28
|
-
<li><a href="?page=1" class="btn
|
|
29
|
-
<li><a href="?page=2" class="btn
|
|
30
|
-
<li><a href="?page=3" class="btn" aria-current="page" aria-label="Page 3">3</a></li>
|
|
31
|
-
<li><a href="?page=4" class="btn
|
|
32
|
-
<li><a href="?page=5" class="btn
|
|
27
|
+
<li><a href="?page=2" class="btn ghost" rel="prev"><i class="ti ti-chevron-left" aria-hidden="true"></i> Previous</a></li>
|
|
28
|
+
<li><a href="?page=1" class="btn ghost" aria-label="Page 1">1</a></li>
|
|
29
|
+
<li><a href="?page=2" class="btn ghost" aria-label="Page 2">2</a></li>
|
|
30
|
+
<li><a href="?page=3" class="btn ghost" aria-current="page" aria-label="Page 3">3</a></li>
|
|
31
|
+
<li><a href="?page=4" class="btn ghost" aria-label="Page 4">4</a></li>
|
|
32
|
+
<li><a href="?page=5" class="btn ghost" rel="next">Next <i class="ti ti-chevron-right" aria-hidden="true"></i></a></li>
|
|
33
33
|
</ol>
|
|
34
34
|
</nav>
|
|
35
35
|
```
|
|
@@ -42,15 +42,15 @@ buttons — they are decorative, not actionable.
|
|
|
42
42
|
```html demo
|
|
43
43
|
<nav aria-label="Pagination">
|
|
44
44
|
<ol class="pagination sm">
|
|
45
|
-
<li><a href="?page=
|
|
46
|
-
<li><a href="?page=1" class="btn
|
|
45
|
+
<li><a href="?page=7" class="btn ghost" rel="prev"><i class="ti ti-chevron-left" aria-hidden="true"></i> Previous</a></li>
|
|
46
|
+
<li><a href="?page=1" class="btn ghost" aria-label="Page 1">1</a></li>
|
|
47
47
|
<li><span class="muted" aria-hidden="true">…</span></li>
|
|
48
|
-
<li><a href="?page=7" class="btn
|
|
49
|
-
<li><a href="?page=8" class="btn" aria-current="page" aria-label="Page 8">8</a></li>
|
|
50
|
-
<li><a href="?page=9" class="btn
|
|
48
|
+
<li><a href="?page=7" class="btn ghost" aria-label="Page 7">7</a></li>
|
|
49
|
+
<li><a href="?page=8" class="btn ghost" aria-current="page" aria-label="Page 8">8</a></li>
|
|
50
|
+
<li><a href="?page=9" class="btn ghost" aria-label="Page 9">9</a></li>
|
|
51
51
|
<li><span class="muted" aria-hidden="true">…</span></li>
|
|
52
|
-
<li><a href="?page=20" class="btn
|
|
53
|
-
<li><a href="?page=9" class="btn
|
|
52
|
+
<li><a href="?page=20" class="btn ghost" aria-label="Page 20">20</a></li>
|
|
53
|
+
<li><a href="?page=9" class="btn ghost" rel="next">Next <i class="ti ti-chevron-right" aria-hidden="true"></i></a></li>
|
|
54
54
|
</ol>
|
|
55
55
|
</nav>
|
|
56
56
|
```
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Shimmer
|
|
2
|
+
|
|
3
|
+
> **Module** — import `actual-css/css/effects/shimmer` or `actual-css/css/effects`.
|
|
4
|
+
|
|
5
|
+
Shimmer sweeps a highlight across a text label to show an activity in
|
|
6
|
+
progress: an agent working, a chatbot composing, a job processing.
|
|
7
|
+
|
|
8
|
+
```html demo
|
|
9
|
+
<div class="stack">
|
|
10
|
+
<span class="shimmer" role="status">Working…</span>
|
|
11
|
+
<p class="cluster">
|
|
12
|
+
<span class="spinner" aria-hidden="true"></span>
|
|
13
|
+
<span class="shimmer" role="status">Generating the report…</span>
|
|
14
|
+
</p>
|
|
15
|
+
</div>
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**Related terms:** shimmering text, loading text, thinking indicator, pending
|
|
19
|
+
label, typing indicator.
|
|
20
|
+
|
|
21
|
+
Shimmer is presentation only and selects no ARIA attribute. Put
|
|
22
|
+
`role="status"` on a message that should be announced, and `aria-busy="true"`
|
|
23
|
+
on the region whose content is being updated — not on the message because it
|
|
24
|
+
looks busy. Assistive technology may hold back changes inside a busy region
|
|
25
|
+
until it is released.
|
|
26
|
+
|
|
27
|
+
The label rests on `--shimmer-color` and the band passes in
|
|
28
|
+
`--shimmer-highlight`; one pass takes `--duration-shimmer`, the pace shared
|
|
29
|
+
with `.skeleton` and indeterminate `.progress`. With reduced motion, or in a
|
|
30
|
+
browser without `background-clip: text`, the label is plain
|
|
31
|
+
`--shimmer-color` text. Recolor a label through these hooks: its own `color`
|
|
32
|
+
shows only where the sweep does not run.
|
|
33
|
+
|
|
34
|
+
## Choosing a waiting signal
|
|
35
|
+
|
|
36
|
+
| Primitive | Signals |
|
|
37
|
+
| -------------------------- | -------------------------------------------- |
|
|
38
|
+
| [`.spinner`](spinner.md) | An operation takes time |
|
|
39
|
+
| [`.skeleton`](skeleton.md) | Content is not available yet |
|
|
40
|
+
| `.shimmer` | This label describes an activity in progress |
|
|
41
|
+
| [`.aura`](aura.md) | This object is emphasized |
|
|
42
|
+
|
|
43
|
+
They compose rather than imply one another: `aria-busy` never adds an aura or
|
|
44
|
+
a shimmer. A card being processed can carry several, each for its own reason:
|
|
45
|
+
|
|
46
|
+
```html demo
|
|
47
|
+
<span class="aura primary">
|
|
48
|
+
<article class="card stack" style="inline-size: 18rem">
|
|
49
|
+
<p><strong>Quarterly import</strong></p>
|
|
50
|
+
<p class="shimmer" role="status">Processing 1,204 rows…</p>
|
|
51
|
+
<div class="stack" aria-busy="true">
|
|
52
|
+
<div class="skeleton" data-shape="text" aria-hidden="true"></div>
|
|
53
|
+
<div class="skeleton" data-shape="text" aria-hidden="true"></div>
|
|
54
|
+
</div>
|
|
55
|
+
</article>
|
|
56
|
+
</span>
|
|
57
|
+
```
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
- Use layout utilities for placeholder arrangement.
|
|
9
9
|
- Only relevant for simple placeholders - use more structural solutions like phantom-ui for complex cases.
|
|
10
10
|
|
|
11
|
-
**Related terms:** skeleton screen, shimmer, loading placeholder.
|
|
11
|
+
**Related terms:** skeleton screen, shimmer, loading placeholder. For a text
|
|
12
|
+
label showing an activity in progress, see [Shimmer](shimmer.md).
|
|
12
13
|
|
|
13
14
|
## Class reference
|
|
14
15
|
|
|
@@ -12,11 +12,15 @@
|
|
|
12
12
|
|
|
13
13
|
## Class reference
|
|
14
14
|
|
|
15
|
-
| Class
|
|
16
|
-
|
|
|
17
|
-
| `.spinner`
|
|
18
|
-
|
|
|
19
|
-
|
|
|
15
|
+
| Class | Kind | Description |
|
|
16
|
+
| -------------------- | --------- | ------------------------------------------------ |
|
|
17
|
+
| `.spinner` | Component | Circular loading indicator using `currentColor`. |
|
|
18
|
+
| `[aria-busy="true"]` | State | Loading region; see Busy state below. |
|
|
19
|
+
| `.sm` / `.lg` | Size | Smaller (`0.75em`) or larger (`2rem`) spinner. |
|
|
20
|
+
| Shared intents | Intent | `.primary`, `.secondary`, `.success`, … |
|
|
21
|
+
|
|
22
|
+
The shared intents are `.primary`, `.secondary`, `.success`, `.warning` and
|
|
23
|
+
`.danger`.
|
|
20
24
|
|
|
21
25
|
## Basic usage
|
|
22
26
|
|
|
@@ -68,13 +72,14 @@ Size follows the font (`1em`); use `.sm` / `.lg` rather than sizing it directly.
|
|
|
68
72
|
|
|
69
73
|
## Busy state
|
|
70
74
|
|
|
71
|
-
|
|
75
|
+
The spinner is the indicator; `aria-busy` is the state. A container-wide
|
|
76
|
+
loading state keeps the underlying content in place. It is
|
|
72
77
|
driven by `aria-busy="true"` plus a direct last-child `.spinner` — there is no
|
|
73
78
|
separate `.busy` class. The spinner is shown as a centered overlay over a faded
|
|
74
79
|
surface; buttons keep their spinners inline instead (see Button).
|
|
75
80
|
|
|
76
81
|
- Set `aria-busy="true"` on the container and add `<span class="spinner" aria-hidden="true"></span>` as its last direct child.
|
|
77
|
-
- The overlay uses `--busy-overlay-bg`;
|
|
82
|
+
- The overlay uses `--busy-overlay-bg`; a card derives it from its own surface.
|
|
78
83
|
- Decorative spinners stay `aria-hidden="true"`; announce progress on the region with `role="status"` and a label when needed.
|
|
79
84
|
|
|
80
85
|
```html demo
|
|
@@ -89,5 +94,5 @@ surface; buttons keep their spinners inline instead (see Button).
|
|
|
89
94
|
|
|
90
95
|
- `--spinner-track` — the ring color.
|
|
91
96
|
- `--spinner-value` — the moving gap; swap the two for an inverted spinner.
|
|
92
|
-
- `--busy-overlay-bg` — background of the busy overlay.
|
|
93
|
-
|
|
97
|
+
- `--busy-overlay-bg` — background of the busy overlay. Set it on a surface you
|
|
98
|
+
paint yourself so the overlay blends with that surface.
|
|
@@ -124,6 +124,19 @@ same vocabulary as `.card.compact`.
|
|
|
124
124
|
</div>
|
|
125
125
|
```
|
|
126
126
|
|
|
127
|
+
## When a table stops reading as a table
|
|
128
|
+
|
|
129
|
+
Responsive strategy is horizontal overflow: the wrap scrolls, the table keeps
|
|
130
|
+
its columns and its column scanability. No `data-label` restructuring, no
|
|
131
|
+
second representation of the data.
|
|
132
|
+
|
|
133
|
+
For datasets that no longer read well as a table on narrow screens, compose a
|
|
134
|
+
different view instead of restructuring the table: a `.list` / `.media` row
|
|
135
|
+
with badges and actions for a CRUD collection, [`.data-list`](data-list.md)
|
|
136
|
+
for one object's properties, or a dedicated data grid for interactive tables
|
|
137
|
+
(sorting, filtering, selection). Two views for two contexts is a feature, not
|
|
138
|
+
a duplication.
|
|
139
|
+
|
|
127
140
|
## CSS hooks
|
|
128
141
|
|
|
129
142
|
- `--table-cell-pad` — cell padding; `.compact` re-declares it tighter.
|
|
@@ -522,6 +522,8 @@ delay; a number sets the delay in milliseconds.
|
|
|
522
522
|
|
|
523
523
|
The repetition is the point: the two hooks are different contracts, and only
|
|
524
524
|
the cap may enter the runtime's `min()`.
|
|
525
|
+
- `--flyout-pad` — panel padding. Defaults to `var(--space-10)`, tight for
|
|
526
|
+
action menus; rich panels opt into dialog air per instance.
|
|
525
527
|
- `--menu-item-size` — minimum row height of `.menu-item`.
|
|
526
528
|
- `--menu-item-icon-size` — shared leading-column width for icons and checked-state indicators.
|
|
527
529
|
|
|
@@ -53,6 +53,11 @@ Enhancer modules self-register when imported. They do not require init calls and
|
|
|
53
53
|
are safe to import during server-side rendering: outside a browser, registration
|
|
54
54
|
is a no-op until the module is loaded again with a DOM.
|
|
55
55
|
|
|
56
|
+
Load the full bundle **or** the source modules, never both: each evaluation
|
|
57
|
+
owns its registry and document handlers, so a dist bundle mixed with
|
|
58
|
+
`actual-css/js/*` source subpaths (or two dist bundles) registers every
|
|
59
|
+
behavior twice and a flyout opens then immediately closes.
|
|
60
|
+
|
|
56
61
|
## Component pages
|
|
57
62
|
|
|
58
63
|
Each interactive component has its own page documenting the exact markup its
|
|
@@ -22,6 +22,10 @@
|
|
|
22
22
|
- JavaScript owns roving `tabindex`, `aria-selected`, `hidden`, and keyboard behavior.
|
|
23
23
|
- Left/Right select tabs and wrap at the ends. Home/End jump to first/last. Down moves focus into the selected panel.
|
|
24
24
|
- A tab list needs both `.tabs` and `role="tablist"`; `.tab` styles each trigger.
|
|
25
|
+
- Naming follows the container/item convention (like `menu` / `menu-item`):
|
|
26
|
+
`.tabs` is the strip, `.tab` is one trigger. The JS module
|
|
27
|
+
(`actual-css/js/tab`) is named for the file; the behavior token
|
|
28
|
+
(`data-enhance="tabs"`) is named for what it wires.
|
|
25
29
|
- A `.tab` with an icon uses `--tab-gap` (default `0.375em`) for the space between icon and label.
|
|
26
30
|
- A tab that is `hidden`, `disabled`, `aria-disabled`, or has no panel is skipped
|
|
27
31
|
by the arrow keys. An application filtering a tab strip only has to set
|