@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,434 @@
1
+ @layer slotted.components {
2
+ /**
3
+ * A set of controls that share one tab stop.
4
+ *
5
+ * The family paints the bar and nothing inside it: every control keeps its
6
+ * own fill, its own states and its own type step, which is what lets one bar
7
+ * hold a small icon button beside a medium select. Three families arrange
8
+ * controls in a row and each owns one question — `button-group` owns the
9
+ * shape of a run of actions, `tabs` owns the selection of a view, and this
10
+ * one owns the keyboard.
11
+ *
12
+ * So there is no gap axis, no alignment axis and no joined bar here. A run of
13
+ * joined actions inside a toolbar is a `button-group` inside a toolbar, and
14
+ * the arrows reach the buttons through it because the items are found by
15
+ * being focusable rather than by being children.
16
+ */
17
+ [data-ui='toolbar'] {
18
+ /**
19
+ * The bar's own rhythm, from the control scales, so the three densities
20
+ * move it without a rule of their own.
21
+ */
22
+ --_gap: var(--slotted-control-gap-md, 0.375rem);
23
+ --_inset: var(--slotted-space-2, 0.25rem);
24
+ --_height: var(--slotted-control-height-md, 34px);
25
+ --_separator-inset: var(--slotted-space-2, 0.25rem);
26
+ --_font-size: var(--slotted-control-font-size-md, 0.875rem);
27
+ --_icon-size: var(--slotted-control-icon-size-md, 16px);
28
+ --_inner-size: var(--slotted-control-inner-size-md, 24px);
29
+ /**
30
+ * What the bar actually pads with. It is the size step for a bar with no
31
+ * frame, and at least the reach of a focus ring for one with a frame: the
32
+ * ring belongs to the control, it is drawn outward, and at the small step a
33
+ * two-pixel inset put it on top of the bar's own edge. Stated here rather
34
+ * than in the size rules because a custom property cannot take the
35
+ * maximum of itself.
36
+ */
37
+ --_pad: var(--_inset);
38
+
39
+ align-items: center;
40
+ display: flex;
41
+ flex-wrap: wrap;
42
+ gap: var(--slotted-toolbar-gap, var(--_gap));
43
+ min-inline-size: 0;
44
+ padding: var(--slotted-toolbar-inset, var(--_pad));
45
+ }
46
+
47
+ [data-ui='toolbar'][data-size='sm'] {
48
+ --_gap: var(--slotted-control-gap-sm, 0.25rem);
49
+ --_inset: var(--slotted-space-1, 0.125rem);
50
+ --_height: var(--slotted-control-height-sm, 30px);
51
+ --_separator-inset: var(--slotted-space-1, 0.125rem);
52
+ --_font-size: var(--slotted-control-font-size-sm, 0.8125rem);
53
+ --_icon-size: var(--slotted-control-icon-size-sm, 14px);
54
+ --_inner-size: var(--slotted-control-inner-size-sm, 22px);
55
+ }
56
+
57
+ [data-ui='toolbar'][data-size='lg'] {
58
+ --_gap: var(--slotted-control-gap-lg, 0.5rem);
59
+ --_inset: var(--slotted-space-3, 0.375rem);
60
+ --_height: var(--slotted-control-height-lg, 40px);
61
+ --_separator-inset: var(--slotted-space-3, 0.375rem);
62
+ --_font-size: var(--slotted-control-font-size-lg, 0.9375rem);
63
+ --_icon-size: var(--slotted-control-icon-size-lg, 18px);
64
+ --_inner-size: var(--slotted-control-inner-size-lg, 28px);
65
+ }
66
+
67
+ /**
68
+ * A bar that ends up holding nothing takes no room, which is the rule
69
+ * `button-group` records: an actions area built from a permission filter
70
+ * renders an empty container often, and an empty box still consumes the gap
71
+ * of the row that holds it.
72
+ */
73
+ [data-ui='toolbar']:empty {
74
+ display: none;
75
+ }
76
+
77
+ /* ── Orientation ──────────────────────────────────────────────────────── */
78
+
79
+ /**
80
+ * A column stretches its controls, because a column of controls at their own
81
+ * natural widths is a ragged edge rather than a bar. A row centres them,
82
+ * because two controls of different heights in one line share a middle.
83
+ */
84
+ [data-ui='toolbar'][data-orientation='vertical'] {
85
+ align-items: stretch;
86
+ flex-direction: column;
87
+ inline-size: fit-content;
88
+ }
89
+
90
+ /* ── Appearance ───────────────────────────────────────────────────────── */
91
+
92
+ /**
93
+ * `plain` is the default and paints no ground: a bar inside a card header or
94
+ * above a table is already standing on a surface, and a second one there
95
+ * reads as a box nobody asked for.
96
+ */
97
+ [data-ui='toolbar'][data-variant='outline'] {
98
+ --_pad: max(
99
+ var(--_inset),
100
+ calc(var(--slotted-focus-ring-offset, 2px) + var(--slotted-focus-ring-width, 2px))
101
+ );
102
+
103
+ background-color: var(--slotted-toolbar-background, var(--slotted-surface-raised));
104
+ border: var(--slotted-border-width-thin, 1px) solid
105
+ var(--slotted-toolbar-border-color, var(--slotted-border-subtle, ButtonBorder));
106
+ border-radius: var(--slotted-radius-md, 6px);
107
+ }
108
+
109
+ /* ── Overflow ─────────────────────────────────────────────────────────── */
110
+
111
+ /**
112
+ * `wrap` is the default, and it is the half of the answer that needs no
113
+ * menu: every control stays visible on a second row, and the arrows wrap
114
+ * from row to row because the item list is linear — which is the APG's own
115
+ * multi-row bullet, for free.
116
+ *
117
+ * `scroll` and `menu` are both one line. They share this rule because they
118
+ * share the same last resort: a bar that cannot give anything up scrolls
119
+ * past what is left rather than cutting a control in half, which is what
120
+ * `menu` does when every unit in it is pinned and what Primer does by
121
+ * design — its spacer exists so the first item "can wrap to the next line
122
+ * and get clipped".
123
+ */
124
+ [data-ui='toolbar']:is([data-overflow='scroll'], [data-overflow='menu']) {
125
+ /**
126
+ * A scroll container clips at its padding edge whether or not a scrollbar
127
+ * is drawn, and a control's focus ring is drawn outward. The bar therefore
128
+ * takes the frame's own floor here too: without it the ring of the first
129
+ * control was cut against the edge of a bar that was not even overflowing.
130
+ */
131
+ --_pad: max(
132
+ var(--_inset),
133
+ calc(var(--slotted-focus-ring-offset, 2px) + var(--slotted-focus-ring-width, 2px))
134
+ );
135
+
136
+ flex-wrap: nowrap;
137
+ overflow-x: auto;
138
+ overscroll-behavior-inline: contain;
139
+ scrollbar-width: thin;
140
+ }
141
+
142
+ [data-ui='toolbar']:is(
143
+ [data-overflow='scroll'],
144
+ [data-overflow='menu']
145
+ )[data-orientation='vertical'] {
146
+ inline-size: auto;
147
+ overflow-x: hidden;
148
+ overflow-y: auto;
149
+ }
150
+
151
+ /**
152
+ * A one-line bar must not shrink its controls to fit; it scrolls past them,
153
+ * or hides them. Without this a flex item narrower than its content is the
154
+ * browser's preferred answer, and a row of squeezed buttons is what a reader
155
+ * gets instead — and the collapse would then measure a control at a width it
156
+ * only has while it is being squeezed.
157
+ */
158
+ [data-ui='toolbar']:is([data-overflow='scroll'], [data-overflow='menu']) > * {
159
+ flex: none;
160
+ }
161
+
162
+ /* ── What the collapse hides, and the control that holds it ───────────── */
163
+
164
+ /**
165
+ * A unit the bar may give up. It is a box rather than nothing, because the
166
+ * family is the thing that hides it and a family cannot hide what it does not
167
+ * own — which is the one place this family's own anatomy bends: the items are
168
+ * found by being focusable at any depth, and a *unit* is a direct child of
169
+ * the root. A `button-group` in a bar is one unit and four items.
170
+ *
171
+ * It paints nothing. Everything a reader sees inside it belongs to the
172
+ * control the consumer placed.
173
+ */
174
+ [data-ui='toolbar'] [data-part='item'] {
175
+ align-items: center;
176
+ display: inline-flex;
177
+ min-inline-size: 0;
178
+ }
179
+
180
+ [data-ui='toolbar'][data-orientation='vertical'] [data-part='item'] {
181
+ align-items: stretch;
182
+ flex-direction: column;
183
+ }
184
+
185
+ /**
186
+ * `display: none` written by this family rather than left to the user agent,
187
+ * for the reason `breadcrumb` records: an author's `display: flex` on the
188
+ * same element beats the user agent's own `[hidden] { display: none }`, so
189
+ * without this rule every collapsed unit stayed on the bar and the collapse
190
+ * did nothing at all.
191
+ */
192
+ [data-ui='toolbar']
193
+ :is(
194
+ [data-part='item'],
195
+ [data-part='group'],
196
+ [data-part='separator'],
197
+ [data-part='overflow']
198
+ )[hidden] {
199
+ display: none;
200
+ }
201
+
202
+ /**
203
+ * The control that opens what did not fit. It is `menu`'s own trigger wearing
204
+ * this family's geometry: the bar's height, the minimum target in the other
205
+ * axis, and the muted ink `tabs` gives the one control it draws itself.
206
+ *
207
+ * The mark is the `ellipsis` Glyph element in an `icon` box, sized here to
208
+ * the control glyph size, the same as `breadcrumb` draws it (BC2). It was
209
+ * U+2026 as text, on the exception `breadcrumb` took to rule 3 of
210
+ * `docs/token-foundation.md` — and the two quantities that exception needed
211
+ * here are what closed it: a type step of one and a half to stop three dots
212
+ * reading as specks, and a lift of half an x-height to get them off their own
213
+ * baseline and onto the middle of the control. A glyph is centred in its box
214
+ * by construction and sized by the same scale as every other mark on the bar.
215
+ *
216
+ * Its accessible name carries the count, so what a reader hears is a number
217
+ * rather than three dots.
218
+ */
219
+ [data-ui='toolbar'] [data-part='overflow'] {
220
+ --slotted-icon-size: var(--_icon-size);
221
+
222
+ align-items: center;
223
+ appearance: none;
224
+ background-color: transparent;
225
+ border: 0;
226
+ border-radius: var(--slotted-control-radius, 4px);
227
+ color: var(--slotted-toolbar-overflow-color, var(--slotted-text-muted, GrayText));
228
+ cursor: pointer;
229
+ display: inline-flex;
230
+ flex: none;
231
+ font-family: var(--slotted-control-font-family, inherit);
232
+ justify-content: center;
233
+ line-height: 1;
234
+ min-block-size: var(--_height);
235
+ /**
236
+ * An inner control, not a button (R2): as tall as the bar's items, as
237
+ * wide as the control glyph plus a step of air on each side, floored at
238
+ * the WCAG 2.2 minimum. It was a square the height of the bar before.
239
+ */
240
+ min-inline-size: max(
241
+ var(--slotted-target-min, 24px),
242
+ min(calc(var(--_icon-size) + 2 * var(--slotted-space-2, 0.25rem)), var(--_inner-size))
243
+ );
244
+ padding: 0;
245
+ transition:
246
+ background-color var(--slotted-control-transition-duration)
247
+ var(--slotted-control-transition-easing),
248
+ color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing);
249
+ }
250
+
251
+ /* The ground moves under the pointer and nothing else does (R2). */
252
+ [data-ui='toolbar'] [data-part='overflow']:not(:disabled):hover {
253
+ background-color: var(
254
+ --slotted-toolbar-overflow-hover-background,
255
+ var(--slotted-tone-secondary-subtle-hover)
256
+ );
257
+ }
258
+
259
+ [data-ui='toolbar'] [data-part='overflow']:not(:disabled):active {
260
+ background-color: var(
261
+ --slotted-toolbar-overflow-active-background,
262
+ var(--slotted-tone-secondary-subtle-active)
263
+ );
264
+ }
265
+
266
+ /**
267
+ * The surface is open, and the control that opened it says so: without it a
268
+ * reader who moved the pointer off the trigger loses every sign of which
269
+ * control the layer belongs to.
270
+ */
271
+ [data-ui='toolbar'] [data-part='overflow'][data-open] {
272
+ background-color: var(
273
+ --slotted-toolbar-overflow-open-background,
274
+ var(--slotted-tone-secondary-subtle-active)
275
+ );
276
+ color: var(--slotted-toolbar-overflow-hover-color, var(--slotted-text, CanvasText));
277
+ }
278
+
279
+ /**
280
+ * A bar out of action is a `fieldset` around it, and the platform disables
281
+ * every control inside — this one included. It says so rather than looking
282
+ * operable, and it answers neither hover nor press, which is the precedence
283
+ * `docs/state-and-events.md` fixes.
284
+ */
285
+ /* On a finger the trigger is a target in both directions, as the items beside
286
+ it are, and square: one value for both axes, so a bar taller than the
287
+ comfortable target does not stand it on end. */
288
+ @media (pointer: coarse) {
289
+ [data-ui='toolbar'] [data-part='overflow'] {
290
+ min-block-size: max(var(--slotted-target-comfortable, 44px), var(--_height));
291
+ min-inline-size: max(var(--slotted-target-comfortable, 44px), var(--_height));
292
+ }
293
+ }
294
+
295
+ [data-ui='toolbar'] [data-part='overflow']:disabled {
296
+ color: var(--slotted-disabled-foreground, GrayText);
297
+ cursor: default;
298
+ }
299
+
300
+ /**
301
+ * The inward ring the scroll container needs. The bar clips at its padding
302
+ * edge, and the trigger is the control closest to it, so an outward ring here
303
+ * is the one this family cannot afford.
304
+ */
305
+ [data-ui='toolbar'] [data-part='overflow']:focus-visible {
306
+ outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
307
+ outline-offset: calc(-1 * var(--slotted-focus-ring-width, 2px));
308
+ }
309
+
310
+ /* ── A group inside the bar ───────────────────────────────────────────── */
311
+
312
+ /**
313
+ * A run of related controls, announced as a group and read as one. The
314
+ * distance inside it is half the bar's gap and the distance around it is a
315
+ * gap and a half, so the boundary between two groups reads wider than the
316
+ * boundary between two controls — which is what keeps a destructive action
317
+ * from sitting flush against a frequent one.
318
+ *
319
+ * Both distances derive from the bar's own gap rather than from a step of
320
+ * their own, for the reason `button-group` records: a fixed nested distance
321
+ * puts the clusters of a loosely spaced bar closer together than the
322
+ * controls inside them.
323
+ */
324
+ [data-ui='toolbar'] [data-part='group'] {
325
+ align-items: center;
326
+ display: flex;
327
+ flex-wrap: inherit;
328
+ gap: calc(var(--_gap) / 2);
329
+ min-inline-size: 0;
330
+ }
331
+
332
+ [data-ui='toolbar'][data-orientation='vertical'] [data-part='group'] {
333
+ align-items: stretch;
334
+ flex-direction: column;
335
+ }
336
+
337
+ [data-ui='toolbar'] [data-part='group']:not(:first-child) {
338
+ margin-inline-start: calc(var(--_gap) / 2);
339
+ }
340
+
341
+ [data-ui='toolbar'] [data-part='group']:not(:last-child) {
342
+ margin-inline-end: calc(var(--_gap) / 2);
343
+ }
344
+
345
+ [data-ui='toolbar'][data-orientation='vertical'] [data-part='group']:not(:first-child) {
346
+ margin-block-start: calc(var(--_gap) / 2);
347
+ margin-inline-start: 0;
348
+ }
349
+
350
+ [data-ui='toolbar'][data-orientation='vertical'] [data-part='group']:not(:last-child) {
351
+ margin-block-end: calc(var(--_gap) / 2);
352
+ margin-inline-end: 0;
353
+ }
354
+
355
+ /* ── The separator ────────────────────────────────────────────────────── */
356
+
357
+ /**
358
+ * A hairline between two runs. It is a part of this family rather than the
359
+ * `divider` family because its geometry belongs to the bar: it is measured
360
+ * against the controls beside it, and the toolbar that shipped before this
361
+ * one reached into the `divider` family's own class from this stylesheet —
362
+ * one family styling another's DOM, which is what `identity.test.mjs`
363
+ * refuses.
364
+ *
365
+ * It is one border width. A thick rule in a bar of hairlines is not a
366
+ * stronger boundary, it is a slab.
367
+ */
368
+ [data-ui='toolbar'] [data-part='separator'] {
369
+ align-self: stretch;
370
+ /**
371
+ * The control edge rather than the subtle rule `divider` reaches for: this
372
+ * rule divides controls, and it stands at the weight of the edges beside
373
+ * it — a darker line between two outline buttons read as a third control.
374
+ */
375
+ background-color: var(
376
+ --slotted-toolbar-separator-color,
377
+ var(--slotted-control-border-color, ButtonBorder)
378
+ );
379
+ border: 0;
380
+ flex: none;
381
+ inline-size: var(--slotted-border-width-thin, 1px);
382
+ /**
383
+ * Along the flow: half a gap on each side, so the boundary a rule draws is
384
+ * exactly the boundary a group draws, and the two ways of saying "these
385
+ * belong apart" say it at the same distance. Across it: a step short of the
386
+ * controls at each end, because a rule running their full height reads as
387
+ * the edge of a box that is not there.
388
+ */
389
+ margin-block: var(--_separator-inset);
390
+ margin-inline: calc(var(--_gap) / 2);
391
+ min-block-size: calc(var(--_height) - 2 * var(--_separator-inset));
392
+ }
393
+
394
+ [data-ui='toolbar'][data-orientation='vertical'] [data-part='separator'] {
395
+ block-size: var(--slotted-border-width-thin, 1px);
396
+ inline-size: auto;
397
+ margin-block: calc(var(--_gap) / 2);
398
+ margin-inline: var(--_separator-inset);
399
+ min-block-size: 0;
400
+ }
401
+
402
+ /**
403
+ * Forced colours flatten a background to `Canvas`, and a rule painted with
404
+ * one disappears with it. The separator is a background rather than a border,
405
+ * so keeping the paint is the only way the boundary is still there to read.
406
+ */
407
+ @media (forced-colors: active) {
408
+ [data-ui='toolbar'] [data-part='separator'] {
409
+ background-color: CanvasText;
410
+ forced-color-adjust: none;
411
+ }
412
+ }
413
+
414
+ /* ── The spacer ───────────────────────────────────────────────────────── */
415
+
416
+ /**
417
+ * It consumes what is left of the line, so what follows sits at the end of
418
+ * the bar. It replaces a `justify` axis: an axis decides the placement of
419
+ * every control at once, and what a bar needs is one boundary — the editing
420
+ * controls at the start, the destructive one at the end.
421
+ *
422
+ * One declaration serves both orientations, because `flex` grows along
423
+ * whichever axis the bar runs. The basis is zero rather than `auto` so the
424
+ * spacer never takes part in where a wrapping bar breaks its lines: a flex
425
+ * container assigns items to lines at their base size and grows them
426
+ * afterwards, so a zero-width spacer moves what follows to the end of its own
427
+ * line and pushes nothing onto the next one.
428
+ */
429
+ [data-ui='toolbar'] [data-part='spacer'] {
430
+ flex: 1 1 0;
431
+ min-block-size: 0;
432
+ min-inline-size: 0;
433
+ }
434
+ }
@@ -0,0 +1,49 @@
1
+ [
2
+ "--slotted-border-subtle",
3
+ "--slotted-border-width-thin",
4
+ "--slotted-control-border-color",
5
+ "--slotted-control-font-family",
6
+ "--slotted-control-font-size-lg",
7
+ "--slotted-control-font-size-md",
8
+ "--slotted-control-font-size-sm",
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-inner-size-lg",
19
+ "--slotted-control-inner-size-md",
20
+ "--slotted-control-inner-size-sm",
21
+ "--slotted-control-radius",
22
+ "--slotted-control-transition-duration",
23
+ "--slotted-control-transition-easing",
24
+ "--slotted-disabled-foreground",
25
+ "--slotted-focus-ring-color",
26
+ "--slotted-focus-ring-offset",
27
+ "--slotted-focus-ring-width",
28
+ "--slotted-radius-md",
29
+ "--slotted-space-1",
30
+ "--slotted-space-2",
31
+ "--slotted-space-3",
32
+ "--slotted-surface-raised",
33
+ "--slotted-target-comfortable",
34
+ "--slotted-target-min",
35
+ "--slotted-text",
36
+ "--slotted-text-muted",
37
+ "--slotted-tone-secondary-subtle-active",
38
+ "--slotted-tone-secondary-subtle-hover",
39
+ "--slotted-toolbar-background",
40
+ "--slotted-toolbar-border-color",
41
+ "--slotted-toolbar-gap",
42
+ "--slotted-toolbar-inset",
43
+ "--slotted-toolbar-overflow-active-background",
44
+ "--slotted-toolbar-overflow-color",
45
+ "--slotted-toolbar-overflow-hover-background",
46
+ "--slotted-toolbar-overflow-hover-color",
47
+ "--slotted-toolbar-overflow-open-background",
48
+ "--slotted-toolbar-separator-color"
49
+ ]