actual-css 0.1.0 → 0.3.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 +90 -1
- package/README.md +25 -8
- package/dist/actual-themes.min.css +1 -0
- package/dist/actual.css +1492 -931
- package/dist/actual.js +1 -3
- package/dist/actual.min.css +1 -1
- package/dist/optional.css +1048 -0
- package/dist/optional.min.css +1 -0
- package/docs/design-notes/browser-support.md +95 -6
- package/docs/design-notes/cascade-layer.md +1 -1
- package/docs/design-notes/enhancement-contract.md +101 -0
- package/docs/design-notes/forced-colors.md +105 -0
- package/docs/design-notes/naming.md +3 -1
- package/docs/design-notes/platform-alignment.md +492 -0
- package/docs/design-notes/references.md +8 -0
- package/docs/design-notes/widget-primitives.md +119 -0
- package/docs/navigation.json +135 -0
- package/docs/pages/components/accordion.md +80 -0
- package/docs/pages/components/alert.md +203 -0
- package/docs/pages/components/aura.md +35 -0
- package/docs/pages/components/avatar.md +95 -0
- package/docs/pages/components/badge.md +102 -0
- package/docs/pages/components/breadcrumb.md +19 -0
- package/docs/pages/components/button.md +205 -0
- package/docs/pages/components/card.md +183 -0
- package/docs/pages/components/chat.md +50 -0
- package/docs/pages/components/dialog.md +367 -0
- package/docs/pages/components/drawer.md +113 -0
- package/docs/pages/components/fab.md +118 -0
- package/docs/pages/components/key.md +33 -0
- package/docs/pages/components/meter.md +23 -0
- package/docs/pages/components/navbar.md +92 -0
- package/docs/pages/components/pagination.md +55 -0
- package/docs/pages/components/progress.md +29 -0
- package/docs/pages/components/skeleton.md +38 -0
- package/docs/pages/components/spinner.md +93 -0
- package/docs/pages/components/table.md +102 -0
- package/docs/pages/enhancements/flyout.md +391 -0
- package/docs/pages/enhancements/overview.md +36 -0
- package/docs/pages/enhancements/scrollspy.md +71 -0
- package/docs/pages/enhancements/status-bar.md +72 -0
- package/docs/pages/enhancements/tabs.md +80 -0
- package/docs/pages/enhancements/tooltip.md +130 -0
- package/docs/pages/examples/overview.md +41 -0
- package/docs/pages/forms/choice-cards.md +102 -0
- package/docs/pages/forms/controls.md +32 -0
- package/docs/pages/forms/detached-actions.md +59 -0
- package/docs/pages/forms/floating-field.md +88 -0
- package/docs/pages/forms/form-actions.md +56 -0
- package/docs/pages/forms/input-policy.md +91 -0
- package/docs/pages/forms/joined-controls.md +37 -0
- package/docs/pages/forms/labels.md +42 -0
- package/docs/pages/forms/otp.md +50 -0
- package/docs/pages/forms/overview.md +188 -0
- package/docs/pages/forms/password.md +40 -0
- package/docs/pages/forms/range.md +17 -0
- package/docs/pages/forms/states-and-sizes.md +321 -0
- package/docs/pages/forms/sticky-actions.md +187 -0
- package/docs/pages/forms/switch.md +31 -0
- package/docs/pages/forms/validation.md +241 -0
- package/docs/{mental-model.md → pages/foundations/philosophy.md} +33 -18
- package/docs/pages/foundations/theming.md +92 -0
- package/docs/pages/foundations/tokens.md +421 -0
- package/docs/{typography.md → pages/foundations/typography.md} +27 -9
- package/docs/pages/guides/bootstrap.md +438 -0
- package/docs/pages/guides/introduction.md +157 -0
- package/docs/pages/guides/optional-components.md +33 -0
- package/docs/pages/guides/progressive-enhancement.md +686 -0
- package/docs/pages/guides/tailwind.md +455 -0
- package/docs/pages/layout/app-shell.md +25 -0
- package/docs/pages/layout/center.md +29 -0
- package/docs/pages/layout/cluster.md +57 -0
- package/docs/pages/layout/frame.md +30 -0
- package/docs/pages/layout/grid.md +142 -0
- package/docs/pages/layout/list.md +41 -0
- package/docs/pages/layout/media.md +21 -0
- package/docs/pages/layout/overview.md +37 -0
- package/docs/pages/layout/scroll-snap.md +54 -0
- package/docs/pages/layout/sidebar-layout.md +27 -0
- package/docs/pages/layout/stack.md +18 -0
- package/docs/pages/layout/switcher.md +36 -0
- package/docs/pages/layout/topbar.md +23 -0
- package/docs/pages/patterns/actions.md +52 -0
- package/docs/pages/patterns/code-block.md +36 -0
- package/docs/pages/patterns/exclusive-accordion.md +16 -0
- package/docs/pages/patterns/hierarchical-nav.md +26 -0
- package/docs/pages/patterns/icon-input.md +25 -0
- package/docs/pages/patterns/intent-nesting.md +3 -0
- package/docs/pages/patterns/navigation-list.md +235 -0
- package/docs/pages/patterns/overview.md +58 -0
- package/docs/pages/patterns/structured-lists.md +47 -0
- package/docs/pages/utilities/accessibility.md +34 -0
- package/docs/pages/utilities/flex.md +105 -0
- package/docs/pages/utilities/links.md +18 -0
- package/docs/pages/utilities/list.md +31 -0
- package/docs/pages/utilities/overflow.md +43 -0
- package/docs/pages/utilities/overview.md +18 -0
- package/docs/pages/utilities/shape.md +25 -0
- package/docs/pages/utilities/sizing-wrapping.md +115 -0
- package/docs/pages/utilities/spacing.md +79 -0
- package/docs/pages/utilities/text.md +43 -0
- package/llms.txt +10 -4
- package/package.json +30 -16
- package/src/css/actual.css +12 -1
- package/src/css/base.css +3 -9
- package/src/css/components/accordion.css +18 -30
- package/src/css/components/actions.css +4 -1
- package/src/css/components/alert.css +162 -49
- package/src/css/components/avatar.css +16 -10
- package/src/css/components/badge.css +82 -39
- package/src/css/components/breadcrumb.css +7 -15
- package/src/css/components/busy.css +7 -0
- package/src/css/components/button.css +82 -38
- package/src/css/components/card.css +17 -37
- package/src/css/components/drawer.css +30 -13
- package/src/css/components/flyout.css +39 -110
- package/src/css/components/index.css +1 -0
- package/src/css/components/join.css +14 -3
- package/src/css/components/key.css +2 -0
- package/src/css/components/menu.css +125 -0
- package/src/css/components/meter.css +0 -23
- package/src/css/components/modal.css +162 -7
- package/src/css/components/navbar.css +17 -18
- package/src/css/components/overline.css +0 -7
- package/src/css/components/pagination.css +1 -1
- package/src/css/components/progress.css +8 -26
- package/src/css/components/scrollspy.css +2 -2
- package/src/css/components/skeleton.css +7 -0
- package/src/css/components/spinner.css +10 -11
- package/src/css/components/status-bar.css +18 -28
- package/src/css/components/surface.css +2 -8
- package/src/css/components/tab.css +20 -48
- package/src/css/components/table.css +7 -5
- package/src/css/components/tooltip.css +14 -7
- package/src/css/focus.css +16 -3
- package/src/css/forms/choice-card.css +13 -15
- package/src/css/forms/choice.css +21 -28
- package/src/css/forms/control.css +16 -26
- package/src/css/forms/custom-select.css +9 -11
- package/src/css/forms/form-actions.css +14 -3
- package/src/css/forms/form.css +7 -4
- package/src/css/forms/index.css +5 -4
- package/src/css/forms/input-icon.css +30 -12
- package/src/css/forms/native.css +48 -33
- package/src/css/forms/range.css +103 -0
- package/src/css/forms/select.css +8 -8
- package/src/css/forms/switch.css +14 -13
- package/src/css/forms/validation.css +32 -5
- package/src/css/grid.css +19 -18
- package/src/css/intents.css +2 -2
- package/src/css/layout.css +29 -1
- package/src/css/optional/aura.css +93 -0
- package/src/css/optional/chat.css +105 -0
- package/src/css/optional/fab.css +104 -0
- package/src/css/optional/floating-field.css +87 -0
- package/src/css/optional/index.css +5 -0
- package/src/css/optional/layout-extra.css +7 -4
- package/src/css/optional/otp.css +115 -0
- package/src/css/optional/scroll-snap.css +6 -0
- package/src/css/optional/scroller.css +19 -7
- package/src/css/optional/typography-fluid.css +5 -0
- package/src/css/optional/utilities-extra.css +17 -2
- package/src/css/prose.css +18 -8
- package/src/css/reset.css +0 -10
- package/src/css/theme.css +29 -13
- package/src/css/themes/cyberpunk.css +1 -1
- package/src/css/themes/dim.css +3 -3
- package/src/css/themes/edge.css +11 -37
- package/src/css/themes/index.css +3 -3
- package/src/css/themes/{dark.css → indigo.css} +5 -4
- package/src/css/themes/neon.css +5 -5
- package/src/css/themes/square.css +0 -3
- package/src/css/tokens.css +81 -21
- package/src/css/utilities.css +8 -10
- package/src/css/variants.css +37 -65
- package/src/js/command.js +1 -3
- package/src/js/context-menu.js +72 -53
- package/src/js/dialog.js +68 -79
- package/src/js/dismiss.js +15 -0
- package/src/js/enhance.js +76 -19
- package/src/js/enhancement-loader.js +301 -0
- package/src/js/events.js +3 -0
- package/src/js/filter.js +3 -3
- package/src/js/floating.js +101 -131
- package/src/js/flyout.js +106 -96
- package/src/js/focus-group.js +116 -0
- package/src/js/focus.js +6 -1
- package/src/js/index.js +4 -2
- package/src/js/input.js +1 -1
- package/src/js/keys.js +27 -0
- package/src/js/mask.js +7 -6
- package/src/js/menu.js +89 -35
- package/src/js/parse-config.js +47 -0
- package/src/js/password.js +9 -1
- package/src/js/scrollspy.js +133 -62
- package/src/js/selectors.js +14 -31
- package/src/js/status.js +16 -14
- package/src/js/surface.js +219 -125
- package/src/js/tab.js +46 -66
- package/src/js/tooltip.js +53 -31
- package/src/js/validation.js +45 -51
- package/dist/actual.js.map +0 -31
- package/docs/README.md +0 -26
- package/docs/components.md +0 -860
- package/docs/design-notes/previous-work.md +0 -5
- package/docs/forms.md +0 -1265
- package/docs/javascript.md +0 -426
- package/docs/layout.md +0 -480
- package/docs/patterns.md +0 -415
- package/docs/reserved.md +0 -7
- package/docs/tokens.md +0 -455
- package/docs/ui.md +0 -937
- package/docs/utilities.md +0 -384
- package/src/css/dialog-fallback.css +0 -56
- package/src/js/dialog-fallback.js +0 -163
|
@@ -10,23 +10,20 @@
|
|
|
10
10
|
* the coloring via --intent / --intent-fg. status.js applies these as plain
|
|
11
11
|
* classes on the target; it does not know their names or that they exist.
|
|
12
12
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
13
|
+
* CSS API: .status-bar
|
|
14
|
+
* JS target contract: [data-status][role="status"]
|
|
15
|
+
* Normally combined, but they describe separate concerns.
|
|
16
|
+
*
|
|
17
|
+
* Internal:
|
|
18
|
+
* --status-bg
|
|
19
|
+
* --status-fg
|
|
17
20
|
*/
|
|
18
21
|
|
|
19
22
|
/* Intent boundary — inherited intents do not tint this component.
|
|
20
23
|
Local intent classes still win because :where() has zero specificity. */
|
|
21
24
|
:where(.status-bar) {
|
|
22
|
-
/* @sync intent-boundary */
|
|
23
25
|
--intent: initial;
|
|
24
26
|
--intent-fg: initial;
|
|
25
|
-
--ui-bg: initial;
|
|
26
|
-
--ui-fg: initial;
|
|
27
|
-
--ui-border: initial;
|
|
28
|
-
--ui-hover-bg: initial;
|
|
29
|
-
/* @sync intent-boundary */
|
|
30
27
|
}
|
|
31
28
|
|
|
32
29
|
.status-bar {
|
|
@@ -34,22 +31,22 @@
|
|
|
34
31
|
--status-fg: var(--intent-fg, var(--surface));
|
|
35
32
|
|
|
36
33
|
position: fixed;
|
|
37
|
-
inset-block-end: var(--space-
|
|
38
|
-
inset-inline: var(--space-
|
|
39
|
-
z-index: var(--z-status
|
|
34
|
+
inset-block-end: var(--space-40);
|
|
35
|
+
inset-inline: var(--space-40);
|
|
36
|
+
z-index: var(--z-status);
|
|
40
37
|
|
|
41
38
|
display: inline-flex;
|
|
42
39
|
align-items: center;
|
|
43
40
|
justify-content: center;
|
|
44
|
-
gap: var(--space-
|
|
41
|
+
gap: var(--space-20);
|
|
45
42
|
|
|
46
43
|
inline-size: fit-content;
|
|
47
|
-
max-inline-size: min(calc(
|
|
44
|
+
max-inline-size: min(calc(var(--viewport-inline) - var(--space-60)), 32rem);
|
|
48
45
|
margin-inline: auto;
|
|
49
46
|
overflow-wrap: anywhere;
|
|
50
47
|
|
|
51
|
-
padding-block: var(--space-
|
|
52
|
-
padding-inline: var(--space-
|
|
48
|
+
padding-block: var(--space-20);
|
|
49
|
+
padding-inline: var(--space-30);
|
|
53
50
|
|
|
54
51
|
border-radius: var(--radius-full);
|
|
55
52
|
background: var(--status-bg);
|
|
@@ -62,21 +59,14 @@
|
|
|
62
59
|
pointer-events: none;
|
|
63
60
|
|
|
64
61
|
transition:
|
|
65
|
-
opacity var(--duration-slow) var(--ease
|
|
66
|
-
scale var(--duration-slow) var(--ease
|
|
67
|
-
translate var(--duration-slow) var(--ease
|
|
62
|
+
opacity var(--duration-slow) var(--ease),
|
|
63
|
+
scale var(--duration-slow) var(--ease),
|
|
64
|
+
translate var(--duration-slow) var(--ease);
|
|
68
65
|
}
|
|
69
66
|
|
|
70
67
|
.status-bar:empty {
|
|
71
68
|
opacity: 0;
|
|
72
69
|
scale: 0.96;
|
|
73
|
-
translate: 0 var(--space-
|
|
70
|
+
translate: 0 var(--space-20);
|
|
74
71
|
pointer-events: none;
|
|
75
72
|
}
|
|
76
|
-
|
|
77
|
-
@media (forced-colors: active) {
|
|
78
|
-
.status-bar {
|
|
79
|
-
border: var(--border-width) solid ButtonText;
|
|
80
|
-
box-shadow: none;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
z-index: calc(var(--z-menu) - 1);
|
|
20
20
|
background: var(--backdrop-fill);
|
|
21
21
|
opacity: 1;
|
|
22
|
-
transition: opacity var(--duration) var(--ease
|
|
22
|
+
transition: opacity var(--duration) var(--ease);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
.surface-backdrop[hidden] {
|
|
@@ -36,13 +36,7 @@
|
|
|
36
36
|
@supports (transition-behavior: allow-discrete) {
|
|
37
37
|
.surface-backdrop {
|
|
38
38
|
transition:
|
|
39
|
-
opacity var(--duration) var(--ease
|
|
39
|
+
opacity var(--duration) var(--ease),
|
|
40
40
|
display var(--duration) allow-discrete;
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
|
-
|
|
44
|
-
@media (forced-colors: active) {
|
|
45
|
-
.surface-backdrop {
|
|
46
|
-
background: Canvas;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
@@ -4,24 +4,20 @@
|
|
|
4
4
|
* JavaScript owns roving tabindex, aria-selected, panel visibility,
|
|
5
5
|
* and arrow-key navigation. CSS owns the tab strip appearance and
|
|
6
6
|
* active indicator.
|
|
7
|
+
*
|
|
8
|
+
* Public hooks:
|
|
9
|
+
* --tab-gap
|
|
7
10
|
*/
|
|
8
11
|
/* Intent boundary — inherited intents do not tint this component.
|
|
9
12
|
Local intent classes still win because :where() has zero specificity. */
|
|
10
13
|
:where(.tab) {
|
|
11
|
-
/* @sync intent-boundary */
|
|
12
14
|
--intent: initial;
|
|
13
|
-
--intent-fg: initial;
|
|
14
|
-
--ui-bg: initial;
|
|
15
|
-
--ui-fg: initial;
|
|
16
|
-
--ui-border: initial;
|
|
17
|
-
--ui-hover-bg: initial;
|
|
18
|
-
/* @sync intent-boundary */
|
|
19
15
|
}
|
|
20
16
|
|
|
21
17
|
.tabs {
|
|
22
18
|
display: flex;
|
|
23
19
|
flex-wrap: wrap;
|
|
24
|
-
gap: var(--space-
|
|
20
|
+
gap: var(--space-10);
|
|
25
21
|
margin: 0;
|
|
26
22
|
padding: 0;
|
|
27
23
|
border-block-end: var(--border-width) solid var(--border);
|
|
@@ -39,8 +35,9 @@
|
|
|
39
35
|
.tab {
|
|
40
36
|
display: inline-flex;
|
|
41
37
|
align-items: center;
|
|
38
|
+
gap: var(--tab-gap, 0.375em);
|
|
42
39
|
min-block-size: var(--control-size);
|
|
43
|
-
padding-inline: var(--space-
|
|
40
|
+
padding-inline: var(--space-30);
|
|
44
41
|
border: 0;
|
|
45
42
|
border-block-end: 2px solid transparent;
|
|
46
43
|
border-radius: 0;
|
|
@@ -56,7 +53,7 @@
|
|
|
56
53
|
justify-content: flex-start;
|
|
57
54
|
border-block-end: 0;
|
|
58
55
|
border-inline-end: 2px solid transparent;
|
|
59
|
-
padding-inline-end: var(--space-
|
|
56
|
+
padding-inline-end: var(--space-40);
|
|
60
57
|
}
|
|
61
58
|
|
|
62
59
|
.tab:is(:disabled, [aria-disabled="true"]) {
|
|
@@ -64,64 +61,39 @@
|
|
|
64
61
|
opacity: var(--disabled-opacity);
|
|
65
62
|
}
|
|
66
63
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
color: var(--text);
|
|
70
|
-
}
|
|
64
|
+
.tab:hover:not(:where(:disabled, [aria-disabled="true"])) {
|
|
65
|
+
color: var(--text);
|
|
71
66
|
}
|
|
72
67
|
|
|
73
68
|
.tab:focus-visible {
|
|
74
69
|
outline: var(--focus-outline);
|
|
70
|
+
outline-color: var(--focus);
|
|
75
71
|
outline-offset: -2px;
|
|
76
72
|
border-radius: var(--radius-sm) var(--radius-sm) 0 0;
|
|
77
73
|
}
|
|
78
74
|
|
|
79
|
-
.tab[aria-selected="true"]
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
border-block-end-color: var(--intent, var(--primary));
|
|
83
|
-
color: var(--intent, var(--primary));
|
|
75
|
+
.tab[aria-selected="true"] {
|
|
76
|
+
border-block-end-color: var(--intent, var(--state-selected));
|
|
77
|
+
color: var(--intent, var(--state-selected));
|
|
84
78
|
}
|
|
85
79
|
|
|
86
|
-
.tabs[aria-orientation="vertical"] .tab[aria-selected="true"]
|
|
87
|
-
.tabs[aria-orientation="vertical"] .tab[aria-current]:not([aria-current="false"]),
|
|
88
|
-
.tabs[aria-orientation="vertical"] .tab[aria-pressed="true"] {
|
|
80
|
+
.tabs[aria-orientation="vertical"] .tab[aria-selected="true"] {
|
|
89
81
|
border-block-end-color: transparent;
|
|
90
|
-
border-inline-end-color: var(--intent, var(--
|
|
82
|
+
border-inline-end-color: var(--intent, var(--state-selected));
|
|
91
83
|
}
|
|
92
84
|
|
|
93
85
|
@media (forced-colors: active) {
|
|
94
|
-
.
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
.tabs[aria-orientation="vertical"] {
|
|
99
|
-
border-block-end-color: transparent;
|
|
100
|
-
border-inline-end-color: ButtonText;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
.tab {
|
|
104
|
-
color: ButtonText;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
@media (hover: hover) {
|
|
108
|
-
.tab:hover:not(:where(:disabled, [aria-disabled="true"])) {
|
|
109
|
-
color: ButtonText;
|
|
110
|
-
text-decoration: underline;
|
|
111
|
-
text-underline-offset: 0.18em;
|
|
112
|
-
}
|
|
86
|
+
.tab:hover:not(:where(:disabled, [aria-disabled="true"])) {
|
|
87
|
+
text-decoration: underline;
|
|
88
|
+
text-underline-offset: 0.18em;
|
|
113
89
|
}
|
|
114
90
|
|
|
115
|
-
.tab[aria-selected="true"]
|
|
116
|
-
.tab[aria-current]:not([aria-current="false"]),
|
|
117
|
-
.tab[aria-pressed="true"] {
|
|
91
|
+
.tab[aria-selected="true"] {
|
|
118
92
|
border-block-end-color: Highlight;
|
|
119
93
|
color: Highlight;
|
|
120
94
|
}
|
|
121
95
|
|
|
122
|
-
.tabs[aria-orientation="vertical"] .tab[aria-selected="true"]
|
|
123
|
-
.tabs[aria-orientation="vertical"] .tab[aria-current]:not([aria-current="false"]),
|
|
124
|
-
.tabs[aria-orientation="vertical"] .tab[aria-pressed="true"] {
|
|
96
|
+
.tabs[aria-orientation="vertical"] .tab[aria-selected="true"] {
|
|
125
97
|
border-block-end-color: transparent;
|
|
126
98
|
border-inline-end-color: Highlight;
|
|
127
99
|
}
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* .table-wrap provides the scroll container and outer chrome; .table owns row
|
|
5
5
|
* and cell rules. Tokens are sourced from the shared scale.
|
|
6
|
+
*
|
|
7
|
+
* Public hooks:
|
|
8
|
+
* --table-min
|
|
9
|
+
* --table-cell-pad
|
|
6
10
|
*/
|
|
7
11
|
.table-wrap {
|
|
8
12
|
inline-size: 100%;
|
|
@@ -16,7 +20,7 @@
|
|
|
16
20
|
|
|
17
21
|
.table {
|
|
18
22
|
--table-min: 100%;
|
|
19
|
-
--table-cell-pad: var(--space-
|
|
23
|
+
--table-cell-pad: var(--space-30);
|
|
20
24
|
|
|
21
25
|
inline-size: max(var(--table-min), 100%);
|
|
22
26
|
border-collapse: collapse;
|
|
@@ -52,10 +56,8 @@
|
|
|
52
56
|
background: var(--surface-subtle);
|
|
53
57
|
}
|
|
54
58
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
background-color: var(--hover-overlay);
|
|
58
|
-
}
|
|
59
|
+
.table tbody tr:hover {
|
|
60
|
+
background-color: var(--hover-overlay);
|
|
59
61
|
}
|
|
60
62
|
|
|
61
63
|
.table > tr:last-child > *,
|
|
@@ -4,6 +4,15 @@
|
|
|
4
4
|
* Position, placement, and arrow position are managed by JavaScript
|
|
5
5
|
* via position: fixed, left, top, data-placement, and --arrow-x.
|
|
6
6
|
* Visibility is managed with hidden; CSS owns entry and exit animation.
|
|
7
|
+
*
|
|
8
|
+
* Public hooks:
|
|
9
|
+
* --tooltip-bg
|
|
10
|
+
* --tooltip-fg
|
|
11
|
+
* --tooltip-arrow-size
|
|
12
|
+
*
|
|
13
|
+
* Internal:
|
|
14
|
+
* --arrow-x (arrow position, written by floating.js)
|
|
15
|
+
* --arrow-y (arrow position, written by floating.js)
|
|
7
16
|
*/
|
|
8
17
|
.tooltip {
|
|
9
18
|
--tooltip-bg: var(--surface-solid);
|
|
@@ -25,8 +34,8 @@
|
|
|
25
34
|
opacity: 1;
|
|
26
35
|
scale: 1;
|
|
27
36
|
transition:
|
|
28
|
-
opacity var(--duration-fast
|
|
29
|
-
scale var(--duration-fast
|
|
37
|
+
opacity var(--duration-fast) var(--ease),
|
|
38
|
+
scale var(--duration-fast) var(--ease);
|
|
30
39
|
}
|
|
31
40
|
|
|
32
41
|
.tooltip[hidden] {
|
|
@@ -45,9 +54,9 @@
|
|
|
45
54
|
@supports (transition-behavior: allow-discrete) {
|
|
46
55
|
.tooltip {
|
|
47
56
|
transition:
|
|
48
|
-
opacity var(--duration-fast
|
|
49
|
-
scale var(--duration-fast
|
|
50
|
-
display var(--duration-fast
|
|
57
|
+
opacity var(--duration-fast) var(--ease),
|
|
58
|
+
scale var(--duration-fast) var(--ease),
|
|
59
|
+
display var(--duration-fast) allow-discrete;
|
|
51
60
|
}
|
|
52
61
|
}
|
|
53
62
|
|
|
@@ -97,8 +106,6 @@
|
|
|
97
106
|
.tooltip {
|
|
98
107
|
--tooltip-bg: Canvas;
|
|
99
108
|
--tooltip-fg: CanvasText;
|
|
100
|
-
|
|
101
|
-
border: var(--border-width) solid ButtonText;
|
|
102
109
|
}
|
|
103
110
|
|
|
104
111
|
.tooltip::before {
|
package/src/css/focus.css
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
/* Focus baseline —
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/* Focus baseline — a visible outline is the guaranteed focus affordance. The
|
|
2
|
+
:focus outline covers legacy browsers; modern browsers hide it for
|
|
3
|
+
pointer/mouse focus and interactive components layer their ring on top.
|
|
4
|
+
|
|
5
|
+
Invariant: an interactive component must never rely on box-shadow alone
|
|
6
|
+
for its keyboard focus indicator. Components that remove the native
|
|
7
|
+
outline on :focus-visible replace it with a transparent outline — invisible
|
|
8
|
+
normally, forced to the system focus color under forced-colors. */
|
|
4
9
|
:focus {
|
|
5
10
|
outline: var(--focus-outline);
|
|
6
11
|
outline-offset: var(--focus-outline-offset);
|
|
@@ -10,4 +15,12 @@
|
|
|
10
15
|
:focus:not(:focus-visible) {
|
|
11
16
|
outline: none;
|
|
12
17
|
}
|
|
18
|
+
|
|
19
|
+
/* Pointer focus must still signal in high-contrast mode, where the shared
|
|
20
|
+
box-shadow rings are disabled (--focus-ring-shadow: none). */
|
|
21
|
+
@media (forced-colors: active) {
|
|
22
|
+
:focus:not(:focus-visible) {
|
|
23
|
+
outline: var(--focus-outline);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
13
26
|
}
|
|
@@ -10,20 +10,21 @@
|
|
|
10
10
|
* The badge overhangs the top-right corner by 0.375em; ancestors with
|
|
11
11
|
* overflow: hidden will clip it. Pair with grid or flex utilities for group
|
|
12
12
|
* layout.
|
|
13
|
+
*
|
|
14
|
+
* Public hooks:
|
|
15
|
+
* --choice-card-pad
|
|
16
|
+
* --choice-card-radius
|
|
17
|
+
* --choice-card-border
|
|
18
|
+
* --choice-card-bg
|
|
19
|
+
* --choice-card-check-size
|
|
13
20
|
*/
|
|
14
21
|
:where(.choice-card) {
|
|
15
|
-
/* @sync intent-boundary */
|
|
16
22
|
--intent: initial;
|
|
17
23
|
--intent-fg: initial;
|
|
18
|
-
--ui-bg: initial;
|
|
19
|
-
--ui-fg: initial;
|
|
20
|
-
--ui-border: initial;
|
|
21
|
-
--ui-hover-bg: initial;
|
|
22
|
-
/* @sync intent-boundary */
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
.choice-card {
|
|
26
|
-
--choice-card-pad: var(--
|
|
27
|
+
--choice-card-pad: var(--density-space, var(--space-40));
|
|
27
28
|
--choice-card-radius: var(--radius);
|
|
28
29
|
--choice-card-border: var(--border);
|
|
29
30
|
--choice-card-bg: var(--surface);
|
|
@@ -63,8 +64,7 @@
|
|
|
63
64
|
|
|
64
65
|
/* Focus ring on the label follows the hidden input's focus. */
|
|
65
66
|
.choice-card:has(:focus-visible) {
|
|
66
|
-
outline:
|
|
67
|
-
outline-offset: var(--focus-outline-offset);
|
|
67
|
+
outline: 2px solid transparent;
|
|
68
68
|
box-shadow: var(--focus-ring-shadow);
|
|
69
69
|
}
|
|
70
70
|
|
|
@@ -73,10 +73,8 @@
|
|
|
73
73
|
cursor: not-allowed;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
--choice-card-border: var(--text-subtle);
|
|
79
|
-
}
|
|
76
|
+
.choice-card:hover:not(:has(:disabled)) {
|
|
77
|
+
--choice-card-border: var(--text-subtle);
|
|
80
78
|
}
|
|
81
79
|
|
|
82
80
|
/* Checked border — shared by radio and checkbox */
|
|
@@ -123,8 +121,8 @@
|
|
|
123
121
|
/* Check mark */
|
|
124
122
|
.choice-card::after {
|
|
125
123
|
background: var(--intent-fg, var(--primary-fg));
|
|
126
|
-
-webkit-mask: var(--icon-check
|
|
127
|
-
mask: var(--icon-check
|
|
124
|
+
-webkit-mask: var(--icon-check) center / 60% no-repeat;
|
|
125
|
+
mask: var(--icon-check) center / 60% no-repeat;
|
|
128
126
|
z-index: 2;
|
|
129
127
|
}
|
|
130
128
|
|
package/src/css/forms/choice.css
CHANGED
|
@@ -8,23 +8,23 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Switches (input[role="switch"]) are excluded so switch.css owns their
|
|
10
10
|
* geometry and states. switch.css is imported after this file.
|
|
11
|
+
*
|
|
12
|
+
* Public hooks:
|
|
13
|
+
* --choice-control-offset
|
|
14
|
+
* --choice-border
|
|
15
|
+
* --choice-bg
|
|
16
|
+
* --choice-mark
|
|
11
17
|
*/
|
|
12
18
|
/* Intent boundary — inherited intents do not tint this component.
|
|
13
19
|
Local intent classes still win because :where() has zero specificity. */
|
|
14
20
|
:where(.choice, .check, .radio) {
|
|
15
|
-
/* @sync intent-boundary */
|
|
16
21
|
--intent: initial;
|
|
17
22
|
--intent-fg: initial;
|
|
18
|
-
--ui-bg: initial;
|
|
19
|
-
--ui-fg: initial;
|
|
20
|
-
--ui-border: initial;
|
|
21
|
-
--ui-hover-bg: initial;
|
|
22
|
-
/* @sync intent-boundary */
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
/* A classed .choice is the component surface. Let its
|
|
25
|
+
/* A classed .choice is the component surface. Let its direct input consume a
|
|
26
26
|
local intent without reopening inherited page-level intents. */
|
|
27
|
-
:where(.choice) :where(input[type="checkbox"]:not([role="switch"]), input[type="radio"]) {
|
|
27
|
+
:where(.choice) > :where(input[type="checkbox"]:not([role="switch"]), input[type="radio"]) {
|
|
28
28
|
--intent: inherit;
|
|
29
29
|
--intent-fg: inherit;
|
|
30
30
|
}
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
|
|
35
35
|
display: inline-flex;
|
|
36
36
|
align-items: flex-start;
|
|
37
|
-
gap: var(--space-
|
|
37
|
+
gap: var(--space-20);
|
|
38
38
|
color: var(--text);
|
|
39
39
|
font-size: var(--control-font-size);
|
|
40
40
|
cursor: pointer;
|
|
@@ -57,8 +57,11 @@
|
|
|
57
57
|
display: block;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
/* Progressive enhancement: dim the whole row when one of its controls is
|
|
61
|
+
disabled. Without :has() the native disabled control keeps its own state
|
|
62
|
+
styling — the row-level dim is lost but the field stays clearly disabled. */
|
|
63
|
+
.choice:has(> :disabled) {
|
|
64
|
+
color: var(--state-disabled);
|
|
62
65
|
cursor: not-allowed;
|
|
63
66
|
}
|
|
64
67
|
|
|
@@ -75,8 +78,7 @@
|
|
|
75
78
|
place-content: center;
|
|
76
79
|
inline-size: 1.125em;
|
|
77
80
|
block-size: 1.125em;
|
|
78
|
-
margin
|
|
79
|
-
margin-block-end: 0;
|
|
81
|
+
margin: 0;
|
|
80
82
|
border: var(--border-width) solid var(--form-invalid-border, var(--choice-border));
|
|
81
83
|
background: var(--choice-bg);
|
|
82
84
|
color: var(--choice-mark);
|
|
@@ -117,7 +119,7 @@
|
|
|
117
119
|
background: currentColor;
|
|
118
120
|
}
|
|
119
121
|
|
|
120
|
-
.check:checked,
|
|
122
|
+
.check:is(:checked, :indeterminate),
|
|
121
123
|
.radio:checked {
|
|
122
124
|
--choice-border: var(--intent, var(--primary));
|
|
123
125
|
--choice-bg: var(--intent, var(--primary));
|
|
@@ -128,12 +130,6 @@
|
|
|
128
130
|
transform: translateY(-0.06em) rotate(-45deg) scale(1);
|
|
129
131
|
}
|
|
130
132
|
|
|
131
|
-
.check:indeterminate {
|
|
132
|
-
--choice-border: var(--intent, var(--primary));
|
|
133
|
-
--choice-bg: var(--intent, var(--primary));
|
|
134
|
-
--choice-mark: var(--intent-fg, var(--primary-fg));
|
|
135
|
-
}
|
|
136
|
-
|
|
137
133
|
.check:indeterminate::before {
|
|
138
134
|
border-inline-start: 0;
|
|
139
135
|
inline-size: 0.6em;
|
|
@@ -146,18 +142,15 @@
|
|
|
146
142
|
transform: scale(1);
|
|
147
143
|
}
|
|
148
144
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
--choice-border: var(--text-subtle);
|
|
153
|
-
}
|
|
145
|
+
.check:hover:not(:checked, :indeterminate, :disabled),
|
|
146
|
+
.radio:hover:not(:checked, :indeterminate, :disabled) {
|
|
147
|
+
--choice-border: var(--text-subtle);
|
|
154
148
|
}
|
|
155
149
|
|
|
156
150
|
.check:focus-visible,
|
|
157
151
|
.radio:focus-visible {
|
|
158
152
|
--choice-border: var(--focus);
|
|
159
|
-
outline:
|
|
160
|
-
outline-offset: var(--focus-outline-offset);
|
|
153
|
+
outline: 2px solid transparent;
|
|
161
154
|
box-shadow: var(--focus-ring-shadow);
|
|
162
155
|
}
|
|
163
156
|
|
|
@@ -165,7 +158,7 @@
|
|
|
165
158
|
.radio:disabled {
|
|
166
159
|
--choice-bg: var(--surface-subtle);
|
|
167
160
|
--choice-border: var(--border);
|
|
168
|
-
--choice-mark: var(--
|
|
161
|
+
--choice-mark: var(--state-disabled);
|
|
169
162
|
cursor: not-allowed;
|
|
170
163
|
opacity: 1;
|
|
171
164
|
}
|
|
@@ -14,6 +14,12 @@
|
|
|
14
14
|
* --control-border-block-end-color/-width are unset extension points, mirroring
|
|
15
15
|
* --btn-border-block-end-* (button.css), for themes that give text controls an
|
|
16
16
|
* underline-style lower edge instead of a uniform border.
|
|
17
|
+
*
|
|
18
|
+
* Public hooks:
|
|
19
|
+
* --control-border
|
|
20
|
+
* --control-bg
|
|
21
|
+
* --control-fg
|
|
22
|
+
* --control-cursor
|
|
17
23
|
*/
|
|
18
24
|
.input,
|
|
19
25
|
.textarea,
|
|
@@ -21,14 +27,12 @@
|
|
|
21
27
|
--control-border: var(--border);
|
|
22
28
|
--control-bg: var(--surface);
|
|
23
29
|
--control-fg: var(--text);
|
|
24
|
-
--control-ring: none;
|
|
25
30
|
--control-cursor: auto;
|
|
26
|
-
--control-opacity: 1;
|
|
27
31
|
|
|
28
32
|
appearance: none;
|
|
29
33
|
inline-size: 100%;
|
|
30
34
|
min-block-size: var(--control-size);
|
|
31
|
-
padding-inline: var(--space-
|
|
35
|
+
padding-inline: var(--space-30);
|
|
32
36
|
border: var(--border-width) solid var(--form-invalid-border, var(--control-border));
|
|
33
37
|
border-block-end-color: var(
|
|
34
38
|
--form-invalid-border,
|
|
@@ -39,9 +43,7 @@
|
|
|
39
43
|
background: var(--control-bg);
|
|
40
44
|
color: var(--control-fg);
|
|
41
45
|
font-size: var(--control-font-size);
|
|
42
|
-
box-shadow: var(--control-ring);
|
|
43
46
|
cursor: var(--control-cursor);
|
|
44
|
-
opacity: var(--control-opacity);
|
|
45
47
|
outline: none;
|
|
46
48
|
transition:
|
|
47
49
|
border-color var(--duration),
|
|
@@ -52,27 +54,24 @@
|
|
|
52
54
|
|
|
53
55
|
.textarea {
|
|
54
56
|
min-block-size: 6rem;
|
|
55
|
-
padding-block: var(--space-
|
|
57
|
+
padding-block: var(--space-20);
|
|
56
58
|
resize: vertical;
|
|
57
59
|
}
|
|
58
60
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
61
|
+
.input:hover:not(:disabled),
|
|
62
|
+
.textarea:hover:not(:disabled) {
|
|
63
|
+
--control-border: var(--text-subtle);
|
|
64
|
+
}
|
|
64
65
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
66
|
+
.select:hover:not(:disabled) {
|
|
67
|
+
--control-bg: var(--surface-subtle);
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
.input:focus-visible,
|
|
71
71
|
.textarea:focus-visible,
|
|
72
72
|
.select:focus-visible {
|
|
73
73
|
--control-border: var(--focus);
|
|
74
|
-
outline:
|
|
75
|
-
outline-offset: var(--focus-outline-offset);
|
|
74
|
+
outline: 2px solid transparent;
|
|
76
75
|
box-shadow: var(--focus-ring-shadow);
|
|
77
76
|
}
|
|
78
77
|
|
|
@@ -86,21 +85,12 @@
|
|
|
86
85
|
.textarea:disabled,
|
|
87
86
|
.select:disabled {
|
|
88
87
|
--control-bg: var(--surface-subtle);
|
|
89
|
-
--control-fg: var(--
|
|
88
|
+
--control-fg: var(--state-disabled);
|
|
90
89
|
--control-border: var(--border);
|
|
91
90
|
--control-cursor: not-allowed;
|
|
92
|
-
--control-opacity: 1;
|
|
93
91
|
}
|
|
94
92
|
|
|
95
93
|
.input::placeholder,
|
|
96
94
|
.textarea::placeholder {
|
|
97
95
|
color: var(--text-muted);
|
|
98
96
|
}
|
|
99
|
-
|
|
100
|
-
@media (forced-colors: active) {
|
|
101
|
-
.input:focus-visible,
|
|
102
|
-
.textarea:focus-visible,
|
|
103
|
-
.select:focus-visible {
|
|
104
|
-
box-shadow: none;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
@@ -7,6 +7,10 @@
|
|
|
7
7
|
*
|
|
8
8
|
* No layout or interaction contract may depend on appearance: base-select.
|
|
9
9
|
* Arbitrary menu and popover behavior belongs elsewhere.
|
|
10
|
+
*
|
|
11
|
+
* Internal:
|
|
12
|
+
* --control-border
|
|
13
|
+
* --control-bg
|
|
10
14
|
*/
|
|
11
15
|
@media (forced-colors: none) and (prefers-contrast: no-preference) and (hover: hover) and (
|
|
12
16
|
pointer: fine
|
|
@@ -19,7 +23,7 @@
|
|
|
19
23
|
&::picker(select) {
|
|
20
24
|
appearance: base-select;
|
|
21
25
|
max-height: min(24rem, calc(var(--viewport-block) * 0.7));
|
|
22
|
-
margin-block: var(--space-
|
|
26
|
+
margin-block: var(--space-20);
|
|
23
27
|
padding: 0;
|
|
24
28
|
border: var(--border-width) solid var(--border);
|
|
25
29
|
border-radius: var(--radius);
|
|
@@ -41,8 +45,8 @@
|
|
|
41
45
|
|
|
42
46
|
& option {
|
|
43
47
|
position: relative;
|
|
44
|
-
padding-block: var(--space-
|
|
45
|
-
padding-inline: var(--space-
|
|
48
|
+
padding-block: var(--space-20);
|
|
49
|
+
padding-inline: var(--space-30);
|
|
46
50
|
white-space: normal;
|
|
47
51
|
transition-property: color, background-color;
|
|
48
52
|
transition-duration: var(--duration);
|
|
@@ -70,14 +74,8 @@
|
|
|
70
74
|
inline-size: 1rem;
|
|
71
75
|
block-size: 1rem;
|
|
72
76
|
background-color: currentColor;
|
|
73
|
-
-webkit-mask
|
|
74
|
-
mask
|
|
75
|
-
-webkit-mask-repeat: no-repeat;
|
|
76
|
-
mask-repeat: no-repeat;
|
|
77
|
-
-webkit-mask-size: contain;
|
|
78
|
-
mask-size: contain;
|
|
79
|
-
-webkit-mask-position: center;
|
|
80
|
-
mask-position: center;
|
|
77
|
+
-webkit-mask: var(--icon-check) center / contain no-repeat;
|
|
78
|
+
mask: var(--icon-check) center / contain no-repeat;
|
|
81
79
|
}
|
|
82
80
|
}
|
|
83
81
|
|