@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,455 @@
1
+ @layer slotted.components {
2
+ /**
3
+ * The actions that finish a task on a page or in a panel.
4
+ *
5
+ * Three families in this library put controls in a row and each owns one
6
+ * question. `button-group` owns the shape of a run — gap, join, orientation.
7
+ * `toolbar` owns the keyboard of a set of tools — one tab stop, arrows,
8
+ * `Home`, `End`. This one owns **which action never gives way, and where the
9
+ * bar assents**: the rank, the anchor that keeps the confirming action still,
10
+ * and the offset that stops a sticky bar covering the page's own footer.
11
+ *
12
+ * So there is no roving focus here and no `toolbar` role: `Tab` reaches every
13
+ * action, because these are the page's own form actions and a reader walking
14
+ * a form expects to arrive at Cancel and then at Save. A strip of ten icon
15
+ * buttons is a `toolbar`, and that family already binds the arrows.
16
+ *
17
+ * The bar paints itself, its own rule and the one control it draws — the
18
+ * overflow trigger. Everything else a reader sees belongs to the control the
19
+ * consumer placed.
20
+ */
21
+ [data-ui='action-bar'] {
22
+ /**
23
+ * The bar's own rhythm, from the control scales, so the three densities
24
+ * move it without a rule of their own.
25
+ */
26
+ --_gap: var(--slotted-control-gap-md, 0.5rem);
27
+ --_inset-block: var(--slotted-space-4, 0.5rem);
28
+ --_inset-inline: var(--slotted-space-5, 0.75rem);
29
+ --_height: var(--slotted-control-height-md, 34px);
30
+ --_font-size: var(--slotted-control-font-size-md, 0.8125rem);
31
+ --_icon-size: var(--slotted-control-icon-size-md, 16px);
32
+ --_separator-inset: var(--slotted-space-2, 0.25rem);
33
+ --_duration: var(--slotted-control-transition-duration);
34
+ --_easing: var(--slotted-control-transition-easing);
35
+
36
+ align-items: center;
37
+ box-sizing: border-box;
38
+ /**
39
+ * The bar answers its own width rather than the viewport's, and the query
40
+ * that stacks it reaches `actions` — a container is a container for its
41
+ * descendants and not for itself, which is the split
42
+ * `docs/build-briefing.md` records.
43
+ */
44
+ container-name: slotted-action-bar;
45
+ container-type: inline-size;
46
+ display: flex;
47
+ flex-wrap: wrap;
48
+ gap: var(--slotted-action-bar-gap, var(--_gap));
49
+ /* A size container has no intrinsic inline size: as a flex item — the
50
+ page footer's actions row — the bar shrank to nothing and stacked its
51
+ letters. A bar is as wide as the line it stands on. */
52
+ inline-size: 100%;
53
+ min-block-size: calc(var(--_height) + 2 * var(--_inset-block));
54
+ min-inline-size: 0;
55
+ padding-block: var(--slotted-action-bar-inset-block, var(--_inset-block));
56
+ padding-inline: var(--slotted-action-bar-inset-inline, var(--_inset-inline));
57
+ }
58
+
59
+ [data-ui='action-bar'][data-size='sm'] {
60
+ --_gap: var(--slotted-control-gap-sm, 0.375rem);
61
+ --_inset-block: var(--slotted-space-3, 0.375rem);
62
+ --_inset-inline: var(--slotted-space-4, 0.5rem);
63
+ --_height: var(--slotted-control-height-sm, 30px);
64
+ --_font-size: var(--slotted-control-font-size-sm, 0.75rem);
65
+ --_icon-size: var(--slotted-control-icon-size-sm, 14px);
66
+ --_separator-inset: var(--slotted-space-1, 0.125rem);
67
+ }
68
+
69
+ [data-ui='action-bar'][data-size='lg'] {
70
+ --_gap: var(--slotted-control-gap-lg, 0.5rem);
71
+ --_inset-block: var(--slotted-space-5, 0.75rem);
72
+ --_inset-inline: var(--slotted-space-6, 1rem);
73
+ --_height: var(--slotted-control-height-lg, 38px);
74
+ --_font-size: var(--slotted-control-font-size-lg, 0.875rem);
75
+ --_icon-size: var(--slotted-control-icon-size-lg, 18px);
76
+ --_separator-inset: var(--slotted-space-3, 0.375rem);
77
+ }
78
+
79
+ /**
80
+ * A bar that ends up holding nothing takes no room. An actions area built
81
+ * from a permission filter renders an empty container often, and an empty box
82
+ * still consumes the gap of the column that holds it — and, under `raised`,
83
+ * draws a rule straight across the screen with nothing under it.
84
+ */
85
+ [data-ui='action-bar']:not(:has([data-part='actions'] > *:not([hidden]))):not(
86
+ :has([data-part='status'])
87
+ ) {
88
+ display: none;
89
+ }
90
+
91
+ /* ── Appearance ───────────────────────────────────────────────────────── */
92
+
93
+ /**
94
+ * `plain` is the default and paints nothing: the bar inside `page`'s footer
95
+ * is already standing on a ground that family painted, and a second one there
96
+ * reads as a box nobody asked for.
97
+ *
98
+ * `raised` is the bar with no page around it — in a drawer, a dialog, a card,
99
+ * or above a table. It takes the surface and one hairline at the top, which
100
+ * is the whole of the separation a bar at the end of a region needs.
101
+ */
102
+ [data-ui='action-bar'][data-variant='raised'] {
103
+ background-color: var(--slotted-action-bar-background, var(--slotted-surface, Canvas));
104
+ border-block-start: var(--slotted-border-width-thin, 1px) solid
105
+ var(--slotted-action-bar-border-color, var(--slotted-border-subtle, ButtonBorder));
106
+ }
107
+
108
+ /* ── Sticky ───────────────────────────────────────────────────────────── */
109
+
110
+ /**
111
+ * Stuck and never fixed, for the reason `page` already wrote into its own
112
+ * contract: a fixed bar covers the last line of content, and every
113
+ * implementation that uses one then pads the body by a number no token
114
+ * explains. A sticky bar takes its own height in the flow.
115
+ *
116
+ * The offset is what the page publishes on the element that scrolls, so a
117
+ * sticky action bar inside a page that has a footer stops **above** that
118
+ * footer rather than sliding under it. With no page around it the property is
119
+ * unset and the fallback sticks the bar to the end of whatever scrolls. None
120
+ * of the surveyed implementations composes with the page's own chrome; each
121
+ * of them fixes the bar and then compensates.
122
+ */
123
+ [data-ui='action-bar'][data-sticky] {
124
+ inset-block-end: var(--slotted-page-sticky-bottom, 0px);
125
+ position: sticky;
126
+ z-index: var(--slotted-z-index-sticky, 100);
127
+ }
128
+
129
+ /**
130
+ * Entering from below and leaving the same way, held through the exit by
131
+ * `@slotted/core/presence`. A bulk bar appears when a selection starts and a
132
+ * contextual save bar when a field is edited, and a bar that popped into
133
+ * existence under the reader's hands is the jump
134
+ * `docs/component-features.md` §11 forbids by name.
135
+ */
136
+ [data-ui='action-bar'][data-status] {
137
+ transition:
138
+ translate var(--_duration) var(--_easing),
139
+ opacity var(--_duration) var(--_easing);
140
+ }
141
+
142
+ [data-ui='action-bar']:is([data-status='entering'], [data-status='exiting']) {
143
+ opacity: 0;
144
+ translate: 0 100%;
145
+ }
146
+
147
+ /* ── The two regions ──────────────────────────────────────────────────── */
148
+
149
+ /**
150
+ * The sentence at the start: a dirty-state marker, a timestamp, the count of
151
+ * what is selected. It takes what is left over and gives way first, so a long
152
+ * message shortens itself rather than pushing the actions off the bar.
153
+ */
154
+ [data-ui='action-bar'] [data-part='status'] {
155
+ align-items: center;
156
+ color: var(--slotted-action-bar-status-color, var(--slotted-text-muted, GrayText));
157
+ display: flex;
158
+ flex: 1 1 auto;
159
+ font-family: var(--slotted-control-font-family, inherit);
160
+ font-size: var(--_font-size);
161
+ gap: var(--_gap);
162
+ min-inline-size: 0;
163
+ }
164
+
165
+ /**
166
+ * **The anchor, and it is the whole of the third scope line.** The run is
167
+ * pushed to the bar's end edge by a margin rather than placed by a
168
+ * `justify-content`, so it is anchored to that edge and not to its
169
+ * neighbours: a message appearing in `status`, a button going busy, and a
170
+ * permission filter removing a control all move what is *before* the last
171
+ * action and never the last action itself. The property is logical, so the
172
+ * anchor mirrors with the bar in a right-to-left document.
173
+ */
174
+ [data-ui='action-bar'] [data-part='actions'] {
175
+ align-items: center;
176
+ display: flex;
177
+ flex: 0 0 auto;
178
+ flex-wrap: wrap;
179
+ gap: var(--_gap);
180
+ justify-content: flex-end;
181
+ margin-inline-start: auto;
182
+ /**
183
+ * The run is content-sized, which is what lets it sit against the end edge,
184
+ * and content-sized means it does not shrink: two German labels are wider
185
+ * than the bar, and without a ceiling the second one is drawn past its
186
+ * edge. Read at 420 pixels, where `Zur Genehmigung einreichen` was cut
187
+ * mid-word. The ceiling is what turns the run's own `flex-wrap` on.
188
+ */
189
+ max-inline-size: 100%;
190
+ min-inline-size: 0;
191
+ }
192
+
193
+ /**
194
+ * `align` places the run in the room left after the status, and it is the
195
+ * axis the field disagrees about: Salesforce centres a docked footer's
196
+ * buttons, Polaris puts them at the end, Fluent at the start. The anchor is
197
+ * what `end` is, so the other two are the ones that state a margin.
198
+ */
199
+ [data-ui='action-bar'][data-align='start'] [data-part='actions'] {
200
+ justify-content: flex-start;
201
+ margin-inline: 0 auto;
202
+ }
203
+
204
+ [data-ui='action-bar'][data-align='center'] [data-part='actions'] {
205
+ justify-content: center;
206
+ margin-inline: auto;
207
+ }
208
+
209
+ /**
210
+ * A bar with no status region at all still puts its run where `align` says,
211
+ * which without this is where the first `auto` margin happens to leave it.
212
+ */
213
+ [data-ui='action-bar'][data-align='center']:not(:has([data-part='status']))
214
+ [data-part='actions'] {
215
+ margin-inline: auto;
216
+ }
217
+
218
+ /* ── A unit, and what the collapse does to it ─────────────────────────── */
219
+
220
+ /**
221
+ * One action the bar may give up, and the rank it gives way at. It is a box
222
+ * rather than nothing, because the family is what hides it and a family
223
+ * cannot hide what it does not own.
224
+ *
225
+ * It paints nothing: everything a reader sees inside it belongs to the
226
+ * control the consumer placed.
227
+ */
228
+ [data-ui='action-bar'] [data-part='action'] {
229
+ align-items: center;
230
+ display: inline-flex;
231
+ flex: none;
232
+ min-inline-size: 0;
233
+ }
234
+
235
+ /**
236
+ * `display: none` written here rather than left to the user agent, for the
237
+ * reason `breadcrumb` and `toolbar` both record: an author's `display: flex`
238
+ * on the same element beats the user agent's own `[hidden] { display: none }`,
239
+ * and without this every collapsed unit stays on the bar and the collapse
240
+ * does nothing at all.
241
+ */
242
+ [data-ui='action-bar']
243
+ :is([data-part='action'], [data-part='separator'], [data-part='overflow'])[hidden] {
244
+ display: none;
245
+ }
246
+
247
+ /* ── The separator ────────────────────────────────────────────────────── */
248
+
249
+ /**
250
+ * A hairline between two runs, and the answer to the one line of
251
+ * `docs/component-features.md` §5 that names no mechanism: a destructive
252
+ * action does not sit flush against a frequent one. Half a gap on each side,
253
+ * so the boundary a rule draws is wider than the boundary a gap draws; a step
254
+ * short of the controls across the axis, because a rule at their full height
255
+ * reads as the edge of a box that is not there.
256
+ *
257
+ * It is a part of this family rather than the `divider` family because its
258
+ * geometry belongs to the bar: it is measured against the controls beside it.
259
+ */
260
+ [data-ui='action-bar'] [data-part='separator'] {
261
+ align-self: stretch;
262
+ background-color: var(
263
+ --slotted-action-bar-separator-color,
264
+ var(--slotted-border-strong, ButtonBorder)
265
+ );
266
+ border: 0;
267
+ flex: none;
268
+ inline-size: var(--slotted-border-width-thin, 1px);
269
+ margin-block: var(--_separator-inset);
270
+ margin-inline: calc(var(--_gap) / 2);
271
+ min-block-size: calc(var(--_height) - 2 * var(--_separator-inset));
272
+ }
273
+
274
+ /* ── The control that holds what did not fit ──────────────────────────── */
275
+
276
+ /**
277
+ * `menu`'s own trigger wearing this family's geometry: the bar's height, the
278
+ * WCAG 2.2 minimum in the other axis, and the muted ink the library gives a
279
+ * control a family draws itself. The mark is the `ellipsis` Glyph element in
280
+ * an `icon` box sized here to the glyph scale, because a character is never
281
+ * an icon.
282
+ *
283
+ * Its accessible name carries the count, so what a reader hears is a number
284
+ * rather than three dots.
285
+ */
286
+ [data-ui='action-bar'] [data-part='overflow'] {
287
+ align-items: center;
288
+ appearance: none;
289
+ background-color: transparent;
290
+ border: 0;
291
+ --slotted-icon-size: var(--_icon-size);
292
+
293
+ border-radius: var(--slotted-control-radius, 4px);
294
+ color: var(--slotted-action-bar-overflow-color, var(--slotted-text-muted, GrayText));
295
+ cursor: pointer;
296
+ display: inline-flex;
297
+ flex: none;
298
+ font-family: var(--slotted-control-font-family, inherit);
299
+ justify-content: center;
300
+ line-height: 1;
301
+ /**
302
+ * Half a gap more than the distance between two actions, so the control
303
+ * that holds what is missing does not read as one more action. It is the
304
+ * same distance the separator puts between two runs, for the same reason.
305
+ */
306
+ margin-inline-start: calc(var(--_gap) / 2);
307
+ min-block-size: var(--_height);
308
+ /**
309
+ * A square the height of the bar's controls, which is where this family
310
+ * parts from `toolbar`. There the trigger is an inner control among icon
311
+ * buttons and was deliberately narrowed to the glyph plus a step of air;
312
+ * here it stands at the end of a run of **labelled** buttons, and three
313
+ * muted dots at 24 pixels beside a solid `Guardar` read as a stray glyph
314
+ * rather than as a control. Read at 420 in the collapsed `priority` scene.
315
+ */
316
+ min-inline-size: max(var(--slotted-target-min, 24px), var(--_height));
317
+ padding: 0;
318
+ transition:
319
+ background-color var(--_duration) var(--_easing),
320
+ color var(--_duration) var(--_easing);
321
+ }
322
+
323
+ /* The ground moves under the pointer and nothing else does. */
324
+ [data-ui='action-bar'] [data-part='overflow']:not(:disabled):hover {
325
+ background-color: var(
326
+ --slotted-action-bar-overflow-hover-background,
327
+ var(--slotted-tone-secondary-subtle-hover)
328
+ );
329
+ color: var(--slotted-action-bar-overflow-hover-color, var(--slotted-text, CanvasText));
330
+ }
331
+
332
+ [data-ui='action-bar'] [data-part='overflow']:not(:disabled):active {
333
+ background-color: var(
334
+ --slotted-action-bar-overflow-active-background,
335
+ var(--slotted-tone-secondary-subtle-active)
336
+ );
337
+ }
338
+
339
+ /**
340
+ * The surface is open, and the control that opened it says so: without it a
341
+ * reader who moved the pointer off the trigger loses every sign of which
342
+ * control the layer belongs to.
343
+ */
344
+ [data-ui='action-bar'] [data-part='overflow'][data-open] {
345
+ background-color: var(
346
+ --slotted-action-bar-overflow-open-background,
347
+ var(--slotted-tone-secondary-subtle-active)
348
+ );
349
+ color: var(--slotted-action-bar-overflow-hover-color, var(--slotted-text, CanvasText));
350
+ }
351
+
352
+ /**
353
+ * A bar out of action is a `<fieldset disabled>` around it, and the platform
354
+ * disables every control inside — this one included. It says so rather than
355
+ * looking operable, and it answers neither hover nor press, which is the
356
+ * precedence `docs/state-and-events.md` fixes.
357
+ */
358
+ [data-ui='action-bar'] [data-part='overflow']:disabled {
359
+ color: var(--slotted-disabled-foreground, GrayText);
360
+ cursor: default;
361
+ }
362
+
363
+ [data-ui='action-bar'] [data-part='overflow']:focus-visible {
364
+ outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
365
+ outline-offset: var(--slotted-focus-ring-offset, 2px);
366
+ }
367
+
368
+ /* ── The narrow bar ───────────────────────────────────────────────────── */
369
+
370
+ /**
371
+ * Below the breakpoint the run becomes a full-width column with the action
372
+ * that confirms on top — the composition change `docs/component-features.md`
373
+ * §2.7 asks for, rather than the same row at a smaller size. A bar of
374
+ * sentences has nowhere to go sideways: a `Guardar` reached by scrolling
375
+ * horizontally is a `Guardar` nobody finds.
376
+ *
377
+ * The number is literal because `@container (width < var(--x))` is invalid —
378
+ * rule 4 of `docs/token-foundation.md` — and it is written **once**. The
379
+ * property below is what the binding reads back to know the bar is stacked,
380
+ * so the measurement and the layout cannot disagree about where the
381
+ * breakpoint is. While it is raised the collapse does not run: a column has
382
+ * room for every action, and a surface holding what did not fit would be a
383
+ * menu for nothing.
384
+ */
385
+ @container slotted-action-bar (width < 24rem) {
386
+ /**
387
+ * `column-reverse` is what puts the confirming action on top without moving
388
+ * it in the DOM: the tab order stays the order the author wrote, which is
389
+ * the order a form is read in, and only the paint is reversed. `stretch`
390
+ * fills the column, because a column of natural widths is a ragged edge.
391
+ */
392
+ [data-ui='action-bar'] [data-part='actions'] {
393
+ --_stacked: 1;
394
+
395
+ align-items: stretch;
396
+ flex: 1 1 100%;
397
+ flex-direction: column-reverse;
398
+ margin-inline: 0;
399
+ }
400
+
401
+ [data-ui='action-bar'] [data-part='action'] > * {
402
+ inline-size: 100%;
403
+ }
404
+
405
+ /**
406
+ * While the bar is a column there is no overflow, because a column has room
407
+ * for every action — the binding stops measuring, and the rule says the same
408
+ * thing on the side a reader is looking at. Without it the trigger is
409
+ * painted at the top of the column by the reversal, which is where the
410
+ * action that confirms belongs.
411
+ */
412
+ [data-ui='action-bar'] [data-part='overflow'] {
413
+ display: none;
414
+ }
415
+
416
+ /**
417
+ * A rule that divided two controls in a row divides two rows here, so it
418
+ * turns with them.
419
+ */
420
+ [data-ui='action-bar'] [data-part='separator'] {
421
+ block-size: var(--slotted-border-width-thin, 1px);
422
+ inline-size: auto;
423
+ margin-block: calc(var(--_gap) / 2);
424
+ margin-inline: var(--_separator-inset);
425
+ min-block-size: 0;
426
+ }
427
+
428
+ [data-ui='action-bar'] [data-part='status'] {
429
+ flex: 1 1 100%;
430
+ }
431
+
432
+ /* What the consumer put in the status, addressed as the part's child and
433
+ never by a class of its own: while the bar is a column the status fills
434
+ the row, as an action does two rules above. */
435
+ [data-ui='action-bar'] [data-part='status'] > * {
436
+ align-content: space-between;
437
+ inline-size: 100%;
438
+ }
439
+ }
440
+
441
+ /* ── Forced colours ───────────────────────────────────────────────────── */
442
+
443
+ /**
444
+ * A rule painted with a background disappears when the system flattens every
445
+ * background to `Canvas`, and the separator is a background rather than a
446
+ * border. Keeping the paint is the only way the boundary between a
447
+ * destructive action and a frequent one is still there to read.
448
+ */
449
+ @media (forced-colors: active) {
450
+ [data-ui='action-bar'] [data-part='separator'] {
451
+ background-color: CanvasText;
452
+ forced-color-adjust: none;
453
+ }
454
+ }
455
+ }
@@ -0,0 +1,50 @@
1
+ [
2
+ "--slotted-action-bar-background",
3
+ "--slotted-action-bar-border-color",
4
+ "--slotted-action-bar-gap",
5
+ "--slotted-action-bar-inset-block",
6
+ "--slotted-action-bar-inset-inline",
7
+ "--slotted-action-bar-overflow-active-background",
8
+ "--slotted-action-bar-overflow-color",
9
+ "--slotted-action-bar-overflow-hover-background",
10
+ "--slotted-action-bar-overflow-hover-color",
11
+ "--slotted-action-bar-overflow-open-background",
12
+ "--slotted-action-bar-separator-color",
13
+ "--slotted-action-bar-status-color",
14
+ "--slotted-border-strong",
15
+ "--slotted-border-subtle",
16
+ "--slotted-border-width-thin",
17
+ "--slotted-control-font-family",
18
+ "--slotted-control-font-size-lg",
19
+ "--slotted-control-font-size-md",
20
+ "--slotted-control-font-size-sm",
21
+ "--slotted-control-gap-lg",
22
+ "--slotted-control-gap-md",
23
+ "--slotted-control-gap-sm",
24
+ "--slotted-control-height-lg",
25
+ "--slotted-control-height-md",
26
+ "--slotted-control-height-sm",
27
+ "--slotted-control-icon-size-lg",
28
+ "--slotted-control-icon-size-md",
29
+ "--slotted-control-icon-size-sm",
30
+ "--slotted-control-radius",
31
+ "--slotted-control-transition-duration",
32
+ "--slotted-control-transition-easing",
33
+ "--slotted-disabled-foreground",
34
+ "--slotted-focus-ring-color",
35
+ "--slotted-focus-ring-offset",
36
+ "--slotted-focus-ring-width",
37
+ "--slotted-space-1",
38
+ "--slotted-space-2",
39
+ "--slotted-space-3",
40
+ "--slotted-space-4",
41
+ "--slotted-space-5",
42
+ "--slotted-space-6",
43
+ "--slotted-surface",
44
+ "--slotted-target-min",
45
+ "--slotted-text",
46
+ "--slotted-text-muted",
47
+ "--slotted-tone-secondary-subtle-active",
48
+ "--slotted-tone-secondary-subtle-hover",
49
+ "--slotted-z-index-sticky"
50
+ ]