actual-css 0.5.0 → 0.7.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 +63 -0
- package/dist/actual.css +1 -0
- package/dist/actual.full.css +589 -131
- package/dist/actual.full.js +1 -1
- package/dist/actual.full.min.css +1 -1
- package/dist/actual.min.css +1 -1
- package/docs/design-notes/browser-support.md +39 -14
- package/docs/design-notes/css-anchor.md +1 -1
- package/docs/design-notes/enhancement-contract.md +30 -13
- package/docs/design-notes/forced-colors.md +11 -7
- package/docs/design-notes/grid.md +4 -4
- package/docs/design-notes/naming.md +15 -9
- package/docs/design-notes/platform-alignment.md +60 -0
- package/docs/design-notes/popover-manual-poc.md +248 -0
- package/docs/design-notes/references.md +4 -0
- package/docs/design-notes/steps.md +748 -0
- package/docs/design-notes/surface-reparenting.md +122 -0
- package/docs/design-notes/widget-primitives.md +32 -15
- package/docs/navigation.json +1 -0
- package/docs/pages/components/alert.md +13 -8
- package/docs/pages/components/aura.md +102 -6
- package/docs/pages/components/avatar.md +9 -6
- package/docs/pages/components/badge.md +11 -7
- package/docs/pages/components/button.md +17 -17
- package/docs/pages/components/card.md +15 -8
- package/docs/pages/components/chat.md +1 -1
- package/docs/pages/components/dialog.md +10 -7
- package/docs/pages/components/drawer.md +1 -1
- package/docs/pages/components/fab.md +12 -10
- package/docs/pages/components/indicator.md +6 -6
- package/docs/pages/components/list.md +11 -2
- package/docs/pages/components/navbar.md +1 -1
- package/docs/pages/components/pagination.md +1 -1
- package/docs/pages/components/rating.md +4 -4
- package/docs/pages/components/skeleton.md +1 -1
- package/docs/pages/components/spinner.md +1 -1
- package/docs/pages/components/steps.md +376 -52
- package/docs/pages/components/table.md +5 -5
- package/docs/pages/enhancements/flyout.md +104 -12
- package/docs/pages/enhancements/overview.md +2 -2
- package/docs/pages/enhancements/scrollspy.md +1 -1
- package/docs/pages/enhancements/status-bar.md +20 -0
- package/docs/pages/enhancements/tabs.md +1 -1
- package/docs/pages/enhancements/tooltip.md +12 -0
- package/docs/pages/examples/overview.md +2 -0
- package/docs/pages/forms/choice-cards.md +4 -4
- package/docs/pages/forms/combobox.md +87 -0
- package/docs/pages/forms/floating-field.md +5 -3
- package/docs/pages/forms/joined-controls.md +4 -4
- package/docs/pages/forms/labels.md +8 -5
- package/docs/pages/forms/overview.md +25 -18
- package/docs/pages/forms/password.md +3 -2
- package/docs/pages/forms/range.md +13 -2
- package/docs/pages/forms/states-and-sizes.md +6 -4
- package/docs/pages/forms/validation.md +13 -9
- package/docs/pages/foundations/philosophy.md +15 -1
- package/docs/pages/foundations/theming.md +8 -0
- package/docs/pages/foundations/tokens.md +9 -6
- package/docs/pages/foundations/typography.md +1 -1
- package/docs/pages/guides/bootstrap.md +3 -3
- package/docs/pages/guides/introduction.md +1 -1
- package/docs/pages/guides/modular-import.md +21 -10
- package/docs/pages/guides/progressive-enhancement.md +96 -73
- package/docs/pages/guides/tailwind.md +2 -2
- package/docs/pages/layout/app-shell.md +4 -4
- package/docs/pages/layout/choosing.md +10 -6
- package/docs/pages/layout/grid.md +11 -10
- package/docs/pages/layout/stack.md +10 -6
- package/docs/pages/patterns/structured-lists.md +7 -7
- package/docs/pages/utilities/accessibility.md +1 -1
- package/docs/pages/utilities/flex.md +20 -13
- package/docs/pages/utilities/links.md +1 -1
- package/docs/pages/utilities/list.md +1 -1
- package/docs/pages/utilities/overflow.md +14 -7
- package/docs/pages/utilities/overview.md +22 -0
- package/docs/pages/utilities/shape.md +1 -1
- package/docs/pages/utilities/sizing-wrapping.md +10 -8
- package/docs/pages/utilities/spacing.md +26 -19
- package/docs/pages/utilities/text.md +1 -1
- package/llms.txt +27 -4
- package/package.json +7 -4
- package/scripts/reserved-classes.json +4 -1
- package/src/css/components/fab.css +44 -8
- package/src/css/components/flyout.css +49 -3
- package/src/css/components/join.css +7 -0
- package/src/css/components/list.css +3 -1
- package/src/css/components/menu.css +16 -10
- package/src/css/components/steps.css +277 -69
- package/src/css/components/tooltip.css +37 -1
- package/src/css/core/tokens.css +1 -0
- package/src/css/effects/aura.css +101 -11
- package/src/css/forms/custom-select.css +1 -1
- package/src/css/forms/floating-field.css +8 -6
- package/src/css/layout/container-query.css +37 -13
- package/src/css/layout/grid.css +7 -7
- package/src/css/layout/index.css +1 -1
- package/src/js/password.js +1 -1
- package/src/js/status.js +38 -2
- package/src/js/surface.js +28 -12
- package/src/js/tooltip.js +2 -2
- package/src/js/floating.js +0 -432
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Surface reparenting breaks inherited presentation context
|
|
2
|
+
|
|
3
|
+
Known defect, present on the current Minimal floor. Tracked separately from
|
|
4
|
+
Popover adoption on purpose: Popover is the likely cure, but the defect exists
|
|
5
|
+
now and needs to be understood on its own terms.
|
|
6
|
+
|
|
7
|
+
## What happens
|
|
8
|
+
|
|
9
|
+
`surface.js` moves an open surface out of its place in the document:
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
getSurfaceRoot() → nearest <dialog>, else body
|
|
13
|
+
mountSurface() → root.append(panel)
|
|
14
|
+
restoreSurface() → put it back once the exit transition ends
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The move exists for good reasons — it escapes `overflow` clipping on any
|
|
18
|
+
ancestor and sidesteps `z-index` stacking. But it also takes the panel out of
|
|
19
|
+
every scope that reached it *by inheritance*. The panel is styled by one set of
|
|
20
|
+
ancestors while it is closed, and by a different set from the moment it becomes
|
|
21
|
+
visible.
|
|
22
|
+
|
|
23
|
+
Actual leans on inheritance deliberately: theme islands, density, `.inverted`,
|
|
24
|
+
and the custom properties an application scopes to its own containers all
|
|
25
|
+
travel that way. So this is not one bug about themes. It is the same bug in as
|
|
26
|
+
many forms as there are inherited contexts.
|
|
27
|
+
|
|
28
|
+
## Measured
|
|
29
|
+
|
|
30
|
+
Chrome, one `.flyout` per scope, values read off the panel before and after the
|
|
31
|
+
click that opens it:
|
|
32
|
+
|
|
33
|
+
| Scope | Closed | Open |
|
|
34
|
+
| ------------------------- | ---------------------------------------- | -------------------- |
|
|
35
|
+
| `[data-theme="dark"]` | `background: rgb(30, 26, 35)` | `rgb(255, 255, 255)` |
|
|
36
|
+
| `.sm` | `--control-size: 2rem` | `2.375rem` |
|
|
37
|
+
| `.inverted` | `--ui-fg: light-dark(hsl(0 0% 100%), …)` | *(unset)* |
|
|
38
|
+
| app-scoped `--app-accent` | `rgb(1, 2, 3)` | *(unset)* |
|
|
39
|
+
| `.sm` inside a `<dialog>` | `--control-size: 2rem` | `2.375rem` |
|
|
40
|
+
|
|
41
|
+
Every context breaks. Three consequences are worth stating plainly:
|
|
42
|
+
|
|
43
|
+
- The theme case is visible, not theoretical: a flyout inside a dark island
|
|
44
|
+
turns light at the moment it opens.
|
|
45
|
+
- The density case is measurable: menu rows render 38px instead of the 32px the
|
|
46
|
+
scope asked for.
|
|
47
|
+
- The dialog case shows the `getSurfaceRoot()` special case does not help. The
|
|
48
|
+
panel does land inside the dialog, and still loses any scope sitting between
|
|
49
|
+
that dialog and its trigger. Choosing a nearer root loses less context; it
|
|
50
|
+
does not preserve it.
|
|
51
|
+
|
|
52
|
+
Locked by `tests/browser/surface-inherited-context.test.js`, whose assertions
|
|
53
|
+
describe the contract Actual owes and are marked `test.failing` until the
|
|
54
|
+
transport stops reparenting.
|
|
55
|
+
|
|
56
|
+
## Why the obvious repairs are wrong
|
|
57
|
+
|
|
58
|
+
**Copying `data-theme` onto the moved panel.** Fixes the one symptom that was
|
|
59
|
+
noticed and leaves the other four broken. It also turns an inherited contract
|
|
60
|
+
into an enumerated one, so every future scope has to be added to a list.
|
|
61
|
+
|
|
62
|
+
**Snapshotting custom properties before the move.** There is no bounded set to
|
|
63
|
+
snapshot — an application's own hooks are unknowable by definition, and
|
|
64
|
+
`getComputedStyle` cannot enumerate inherited custom properties portably. It
|
|
65
|
+
would also freeze values that should stay live.
|
|
66
|
+
|
|
67
|
+
**Mounting to a nearer root.** The dialog row above is the experiment: it
|
|
68
|
+
reduces the damage without addressing the cause.
|
|
69
|
+
|
|
70
|
+
The cause is that the panel is moved at all. The repair is a transport that
|
|
71
|
+
promotes the element without relocating it.
|
|
72
|
+
|
|
73
|
+
## The actual repair
|
|
74
|
+
|
|
75
|
+
A native popover renders in the top layer while staying exactly where the
|
|
76
|
+
author put it in the DOM. That removes the reason to reparent, and with it the
|
|
77
|
+
whole mechanism:
|
|
78
|
+
|
|
79
|
+
```text
|
|
80
|
+
mountedSurfaces
|
|
81
|
+
getSurfaceRoot()
|
|
82
|
+
mountSurface()
|
|
83
|
+
restoreSurface()
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`popover="manual"` is the mode that fits: it supplies the top layer and nothing
|
|
87
|
+
else, so `surface.js` keeps its dismissal policy, Escape ordering, focus
|
|
88
|
+
restoration and placement orchestration unchanged. See
|
|
89
|
+
[platform-alignment](platform-alignment.md) for the responsibility split and
|
|
90
|
+
the criteria a component must meet before adopting Popover, and
|
|
91
|
+
[browser-support](browser-support.md) for which tier guarantees it.
|
|
92
|
+
|
|
93
|
+
That change is gated on Popover being available across Minimal. It is not
|
|
94
|
+
available there today, and adopting it behind a capability branch would keep
|
|
95
|
+
the reparenting code alive for the fallback path — so the defect would remain
|
|
96
|
+
for exactly the browsers the branch was written to serve.
|
|
97
|
+
|
|
98
|
+
## Until then
|
|
99
|
+
|
|
100
|
+
The honest interim position is a documented limitation, not a patch:
|
|
101
|
+
|
|
102
|
+
> A surface managed by `surface.js` is presented in the document's own context,
|
|
103
|
+
> not its trigger's. Do not rely on a scoped theme, density, or custom property
|
|
104
|
+
> reaching an anchored surface through inheritance.
|
|
105
|
+
|
|
106
|
+
Applications that need a scoped surface today have two workarounds, both of
|
|
107
|
+
which put the scope where the panel lands rather than where it starts: declare
|
|
108
|
+
the scope on an ancestor that survives the move (`body`, or the dialog), or
|
|
109
|
+
carry the scope on the panel element itself.
|
|
110
|
+
|
|
111
|
+
## Experiment
|
|
112
|
+
|
|
113
|
+
A branch has demonstrated the repair without changing any other contract:
|
|
114
|
+
[popover-manual-poc](popover-manual-poc.md) records what it measured, what it
|
|
115
|
+
refuted, and the checklist for the release that adopts it. Read that before
|
|
116
|
+
attempting this again — it also holds the negative results.
|
|
117
|
+
|
|
118
|
+
## Review trigger
|
|
119
|
+
|
|
120
|
+
Revisit when Popover is guaranteed across Minimal, when a further inherited
|
|
121
|
+
context is found to break, or if a transport that preserves DOM ancestry
|
|
122
|
+
becomes available by another route.
|
|
@@ -4,21 +4,38 @@ The JS runtime doubles as a primitive kit for building custom widgets.
|
|
|
4
4
|
|
|
5
5
|
## Primitives
|
|
6
6
|
|
|
7
|
-
| Need
|
|
8
|
-
|
|
9
|
-
|
|
|
10
|
-
| Per-document LIFO Escape dismissal | `escape`
|
|
11
|
-
| Positioning, flip
|
|
12
|
-
| Open/close, sheet
|
|
13
|
-
| Directional item lookup
|
|
14
|
-
| Menu-item vocabulary
|
|
15
|
-
| Focusable lookup, visibility
|
|
16
|
-
| One remembered tab stop
|
|
17
|
-
| Caret-safe value rewriting
|
|
18
|
-
| Character policies
|
|
19
|
-
| Event namespace
|
|
20
|
-
| Declarative triggers
|
|
21
|
-
| State classes the runtime writes
|
|
7
|
+
| Need | Primitive | Import |
|
|
8
|
+
| ---------------------------------- | ------------- | --------------------------- |
|
|
9
|
+
| Discovery, lifecycle, cleanup | `enhance` | `actual-css/js/enhance` |
|
|
10
|
+
| Per-document LIFO Escape dismissal | `escape` | `actual-css/js/escape` |
|
|
11
|
+
| Positioning, flip and shift | `floating` | `@lekoala/floating` |
|
|
12
|
+
| Open/close, sheet, backdrop, focus | `surface` | `actual-css/js/surface` |
|
|
13
|
+
| Directional item lookup | `keys` | `actual-css/js/keys` |
|
|
14
|
+
| Menu-item vocabulary | `menu` | `actual-css/js/menu` |
|
|
15
|
+
| Focusable lookup, visibility | `focus` | `actual-css/js/focus` |
|
|
16
|
+
| One remembered tab stop | `focus-group` | `actual-css/js/focus-group` |
|
|
17
|
+
| Caret-safe value rewriting | `input` | `actual-css/js/input` |
|
|
18
|
+
| Character policies | `filter` | `actual-css/js/filter` |
|
|
19
|
+
| Event namespace | `events` | `actual-css/js/events` |
|
|
20
|
+
| Declarative triggers | `command` | `actual-css/js/command` |
|
|
21
|
+
| State classes the runtime writes | `selectors` | `actual-css/js/selectors` |
|
|
22
|
+
|
|
23
|
+
The named exports each module carries:
|
|
24
|
+
|
|
25
|
+
- `enhance` — `enhance`, `registerEnhancement`
|
|
26
|
+
- `escape` — `registerEscapeDismissal`
|
|
27
|
+
- `floating` — `autoUpdate`, `reposition`, `repositionAt`, plus
|
|
28
|
+
`--available-height` and `data-placement`
|
|
29
|
+
- `keys` — `itemForKey`, `firstItem`, `lastItem`, `nextItem`, with edge,
|
|
30
|
+
wrapping and RTL handling
|
|
31
|
+
- `focus-group` — `connectFocusGroup`
|
|
32
|
+
- `input` — `onTextInput`, `setCaret`, `dispatchInput`
|
|
33
|
+
- `events` — `EVENTS`, `ACTUAL_EVENT_PREFIX`
|
|
34
|
+
- `command` — `registerCommands`
|
|
35
|
+
- `selectors` — `CLASSES`
|
|
36
|
+
|
|
37
|
+
`surface` also owns outside-click and Escape dismissal, and focus restore.
|
|
38
|
+
`menu` filters to usable items.
|
|
22
39
|
|
|
23
40
|
## Focus group
|
|
24
41
|
|
package/docs/navigation.json
CHANGED
|
@@ -21,13 +21,16 @@ itself needs to change, not `.soft`.
|
|
|
21
21
|
|
|
22
22
|
## Class reference
|
|
23
23
|
|
|
24
|
-
| Class | Kind | Description
|
|
25
|
-
|
|
26
|
-
| `.alert` | Component | Inline status surface; soft by default.
|
|
27
|
-
| `.alert-icon` | Composition | Decorative leading icon
|
|
28
|
-
| `.alert-dismiss` | Modifier | Compact dismiss button
|
|
29
|
-
| `.callout` | Variant | Neutral panel
|
|
30
|
-
| `.admonition` | Variant |
|
|
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
|
+
| `.callout` | Variant | Neutral panel, thick accent leading edge. |
|
|
30
|
+
| `.admonition` | Variant | Tinted title bar, body on the page surface. |
|
|
31
|
+
|
|
32
|
+
`.alert-dismiss` draws itself with the `--icon-close` mask and acts through the
|
|
33
|
+
`--dismiss` command.
|
|
31
34
|
| `.alert-title` | Composition | Admonition title bar; hosts the dismiss button. |
|
|
32
35
|
| `.alert-body` | Composition | Admonition body resting on the page surface. |
|
|
33
36
|
| Shared intents | Intent | `.primary`, `.secondary`, `.success`, `.warning`, `.danger`. |
|
|
@@ -117,10 +120,12 @@ Use `.alert-dismiss` to let a user remove an inline alert. The button is transpa
|
|
|
117
120
|
```html demo
|
|
118
121
|
<div class="alert warning" id="warning-alert">
|
|
119
122
|
<i class="ti ti-alert-triangle alert-icon" aria-hidden="true"></i>
|
|
120
|
-
|
|
123
|
+
|
|
124
|
+
<div class="stack" style="--gap: var(--space-10)">
|
|
121
125
|
<strong>Warning</strong>
|
|
122
126
|
<p>Something needs your attention.</p>
|
|
123
127
|
</div>
|
|
128
|
+
|
|
124
129
|
<button
|
|
125
130
|
class="alert-dismiss"
|
|
126
131
|
type="button"
|
|
@@ -5,6 +5,32 @@
|
|
|
5
5
|
Aura adds a decorative intent-colored border and halo around one direct child.
|
|
6
6
|
It is visual emphasis only and does not change the child's semantics.
|
|
7
7
|
|
|
8
|
+
```html demo
|
|
9
|
+
<div class="cluster" style="gap: 2.5rem">
|
|
10
|
+
<span class="aura primary">
|
|
11
|
+
<article class="card" style="inline-size: 13rem">
|
|
12
|
+
<p><strong>Rotating arc</strong></p>
|
|
13
|
+
<p class="muted">One lit segment travels around the frame.</p>
|
|
14
|
+
</article>
|
|
15
|
+
</span>
|
|
16
|
+
|
|
17
|
+
<span class="aura aura-glow primary">
|
|
18
|
+
<article class="card" style="inline-size: 13rem">
|
|
19
|
+
<p><strong>Breathing glow</strong></p>
|
|
20
|
+
<p class="muted">The whole perimeter lights and breathes.</p>
|
|
21
|
+
</article>
|
|
22
|
+
</span>
|
|
23
|
+
</div>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`.aura` sends a short accent of light travelling around the frame, over a
|
|
27
|
+
permanent halo that keeps the object present between two passes. Add
|
|
28
|
+
`.aura-glow` to light the whole perimeter evenly instead, as a halo that
|
|
29
|
+
breathes slowly.
|
|
30
|
+
|
|
31
|
+
Aura reads best when it has enough perimeter to travel around, and is naturally
|
|
32
|
+
more pronounced on dark surfaces. It still composes on small shapes:
|
|
33
|
+
|
|
8
34
|
```html demo
|
|
9
35
|
<div class="cluster">
|
|
10
36
|
<span class="aura primary">
|
|
@@ -14,22 +40,92 @@ It is visual emphasis only and does not change the child's semantics.
|
|
|
14
40
|
<span class="aura aura-glow secondary">
|
|
15
41
|
<span class="badge">New</span>
|
|
16
42
|
</span>
|
|
43
|
+
|
|
44
|
+
<span class="aura aura-glow success">
|
|
45
|
+
<span class="badge success soft">Live</span>
|
|
46
|
+
</span>
|
|
47
|
+
|
|
48
|
+
<span class="aura danger">
|
|
49
|
+
<span class="badge danger solid" aria-label="12 unread notifications">12</span>
|
|
50
|
+
</span>
|
|
51
|
+
</div>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Note the intent on the wrapper, not on the child: `.aura` is an intent
|
|
55
|
+
boundary, so the badge or alert inside keeps its own color and the frame keeps
|
|
56
|
+
the one you gave the wrapper. Matching them reads as one object; deliberately
|
|
57
|
+
mismatching them reads as two.
|
|
58
|
+
|
|
59
|
+
```html demo
|
|
60
|
+
<div class="stack" style="max-inline-size: 28rem">
|
|
61
|
+
<span class="aura warning">
|
|
62
|
+
<div class="alert warning" role="alert">
|
|
63
|
+
<i class="ti ti-alert-triangle alert-icon" aria-hidden="true"></i>
|
|
64
|
+
<div>Your trial ends in three days.</div>
|
|
65
|
+
</div>
|
|
66
|
+
</span>
|
|
67
|
+
|
|
68
|
+
<span class="aura aura-glow danger">
|
|
69
|
+
<div class="alert danger" role="alert">
|
|
70
|
+
<i class="ti ti-credit-card-off alert-icon" aria-hidden="true"></i>
|
|
71
|
+
<div>Two payment methods failed. <a href="#">Review them</a>.</div>
|
|
72
|
+
</div>
|
|
73
|
+
</span>
|
|
17
74
|
</div>
|
|
18
75
|
```
|
|
19
76
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
77
|
+
Motion changes how the light lives, never whether the effect is there: when the
|
|
78
|
+
user has requested reduced motion, the travelling accent becomes two opposite
|
|
79
|
+
lit corners — a deliberate composition rather than a rotation frozen at an
|
|
80
|
+
arbitrary angle — and the glow stays a full, still halo.
|
|
81
|
+
|
|
82
|
+
The frame color comes from an intent such as `.primary`, `.success`, or
|
|
83
|
+
`.danger`; there are no separate aura color variants. The intent is sovereign:
|
|
84
|
+
a neutral intent produces a neutral aura. Use a chromatic intent when you want
|
|
85
|
+
a visibly luminous effect.
|
|
86
|
+
|
|
87
|
+
Two hooks tune how loud the effect is. `--aura-intensity` scales both halos at
|
|
88
|
+
once, resting and breathing alike, so the breath stays proportional at every
|
|
89
|
+
setting; `--aura-duration` sets one full rotation of the accent, or one breath
|
|
90
|
+
of the glow.
|
|
91
|
+
|
|
92
|
+
```html demo
|
|
93
|
+
<div class="cluster" style="gap: 2rem">
|
|
94
|
+
<span class="aura aura-glow primary" style="--aura-intensity: 0.4">
|
|
95
|
+
<span class="card" style="inline-size: 8rem">Muted</span>
|
|
96
|
+
</span>
|
|
97
|
+
|
|
98
|
+
<span class="aura aura-glow primary">
|
|
99
|
+
<span class="card" style="inline-size: 8rem">Default</span>
|
|
100
|
+
</span>
|
|
101
|
+
|
|
102
|
+
<span class="aura aura-glow primary" style="--aura-intensity: 2">
|
|
103
|
+
<span class="card" style="inline-size: 8rem">Loud</span>
|
|
104
|
+
</span>
|
|
105
|
+
|
|
106
|
+
<span class="aura primary" style="--aura-duration: 2s">
|
|
107
|
+
<span class="card" style="inline-size: 8rem">Fast accent</span>
|
|
108
|
+
</span>
|
|
109
|
+
</div>
|
|
110
|
+
```
|
|
24
111
|
|
|
25
112
|
Keep exactly one direct child and set `--aura-radius` when its shape differs
|
|
26
113
|
from the common button, card, alert, and badge shapes detected as a visual
|
|
27
114
|
enhancement.
|
|
28
115
|
|
|
116
|
+
The child must be opaque. The frame paints across the whole box and relies on
|
|
117
|
+
the child to cover all but its edge, so a transparent child — an `.outline`
|
|
118
|
+
alert, a `.ghost` button — is filled edge to edge with the frame color instead
|
|
119
|
+
of framed by it. Give such a child a surface, or move the aura to an opaque
|
|
120
|
+
wrapper around it.
|
|
121
|
+
|
|
29
122
|
## CSS hooks
|
|
30
123
|
|
|
31
124
|
- `--aura-color` — frame and halo color; follows the local intent.
|
|
32
125
|
- `--aura-width` — frame thickness.
|
|
33
|
-
- `--aura-blur` — halo blur
|
|
126
|
+
- `--aura-blur` — near halo blur; the far halo derives its own blur and its
|
|
127
|
+
spread beyond the frame from this value, so one hook scales both.
|
|
128
|
+
- `--aura-intensity` — multiplies both halo opacities, resting and breathing.
|
|
129
|
+
It does not touch the frame itself, which stays a crisp line at any setting.
|
|
34
130
|
- `--aura-radius` — child corner radius used to derive the outer radius.
|
|
35
|
-
- `--aura-duration` — rotation
|
|
131
|
+
- `--aura-duration` — one rotation of the accent, or one breath of the glow.
|
|
@@ -12,12 +12,15 @@
|
|
|
12
12
|
|
|
13
13
|
## Class reference
|
|
14
14
|
|
|
15
|
-
| Class
|
|
16
|
-
|
|
17
|
-
| `.avatar`
|
|
18
|
-
| `.avatar-stack`
|
|
19
|
-
| `.badge:empty`
|
|
20
|
-
| `.sm` / `.lg`
|
|
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 | Density; also rescales `.avatar-stack`. |
|
|
21
|
+
|
|
22
|
+
`.avatar` works on `div`, `a` and `button`. The status dot is an empty
|
|
23
|
+
`.badge` inside an `.avatar`, and needs an `aria-label` of its own.
|
|
21
24
|
|
|
22
25
|
## Basic usage
|
|
23
26
|
|
|
@@ -20,13 +20,17 @@ full-width badge is intentional.
|
|
|
20
20
|
|
|
21
21
|
## Class reference
|
|
22
22
|
|
|
23
|
-
| Class | Kind | Description
|
|
24
|
-
|
|
25
|
-
| `.badge` | Component | Compact label; soft by default.
|
|
26
|
-
| `.badge:empty` | Composition | Truly-empty badge renders as a solid dot.
|
|
27
|
-
| Shared intents | Intent | `.primary`, `.secondary`, `.success`,
|
|
28
|
-
| Shared variants | Variant | `.solid
|
|
29
|
-
| `.sm` / `.lg` | Size | Compact density.
|
|
23
|
+
| Class | Kind | Description |
|
|
24
|
+
| --------------- | ----------- | ----------------------------------------- |
|
|
25
|
+
| `.badge` | Component | Compact label; soft by default. |
|
|
26
|
+
| `.badge:empty` | Composition | Truly-empty badge renders as a solid dot. |
|
|
27
|
+
| Shared intents | Intent | `.primary`, `.secondary`, `.success`, … |
|
|
28
|
+
| Shared variants | Variant | `.solid`, `.outline`, `.surface`. |
|
|
29
|
+
| `.sm` / `.lg` | Size | Compact density. |
|
|
30
|
+
|
|
31
|
+
The shared intents are `.primary`, `.secondary`, `.success`, `.warning` and
|
|
32
|
+
`.danger`. The variants set emphasis: `.solid` is filled, `.outline` bordered,
|
|
33
|
+
`.surface` untinted.
|
|
30
34
|
|
|
31
35
|
## Basic usage
|
|
32
36
|
|
|
@@ -4,23 +4,23 @@ Actions and navigation with shared intents, variants, sizes, and loading, presse
|
|
|
4
4
|
|
|
5
5
|
## Class reference
|
|
6
6
|
|
|
7
|
-
| Class | Kind | Description
|
|
8
|
-
|
|
9
|
-
| `.btn` | Component | Base button
|
|
10
|
-
| `.primary` | Intent | Primary action.
|
|
11
|
-
| `.secondary` | Intent | Secondary action.
|
|
12
|
-
| `.success` | Intent | Positive outcome.
|
|
13
|
-
| `.warning` | Intent | Caution.
|
|
14
|
-
| `.danger` | Intent | Destructive action.
|
|
15
|
-
| `.neutral` | Intent | Neutral tone (the `.btn` default).
|
|
16
|
-
| `.soft` | Variant | Muted intent-tinted surface.
|
|
17
|
-
| `.outline` | Variant | Transparent with an intent-colored border.
|
|
18
|
-
| `.solid` | Variant | Filled intent background — the `.btn` default.
|
|
19
|
-
| `.surface` | Variant | Page surface
|
|
20
|
-
| `.ghost` | Variant | Borderless text button (button-only).
|
|
21
|
-
| `.link` | Variant | Underlined text button (button-only).
|
|
22
|
-
| `.sm` / `.lg` | Size | Compact or large control height.
|
|
23
|
-
| `.icon-only` | Variant | Square icon button sized to the control height.
|
|
7
|
+
| Class | Kind | Description |
|
|
8
|
+
| ------------- | --------- | -------------------------------------------------- |
|
|
9
|
+
| `.btn` | Component | Base button, solid by default. |
|
|
10
|
+
| `.primary` | Intent | Primary action. |
|
|
11
|
+
| `.secondary` | Intent | Secondary action. |
|
|
12
|
+
| `.success` | Intent | Positive outcome. |
|
|
13
|
+
| `.warning` | Intent | Caution. |
|
|
14
|
+
| `.danger` | Intent | Destructive action. |
|
|
15
|
+
| `.neutral` | Intent | Neutral tone (the `.btn` default). |
|
|
16
|
+
| `.soft` | Variant | Muted intent-tinted surface. |
|
|
17
|
+
| `.outline` | Variant | Transparent with an intent-colored border. |
|
|
18
|
+
| `.solid` | Variant | Filled intent background — the `.btn` default. |
|
|
19
|
+
| `.surface` | Variant | Page surface, neutral border, intent on the label. |
|
|
20
|
+
| `.ghost` | Variant | Borderless text button (button-only). |
|
|
21
|
+
| `.link` | Variant | Underlined text button (button-only). |
|
|
22
|
+
| `.sm` / `.lg` | Size | Compact or large control height. |
|
|
23
|
+
| `.icon-only` | Variant | Square icon button sized to the control height. |
|
|
24
24
|
|
|
25
25
|
## Basic usage
|
|
26
26
|
|
|
@@ -4,14 +4,21 @@ 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 |
|
|
13
|
-
| `.inverted` | Surface modifier | Inverse surface treatment
|
|
14
|
-
| `.compact` | Variant | Tighter padding for dense contexts.
|
|
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` | Variant | Tighter padding for dense contexts. |
|
|
15
|
+
|
|
16
|
+
`.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.
|
|
15
22
|
|
|
16
23
|
## Basic usage
|
|
17
24
|
|
|
@@ -37,7 +37,7 @@ put `role="log"` on individual messages.
|
|
|
37
37
|
## Class reference
|
|
38
38
|
|
|
39
39
|
| Class | Description |
|
|
40
|
-
|
|
40
|
+
| ------------------------------- | -------------------------------------------- |
|
|
41
41
|
| `.chat` | Message row grid. |
|
|
42
42
|
| `.chat-start` / `.chat-end` | Logical inline placement. |
|
|
43
43
|
| `.chat-avatar` | Avatar grid slot; compose it with `.avatar`. |
|
|
@@ -6,13 +6,16 @@
|
|
|
6
6
|
|
|
7
7
|
## Class reference
|
|
8
8
|
|
|
9
|
-
| Class | Kind | Description
|
|
10
|
-
|
|
11
|
-
| `.modal` | Component | Centered
|
|
12
|
-
| `.scrollable` | Variant |
|
|
13
|
-
| `.dialog-confirmation` | Variant |
|
|
14
|
-
| `.dialog-icon` | Component | Circular intent-aware icon well
|
|
15
|
-
| `.dialog-close` | Component | Icon-only close button
|
|
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
|
+
| `.dialog-close` | Component | Icon-only close button, at the top end. |
|
|
16
|
+
|
|
17
|
+
`.dialog-close` sits outside the content flow, so it does not take part in the
|
|
18
|
+
dialog's own layout.
|
|
16
19
|
|
|
17
20
|
## Usage
|
|
18
21
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
## Class reference
|
|
8
8
|
|
|
9
9
|
| Class | Kind | Description |
|
|
10
|
-
|
|
10
|
+
| --------------- | --------- | ---------------------------------------------------------- |
|
|
11
11
|
| `.drawer` | Component | Modal side-sheet built on the native `<dialog>` element. |
|
|
12
12
|
| `.drawer-close` | Component | Icon-only close button that sits inside the drawer header. |
|
|
13
13
|
|
|
@@ -12,10 +12,12 @@ the layout keeps it clear of adaptive application navigation and safe areas.
|
|
|
12
12
|
```html
|
|
13
13
|
<div class="fab">
|
|
14
14
|
<button class="btn circle primary lg icon-only" type="button" aria-label="Create">
|
|
15
|
-
<
|
|
15
|
+
<i class="ti ti-plus" aria-hidden="true"></i>
|
|
16
16
|
</button>
|
|
17
17
|
</div>
|
|
18
18
|
```
|
|
19
|
+
The plain FAB button carries the application's own icon — it is a product
|
|
20
|
+
action, not a toggle.
|
|
19
21
|
|
|
20
22
|
Use native `details` for a no-JavaScript speed dial. List actions in their
|
|
21
23
|
visual top-to-bottom order so keyboard focus follows the same sequence.
|
|
@@ -26,9 +28,7 @@ visual top-to-bottom order so keyboard focus follows the same sequence.
|
|
|
26
28
|
class="btn circle primary icon-only"
|
|
27
29
|
style="--btn-min-size: 3.5rem"
|
|
28
30
|
aria-label="Create"
|
|
29
|
-
>
|
|
30
|
-
<span aria-hidden="true">+</span>
|
|
31
|
-
</summary>
|
|
31
|
+
></summary>
|
|
32
32
|
|
|
33
33
|
<div class="fab-actions">
|
|
34
34
|
<div class="fab-action">
|
|
@@ -65,9 +65,7 @@ not the FAB's containing component. Production `.fab` remains viewport-fixed.
|
|
|
65
65
|
class="btn circle primary icon-only"
|
|
66
66
|
style="--btn-min-size: 3.5rem"
|
|
67
67
|
aria-label="Create"
|
|
68
|
-
>
|
|
69
|
-
<span aria-hidden="true">+</span>
|
|
70
|
-
</summary>
|
|
68
|
+
></summary>
|
|
71
69
|
|
|
72
70
|
<div class="fab-actions">
|
|
73
71
|
<div class="fab-action">
|
|
@@ -101,13 +99,16 @@ Each `.fab-action` keeps its `.fab-label` and secondary button on one compact
|
|
|
101
99
|
line. The example uses the button's existing `.lg` density for 44px secondary
|
|
102
100
|
actions and its `--btn-min-size` hook for a dominant 56px trigger. Size still
|
|
103
101
|
belongs to Button rather than introducing FAB-specific size modifiers.
|
|
104
|
-
|
|
105
|
-
|
|
102
|
+
Unlike the plain FAB, the speed dial trigger takes no icon: FAB owns it as a
|
|
103
|
+
toggle and masks the shared `--icon-plus` glyph while closed and `--icon-close` —
|
|
104
|
+
the same close symbol used by alerts and dialogs — while open, both sized by
|
|
105
|
+
`--fab-icon-size`. No application icon and no rotated glyph is involved, so the
|
|
106
|
+
two states stay visually identical in size and stroke.
|
|
106
107
|
|
|
107
108
|
## Class reference
|
|
108
109
|
|
|
109
110
|
| Class | Description |
|
|
110
|
-
|
|
111
|
+
| -------------- | --------------------------------------------------------- |
|
|
111
112
|
| `.fab` | Fixed viewport placement; use `details` for a speed dial. |
|
|
112
113
|
| `.fab-actions` | Collapsible vertical action list. |
|
|
113
114
|
| `.fab-action` | One horizontal label-and-button unit. |
|
|
@@ -117,6 +118,7 @@ the open state so a plus naturally becomes a close symbol.
|
|
|
117
118
|
|
|
118
119
|
- `--fab-offset` — minimum viewport-edge offset.
|
|
119
120
|
- `--fab-gap` — gap between actions and between the trigger and action list.
|
|
121
|
+
- `--fab-icon-size` — size of the speed dial toggle's open and close markers.
|
|
120
122
|
|
|
121
123
|
FAB is hidden in print and uses `--z-menu`, leaving tooltips and status UI above
|
|
122
124
|
it. Dialogs remain in the browser's top layer.
|
|
@@ -9,12 +9,12 @@ that owns its appearance.
|
|
|
9
9
|
|
|
10
10
|
## Class reference
|
|
11
11
|
|
|
12
|
-
| Class | Kind | Description
|
|
13
|
-
|
|
14
|
-
| `.indicator` | Component | Positioning context for an overlaid child.
|
|
15
|
-
| `.indicator-item` | Part | Item attached to the top-end corner by default.
|
|
16
|
-
| `.start` | Placement | Moves the item to the inline-start corner.
|
|
17
|
-
| `.bottom` | Placement | Moves the item to the bottom corner.
|
|
12
|
+
| Class | Kind | Description |
|
|
13
|
+
| ----------------- | --------- | ----------------------------------------------- |
|
|
14
|
+
| `.indicator` | Component | Positioning context for an overlaid child. |
|
|
15
|
+
| `.indicator-item` | Part | Item attached to the top-end corner by default. |
|
|
16
|
+
| `.start` | Placement | Moves the item to the inline-start corner. |
|
|
17
|
+
| `.bottom` | Placement | Moves the item to the bottom corner. |
|
|
18
18
|
|
|
19
19
|
Combine `.bottom.start` for bottom-start. Logical inline placement follows the
|
|
20
20
|
document direction automatically.
|