@slotted/styles 0.0.0-stage → 0.1.0-beta.1

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.
Files changed (254) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +10 -2
  3. package/package.json +276 -3
  4. package/src/accordion/accordion.css +96 -0
  5. package/src/accordion/accordion.tokens.json +14 -0
  6. package/src/action-bar/action-bar.css +455 -0
  7. package/src/action-bar/action-bar.tokens.json +50 -0
  8. package/src/action-sheet/action-sheet.css +462 -0
  9. package/src/action-sheet/action-sheet.tokens.json +59 -0
  10. package/src/alert/alert.css +764 -0
  11. package/src/alert/alert.tokens.json +77 -0
  12. package/src/app-shell/app-shell.css +1899 -0
  13. package/src/app-shell/app-shell.tokens.json +88 -0
  14. package/src/aspect-ratio/aspect-ratio.css +131 -0
  15. package/src/aspect-ratio/aspect-ratio.tokens.json +1 -0
  16. package/src/attachment/attachment.css +906 -0
  17. package/src/attachment/attachment.tokens.json +85 -0
  18. package/src/avatar/avatar.css +598 -0
  19. package/src/avatar/avatar.tokens.json +64 -0
  20. package/src/avatar-group/avatar-group.css +268 -0
  21. package/src/avatar-group/avatar-group.tokens.json +16 -0
  22. package/src/badge/badge.css +462 -0
  23. package/src/badge/badge.tokens.json +58 -0
  24. package/src/breadcrumb/breadcrumb.css +441 -0
  25. package/src/breadcrumb/breadcrumb.tokens.json +50 -0
  26. package/src/button/button.css +754 -0
  27. package/src/button/button.tokens.json +72 -0
  28. package/src/button-group/button-group.css +455 -0
  29. package/src/button-group/button-group.tokens.json +11 -0
  30. package/src/calendar/calendar.css +846 -0
  31. package/src/calendar/calendar.tokens.json +67 -0
  32. package/src/card/card.css +602 -0
  33. package/src/card/card.tokens.json +68 -0
  34. package/src/carousel/carousel.css +860 -0
  35. package/src/carousel/carousel.tokens.json +62 -0
  36. package/src/cascader/cascader.css +1320 -0
  37. package/src/cascader/cascader.tokens.json +103 -0
  38. package/src/chart/chart.css +1473 -0
  39. package/src/chart/chart.tokens.json +107 -0
  40. package/src/checkbox/checkbox.css +1011 -0
  41. package/src/checkbox/checkbox.tokens.json +102 -0
  42. package/src/checkbox-group/checkbox-group.css +70 -0
  43. package/src/checkbox-group/checkbox-group.tokens.json +6 -0
  44. package/src/code-block/code-block.css +555 -0
  45. package/src/code-block/code-block.tokens.json +69 -0
  46. package/src/collapsible/collapsible.css +546 -0
  47. package/src/collapsible/collapsible.tokens.json +55 -0
  48. package/src/color-picker/color-picker.css +607 -0
  49. package/src/color-picker/color-picker.tokens.json +58 -0
  50. package/src/column-manager/column-manager.css +452 -0
  51. package/src/column-manager/column-manager.tokens.json +43 -0
  52. package/src/combobox/combobox.css +1048 -0
  53. package/src/combobox/combobox.tokens.json +112 -0
  54. package/src/command-palette/command-palette.css +1000 -0
  55. package/src/command-palette/command-palette.tokens.json +75 -0
  56. package/src/container/container.css +198 -0
  57. package/src/container/container.tokens.json +18 -0
  58. package/src/context-menu/context-menu.css +104 -0
  59. package/src/context-menu/context-menu.tokens.json +11 -0
  60. package/src/currency-field/currency-field.css +787 -0
  61. package/src/currency-field/currency-field.tokens.json +80 -0
  62. package/src/dashboard-grid/dashboard-grid.css +748 -0
  63. package/src/dashboard-grid/dashboard-grid.tokens.json +67 -0
  64. package/src/data-grid/data-grid.css +2484 -0
  65. package/src/data-grid/data-grid.tokens.json +100 -0
  66. package/src/data-list/data-list.css +455 -0
  67. package/src/data-list/data-list.tokens.json +35 -0
  68. package/src/date-field/date-field.css +560 -0
  69. package/src/date-field/date-field.tokens.json +80 -0
  70. package/src/date-picker/date-picker.css +420 -0
  71. package/src/date-picker/date-picker.tokens.json +49 -0
  72. package/src/date-range-picker/date-range-picker.css +983 -0
  73. package/src/date-range-picker/date-range-picker.tokens.json +109 -0
  74. package/src/datetime-field/datetime-field.css +850 -0
  75. package/src/datetime-field/datetime-field.tokens.json +91 -0
  76. package/src/datetime-picker/datetime-picker.css +843 -0
  77. package/src/datetime-picker/datetime-picker.tokens.json +78 -0
  78. package/src/datetime-range-picker/datetime-range-picker.css +1375 -0
  79. package/src/datetime-range-picker/datetime-range-picker.tokens.json +135 -0
  80. package/src/description-list/description-list.css +675 -0
  81. package/src/description-list/description-list.tokens.json +66 -0
  82. package/src/detail-panel/detail-panel.css +329 -0
  83. package/src/detail-panel/detail-panel.tokens.json +33 -0
  84. package/src/dialog/dialog.css +968 -0
  85. package/src/dialog/dialog.tokens.json +66 -0
  86. package/src/divider/divider.css +131 -0
  87. package/src/divider/divider.tokens.json +18 -0
  88. package/src/drawer/drawer.css +1303 -0
  89. package/src/drawer/drawer.tokens.json +75 -0
  90. package/src/entity-picker/entity-picker.css +1367 -0
  91. package/src/entity-picker/entity-picker.tokens.json +118 -0
  92. package/src/event-calendar/event-calendar.css +2148 -0
  93. package/src/event-calendar/event-calendar.tokens.json +87 -0
  94. package/src/field/field.css +707 -0
  95. package/src/field/field.tokens.json +58 -0
  96. package/src/field-group/field-group.css +226 -0
  97. package/src/field-group/field-group.tokens.json +33 -0
  98. package/src/filter-bar/filter-bar.css +1306 -0
  99. package/src/filter-bar/filter-bar.tokens.json +78 -0
  100. package/src/form/form.css +218 -0
  101. package/src/form/form.tokens.json +32 -0
  102. package/src/fullscreen/fullscreen.css +376 -0
  103. package/src/fullscreen/fullscreen.tokens.json +50 -0
  104. package/src/grid/grid.css +173 -0
  105. package/src/grid/grid.tokens.json +20 -0
  106. package/src/highlight/highlight.css +135 -0
  107. package/src/highlight/highlight.tokens.json +16 -0
  108. package/src/hover-card/hover-card.css +93 -0
  109. package/src/hover-card/hover-card.tokens.json +17 -0
  110. package/src/icon/icon.css +136 -0
  111. package/src/icon/icon.tokens.json +14 -0
  112. package/src/image/image.css +449 -0
  113. package/src/image/image.tokens.json +27 -0
  114. package/src/import-export-center/import-export-center.css +1175 -0
  115. package/src/import-export-center/import-export-center.tokens.json +84 -0
  116. package/src/inline/inline.css +149 -0
  117. package/src/inline/inline.tokens.json +14 -0
  118. package/src/inline-message/inline-message.css +396 -0
  119. package/src/inline-message/inline-message.tokens.json +19 -0
  120. package/src/kbd/kbd.css +490 -0
  121. package/src/kbd/kbd.tokens.json +40 -0
  122. package/src/link/link.css +237 -0
  123. package/src/link/link.tokens.json +25 -0
  124. package/src/list/list.css +240 -0
  125. package/src/list/list.tokens.json +42 -0
  126. package/src/list-item/list-item.css +937 -0
  127. package/src/list-item/list-item.tokens.json +114 -0
  128. package/src/listbox/listbox.css +674 -0
  129. package/src/listbox/listbox.tokens.json +72 -0
  130. package/src/loading-overlay/loading-overlay.css +730 -0
  131. package/src/loading-overlay/loading-overlay.tokens.json +48 -0
  132. package/src/markdown/markdown.css +168 -0
  133. package/src/markdown/markdown.tokens.json +18 -0
  134. package/src/menu/menu.css +817 -0
  135. package/src/menu/menu.tokens.json +78 -0
  136. package/src/menubar/menubar.css +170 -0
  137. package/src/menubar/menubar.tokens.json +32 -0
  138. package/src/message/message.css +1453 -0
  139. package/src/message/message.tokens.json +85 -0
  140. package/src/message-scroller/message-scroller.css +371 -0
  141. package/src/message-scroller/message-scroller.tokens.json +47 -0
  142. package/src/multi-select/multi-select.css +1427 -0
  143. package/src/multi-select/multi-select.tokens.json +114 -0
  144. package/src/navigation-menu/navigation-menu.css +1029 -0
  145. package/src/navigation-menu/navigation-menu.tokens.json +70 -0
  146. package/src/notification-center/notification-center.css +856 -0
  147. package/src/notification-center/notification-center.tokens.json +84 -0
  148. package/src/number-field/number-field.css +794 -0
  149. package/src/number-field/number-field.tokens.json +80 -0
  150. package/src/otp-input/otp-input.css +525 -0
  151. package/src/otp-input/otp-input.tokens.json +69 -0
  152. package/src/page/page.css +179 -0
  153. package/src/page/page.tokens.json +20 -0
  154. package/src/page-header/page-header.css +1181 -0
  155. package/src/page-header/page-header.tokens.json +71 -0
  156. package/src/pagination/pagination.css +500 -0
  157. package/src/pagination/pagination.tokens.json +56 -0
  158. package/src/popover/popover.css +526 -0
  159. package/src/popover/popover.tokens.json +60 -0
  160. package/src/progress-indicator/progress-indicator.css +1584 -0
  161. package/src/progress-indicator/progress-indicator.tokens.json +50 -0
  162. package/src/prompt-composer/prompt-composer.css +680 -0
  163. package/src/prompt-composer/prompt-composer.tokens.json +99 -0
  164. package/src/prose/prose.css +733 -0
  165. package/src/prose/prose.tokens.json +79 -0
  166. package/src/radio-group/radio-group.css +778 -0
  167. package/src/radio-group/radio-group.tokens.json +103 -0
  168. package/src/rating/rating.css +1071 -0
  169. package/src/rating/rating.tokens.json +88 -0
  170. package/src/result-state/result-state.css +980 -0
  171. package/src/result-state/result-state.tokens.json +63 -0
  172. package/src/runtime-properties.mjs +321 -0
  173. package/src/saved-views/saved-views.css +394 -0
  174. package/src/saved-views/saved-views.tokens.json +41 -0
  175. package/src/scroll-area/scroll-area.css +481 -0
  176. package/src/scroll-area/scroll-area.tokens.json +15 -0
  177. package/src/section/section.css +177 -0
  178. package/src/section/section.tokens.json +39 -0
  179. package/src/segmented-control/segmented-control.css +564 -0
  180. package/src/segmented-control/segmented-control.tokens.json +67 -0
  181. package/src/select/select.css +1593 -0
  182. package/src/select/select.tokens.json +110 -0
  183. package/src/side-navigation/side-navigation.css +1096 -0
  184. package/src/side-navigation/side-navigation.tokens.json +87 -0
  185. package/src/skeleton/skeleton.css +431 -0
  186. package/src/skeleton/skeleton.tokens.json +29 -0
  187. package/src/slider/slider.css +792 -0
  188. package/src/slider/slider.tokens.json +75 -0
  189. package/src/sparkline/sparkline.css +282 -0
  190. package/src/sparkline/sparkline.tokens.json +45 -0
  191. package/src/spinner/spinner.css +224 -0
  192. package/src/spinner/spinner.tokens.json +8 -0
  193. package/src/split-button/split-button.css +253 -0
  194. package/src/split-button/split-button.tokens.json +12 -0
  195. package/src/splitter/splitter.css +336 -0
  196. package/src/splitter/splitter.tokens.json +24 -0
  197. package/src/stack/stack.css +128 -0
  198. package/src/stack/stack.tokens.json +14 -0
  199. package/src/stat-card/stat-card.css +641 -0
  200. package/src/stat-card/stat-card.tokens.json +95 -0
  201. package/src/status-indicator/status-indicator.css +481 -0
  202. package/src/status-indicator/status-indicator.tokens.json +38 -0
  203. package/src/stepper/stepper.css +629 -0
  204. package/src/stepper/stepper.tokens.json +72 -0
  205. package/src/switch/switch.css +703 -0
  206. package/src/switch/switch.tokens.json +75 -0
  207. package/src/table/table.css +1482 -0
  208. package/src/table/table.tokens.json +69 -0
  209. package/src/table-of-contents/table-of-contents.css +533 -0
  210. package/src/table-of-contents/table-of-contents.tokens.json +53 -0
  211. package/src/tabs/tabs.css +998 -0
  212. package/src/tabs/tabs.tokens.json +82 -0
  213. package/src/tag/tag.css +768 -0
  214. package/src/tag/tag.tokens.json +85 -0
  215. package/src/tags-input/tags-input.css +757 -0
  216. package/src/tags-input/tags-input.tokens.json +84 -0
  217. package/src/text-field/text-field.css +900 -0
  218. package/src/text-field/text-field.tokens.json +87 -0
  219. package/src/textarea/textarea.css +365 -0
  220. package/src/textarea/textarea.tokens.json +59 -0
  221. package/src/time-field/time-field.css +719 -0
  222. package/src/time-field/time-field.tokens.json +86 -0
  223. package/src/time-picker/time-picker.css +665 -0
  224. package/src/time-picker/time-picker.tokens.json +66 -0
  225. package/src/time-range-picker/time-range-picker.css +1287 -0
  226. package/src/time-range-picker/time-range-picker.tokens.json +134 -0
  227. package/src/timeline/timeline.css +1596 -0
  228. package/src/timeline/timeline.tokens.json +96 -0
  229. package/src/toast/toast.css +943 -0
  230. package/src/toast/toast.tokens.json +90 -0
  231. package/src/toggle/toggle.css +290 -0
  232. package/src/toggle/toggle.tokens.json +54 -0
  233. package/src/toggle-group/toggle-group.css +463 -0
  234. package/src/toggle-group/toggle-group.tokens.json +54 -0
  235. package/src/toolbar/toolbar.css +434 -0
  236. package/src/toolbar/toolbar.tokens.json +49 -0
  237. package/src/tooltip/tooltip.css +368 -0
  238. package/src/tooltip/tooltip.tokens.json +39 -0
  239. package/src/top-navigation/top-navigation.css +1287 -0
  240. package/src/top-navigation/top-navigation.tokens.json +91 -0
  241. package/src/tour/tour.css +680 -0
  242. package/src/tour/tour.tokens.json +67 -0
  243. package/src/transfer/transfer.css +571 -0
  244. package/src/transfer/transfer.tokens.json +49 -0
  245. package/src/tree/tree.css +1000 -0
  246. package/src/tree/tree.tokens.json +80 -0
  247. package/src/typography/typography.css +211 -0
  248. package/src/typography/typography.tokens.json +31 -0
  249. package/src/upload/upload.css +1706 -0
  250. package/src/upload/upload.tokens.json +123 -0
  251. package/src/visually-hidden/visually-hidden.css +52 -0
  252. package/src/visually-hidden/visually-hidden.tokens.json +1 -0
  253. package/src/wizard/wizard.css +740 -0
  254. 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
+ ]