@slotted/styles 0.0.0-stage → 0.1.0-beta.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/LICENSE +21 -0
- package/README.md +10 -2
- package/package.json +276 -3
- package/src/accordion/accordion.css +96 -0
- package/src/accordion/accordion.tokens.json +14 -0
- package/src/action-bar/action-bar.css +455 -0
- package/src/action-bar/action-bar.tokens.json +50 -0
- package/src/action-sheet/action-sheet.css +462 -0
- package/src/action-sheet/action-sheet.tokens.json +59 -0
- package/src/alert/alert.css +764 -0
- package/src/alert/alert.tokens.json +77 -0
- package/src/app-shell/app-shell.css +1899 -0
- package/src/app-shell/app-shell.tokens.json +88 -0
- package/src/aspect-ratio/aspect-ratio.css +131 -0
- package/src/aspect-ratio/aspect-ratio.tokens.json +1 -0
- package/src/attachment/attachment.css +906 -0
- package/src/attachment/attachment.tokens.json +85 -0
- package/src/avatar/avatar.css +598 -0
- package/src/avatar/avatar.tokens.json +64 -0
- package/src/avatar-group/avatar-group.css +268 -0
- package/src/avatar-group/avatar-group.tokens.json +16 -0
- package/src/badge/badge.css +462 -0
- package/src/badge/badge.tokens.json +58 -0
- package/src/breadcrumb/breadcrumb.css +441 -0
- package/src/breadcrumb/breadcrumb.tokens.json +50 -0
- package/src/button/button.css +754 -0
- package/src/button/button.tokens.json +72 -0
- package/src/button-group/button-group.css +455 -0
- package/src/button-group/button-group.tokens.json +11 -0
- package/src/calendar/calendar.css +846 -0
- package/src/calendar/calendar.tokens.json +67 -0
- package/src/card/card.css +602 -0
- package/src/card/card.tokens.json +68 -0
- package/src/carousel/carousel.css +860 -0
- package/src/carousel/carousel.tokens.json +62 -0
- package/src/cascader/cascader.css +1320 -0
- package/src/cascader/cascader.tokens.json +103 -0
- package/src/chart/chart.css +1473 -0
- package/src/chart/chart.tokens.json +107 -0
- package/src/checkbox/checkbox.css +1011 -0
- package/src/checkbox/checkbox.tokens.json +102 -0
- package/src/checkbox-group/checkbox-group.css +70 -0
- package/src/checkbox-group/checkbox-group.tokens.json +6 -0
- package/src/code-block/code-block.css +555 -0
- package/src/code-block/code-block.tokens.json +69 -0
- package/src/collapsible/collapsible.css +546 -0
- package/src/collapsible/collapsible.tokens.json +55 -0
- package/src/color-picker/color-picker.css +607 -0
- package/src/color-picker/color-picker.tokens.json +58 -0
- package/src/column-manager/column-manager.css +452 -0
- package/src/column-manager/column-manager.tokens.json +43 -0
- package/src/combobox/combobox.css +1048 -0
- package/src/combobox/combobox.tokens.json +112 -0
- package/src/command-palette/command-palette.css +1000 -0
- package/src/command-palette/command-palette.tokens.json +75 -0
- package/src/container/container.css +198 -0
- package/src/container/container.tokens.json +18 -0
- package/src/context-menu/context-menu.css +104 -0
- package/src/context-menu/context-menu.tokens.json +11 -0
- package/src/currency-field/currency-field.css +787 -0
- package/src/currency-field/currency-field.tokens.json +80 -0
- package/src/dashboard-grid/dashboard-grid.css +748 -0
- package/src/dashboard-grid/dashboard-grid.tokens.json +67 -0
- package/src/data-grid/data-grid.css +2484 -0
- package/src/data-grid/data-grid.tokens.json +100 -0
- package/src/data-list/data-list.css +455 -0
- package/src/data-list/data-list.tokens.json +35 -0
- package/src/date-field/date-field.css +560 -0
- package/src/date-field/date-field.tokens.json +80 -0
- package/src/date-picker/date-picker.css +420 -0
- package/src/date-picker/date-picker.tokens.json +49 -0
- package/src/date-range-picker/date-range-picker.css +983 -0
- package/src/date-range-picker/date-range-picker.tokens.json +109 -0
- package/src/datetime-field/datetime-field.css +850 -0
- package/src/datetime-field/datetime-field.tokens.json +91 -0
- package/src/datetime-picker/datetime-picker.css +843 -0
- package/src/datetime-picker/datetime-picker.tokens.json +78 -0
- package/src/datetime-range-picker/datetime-range-picker.css +1375 -0
- package/src/datetime-range-picker/datetime-range-picker.tokens.json +135 -0
- package/src/description-list/description-list.css +675 -0
- package/src/description-list/description-list.tokens.json +66 -0
- package/src/detail-panel/detail-panel.css +329 -0
- package/src/detail-panel/detail-panel.tokens.json +33 -0
- package/src/dialog/dialog.css +968 -0
- package/src/dialog/dialog.tokens.json +66 -0
- package/src/divider/divider.css +131 -0
- package/src/divider/divider.tokens.json +18 -0
- package/src/drawer/drawer.css +1303 -0
- package/src/drawer/drawer.tokens.json +75 -0
- package/src/entity-picker/entity-picker.css +1367 -0
- package/src/entity-picker/entity-picker.tokens.json +118 -0
- package/src/event-calendar/event-calendar.css +2148 -0
- package/src/event-calendar/event-calendar.tokens.json +87 -0
- package/src/field/field.css +707 -0
- package/src/field/field.tokens.json +58 -0
- package/src/field-group/field-group.css +226 -0
- package/src/field-group/field-group.tokens.json +33 -0
- package/src/filter-bar/filter-bar.css +1306 -0
- package/src/filter-bar/filter-bar.tokens.json +78 -0
- package/src/form/form.css +218 -0
- package/src/form/form.tokens.json +32 -0
- package/src/fullscreen/fullscreen.css +376 -0
- package/src/fullscreen/fullscreen.tokens.json +50 -0
- package/src/grid/grid.css +173 -0
- package/src/grid/grid.tokens.json +20 -0
- package/src/highlight/highlight.css +135 -0
- package/src/highlight/highlight.tokens.json +16 -0
- package/src/hover-card/hover-card.css +93 -0
- package/src/hover-card/hover-card.tokens.json +17 -0
- package/src/icon/icon.css +136 -0
- package/src/icon/icon.tokens.json +14 -0
- package/src/image/image.css +449 -0
- package/src/image/image.tokens.json +27 -0
- package/src/import-export-center/import-export-center.css +1175 -0
- package/src/import-export-center/import-export-center.tokens.json +84 -0
- package/src/inline/inline.css +149 -0
- package/src/inline/inline.tokens.json +14 -0
- package/src/inline-message/inline-message.css +396 -0
- package/src/inline-message/inline-message.tokens.json +19 -0
- package/src/kbd/kbd.css +490 -0
- package/src/kbd/kbd.tokens.json +40 -0
- package/src/link/link.css +237 -0
- package/src/link/link.tokens.json +25 -0
- package/src/list/list.css +240 -0
- package/src/list/list.tokens.json +42 -0
- package/src/list-item/list-item.css +937 -0
- package/src/list-item/list-item.tokens.json +114 -0
- package/src/listbox/listbox.css +674 -0
- package/src/listbox/listbox.tokens.json +72 -0
- package/src/loading-overlay/loading-overlay.css +730 -0
- package/src/loading-overlay/loading-overlay.tokens.json +48 -0
- package/src/markdown/markdown.css +168 -0
- package/src/markdown/markdown.tokens.json +18 -0
- package/src/menu/menu.css +817 -0
- package/src/menu/menu.tokens.json +78 -0
- package/src/menubar/menubar.css +170 -0
- package/src/menubar/menubar.tokens.json +32 -0
- package/src/message/message.css +1453 -0
- package/src/message/message.tokens.json +85 -0
- package/src/message-scroller/message-scroller.css +371 -0
- package/src/message-scroller/message-scroller.tokens.json +47 -0
- package/src/multi-select/multi-select.css +1427 -0
- package/src/multi-select/multi-select.tokens.json +114 -0
- package/src/navigation-menu/navigation-menu.css +1029 -0
- package/src/navigation-menu/navigation-menu.tokens.json +70 -0
- package/src/notification-center/notification-center.css +856 -0
- package/src/notification-center/notification-center.tokens.json +84 -0
- package/src/number-field/number-field.css +794 -0
- package/src/number-field/number-field.tokens.json +80 -0
- package/src/otp-input/otp-input.css +525 -0
- package/src/otp-input/otp-input.tokens.json +69 -0
- package/src/page/page.css +179 -0
- package/src/page/page.tokens.json +20 -0
- package/src/page-header/page-header.css +1181 -0
- package/src/page-header/page-header.tokens.json +71 -0
- package/src/pagination/pagination.css +500 -0
- package/src/pagination/pagination.tokens.json +56 -0
- package/src/popover/popover.css +526 -0
- package/src/popover/popover.tokens.json +60 -0
- package/src/progress-indicator/progress-indicator.css +1584 -0
- package/src/progress-indicator/progress-indicator.tokens.json +50 -0
- package/src/prompt-composer/prompt-composer.css +680 -0
- package/src/prompt-composer/prompt-composer.tokens.json +99 -0
- package/src/prose/prose.css +733 -0
- package/src/prose/prose.tokens.json +79 -0
- package/src/radio-group/radio-group.css +778 -0
- package/src/radio-group/radio-group.tokens.json +103 -0
- package/src/rating/rating.css +1071 -0
- package/src/rating/rating.tokens.json +88 -0
- package/src/result-state/result-state.css +980 -0
- package/src/result-state/result-state.tokens.json +63 -0
- package/src/runtime-properties.mjs +321 -0
- package/src/saved-views/saved-views.css +394 -0
- package/src/saved-views/saved-views.tokens.json +41 -0
- package/src/scroll-area/scroll-area.css +481 -0
- package/src/scroll-area/scroll-area.tokens.json +15 -0
- package/src/section/section.css +177 -0
- package/src/section/section.tokens.json +39 -0
- package/src/segmented-control/segmented-control.css +564 -0
- package/src/segmented-control/segmented-control.tokens.json +67 -0
- package/src/select/select.css +1593 -0
- package/src/select/select.tokens.json +110 -0
- package/src/side-navigation/side-navigation.css +1096 -0
- package/src/side-navigation/side-navigation.tokens.json +87 -0
- package/src/skeleton/skeleton.css +431 -0
- package/src/skeleton/skeleton.tokens.json +29 -0
- package/src/slider/slider.css +792 -0
- package/src/slider/slider.tokens.json +75 -0
- package/src/sparkline/sparkline.css +282 -0
- package/src/sparkline/sparkline.tokens.json +45 -0
- package/src/spinner/spinner.css +224 -0
- package/src/spinner/spinner.tokens.json +8 -0
- package/src/split-button/split-button.css +253 -0
- package/src/split-button/split-button.tokens.json +12 -0
- package/src/splitter/splitter.css +336 -0
- package/src/splitter/splitter.tokens.json +24 -0
- package/src/stack/stack.css +128 -0
- package/src/stack/stack.tokens.json +14 -0
- package/src/stat-card/stat-card.css +641 -0
- package/src/stat-card/stat-card.tokens.json +95 -0
- package/src/status-indicator/status-indicator.css +481 -0
- package/src/status-indicator/status-indicator.tokens.json +38 -0
- package/src/stepper/stepper.css +629 -0
- package/src/stepper/stepper.tokens.json +72 -0
- package/src/switch/switch.css +703 -0
- package/src/switch/switch.tokens.json +75 -0
- package/src/table/table.css +1482 -0
- package/src/table/table.tokens.json +69 -0
- package/src/table-of-contents/table-of-contents.css +533 -0
- package/src/table-of-contents/table-of-contents.tokens.json +53 -0
- package/src/tabs/tabs.css +998 -0
- package/src/tabs/tabs.tokens.json +82 -0
- package/src/tag/tag.css +768 -0
- package/src/tag/tag.tokens.json +85 -0
- package/src/tags-input/tags-input.css +757 -0
- package/src/tags-input/tags-input.tokens.json +84 -0
- package/src/text-field/text-field.css +900 -0
- package/src/text-field/text-field.tokens.json +87 -0
- package/src/textarea/textarea.css +365 -0
- package/src/textarea/textarea.tokens.json +59 -0
- package/src/time-field/time-field.css +719 -0
- package/src/time-field/time-field.tokens.json +86 -0
- package/src/time-picker/time-picker.css +665 -0
- package/src/time-picker/time-picker.tokens.json +66 -0
- package/src/time-range-picker/time-range-picker.css +1287 -0
- package/src/time-range-picker/time-range-picker.tokens.json +134 -0
- package/src/timeline/timeline.css +1596 -0
- package/src/timeline/timeline.tokens.json +96 -0
- package/src/toast/toast.css +943 -0
- package/src/toast/toast.tokens.json +90 -0
- package/src/toggle/toggle.css +290 -0
- package/src/toggle/toggle.tokens.json +54 -0
- package/src/toggle-group/toggle-group.css +463 -0
- package/src/toggle-group/toggle-group.tokens.json +54 -0
- package/src/toolbar/toolbar.css +434 -0
- package/src/toolbar/toolbar.tokens.json +49 -0
- package/src/tooltip/tooltip.css +368 -0
- package/src/tooltip/tooltip.tokens.json +39 -0
- package/src/top-navigation/top-navigation.css +1287 -0
- package/src/top-navigation/top-navigation.tokens.json +91 -0
- package/src/tour/tour.css +680 -0
- package/src/tour/tour.tokens.json +67 -0
- package/src/transfer/transfer.css +571 -0
- package/src/transfer/transfer.tokens.json +49 -0
- package/src/tree/tree.css +1000 -0
- package/src/tree/tree.tokens.json +80 -0
- package/src/typography/typography.css +211 -0
- package/src/typography/typography.tokens.json +31 -0
- package/src/upload/upload.css +1706 -0
- package/src/upload/upload.tokens.json +123 -0
- package/src/visually-hidden/visually-hidden.css +52 -0
- package/src/visually-hidden/visually-hidden.tokens.json +1 -0
- package/src/wizard/wizard.css +740 -0
- package/src/wizard/wizard.tokens.json +63 -0
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
@layer slotted.components {
|
|
2
|
+
/**
|
|
3
|
+
* ── A set of two-state buttons that share one value ────────────────────
|
|
4
|
+
*
|
|
5
|
+
* The root is a `div` carrying `role="group"`; each item is a `button`
|
|
6
|
+
* carrying `aria-pressed`. There is no APG pattern called "toggle group":
|
|
7
|
+
* the container is a group, each item is the Button pattern's toggle button,
|
|
8
|
+
* and the movement between them is the Toolbar pattern's roving tabindex.
|
|
9
|
+
* That is why the arrows move focus here and never toggle — the family that
|
|
10
|
+
* moves its value with the arrows is `segmented-control`, and it is a radio
|
|
11
|
+
* group because that is what the pattern describing that interaction is.
|
|
12
|
+
*
|
|
13
|
+
* The items are this family's own rather than `button`'s ToggleButton, and
|
|
14
|
+
* the reason is state and not paint: ToggleButton owns `pressed` with a
|
|
15
|
+
* complete controlled and uncontrolled model, so inside a group that owns
|
|
16
|
+
* the value there would be two owners of one fact. What it costs is written
|
|
17
|
+
* here: one selected colour instead of five tones. A consumer who wants the
|
|
18
|
+
* whole palette in a joined bar writes `button-group` around ToggleButtons.
|
|
19
|
+
*
|
|
20
|
+
* "On" is one colour across the system — the accent ground inside the accent
|
|
21
|
+
* edge, which is the pair `docs/token-foundation.md` names for the chosen
|
|
22
|
+
* row, card, option and toggle, and the same pair `button` paints a pressed
|
|
23
|
+
* ToggleButton with.
|
|
24
|
+
*
|
|
25
|
+
* ── The bar is exactly as tall as a control ───────────────────────────
|
|
26
|
+
*
|
|
27
|
+
* The root states no frame, no padding and no edge of its own: the bar's
|
|
28
|
+
* frame is the items' own borders, joined. So the group is
|
|
29
|
+
* `--slotted-control-height-*` tall to the pixel, and a bar beside a text
|
|
30
|
+
* field in a form lines up with it instead of standing two pixels prouder.
|
|
31
|
+
* The first pass framed the root as well, and the reviewer read the result
|
|
32
|
+
* correctly: a coloured border inside a grey one, and an edge that was one
|
|
33
|
+
* pixel in places and two in others.
|
|
34
|
+
*/
|
|
35
|
+
[data-ui='toggle-group'][data-part='root'] {
|
|
36
|
+
--_height: var(--slotted-control-height-md, 34px);
|
|
37
|
+
--_padding-inline: var(--slotted-control-padding-inline-md, 13px);
|
|
38
|
+
--_font-size: var(--slotted-control-font-size-md, 13px);
|
|
39
|
+
--_icon-size: var(--slotted-control-icon-size-md, 16px);
|
|
40
|
+
--_gap: var(--slotted-control-gap-md, 8px);
|
|
41
|
+
--_radius: var(--slotted-toggle-group-radius, var(--slotted-control-radius, 4px));
|
|
42
|
+
--_border-width: var(--slotted-control-border-width, 1px);
|
|
43
|
+
/** The overlap that puts two joined edges in one column instead of two. */
|
|
44
|
+
--_overlap: calc(-1 * var(--_border-width));
|
|
45
|
+
/**
|
|
46
|
+
* The distance between two items when the bar is not joined. Twice the
|
|
47
|
+
* control gap, for the reason `radio-group` states about its own row: the
|
|
48
|
+
* space between two choices has to read as larger than the space inside
|
|
49
|
+
* one, between a mark and the word it belongs to.
|
|
50
|
+
*/
|
|
51
|
+
--_separation: calc(var(--_gap) * 2);
|
|
52
|
+
/** The edge of the bar, stated by the items that make it. */
|
|
53
|
+
--_border-color: var(
|
|
54
|
+
--slotted-toggle-group-border-color,
|
|
55
|
+
var(--slotted-control-border-color, ButtonBorder)
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
align-items: stretch;
|
|
59
|
+
display: inline-flex;
|
|
60
|
+
flex-direction: row;
|
|
61
|
+
flex-wrap: nowrap;
|
|
62
|
+
font-family: var(--slotted-control-font-family, system-ui, sans-serif);
|
|
63
|
+
/* An item raised by focus or by being on is raised inside the group,
|
|
64
|
+
never over the page. */
|
|
65
|
+
isolation: isolate;
|
|
66
|
+
/**
|
|
67
|
+
* A flex or grid item is at least as wide as its content unless it is told
|
|
68
|
+
* otherwise, so a group nested in one would refuse to narrow below its
|
|
69
|
+
* widest item and push the layout out instead of letting the label clamp.
|
|
70
|
+
*/
|
|
71
|
+
min-inline-size: 0;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* A group that ends up holding nothing takes no room. An actions area built
|
|
76
|
+
* from a permission filter renders one often, and an empty box still eats a
|
|
77
|
+
* gap in the row that holds it — `button-group` records the same defect.
|
|
78
|
+
*/
|
|
79
|
+
[data-ui='toggle-group'][data-part='root']:empty {
|
|
80
|
+
display: none;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/* ── Size ─────────────────────────────────────────────────────────────── */
|
|
84
|
+
|
|
85
|
+
[data-ui='toggle-group'][data-part='root'][data-size='sm'] {
|
|
86
|
+
--_height: var(--slotted-control-height-sm, 30px);
|
|
87
|
+
--_padding-inline: var(--slotted-control-padding-inline-sm, 10px);
|
|
88
|
+
--_font-size: var(--slotted-control-font-size-sm, 12px);
|
|
89
|
+
--_icon-size: var(--slotted-control-icon-size-sm, 14px);
|
|
90
|
+
--_gap: var(--slotted-control-gap-sm, 6px);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
[data-ui='toggle-group'][data-part='root'][data-size='lg'] {
|
|
94
|
+
--_height: var(--slotted-control-height-lg, 38px);
|
|
95
|
+
--_padding-inline: var(--slotted-control-padding-inline-lg, 16px);
|
|
96
|
+
--_font-size: var(--slotted-control-font-size-lg, 14px);
|
|
97
|
+
--_icon-size: var(--slotted-control-icon-size-lg, 18px);
|
|
98
|
+
--_gap: var(--slotted-control-gap-lg, 8px);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/* ── Orientation ──────────────────────────────────────────────────────── */
|
|
102
|
+
|
|
103
|
+
[data-ui='toggle-group'][data-part='root'][data-orientation='vertical'] {
|
|
104
|
+
flex-direction: column;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/* ── Width ────────────────────────────────────────────────────────────── */
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Asking for the whole line means the items share it. Left alone the group
|
|
111
|
+
* shrinks to its content, which is what a set of formatting toggles beside a
|
|
112
|
+
* paragraph needs and what every surveyed implementation defaults to.
|
|
113
|
+
*/
|
|
114
|
+
[data-ui='toggle-group'][data-part='root'][data-full-width] {
|
|
115
|
+
display: flex;
|
|
116
|
+
inline-size: 100%;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
[data-ui='toggle-group'][data-part='root'][data-full-width] [data-part='item'] {
|
|
120
|
+
flex: 1 1 0;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/* ── The item ─────────────────────────────────────────────────────────── */
|
|
124
|
+
|
|
125
|
+
[data-ui='toggle-group'] [data-part='item'] {
|
|
126
|
+
align-items: center;
|
|
127
|
+
appearance: none;
|
|
128
|
+
background: transparent;
|
|
129
|
+
block-size: var(--_height);
|
|
130
|
+
/**
|
|
131
|
+
* Always a border, and always the same width. A state changes its colour
|
|
132
|
+
* and never its presence: a border that appears when an item is pressed
|
|
133
|
+
* moves every label in the bar by a pixel.
|
|
134
|
+
*/
|
|
135
|
+
border: var(--_border-width) solid transparent;
|
|
136
|
+
border-radius: var(--_radius);
|
|
137
|
+
box-sizing: border-box;
|
|
138
|
+
color: var(--slotted-toggle-group-color, var(--slotted-text, ButtonText));
|
|
139
|
+
cursor: pointer;
|
|
140
|
+
display: inline-flex;
|
|
141
|
+
/**
|
|
142
|
+
* An item gives way rather than pushing the page. A bar of three labels
|
|
143
|
+
* that will not shrink ran out through the side of a 240-pixel column and
|
|
144
|
+
* took the layout with it; shrinking, the labels clip at the ellipsis and
|
|
145
|
+
* the bar stays a control. `min-inline-size` is the floor, so no item is
|
|
146
|
+
* ever narrower than it is tall and the WCAG target holds.
|
|
147
|
+
*/
|
|
148
|
+
flex: 0 1 auto;
|
|
149
|
+
font: inherit;
|
|
150
|
+
font-size: var(--_font-size);
|
|
151
|
+
font-weight: var(--slotted-control-font-weight, 600);
|
|
152
|
+
gap: var(--_gap);
|
|
153
|
+
justify-content: center;
|
|
154
|
+
letter-spacing: var(--slotted-control-letter-spacing, 0);
|
|
155
|
+
line-height: var(--slotted-control-line-height, 1);
|
|
156
|
+
margin: 0;
|
|
157
|
+
min-inline-size: var(--_height);
|
|
158
|
+
padding-block: 0;
|
|
159
|
+
padding-inline: var(--_padding-inline);
|
|
160
|
+
position: relative;
|
|
161
|
+
/**
|
|
162
|
+
* Nothing here moves, and that is the right answer for this family: a
|
|
163
|
+
* toggle changes colour, and colour is what the eye has to follow. The
|
|
164
|
+
* duration is the control step, so a theme retunes every control's
|
|
165
|
+
* interaction feedback once and reduced motion collapses it to a frame.
|
|
166
|
+
*/
|
|
167
|
+
transition:
|
|
168
|
+
background-color var(--slotted-control-transition-duration)
|
|
169
|
+
var(--slotted-control-transition-easing),
|
|
170
|
+
border-color var(--slotted-control-transition-duration)
|
|
171
|
+
var(--slotted-control-transition-easing),
|
|
172
|
+
color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* An item with no words is a square holding one mark, so its inline padding
|
|
177
|
+
* is whatever centres that mark rather than the padding a label needs.
|
|
178
|
+
*/
|
|
179
|
+
[data-ui='toggle-group'] [data-part='item']:not(:has([data-part='label'])) {
|
|
180
|
+
padding-inline: 0;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
[data-ui='toggle-group'] [data-part='icon'] {
|
|
184
|
+
block-size: var(--_icon-size);
|
|
185
|
+
display: inline-flex;
|
|
186
|
+
flex: none;
|
|
187
|
+
inline-size: var(--_icon-size);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* The words get a box of their own, as they do in `tabs` and `tag`: it is
|
|
192
|
+
* what `text-overflow` needs to clip a label an equal share made too narrow,
|
|
193
|
+
* and what an icon beside it is aligned against. The string stays whole in
|
|
194
|
+
* the DOM — the library's rule is that truncation never removes content.
|
|
195
|
+
*/
|
|
196
|
+
[data-ui='toggle-group'] [data-part='label'] {
|
|
197
|
+
overflow: hidden;
|
|
198
|
+
text-overflow: ellipsis;
|
|
199
|
+
white-space: nowrap;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/* ── The edge ─────────────────────────────────────────────────────────── */
|
|
203
|
+
|
|
204
|
+
[data-ui='toggle-group'][data-part='root'][data-variant='outline'] [data-part='item'] {
|
|
205
|
+
border-color: var(--_border-color);
|
|
206
|
+
/* A framed item lifts off its ground at rest, as button's outline does. */
|
|
207
|
+
box-shadow: var(--slotted-toggle-group-shadow, var(--slotted-control-shadow, none));
|
|
208
|
+
}
|
|
209
|
+
[data-ui='toggle-group'][data-part='root']:not([data-attached]) {
|
|
210
|
+
gap: var(--_separation);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* ── Joined ────────────────────────────────────────────────────────────
|
|
215
|
+
*
|
|
216
|
+
* A joined bar has one edge, and one edge cannot be the sum of several
|
|
217
|
+
* opinions about their own. So the items make it between them, the way
|
|
218
|
+
* `button-group` makes it for the controls a consumer wrote:
|
|
219
|
+
*
|
|
220
|
+
* - each item keeps the corners on the outside of the bar and loses the ones
|
|
221
|
+
* facing its neighbour;
|
|
222
|
+
* - the items overlap by one border width, so two joined edges occupy one
|
|
223
|
+
* column rather than two;
|
|
224
|
+
* - exactly one border is painted in that column, because two of them are
|
|
225
|
+
* the same line on paper and two different lines at 110%, 150% and 175%
|
|
226
|
+
* zoom, where the browser snaps each border box to device pixels on its
|
|
227
|
+
* own. `button-group` measured five uneven boundaries out of fifteen
|
|
228
|
+
* before it wrote the same rule.
|
|
229
|
+
*
|
|
230
|
+
* The root states no edge of its own, so nothing is ever nested inside
|
|
231
|
+
* anything: an item that is on replaces the grey line in its column with its
|
|
232
|
+
* own, and the bar's outline stays one pixel everywhere.
|
|
233
|
+
*/
|
|
234
|
+
[data-ui='toggle-group'][data-part='root'][data-attached]:not([data-orientation='vertical'])
|
|
235
|
+
[data-part='item']
|
|
236
|
+
+ [data-part='item'] {
|
|
237
|
+
margin-inline-start: var(--_overlap);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
[data-ui='toggle-group'][data-part='root'][data-attached][data-orientation='vertical']
|
|
241
|
+
[data-part='item']
|
|
242
|
+
+ [data-part='item'] {
|
|
243
|
+
margin-block-start: var(--_overlap);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
[data-ui='toggle-group'][data-part='root'][data-attached]:not([data-orientation='vertical'])
|
|
247
|
+
[data-part='item'] {
|
|
248
|
+
border-end-start-radius: 0;
|
|
249
|
+
border-end-end-radius: 0;
|
|
250
|
+
border-start-start-radius: 0;
|
|
251
|
+
border-start-end-radius: 0;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
[data-ui='toggle-group'][data-part='root'][data-attached]:not([data-orientation='vertical'])
|
|
255
|
+
[data-part='item']:first-child {
|
|
256
|
+
border-end-start-radius: var(--_radius);
|
|
257
|
+
border-start-start-radius: var(--_radius);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
[data-ui='toggle-group'][data-part='root'][data-attached]:not([data-orientation='vertical'])
|
|
261
|
+
[data-part='item']:last-child {
|
|
262
|
+
border-end-end-radius: var(--_radius);
|
|
263
|
+
border-start-end-radius: var(--_radius);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
[data-ui='toggle-group'][data-part='root'][data-attached][data-orientation='vertical']
|
|
267
|
+
[data-part='item'] {
|
|
268
|
+
border-end-start-radius: 0;
|
|
269
|
+
border-end-end-radius: 0;
|
|
270
|
+
border-start-start-radius: 0;
|
|
271
|
+
border-start-end-radius: 0;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
[data-ui='toggle-group'][data-part='root'][data-attached][data-orientation='vertical']
|
|
275
|
+
[data-part='item']:first-child {
|
|
276
|
+
border-start-end-radius: var(--_radius);
|
|
277
|
+
border-start-start-radius: var(--_radius);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
[data-ui='toggle-group'][data-part='root'][data-attached][data-orientation='vertical']
|
|
281
|
+
[data-part='item']:last-child {
|
|
282
|
+
border-end-end-radius: var(--_radius);
|
|
283
|
+
border-end-start-radius: var(--_radius);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* One border in each shared column: the trailing edge of the item before it
|
|
288
|
+
* gives way, and the leading edge of the item that follows is what is seen.
|
|
289
|
+
* An item that is on is the exception in both directions — it states its own
|
|
290
|
+
* four edges, and the neighbour after it gives up the leading edge that would
|
|
291
|
+
* otherwise be painted over the accent one.
|
|
292
|
+
*/
|
|
293
|
+
[data-ui='toggle-group'][data-part='root'][data-variant='outline'][data-attached]:not(
|
|
294
|
+
[data-orientation='vertical']
|
|
295
|
+
)
|
|
296
|
+
[data-part='item']:not(:last-child):not([data-pressed]) {
|
|
297
|
+
border-inline-end-color: transparent;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
[data-ui='toggle-group'][data-part='root'][data-variant='outline'][data-attached][data-orientation='vertical']
|
|
301
|
+
[data-part='item']:not(:last-child):not([data-pressed]) {
|
|
302
|
+
border-block-end-color: transparent;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
[data-ui='toggle-group'][data-part='root'][data-variant='outline'][data-attached]:not(
|
|
306
|
+
[data-orientation='vertical']
|
|
307
|
+
)
|
|
308
|
+
[data-part='item'][data-pressed]
|
|
309
|
+
+ [data-part='item'] {
|
|
310
|
+
border-inline-start-color: transparent;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
[data-ui='toggle-group'][data-part='root'][data-variant='outline'][data-attached][data-orientation='vertical']
|
|
314
|
+
[data-part='item'][data-pressed]
|
|
315
|
+
+ [data-part='item'] {
|
|
316
|
+
border-block-start-color: transparent;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* ── Pressed ──────────────────────────────────────────────────────────
|
|
321
|
+
*
|
|
322
|
+
* The accent ground inside the accent edge, and the accent text on it. The
|
|
323
|
+
* item is raised inside the group's own stacking context so that its edge is
|
|
324
|
+
* the one seen in both of the columns it shares, rather than being covered
|
|
325
|
+
* by whichever neighbour the document order puts last.
|
|
326
|
+
*
|
|
327
|
+
* It sits above hover and below disabled, which is the order
|
|
328
|
+
* `STATE_PRECEDENCE` sets.
|
|
329
|
+
*/
|
|
330
|
+
[data-ui='toggle-group'] [data-part='item'][data-pressed]:not(:disabled):not([data-disabled]) {
|
|
331
|
+
background: var(
|
|
332
|
+
--slotted-toggle-group-pressed-background,
|
|
333
|
+
var(--slotted-tone-accent-subtle-active, Highlight)
|
|
334
|
+
);
|
|
335
|
+
border-color: var(
|
|
336
|
+
--slotted-toggle-group-pressed-border-color,
|
|
337
|
+
var(--slotted-tone-accent-border, Highlight)
|
|
338
|
+
);
|
|
339
|
+
color: var(
|
|
340
|
+
--slotted-toggle-group-pressed-color,
|
|
341
|
+
var(--slotted-tone-accent-text, HighlightText)
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
[data-ui='toggle-group'] [data-part='item'][data-pressed] {
|
|
346
|
+
z-index: 1;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* ── Hover and press, each held back for every stronger state ──────────
|
|
351
|
+
*
|
|
352
|
+
* An item that is off takes the neutral ground, whatever the bar is for: a
|
|
353
|
+
* tinted hover on a row of toggles read as five status chips before it read
|
|
354
|
+
* as five hovered controls, which is the reading `button` records. An item
|
|
355
|
+
* that is on answers the pointer on the accent ground's own steps, so the
|
|
356
|
+
* two states share no surface in any of theirs.
|
|
357
|
+
*/
|
|
358
|
+
[data-ui='toggle-group']
|
|
359
|
+
[data-part='item']:hover:not(:disabled):not([data-disabled]):not([data-pressed]) {
|
|
360
|
+
background: var(
|
|
361
|
+
--slotted-toggle-group-hover-background,
|
|
362
|
+
var(--slotted-tone-secondary-subtle-hover, ButtonFace)
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
[data-ui='toggle-group']
|
|
367
|
+
[data-part='item']:active:not(:disabled):not([data-disabled]):not([data-pressed]) {
|
|
368
|
+
background: var(
|
|
369
|
+
--slotted-toggle-group-active-background,
|
|
370
|
+
var(--slotted-tone-secondary-subtle-active, ButtonFace)
|
|
371
|
+
);
|
|
372
|
+
/* The press lands on the frame it went down on and eases out at the
|
|
373
|
+
control's own pace, which is `button`'s rule for the same gesture: a
|
|
374
|
+
transition's timing is read from the state being entered. */
|
|
375
|
+
transition-duration: var(--slotted-duration-instant);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
[data-ui='toggle-group']
|
|
379
|
+
[data-part='item'][data-pressed]:hover:not(:disabled):not([data-disabled]) {
|
|
380
|
+
background: var(
|
|
381
|
+
--slotted-toggle-group-pressed-hover-background,
|
|
382
|
+
var(--slotted-tone-accent-subtle-hover, Highlight)
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
[data-ui='toggle-group']
|
|
387
|
+
[data-part='item'][data-pressed]:active:not(:disabled):not([data-disabled]) {
|
|
388
|
+
background: var(
|
|
389
|
+
--slotted-toggle-group-pressed-background,
|
|
390
|
+
var(--slotted-tone-accent-subtle-active, Highlight)
|
|
391
|
+
);
|
|
392
|
+
transition-duration: var(--slotted-duration-instant);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/* ── Focus ────────────────────────────────────────────────────────────── */
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* A separated bar has room around each item, so the ring is held off the
|
|
399
|
+
* edge the way every other control in the library holds it. The focused item
|
|
400
|
+
* is raised above every other, including one that is on.
|
|
401
|
+
*/
|
|
402
|
+
[data-ui='toggle-group'] [data-part='item']:focus-visible {
|
|
403
|
+
outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
|
|
404
|
+
outline-offset: var(--slotted-focus-ring-offset, 2px);
|
|
405
|
+
z-index: 2;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* A joined bar has no room at all: the items touch, so an outward ring is
|
|
410
|
+
* drawn over the neighbours either side of it. At offset zero it covered the
|
|
411
|
+
* neighbour's own edge and the seam beside a focused item read thicker than
|
|
412
|
+
* every other seam in the same bar — measured at 300% zoom, between a focused
|
|
413
|
+
* item and the one next to it that was on.
|
|
414
|
+
*
|
|
415
|
+
* So the ring is drawn *inside* the item, with its outer edge on the item's
|
|
416
|
+
* border box, which is what a negative offset of exactly the ring's width
|
|
417
|
+
* gives. It then replaces that item's own border rather than standing beside
|
|
418
|
+
* it, and every seam in the bar stays one line wide.
|
|
419
|
+
*/
|
|
420
|
+
[data-ui='toggle-group'][data-part='root'][data-attached] [data-part='item']:focus-visible {
|
|
421
|
+
outline-offset: calc(-1 * var(--slotted-focus-ring-width, 2px));
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/* ── Disabled ─────────────────────────────────────────────────────────── */
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* `[data-disabled]` as well as `:disabled`, because a whole group is taken
|
|
428
|
+
* out of action with a `fieldset` and its items then carry no attribute of
|
|
429
|
+
* their own.
|
|
430
|
+
*/
|
|
431
|
+
[data-ui='toggle-group'] [data-part='item']:disabled,
|
|
432
|
+
[data-ui='toggle-group'] [data-part='item'][data-disabled] {
|
|
433
|
+
background: transparent;
|
|
434
|
+
color: var(--slotted-toggle-group-disabled-color, var(--slotted-disabled-foreground, GrayText));
|
|
435
|
+
cursor: default;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
[data-ui='toggle-group'][data-part='root'][data-variant='outline'] [data-part='item']:disabled,
|
|
439
|
+
[data-ui='toggle-group'][data-part='root'][data-variant='outline']
|
|
440
|
+
[data-part='item'][data-disabled] {
|
|
441
|
+
border-color: var(
|
|
442
|
+
--slotted-toggle-group-disabled-border-color,
|
|
443
|
+
var(--slotted-disabled-border, GrayText)
|
|
444
|
+
);
|
|
445
|
+
/* Nothing a person cannot reach is lifted off the page. */
|
|
446
|
+
box-shadow: none;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* An item that is on and unavailable keeps both facts. The ground says
|
|
451
|
+
* unavailable and the edge says on, in the same two places the live state
|
|
452
|
+
* uses them — so the reader still learns which of the three was chosen from
|
|
453
|
+
* a control they cannot change. In `high-contrast` the ground is the page's
|
|
454
|
+
* own white, and the edge is then the only thing carrying it.
|
|
455
|
+
*/
|
|
456
|
+
[data-ui='toggle-group'] [data-part='item'][data-pressed]:disabled,
|
|
457
|
+
[data-ui='toggle-group'] [data-part='item'][data-pressed][data-disabled] {
|
|
458
|
+
background: var(
|
|
459
|
+
--slotted-toggle-group-disabled-pressed-background,
|
|
460
|
+
var(--slotted-disabled-background, ButtonFace)
|
|
461
|
+
);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
[
|
|
2
|
+
"--slotted-control-border-color",
|
|
3
|
+
"--slotted-control-border-width",
|
|
4
|
+
"--slotted-control-font-family",
|
|
5
|
+
"--slotted-control-font-size-lg",
|
|
6
|
+
"--slotted-control-font-size-md",
|
|
7
|
+
"--slotted-control-font-size-sm",
|
|
8
|
+
"--slotted-control-font-weight",
|
|
9
|
+
"--slotted-control-gap-lg",
|
|
10
|
+
"--slotted-control-gap-md",
|
|
11
|
+
"--slotted-control-gap-sm",
|
|
12
|
+
"--slotted-control-height-lg",
|
|
13
|
+
"--slotted-control-height-md",
|
|
14
|
+
"--slotted-control-height-sm",
|
|
15
|
+
"--slotted-control-icon-size-lg",
|
|
16
|
+
"--slotted-control-icon-size-md",
|
|
17
|
+
"--slotted-control-icon-size-sm",
|
|
18
|
+
"--slotted-control-letter-spacing",
|
|
19
|
+
"--slotted-control-line-height",
|
|
20
|
+
"--slotted-control-padding-inline-lg",
|
|
21
|
+
"--slotted-control-padding-inline-md",
|
|
22
|
+
"--slotted-control-padding-inline-sm",
|
|
23
|
+
"--slotted-control-radius",
|
|
24
|
+
"--slotted-control-shadow",
|
|
25
|
+
"--slotted-control-transition-duration",
|
|
26
|
+
"--slotted-control-transition-easing",
|
|
27
|
+
"--slotted-disabled-background",
|
|
28
|
+
"--slotted-disabled-border",
|
|
29
|
+
"--slotted-disabled-foreground",
|
|
30
|
+
"--slotted-duration-instant",
|
|
31
|
+
"--slotted-focus-ring-color",
|
|
32
|
+
"--slotted-focus-ring-offset",
|
|
33
|
+
"--slotted-focus-ring-width",
|
|
34
|
+
"--slotted-text",
|
|
35
|
+
"--slotted-toggle-group-active-background",
|
|
36
|
+
"--slotted-toggle-group-border-color",
|
|
37
|
+
"--slotted-toggle-group-color",
|
|
38
|
+
"--slotted-toggle-group-disabled-border-color",
|
|
39
|
+
"--slotted-toggle-group-disabled-color",
|
|
40
|
+
"--slotted-toggle-group-disabled-pressed-background",
|
|
41
|
+
"--slotted-toggle-group-hover-background",
|
|
42
|
+
"--slotted-toggle-group-pressed-background",
|
|
43
|
+
"--slotted-toggle-group-pressed-border-color",
|
|
44
|
+
"--slotted-toggle-group-pressed-color",
|
|
45
|
+
"--slotted-toggle-group-pressed-hover-background",
|
|
46
|
+
"--slotted-toggle-group-radius",
|
|
47
|
+
"--slotted-toggle-group-shadow",
|
|
48
|
+
"--slotted-tone-accent-border",
|
|
49
|
+
"--slotted-tone-accent-subtle-active",
|
|
50
|
+
"--slotted-tone-accent-subtle-hover",
|
|
51
|
+
"--slotted-tone-accent-text",
|
|
52
|
+
"--slotted-tone-secondary-subtle-active",
|
|
53
|
+
"--slotted-tone-secondary-subtle-hover"
|
|
54
|
+
]
|