actual-css 0.6.0 → 0.8.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 +214 -1
- package/README.md +13 -11
- package/components.json +668 -0
- package/dist/actual.css +166 -37
- package/dist/actual.full.css +1005 -550
- package/dist/actual.full.js +1 -1
- package/dist/actual.full.min.css +1 -1
- package/dist/actual.js +1 -1
- package/dist/actual.min.css +1 -1
- package/docs/design-notes/accessibility-decisions.md +33 -0
- package/docs/design-notes/browser-support.md +82 -25
- package/docs/design-notes/column-layout.md +3 -3
- package/docs/design-notes/css-anchor.md +75 -21
- package/docs/design-notes/enhancement-contract.md +14 -6
- package/docs/design-notes/grid.md +4 -4
- package/docs/design-notes/naming.md +6 -1
- package/docs/design-notes/platform-alignment.md +99 -2
- package/docs/design-notes/popover-manual-poc.md +328 -0
- package/docs/design-notes/surface-reparenting.md +131 -0
- package/docs/design-notes/tooltip-coordinate-space.md +132 -0
- package/docs/design-notes/widget-primitives.md +9 -6
- package/docs/pages/components/accordion.md +41 -2
- package/docs/pages/components/alert.md +80 -30
- package/docs/pages/components/app-navigation.md +6 -0
- package/docs/pages/components/avatar.md +6 -6
- package/docs/pages/components/badge.md +101 -16
- package/docs/pages/components/button.md +16 -8
- package/docs/pages/components/card.md +10 -10
- package/docs/pages/components/dialog.md +16 -6
- package/docs/pages/components/fab.md +4 -3
- package/docs/pages/components/list.md +42 -4
- package/docs/pages/components/navbar.md +17 -1
- package/docs/pages/components/pagination.md +2 -2
- package/docs/pages/components/steps.md +19 -0
- package/docs/pages/components/table.md +3 -2
- package/docs/pages/enhancements/flyout.md +144 -24
- package/docs/pages/enhancements/overview.md +25 -0
- package/docs/pages/enhancements/status-bar.md +20 -0
- package/docs/pages/enhancements/tabs.md +45 -37
- package/docs/pages/enhancements/tooltip.md +40 -2
- package/docs/pages/examples/overview.md +38 -5
- package/docs/pages/forms/choice-cards.md +6 -2
- package/docs/pages/forms/combobox.md +1 -1
- package/docs/pages/forms/floating-field.md +4 -3
- package/docs/pages/forms/joined-controls.md +22 -0
- package/docs/pages/forms/otp.md +2 -1
- package/docs/pages/forms/overview.md +1 -1
- package/docs/pages/forms/states-and-sizes.md +16 -18
- package/docs/pages/forms/sticky-actions.md +2 -2
- package/docs/pages/forms/switch.md +1 -1
- package/docs/pages/foundations/philosophy.md +67 -22
- package/docs/pages/foundations/theming.md +10 -2
- package/docs/pages/foundations/tokens.md +118 -21
- package/docs/pages/foundations/typography.md +35 -14
- package/docs/pages/guides/introduction.md +11 -9
- package/docs/pages/guides/progressive-enhancement.md +136 -49
- package/docs/pages/guides/tailwind.md +3 -2
- package/docs/pages/layout/media.md +1 -1
- package/docs/pages/layout/overview.md +11 -1
- package/docs/pages/layout/scroll-snap.md +3 -3
- package/docs/pages/layout/stack.md +17 -9
- package/docs/pages/patterns/icon-input.md +4 -2
- package/docs/pages/patterns/icon-slot.md +2 -0
- package/docs/pages/patterns/intent-nesting.md +1 -1
- package/docs/pages/utilities/overview.md +23 -2
- package/docs/pages/utilities/sizing-wrapping.md +1 -1
- package/docs/pages/utilities/spacing.md +10 -8
- package/llms.txt +2 -1
- package/package.json +19 -8
- package/{scripts/reserved-classes.json → reserved-classes.json} +4 -6
- package/src/css/components/accordion.css +42 -3
- package/src/css/components/alert.css +25 -13
- package/src/css/components/app-nav.css +18 -8
- package/src/css/components/avatar.css +13 -1
- package/src/css/components/badge.css +78 -12
- package/src/css/components/breadcrumb.css +2 -3
- package/src/css/components/button.css +9 -16
- package/src/css/components/card.css +9 -2
- package/src/css/components/chat.css +1 -0
- package/src/css/components/data-list.css +1 -1
- package/src/css/components/drawer.css +79 -25
- package/src/css/components/fab.css +0 -6
- package/src/css/components/flyout.css +46 -63
- package/src/css/components/index.css +0 -1
- package/src/css/components/indicator.css +21 -0
- package/src/css/components/join.css +7 -0
- package/src/css/components/key.css +10 -0
- package/src/css/components/list.css +40 -4
- package/src/css/components/menu.css +18 -11
- package/src/css/components/modal.css +48 -33
- package/src/css/components/navbar.css +37 -4
- package/src/css/components/pagination.css +1 -0
- package/src/css/components/spinner.css +6 -6
- package/src/css/components/status-bar.css +0 -5
- package/src/css/components/steps.css +45 -59
- package/src/css/components/tab.css +29 -9
- package/src/css/components/table.css +5 -5
- package/src/css/components/tooltip.css +45 -13
- package/src/css/core/base.css +23 -1
- package/src/css/core/intents.css +17 -6
- package/src/css/core/theme.css +27 -0
- package/src/css/core/tokens.css +35 -15
- package/src/css/core/variants.css +64 -15
- package/src/css/forms/choice-card.css +4 -4
- package/src/css/forms/choice.css +6 -3
- package/src/css/forms/control.css +2 -1
- package/src/css/forms/floating-field.css +3 -3
- package/src/css/forms/form.css +4 -3
- package/src/css/forms/input-icon.css +20 -14
- package/src/css/forms/native.css +6 -1
- package/src/css/forms/otp.css +9 -1
- package/src/css/forms/range.css +2 -0
- package/src/css/forms/select.css +29 -9
- package/src/css/forms/switch.css +19 -5
- package/src/css/layout/app-layout.css +1 -1
- package/src/css/layout/grid.css +50 -76
- package/src/css/layout/scroll-snap.css +11 -7
- package/src/css/layout/scroller.css +3 -4
- package/src/css/layout/stack.css +2 -2
- package/src/css/typography/fluid.css +4 -3
- package/src/css/typography/prose.css +6 -5
- package/src/css/utilities/base.css +2 -1
- package/src/css/utilities/extra.css +20 -17
- package/src/js/context-menu.js +27 -26
- package/src/js/dialog.js +2 -1
- package/src/js/dismiss.js +5 -0
- package/src/js/enhance.js +34 -2
- package/src/js/enhancement-loader.js +36 -43
- package/src/js/events.js +0 -3
- package/src/js/filter.js +0 -1
- package/src/js/floating-space.js +42 -0
- package/src/js/flyout.js +9 -44
- package/src/js/focus-group.js +7 -0
- package/src/js/focus.js +6 -0
- package/src/js/menu.js +10 -1
- package/src/js/selectors.js +5 -9
- package/src/js/status.js +44 -7
- package/src/js/surface.js +106 -132
- package/src/js/tab.js +6 -1
- package/src/js/tooltip.js +152 -53
- package/src/js/validation.js +1 -1
- package/src/css/components/surface.css +0 -49
- package/src/js/floating.js +0 -432
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
- Use native `<details>` and `<summary>` for collapsible content.
|
|
6
6
|
- Use the `name` attribute for exclusive accordions.
|
|
7
7
|
- Supports any valid body element (`div`, `p`, `ul`, ...).
|
|
8
|
-
-
|
|
8
|
+
- Three container treatments: the default common shell, `.flush` (bare separators, for embedding inside an existing surface), and `.separated` (independent items).
|
|
9
|
+
- The toggle marker color is customizable with `--accordion-marker-color`; it reinforces to the summary text color on hover, and the marker icon comes from the shared `--icon-chevron` token.
|
|
9
10
|
|
|
10
11
|
```html demo
|
|
11
12
|
<div class="accordion">
|
|
@@ -34,6 +35,44 @@
|
|
|
34
35
|
</div>
|
|
35
36
|
```
|
|
36
37
|
|
|
38
|
+
## Variants
|
|
39
|
+
|
|
40
|
+
The default builds one raised shell around the whole group. `.flush` and `.separated` only change that chrome — they are integration modes between the component and its container, not decorative skins.
|
|
41
|
+
|
|
42
|
+
- **`flush`** — the ambient box disappears and only the item separators remain, so the group sits edge to edge inside a surface that already exists: a card, a drawer, a page section. A FAQ list without a box inside a box.
|
|
43
|
+
|
|
44
|
+
```html demo
|
|
45
|
+
<div class="accordion flush">
|
|
46
|
+
<details open>
|
|
47
|
+
<summary>Flush keeps just the separators</summary>
|
|
48
|
+
<p>No shell: embed the group in a card, drawer, or page section.</p>
|
|
49
|
+
</details>
|
|
50
|
+
|
|
51
|
+
<details>
|
|
52
|
+
<summary>Edge to edge</summary>
|
|
53
|
+
<p>The summary and panel follow the surrounding surface's own gutter.</p>
|
|
54
|
+
</details>
|
|
55
|
+
</div>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
- **`separated`** — each `<details>` becomes its own card, for groups of standalone items.
|
|
59
|
+
|
|
60
|
+
```html demo
|
|
61
|
+
<div class="accordion separated">
|
|
62
|
+
<details open>
|
|
63
|
+
<summary>Each item is its own card</summary>
|
|
64
|
+
<p>Standalone items share the same gap, border, radius, and raised surface.</p>
|
|
65
|
+
</details>
|
|
66
|
+
|
|
67
|
+
<details>
|
|
68
|
+
<summary>Still native details</summary>
|
|
69
|
+
<p>Exclusive <code>name</code> groups and per-item icons work exactly as in the base component.</p>
|
|
70
|
+
</details>
|
|
71
|
+
</div>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The accordion owns its disclosure marker; the trigger content belongs to the markup. Item accents, per-item shadows, an underlined trigger label, and alternative markers stay application recipes, not framework variants.
|
|
75
|
+
|
|
37
76
|
## Exclusive groups
|
|
38
77
|
|
|
39
78
|
```html demo
|
|
@@ -77,4 +116,4 @@ The end marker is a shared token-based chevron; swapping it for a local icon is
|
|
|
77
116
|
## CSS hooks
|
|
78
117
|
|
|
79
118
|
- `--accordion-radius` — outer corner radius.
|
|
80
|
-
- `--accordion-marker-color` — color of the end marker; forced-colors mode overrides it to `CanvasText`.
|
|
119
|
+
- `--accordion-marker-color` — color of the end marker; it reinforces to the summary text color on hover, and forced-colors mode overrides it to `CanvasText`.
|
|
@@ -5,13 +5,14 @@
|
|
|
5
5
|
- Supports intent colors.
|
|
6
6
|
- Supports longer text and lists.
|
|
7
7
|
- Links inherit alert color by default.
|
|
8
|
-
- Alerts are soft by default. Use `.solid` or `.outline` when the message needs stronger or quieter emphasis.
|
|
8
|
+
- Alerts are soft by default. Use `.surface` for neutral chrome with the intent only in the ink, `.solid` or `.outline` when the message needs stronger or quieter emphasis, and `.inverted` for an inverse surface.
|
|
9
9
|
- Use `<menu class="actions cluster">` for alert action lists.
|
|
10
10
|
- Use `role="alert"` only when the alert is injected dynamically and should be announced.
|
|
11
11
|
- Not a toast.
|
|
12
12
|
- Could have simple or complex html content.
|
|
13
|
+
- A title and a description are plain siblings: the alert owns the small space between its direct content blocks, so neither needs a wrapper. Nested content keeps its own rhythm — wrap several paragraphs in `.prose`, or a differently spaced group in `.stack`, when the message needs a rhythm of its own.
|
|
13
14
|
- Alerts may include a decorative leading icon. Use `.alert-icon` on the icon element; the rest of the content flows into the remaining text column.
|
|
14
|
-
- Use `.
|
|
15
|
+
- Use `.compact` or `.spacious` for density changes. The inline padding stays stable.
|
|
15
16
|
- Use `.alert-dismiss` for a compact dismiss button. It is a direct trailing child in standard alerts and lives inside `.alert-title` in admonitions. It uses the shared `--icon-close` mask and the `--dismiss` runtime command — no icon font or custom JS.
|
|
16
17
|
|
|
17
18
|
Because alerts are soft by default, adding `.soft` to an intent (`.alert.soft.primary`,
|
|
@@ -21,26 +22,33 @@ itself needs to change, not `.soft`.
|
|
|
21
22
|
|
|
22
23
|
## Class reference
|
|
23
24
|
|
|
24
|
-
| Class | Kind | Description
|
|
25
|
-
| ---------------- | ----------- |
|
|
26
|
-
| `.alert` | Component | Inline status surface; soft by default.
|
|
27
|
-
| `.alert-icon` | Composition | Decorative leading icon, in the first column.
|
|
28
|
-
| `.alert-dismiss` | Modifier | Compact dismiss button.
|
|
29
|
-
| `.
|
|
30
|
-
| `.
|
|
31
|
-
|
|
32
|
-
`.
|
|
33
|
-
|
|
34
|
-
|
|
|
35
|
-
| `.
|
|
36
|
-
|
|
|
37
|
-
| Shared variants | Variant | `.solid`, `.outline`, and `.surface` emphasis. |
|
|
38
|
-
| `.sm` / `.lg` | Size | Density; inline padding stays stable. |
|
|
25
|
+
| Class | Kind | Description |
|
|
26
|
+
| ---------------- | ----------- | ----------------------------------------------- |
|
|
27
|
+
| `.alert` | Component | Inline status surface; soft by default. |
|
|
28
|
+
| `.alert-icon` | Composition | Decorative leading icon, in the first column. |
|
|
29
|
+
| `.alert-dismiss` | Modifier | Compact dismiss button. |
|
|
30
|
+
| `.alert-title` | Composition | Admonition title bar; hosts the dismiss button. |
|
|
31
|
+
| `.alert-body` | Composition | Admonition body on the page surface. |
|
|
32
|
+
| `.callout` | Variant | Leading-edge flag; owns the border geometry. |
|
|
33
|
+
| `.admonition` | Variant | Tinted title bar, body on the page surface. |
|
|
34
|
+
| Shared intents | Intent | `.primary`, `.secondary`, `.success`, … |
|
|
35
|
+
| Shared variants | Variant | `.solid`, `.outline`, `.surface`. |
|
|
36
|
+
| `.inverted` | Surface | Inverse surface, any intent. |
|
|
37
|
+
| Density contexts | Density | Descendant rhythm; inline padding stays stable. |
|
|
39
38
|
|
|
40
39
|
## Basic usage
|
|
41
40
|
|
|
41
|
+
`.surface` comes first on purpose: it keeps the theme's own chrome and puts the
|
|
42
|
+
intent in the ink alone, which is what most informational messages want. Add an
|
|
43
|
+
intent treatment when the color itself carries the meaning.
|
|
44
|
+
|
|
42
45
|
```html demo
|
|
43
46
|
<div class="stack">
|
|
47
|
+
<div class="alert surface">
|
|
48
|
+
<i class="ti ti-info-circle alert-icon" aria-hidden="true"></i>
|
|
49
|
+
<div><strong>New message.</strong> 12 unread. <a href="#">Open inbox</a>.</div>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
44
52
|
<div class="alert success">
|
|
45
53
|
<i class="ti ti-circle-check alert-icon" aria-hidden="true"></i>
|
|
46
54
|
<div>Your changes have been saved. <a href="#">View activity</a>.</div>
|
|
@@ -91,16 +99,41 @@ itself needs to change, not `.soft`.
|
|
|
91
99
|
</div>
|
|
92
100
|
```
|
|
93
101
|
|
|
102
|
+
## Trailing action
|
|
103
|
+
|
|
104
|
+
The grid pins `.alert-icon` and `.alert-dismiss` to the outer columns. A
|
|
105
|
+
trailing link or button is content, not anatomy, so it lives in the text column:
|
|
106
|
+
wrap the row in a `.cluster` and push the two ends apart. Same recipe as any
|
|
107
|
+
split / spread row — there is no `.alert-action` class.
|
|
108
|
+
|
|
109
|
+
```html demo
|
|
110
|
+
<div class="alert surface">
|
|
111
|
+
<i class="ti ti-info-circle alert-icon" aria-hidden="true"></i>
|
|
112
|
+
<div class="cluster justify-content-space-between">
|
|
113
|
+
<strong>New message!</strong>
|
|
114
|
+
<a class="btn sm outline" href="#">Open</a>
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
```
|
|
118
|
+
|
|
94
119
|
## Variants
|
|
95
120
|
|
|
96
121
|
```html demo
|
|
97
122
|
<div class="stack">
|
|
98
|
-
<div class="alert
|
|
99
|
-
I'm a
|
|
123
|
+
<div class="alert surface" role="alert">
|
|
124
|
+
I'm a surface alert — theme chrome, intent in the ink
|
|
125
|
+
</div>
|
|
126
|
+
|
|
127
|
+
<div class="alert inverted" role="alert">
|
|
128
|
+
I'm an inverted alert <a href="#">with a link</a>
|
|
100
129
|
</div>
|
|
101
130
|
|
|
102
|
-
<div class="alert danger
|
|
103
|
-
I'm a
|
|
131
|
+
<div class="alert danger compact" role="alert">
|
|
132
|
+
I'm an error in a compact context
|
|
133
|
+
</div>
|
|
134
|
+
|
|
135
|
+
<div class="alert danger spacious" role="alert">
|
|
136
|
+
I'm an error in a spacious context
|
|
104
137
|
</div>
|
|
105
138
|
|
|
106
139
|
<div class="alert danger outline" role="alert">
|
|
@@ -120,11 +153,8 @@ Use `.alert-dismiss` to let a user remove an inline alert. The button is transpa
|
|
|
120
153
|
```html demo
|
|
121
154
|
<div class="alert warning" id="warning-alert">
|
|
122
155
|
<i class="ti ti-alert-triangle alert-icon" aria-hidden="true"></i>
|
|
123
|
-
|
|
124
|
-
<
|
|
125
|
-
<strong>Warning</strong>
|
|
126
|
-
<p>Something needs your attention.</p>
|
|
127
|
-
</div>
|
|
156
|
+
<strong>Warning</strong>
|
|
157
|
+
<p>Something needs your attention.</p>
|
|
128
158
|
|
|
129
159
|
<button
|
|
130
160
|
class="alert-dismiss"
|
|
@@ -156,22 +186,42 @@ In an admonition, place `.alert-dismiss` inside `.alert-title`; it rides the inl
|
|
|
156
186
|
|
|
157
187
|
## Callout
|
|
158
188
|
|
|
159
|
-
|
|
189
|
+
`.callout` is a **leading-edge flag treatment**: it owns the border geometry and
|
|
190
|
+
nothing else, so the surface and the ink keep coming from the alert's own intent
|
|
191
|
+
and treatment. Bare is the soft panel, `.surface` the page surface, `.solid` a
|
|
192
|
+
filled one — and `.outline` has no fill and no other side, since the flag *is*
|
|
193
|
+
the border.
|
|
160
194
|
|
|
161
195
|
```html demo
|
|
162
196
|
<div class="stack">
|
|
163
197
|
<div class="alert callout">
|
|
164
198
|
<strong>Note</strong>
|
|
165
|
-
<p>
|
|
199
|
+
<p>A neutral panel with a thick accent flag on the leading edge.</p>
|
|
166
200
|
</div>
|
|
167
201
|
|
|
168
202
|
<div class="alert warning callout" role="alert">
|
|
169
203
|
<strong>Heads up</strong>
|
|
170
|
-
<p>The
|
|
204
|
+
<p>The intent tints the panel and the flag together.</p>
|
|
205
|
+
</div>
|
|
206
|
+
|
|
207
|
+
<div class="alert success callout surface">
|
|
208
|
+
<strong>On the page surface</strong>
|
|
209
|
+
<p>The flag keeps the intent, the panel drops the tint.</p>
|
|
171
210
|
</div>
|
|
172
211
|
</div>
|
|
173
212
|
```
|
|
174
213
|
|
|
214
|
+
Tune the flag with `--alert-border-inline-start-width` and
|
|
215
|
+
`--alert-border-inline-start-color`; `--alert-radius: 0` turns it into a
|
|
216
|
+
full-bleed notice.
|
|
217
|
+
|
|
218
|
+
```html demo
|
|
219
|
+
<div class="alert danger callout" style="--alert-radius: 0">
|
|
220
|
+
<i class="ti ti-user-x alert-icon" aria-hidden="true"></i>
|
|
221
|
+
<div>Your request to join the team is denied.</div>
|
|
222
|
+
</div>
|
|
223
|
+
```
|
|
224
|
+
|
|
175
225
|
## Admonition
|
|
176
226
|
|
|
177
227
|
An admonition is a structured box with a tinted title bar, an optional icon, and body content on the page surface — like the `!!! note` callouts in mkdocs. Use `.alert-title` for the header and `.alert-body` for the content. Intent classes tint the title bar background and the border.
|
|
@@ -202,7 +252,7 @@ An admonition is a structured box with a tinted title bar, an optional icon, and
|
|
|
202
252
|
|
|
203
253
|
## CSS hooks
|
|
204
254
|
|
|
205
|
-
- `--alert-pad-inline` — inline padding. Stays stable across
|
|
255
|
+
- `--alert-pad-inline` — inline padding. Stays stable across density contexts.
|
|
206
256
|
- `--alert-pad-block` — block padding.
|
|
207
257
|
- `--alert-font-size` — base font size.
|
|
208
258
|
- `--alert-icon-size` — size of a leading `.alert-icon`.
|
|
@@ -5,6 +5,12 @@
|
|
|
5
5
|
Use one `.app-nav` landmark for the application's primary destinations. Links
|
|
6
6
|
remain links, and `aria-current="page"` is the only current-page state.
|
|
7
7
|
|
|
8
|
+
Reach for `.app-nav` only as part of a persistent application shell: it exists
|
|
9
|
+
as a direct child of `.app-layout`, which turns the landmark from a bottom bar
|
|
10
|
+
into side navigation. A site or webapp header with normal scrolling stays
|
|
11
|
+
`.navbar` — `.app-nav` is not a stacked-icon variant of the horizontal bar. See
|
|
12
|
+
[Navbar](navbar.md).
|
|
13
|
+
|
|
8
14
|
**Related terms:** tab bar, bottom navigation, bottom nav, navigation rail, side navigation.
|
|
9
15
|
|
|
10
16
|
```html demo
|
|
@@ -12,12 +12,12 @@
|
|
|
12
12
|
|
|
13
13
|
## Class reference
|
|
14
14
|
|
|
15
|
-
| Class | Kind | Description
|
|
16
|
-
| --------------- | ----------- |
|
|
17
|
-
| `.avatar` | Component | Initials or image in a circular box.
|
|
18
|
-
| `.avatar-stack` | Composition | Overlapping avatar group.
|
|
19
|
-
| `.badge:empty` | Composition | Status dot, at the bottom-end corner.
|
|
20
|
-
| `.sm` / `.lg` | Size |
|
|
15
|
+
| Class | Kind | Description |
|
|
16
|
+
| --------------- | ----------- | -------------------------------------------- |
|
|
17
|
+
| `.avatar` | Component | Initials or image in a circular box. |
|
|
18
|
+
| `.avatar-stack` | Composition | Overlapping avatar group. |
|
|
19
|
+
| `.badge:empty` | Composition | Status dot, at the bottom-end corner. |
|
|
20
|
+
| `.sm` / `.lg` | Size | Optical size; also rescales `.avatar-stack`. |
|
|
21
21
|
|
|
22
22
|
`.avatar` works on `div`, `a` and `button`. The status dot is an empty
|
|
23
23
|
`.badge` inside an `.avatar`, and needs an `aria-label` of its own.
|
|
@@ -4,17 +4,18 @@
|
|
|
4
4
|
|
|
5
5
|
- Supports intent colors.
|
|
6
6
|
- Soft by default. Use `.solid` for counters and notification badges, or `.outline` for quieter emphasis.
|
|
7
|
-
-
|
|
8
|
-
- Use `.sm` or `.lg`
|
|
7
|
+
- Empty badges are solid status dots: visual variants such as `.soft` and `.outline` do not change their fill.
|
|
8
|
+
- Use `.sm` or `.lg` to scale the badge locally.
|
|
9
|
+
- Use `.compact` or `.spacious` on a context to change geometry without changing the label or icon size.
|
|
9
10
|
- Can be used inline in headings.
|
|
10
11
|
- Can be used as a count badge.
|
|
11
12
|
- Can be used as a stable dot badge when empty and given an accessible name.
|
|
12
13
|
- Empty badges render as dots. The element must be truly empty: no text and no whitespace.
|
|
13
14
|
|
|
14
15
|
A badge is **content-sized**: it never stretches to fill its container, even as a
|
|
15
|
-
direct child of `.stack` (where flex children otherwise stretch)
|
|
16
|
-
`inline-size: 100%` — or the
|
|
17
|
-
full-width badge is intentional.
|
|
16
|
+
direct child of `.stack` (where flex children otherwise stretch), and a flex
|
|
17
|
+
parent never compresses it (`flex: none`). Use `inline-size: 100%` — or the
|
|
18
|
+
optional `.inline-size-full` utility — when a full-width badge is intentional.
|
|
18
19
|
|
|
19
20
|
**Related terms:** chip, tag, pill, removable tag.
|
|
20
21
|
|
|
@@ -24,9 +25,10 @@ full-width badge is intentional.
|
|
|
24
25
|
| --------------- | ----------- | ----------------------------------------- |
|
|
25
26
|
| `.badge` | Component | Compact label; soft by default. |
|
|
26
27
|
| `.badge:empty` | Composition | Truly-empty badge renders as a solid dot. |
|
|
28
|
+
| `.dot` | Composition | Status dot inside a badge. |
|
|
27
29
|
| Shared intents | Intent | `.primary`, `.secondary`, `.success`, … |
|
|
28
30
|
| Shared variants | Variant | `.solid`, `.outline`, `.surface`. |
|
|
29
|
-
| `.sm` / `.lg` | Size |
|
|
31
|
+
| `.sm` / `.lg` | Size | Smaller or larger optical scale. |
|
|
30
32
|
|
|
31
33
|
The shared intents are `.primary`, `.secondary`, `.success`, `.warning` and
|
|
32
34
|
`.danger`. The variants set emphasis: `.solid` is filled, `.outline` bordered,
|
|
@@ -42,6 +44,9 @@ The shared intents are `.primary`, `.secondary`, `.success`, `.warning` and
|
|
|
42
44
|
<span class="badge danger">Danger</span>
|
|
43
45
|
<span class="badge success outline">Outline success</span>
|
|
44
46
|
<span class="badge warning soft">Soft warning</span>
|
|
47
|
+
<span class="badge primary solid">Solid primary</span>
|
|
48
|
+
<span class="badge success solid">Solid success</span>
|
|
49
|
+
<span class="badge danger solid">Solid danger</span>
|
|
45
50
|
```
|
|
46
51
|
|
|
47
52
|
## In a title
|
|
@@ -73,6 +78,29 @@ The shared intents are `.primary`, `.secondary`, `.success`, `.warning` and
|
|
|
73
78
|
An autonomous dot conveys state without visible text, so give it an accessible
|
|
74
79
|
name.
|
|
75
80
|
|
|
81
|
+
For a dot beside a label, put the shared `.dot` utility inside the badge. It
|
|
82
|
+
paints with `currentColor`, so it follows the badge ink instead of needing the
|
|
83
|
+
intent class repeated on it.
|
|
84
|
+
|
|
85
|
+
```html demo
|
|
86
|
+
<span class="badge warning">
|
|
87
|
+
<span class="dot" aria-hidden="true"></span>
|
|
88
|
+
In progress
|
|
89
|
+
</span>
|
|
90
|
+
<span class="badge danger">
|
|
91
|
+
<span class="dot" aria-hidden="true"></span>
|
|
92
|
+
Blocked
|
|
93
|
+
</span>
|
|
94
|
+
<span class="badge success">
|
|
95
|
+
<span class="dot" aria-hidden="true"></span>
|
|
96
|
+
Completed
|
|
97
|
+
</span>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Custom status or category dots define a custom intent (`--intent` /
|
|
101
|
+
`--intent-fg`); `--ui-*` controls treatment, while empty dots intentionally
|
|
102
|
+
remain solid.
|
|
103
|
+
|
|
76
104
|
## Color marker
|
|
77
105
|
|
|
78
106
|
Use an empty badge as a compact intent-colored marker in legends and status
|
|
@@ -87,9 +115,64 @@ Regular
|
|
|
87
115
|
## Size variants
|
|
88
116
|
|
|
89
117
|
```html demo
|
|
90
|
-
<span class="badge success sm">Small
|
|
91
|
-
<span class="badge success">
|
|
92
|
-
<span class="badge success lg">Large
|
|
118
|
+
<span class="badge success sm">Small</span>
|
|
119
|
+
<span class="badge success">Default</span>
|
|
120
|
+
<span class="badge success lg">Large</span>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Density
|
|
124
|
+
|
|
125
|
+
Density changes the pill geometry without scaling its label or icon.
|
|
126
|
+
|
|
127
|
+
```html demo
|
|
128
|
+
<span class="compact"><span class="badge success">Compact</span></span>
|
|
129
|
+
<span><span class="badge success">Default</span></span>
|
|
130
|
+
<span class="spacious"><span class="badge success">Spacious</span></span>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## With an icon
|
|
134
|
+
|
|
135
|
+
Decorative SVG, image, or `[aria-hidden="true"]` children follow
|
|
136
|
+
`--badge-icon-size`.
|
|
137
|
+
|
|
138
|
+
```html demo
|
|
139
|
+
<span class="badge success">
|
|
140
|
+
<i class="ti ti-rosette-discount-check" aria-hidden="true"></i>
|
|
141
|
+
Verified
|
|
142
|
+
</span>
|
|
143
|
+
<span class="badge warning">
|
|
144
|
+
<i class="ti ti-clock" aria-hidden="true"></i>
|
|
145
|
+
Pending
|
|
146
|
+
</span>
|
|
147
|
+
<span class="badge danger solid">
|
|
148
|
+
<i class="ti ti-alert-circle" aria-hidden="true"></i>
|
|
149
|
+
Failed
|
|
150
|
+
</span>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Loading status
|
|
154
|
+
|
|
155
|
+
A decorative spinner follows the badge color and optical size.
|
|
156
|
+
|
|
157
|
+
```html demo
|
|
158
|
+
<span class="badge danger sm">
|
|
159
|
+
<span class="spinner" aria-hidden="true"></span>
|
|
160
|
+
Deleting
|
|
161
|
+
</span>
|
|
162
|
+
<span class="badge sm">
|
|
163
|
+
Generating
|
|
164
|
+
<span class="spinner" aria-hidden="true"></span>
|
|
165
|
+
</span>
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Custom sizing
|
|
169
|
+
|
|
170
|
+
Override the existing hooks when the three-step scale does not fit the content.
|
|
171
|
+
|
|
172
|
+
```html demo
|
|
173
|
+
<span class="badge primary" style="--badge-size: 2rem; --badge-font-size: var(--font-size-md);">
|
|
174
|
+
Prominent
|
|
175
|
+
</span>
|
|
93
176
|
```
|
|
94
177
|
|
|
95
178
|
## Removable tag pattern
|
|
@@ -98,17 +181,17 @@ Use `.badge soft` for tag visuals. Add a direct dismiss button only when the tag
|
|
|
98
181
|
For a compact action or filter, use `.btn.sm` instead; badges describe content
|
|
99
182
|
and must not be turned into toggle controls merely to obtain a compact shape.
|
|
100
183
|
|
|
184
|
+
Leave the dismiss button empty: it paints its own X, so the pattern needs no
|
|
185
|
+
icon font and no text glyph. Put your own icon inside it and that content is
|
|
186
|
+
used instead.
|
|
187
|
+
|
|
101
188
|
```html demo
|
|
102
189
|
<span class="badge primary soft">
|
|
103
190
|
Design
|
|
104
|
-
<button type="button" aria-label="Remove Design">
|
|
105
|
-
<i class="ti ti-x" aria-hidden="true"></i>
|
|
106
|
-
</button>
|
|
191
|
+
<button type="button" aria-label="Remove Design"></button>
|
|
107
192
|
</span>
|
|
108
193
|
<span class="badge primary soft">
|
|
109
|
-
<button type="button" aria-label="Remove Design">
|
|
110
|
-
<i class="ti ti-x" aria-hidden="true"></i>
|
|
111
|
-
</button>
|
|
194
|
+
<button type="button" aria-label="Remove Design"></button>
|
|
112
195
|
Design
|
|
113
196
|
</span>
|
|
114
197
|
```
|
|
@@ -119,4 +202,6 @@ and must not be turned into toggle controls merely to obtain a compact shape.
|
|
|
119
202
|
- `--badge-size` — minimum block size; also the square size of an `:empty` dot badge.
|
|
120
203
|
- `--badge-dot-size` — size of an `:empty` dot badge.
|
|
121
204
|
- `--badge-font-size` — label font size.
|
|
122
|
-
- `--badge-
|
|
205
|
+
- `--badge-icon-size` — decorative child size; `1em` follows the label by default.
|
|
206
|
+
- `--badge-pad-x` — inline padding. Derived from `--badge-size`, so it stays proportional to the pill; set it to opt out.
|
|
207
|
+
- `--badge-dismiss-icon-size` — size of the X painted by an empty dismiss button.
|
|
@@ -110,21 +110,29 @@ Always name it with an `aria-label` since there is no visible text.
|
|
|
110
110
|
|
|
111
111
|
### Button groups
|
|
112
112
|
|
|
113
|
-
Join adjacent buttons with `.join`. The joined group is not a new component
|
|
114
|
-
|
|
113
|
+
Join adjacent buttons with `.join`. The joined group is not a new component:
|
|
114
|
+
each button keeps its own classes, and `.join` only reshapes the outer corners
|
|
115
|
+
and collapses the shared edges.
|
|
115
116
|
|
|
116
117
|
```html demo
|
|
117
|
-
<div class="join" role="group" aria-label="
|
|
118
|
-
<button class="btn" type="button">
|
|
119
|
-
<button class="btn outline" type="button">
|
|
120
|
-
<button class="btn
|
|
118
|
+
<div class="join" role="group" aria-label="Row actions">
|
|
119
|
+
<button class="btn outline" type="button">Edit</button>
|
|
120
|
+
<button class="btn outline" type="button">Duplicate</button>
|
|
121
|
+
<button class="btn outline" type="button">Archive</button>
|
|
121
122
|
</div>
|
|
122
123
|
```
|
|
123
124
|
|
|
125
|
+
Keep one variant family inside a group. Because each button keeps its own
|
|
126
|
+
classes, nothing stops `.btn`, `.btn outline` and `.btn soft` from sitting side
|
|
127
|
+
by side — but three fills and three border treatments in one shape read as
|
|
128
|
+
unrelated controls that happen to touch, not as one unit. Change the variant
|
|
129
|
+
only to carry meaning: [Toggle](#toggle) marks the active segment with a solid
|
|
130
|
+
button among outlines, which is the pattern a segmented control wants.
|
|
131
|
+
|
|
124
132
|
## Sizes
|
|
125
133
|
|
|
126
|
-
Prefer `.sm` and `.lg` over setting sizes directly.
|
|
127
|
-
change
|
|
134
|
+
Prefer `.sm` and `.lg` over setting sizes directly. They scale control geometry
|
|
135
|
+
and typography together; `.compact` and `.spacious` only change density.
|
|
128
136
|
|
|
129
137
|
```html demo
|
|
130
138
|
<div class="cluster">
|
|
@@ -4,14 +4,14 @@ Flexible content container with optional header, body, and footer regions, plus
|
|
|
4
4
|
|
|
5
5
|
## Class reference
|
|
6
6
|
|
|
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
|
-
| `.inverted` | Surface modifier | Inverse surface treatment.
|
|
14
|
-
| `.compact` |
|
|
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
|
+
| `.inverted` | Surface modifier | Inverse surface treatment. |
|
|
14
|
+
| `.compact` | Density | Tighter padding and compact descendant context. |
|
|
15
15
|
|
|
16
16
|
`.surface` is a shared variant: it paints the page surface instead of
|
|
17
17
|
`--surface-raised` and leaves the intent to the text.
|
|
@@ -88,7 +88,7 @@ colored headers, or footers.
|
|
|
88
88
|
<p class="muted">For growing products</p>
|
|
89
89
|
</hgroup>
|
|
90
90
|
<p>
|
|
91
|
-
<span style="font-size: 2rem; font-weight: var(--font-weight-
|
|
91
|
+
<span style="font-size: 2rem; font-weight: var(--font-weight-semibold); line-height: 1">$24</span>
|
|
92
92
|
<span class="muted">/ user / month</span>
|
|
93
93
|
</p>
|
|
94
94
|
</header>
|
|
@@ -220,4 +220,4 @@ treatments on either side of it.
|
|
|
220
220
|
- `--card-radius` — corner radius.
|
|
221
221
|
- `--card-max-inline-size` — maximum width.
|
|
222
222
|
- `--card-pad` — inner padding; also drives the negative offsets that let a `.bleed` child reach the card edge. `.compact` lowers it.
|
|
223
|
-
- `--card-gap` — space between direct children of a bare card. A composed layout primitive owns its own gap instead.
|
|
223
|
+
- `--card-gap` — space between direct children of a bare card. A composed layout primitive owns its own gap instead.
|
|
@@ -167,7 +167,8 @@ Use `modal scrollable` when the header and footer should stay visible while the
|
|
|
167
167
|
dialog body scrolls. Modal dialogs lock page scroll while a modal is open: the
|
|
168
168
|
runtime writes `html.has-modal-open`, and the stylesheet applies `overflow:
|
|
169
169
|
hidden` (and reserves the scrollbar gutter with `scrollbar-gutter: stable` when
|
|
170
|
-
one was present).
|
|
170
|
+
one was present). The height cap follows the small viewport, so the panel keeps
|
|
171
|
+
a stable size while mobile browser chrome expands or collapses.
|
|
171
172
|
|
|
172
173
|
```html demo
|
|
173
174
|
<button class="btn"
|
|
@@ -213,8 +214,15 @@ one was present).
|
|
|
213
214
|
|
|
214
215
|
## Overlays inside modals
|
|
215
216
|
|
|
216
|
-
Flyouts and tooltips opened from inside a modal dialog
|
|
217
|
-
|
|
217
|
+
Flyouts and tooltips opened from inside a modal dialog stay exactly where they
|
|
218
|
+
are authored. The runtime promotes them to the top layer instead of moving
|
|
219
|
+
them, which is what keeps them inside every scope that reaches them by
|
|
220
|
+
inheritance.
|
|
221
|
+
|
|
222
|
+
Author them inside the dialog. Promotion paints an element above a modal, but
|
|
223
|
+
it does not lift it out of the modal's inertness — that is computed on the DOM,
|
|
224
|
+
not on paint order — so an overlay authored outside the dialog would be
|
|
225
|
+
promoted above it and still unclickable.
|
|
218
226
|
|
|
219
227
|
```html demo
|
|
220
228
|
<button class="btn"
|
|
@@ -295,7 +303,7 @@ Available options:
|
|
|
295
303
|
## Browser support
|
|
296
304
|
|
|
297
305
|
Actual relies on the native `<dialog>` API in its supported JavaScript range
|
|
298
|
-
(Safari
|
|
306
|
+
(Safari 17+, Firefox 125+, Chromium 116+). No dialog polyfill or fallback shim
|
|
299
307
|
is shipped.
|
|
300
308
|
|
|
301
309
|
## Animation
|
|
@@ -306,7 +314,7 @@ remain in the top layer while `display` and `overlay` transition out. Browsers
|
|
|
306
314
|
without that support keep native close behavior.
|
|
307
315
|
|
|
308
316
|
The open dialog root intentionally ends at `transform: none`; fixed flyouts and
|
|
309
|
-
tooltips
|
|
317
|
+
tooltips authored inside a modal dialog rely on viewport coordinates.
|
|
310
318
|
|
|
311
319
|
### View transition
|
|
312
320
|
|
|
@@ -362,7 +370,9 @@ Keep the button a direct child of `dialog.modal` so the scrolling content
|
|
|
362
370
|
|
|
363
371
|
## CSS hooks
|
|
364
372
|
|
|
365
|
-
- `--modal-size` — maximum dialog width.
|
|
373
|
+
- `--modal-size` — maximum dialog width. Fallback-only, so a class on the
|
|
374
|
+
dialog or an inherited value both reach it. A dialog is shrink-to-fit: a
|
|
375
|
+
composition that must fill this width sets `inline-size` as well.
|
|
366
376
|
- `--dialog-viewport-gap` — distance kept between the dialog and the viewport edges.
|
|
367
377
|
- `--dialog-icon-size` — diameter of the `.dialog-icon` circle.
|
|
368
378
|
- `--dialog-icon-glyph-size` — size of the glyph centered inside `.dialog-icon`.
|
|
@@ -96,7 +96,7 @@ does not close automatically after an action, on outside click, or on Escape;
|
|
|
96
96
|
add application behavior only when the product requires those policies.
|
|
97
97
|
|
|
98
98
|
Each `.fab-action` keeps its `.fab-label` and secondary button on one compact
|
|
99
|
-
line. The example uses the button's existing `.lg`
|
|
99
|
+
line. The example uses the button's existing `.lg` size for 44px secondary
|
|
100
100
|
actions and its `--btn-min-size` hook for a dominant 56px trigger. Size still
|
|
101
101
|
belongs to Button rather than introducing FAB-specific size modifiers.
|
|
102
102
|
Unlike the plain FAB, the speed dial trigger takes no icon: FAB owns it as a
|
|
@@ -120,5 +120,6 @@ two states stay visually identical in size and stroke.
|
|
|
120
120
|
- `--fab-gap` — gap between actions and between the trigger and action list.
|
|
121
121
|
- `--fab-icon-size` — size of the speed dial toggle's open and close markers.
|
|
122
122
|
|
|
123
|
-
FAB
|
|
124
|
-
|
|
123
|
+
FAB uses `--z-menu`, leaving `status-bar` above it on the scale. Open flyouts
|
|
124
|
+
and tooltips are promoted to the top layer and paint above it whatever their
|
|
125
|
+
number. Dialogs remain in the browser's top layer.
|