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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,546 @@
1
+ @layer slotted.components {
2
+ /**
3
+ * One disclosure: a header the reader operates and a panel it controls.
4
+ *
5
+ * The family is a two-column, two-row grid. The header takes the first cell
6
+ * and the always-visible actions the second, because the APG requires the
7
+ * trigger to be the only element inside the heading — an action inside it
8
+ * would be a control inside a `button`, which is invalid besides. The panel
9
+ * spans both columns on the second row.
10
+ *
11
+ * ┌──────────────────────────────┬───────────┐
12
+ * │ header ▸ trigger │ actions │
13
+ * ├──────────────────────────────┴───────────┤
14
+ * │ panel ▸ content │
15
+ * └───────────────────────────────────────────┘
16
+ *
17
+ * Every part the family owns is reached with a child combinator rather than
18
+ * a descendant one. A collapsible inside another collapsible's panel is the
19
+ * ordinary case — a nested accordion is two of these — and a descendant rule
20
+ * would open the inner panel because the outer one is open.
21
+ */
22
+ [data-ui='collapsible'] {
23
+ /**
24
+ * The control scales, read once at the root, so `size` and the three
25
+ * densities are one decision each rather than one per rule.
26
+ */
27
+ --_height: var(--slotted-control-height-md, 34px);
28
+ --_padding-inline: var(--slotted-control-padding-inline-md, 0.8125rem);
29
+ --_gap: var(--slotted-control-gap-md, 0.5rem);
30
+ --_icon-size: var(--slotted-control-icon-size-md, 16px);
31
+ /**
32
+ * ── Why the title is not on the control type scale ──────────────────
33
+ *
34
+ * The first capture showed a header set smaller than the paragraph it
35
+ * revealed, which is a heading that reads as a caption. The control type
36
+ * scale is 12, 13 and 14 pixels, because it is the scale of a label inside
37
+ * a button; a disclosure header is prose that happens to be inside one, and
38
+ * the outline it belongs to is set on the type scale like every other
39
+ * heading in the library.
40
+ *
41
+ * Density still moves everything geometric — the row's height, its padding,
42
+ * the gap and the mark all come from the control scales — so a dense
43
+ * accordion is a tighter accordion rather than a smaller one. That is what
44
+ * "density changes size without changing meaning" asks for.
45
+ */
46
+ --_font-size: var(--slotted-font-size-md, 0.875rem);
47
+ --_description-font-size: var(--slotted-font-size-xs, 0.75rem);
48
+ /* The panel's own text, so a consumer who writes bare prose in it gets the
49
+ step the header was set against rather than the document's. */
50
+ --_panel-font-size: var(--slotted-font-size-md, 0.875rem);
51
+ /**
52
+ * The air above and below the words. It is not the control's own padding,
53
+ * because a header is a line of prose rather than a button's label: it
54
+ * wraps, and a wrapped second line needs the same distance from the rule as
55
+ * the first has from the one above it.
56
+ */
57
+ --_padding-block: var(--slotted-space-4, 0.5rem);
58
+ --_rule-size: var(--slotted-border-width-thin, 1px);
59
+
60
+ display: grid;
61
+ grid-template-columns: minmax(0, 1fr) auto;
62
+ grid-template-rows: auto auto;
63
+ /**
64
+ * `container-type: inline-size` below applies `contain: inline-size`, which
65
+ * makes the box's intrinsic width zero — that is the whole point of the
66
+ * containment, and it is why the width is stated rather than left to
67
+ * `auto`. `alert` learned it first, and this family relearned it in its own
68
+ * rendered reference page: on a stage that shrink-wraps its children every
69
+ * disclosure collapsed to one character wide and set its title one letter
70
+ * per line. A consumer writing `<Stack>` around three of these would find
71
+ * the same thing.
72
+ */
73
+ inline-size: 100%;
74
+ min-inline-size: 0;
75
+ }
76
+
77
+ [data-ui='collapsible'][data-size='sm'] {
78
+ --_height: var(--slotted-control-height-sm, 30px);
79
+ --_font-size: var(--slotted-font-size-sm, 0.8125rem);
80
+ --_description-font-size: var(--slotted-font-size-xs, 0.75rem);
81
+ --_panel-font-size: var(--slotted-font-size-sm, 0.8125rem);
82
+ --_padding-inline: var(--slotted-control-padding-inline-sm, 0.625rem);
83
+ --_gap: var(--slotted-control-gap-sm, 0.375rem);
84
+ --_icon-size: var(--slotted-control-icon-size-sm, 14px);
85
+ --_padding-block: var(--slotted-space-3, 0.375rem);
86
+ }
87
+
88
+ [data-ui='collapsible'][data-size='lg'] {
89
+ --_height: var(--slotted-control-height-lg, 38px);
90
+ --_font-size: var(--slotted-font-size-lg, 1rem);
91
+ --_description-font-size: var(--slotted-font-size-sm, 0.8125rem);
92
+ --_panel-font-size: var(--slotted-font-size-md, 0.875rem);
93
+ --_padding-inline: var(--slotted-control-padding-inline-lg, 1rem);
94
+ --_gap: var(--slotted-control-gap-lg, 0.5rem);
95
+ --_icon-size: var(--slotted-control-icon-size-lg, 18px);
96
+ --_padding-block: var(--slotted-space-5, 0.75rem);
97
+ }
98
+
99
+ /* ── The header, which is a heading ───────────────────────────────────── */
100
+
101
+ /**
102
+ * `level` renders `h1` through `h6`, and the browser's own heading margins
103
+ * and type size would then make one disclosure taller than the next. The
104
+ * family states both, so the outline is semantic and the picture is not.
105
+ */
106
+ [data-ui='collapsible'] > [data-part='header'] {
107
+ font: inherit;
108
+ grid-column: 1;
109
+ grid-row: 1;
110
+ margin: 0;
111
+ min-inline-size: 0;
112
+ }
113
+
114
+ /* ── The trigger ──────────────────────────────────────────────────────── */
115
+
116
+ /**
117
+ * Two columns and two rows: the words take the first column, over one or two
118
+ * rows, and the indicator keeps a column of its own so a title that wraps
119
+ * grows the row instead of pushing the mark off the line. Carbon truncates
120
+ * that title instead; the row growing is the honest answer, and `truncate`
121
+ * is the word for the case where it may not.
122
+ */
123
+ [data-ui='collapsible'] > [data-part='header'] > [data-part='trigger'] {
124
+ align-items: center;
125
+ appearance: none;
126
+ background-color: var(--slotted-collapsible-background, transparent);
127
+ border: 0;
128
+ color: var(--slotted-collapsible-color, var(--slotted-text, CanvasText));
129
+ column-gap: var(--_gap);
130
+ cursor: pointer;
131
+ display: grid;
132
+ font-family: var(--slotted-control-font-family, inherit);
133
+ font-size: var(--_font-size);
134
+ font-weight: var(--slotted-font-weight-medium, 500);
135
+ grid-template-columns: minmax(0, 1fr) auto;
136
+ grid-template-rows: auto auto;
137
+ /* A `button` does not stretch into its grid cell on its own, and the mark
138
+ then sits against the last word instead of at the row's end. */
139
+ justify-self: stretch;
140
+ letter-spacing: var(--slotted-control-letter-spacing, 0);
141
+ line-height: var(--slotted-line-height-md, 1.5);
142
+ min-block-size: var(--_height);
143
+ min-inline-size: 0;
144
+ padding-block: var(--_padding-block);
145
+ padding-inline: var(--slotted-collapsible-padding-inline, var(--_padding-inline));
146
+ text-align: start;
147
+ transition:
148
+ background-color var(--slotted-control-transition-duration, var(--slotted-duration-short))
149
+ var(--slotted-control-transition-easing, var(--slotted-easing-standard)),
150
+ color var(--slotted-control-transition-duration, var(--slotted-duration-short))
151
+ var(--slotted-control-transition-easing, var(--slotted-easing-standard));
152
+ }
153
+
154
+ [data-ui='collapsible'] > [data-part='header'] > [data-part='trigger']:focus-visible {
155
+ outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
156
+ outline-offset: calc(-1 * var(--slotted-focus-ring-offset, 2px));
157
+ }
158
+
159
+ /**
160
+ * The words and the second line share the first column; the mark sits in the
161
+ * second across both rows, so it is centred on the pair rather than on the
162
+ * title alone.
163
+ */
164
+ [data-ui='collapsible'] > [data-part='header'] > [data-part='trigger'] > [data-part='label'] {
165
+ grid-column: 1;
166
+ grid-row: 1;
167
+ min-inline-size: 0;
168
+ /**
169
+ * ── Isolated, not plaintext; break-word, not anywhere ──────────────
170
+ *
171
+ * A title in another script has to read its own way without reordering the
172
+ * row around it, and an unbroken token has to break inside itself rather
173
+ * than set the width of the row.
174
+ *
175
+ * `break-word` rather than `anywhere`, and the difference is the whole of
176
+ * why the reference page found it: `anywhere` counts toward the box's
177
+ * min-content size, so a disclosure placed on a stage that sizes to its
178
+ * content collapsed to one character wide and set every title one letter
179
+ * per line. `break-word` breaks the same unbroken token when the row is
180
+ * too narrow and leaves the min-content width the longest word, which is
181
+ * what a shrink-to-fit parent asks for.
182
+ *
183
+ * `tag` and `tabs` use `plaintext`, which takes the base direction from the
184
+ * string's own first strong character. That is right for a chip whose whole
185
+ * box is the string, and wrong here: `start` is then resolved against the
186
+ * string rather than the page, and the first right-to-left capture showed a
187
+ * Latin title stranded at the far edge of an Arabic page, hugging the mark.
188
+ * `isolate` keeps the string from reordering anything outside it and leaves
189
+ * the base direction — and therefore the alignment — to the page, which is
190
+ * what a heading in an outline needs.
191
+ */
192
+ overflow-wrap: break-word;
193
+ unicode-bidi: isolate;
194
+ }
195
+
196
+ [data-ui='collapsible'][data-truncate]
197
+ > [data-part='header']
198
+ > [data-part='trigger']
199
+ > [data-part='label'] {
200
+ overflow: hidden;
201
+ overflow-wrap: normal;
202
+ text-overflow: ellipsis;
203
+ white-space: nowrap;
204
+ }
205
+
206
+ /**
207
+ * The second line. It is inside the trigger, so it is part of the accessible
208
+ * name — "Entrega, 3 de 12 itens" is what a reader hears, which is what a
209
+ * summary of the hidden content is for.
210
+ */
211
+ [data-ui='collapsible']
212
+ > [data-part='header']
213
+ > [data-part='trigger']
214
+ > [data-part='description'] {
215
+ color: var(--slotted-collapsible-description-color, var(--slotted-text-muted, GrayText));
216
+ font-size: var(--_description-font-size);
217
+ font-weight: var(--slotted-font-weight-regular, 400);
218
+ grid-column: 1;
219
+ grid-row: 2;
220
+ min-inline-size: 0;
221
+ overflow-wrap: break-word;
222
+ unicode-bidi: isolate;
223
+ }
224
+
225
+ [data-ui='collapsible'][data-truncate]
226
+ > [data-part='header']
227
+ > [data-part='trigger']
228
+ > [data-part='description'] {
229
+ overflow: hidden;
230
+ overflow-wrap: normal;
231
+ text-overflow: ellipsis;
232
+ white-space: nowrap;
233
+ }
234
+
235
+ /* ── The indicator ────────────────────────────────────────────────────── */
236
+
237
+ /**
238
+ * The mark is the library's own `Glyph` — an `<svg>` the binding draws inside
239
+ * an `icon` box, chevron or plus and minus as the indicator and state say —
240
+ * never a character or a mask. This part is the slot it stands in: the box
241
+ * takes the part's size through `--slotted-icon-size`, and the part is a flex
242
+ * container so the box's own baseline shift does not move it off the slot.
243
+ * The chevron turns rather than pointing along the inline axis: a chevron
244
+ * that pointed at the start edge would need mirrored artwork for a
245
+ * right-to-left document, and a mark that rotates between down and up is the
246
+ * same mark in every direction.
247
+ */
248
+ [data-ui='collapsible'] > [data-part='header'] > [data-part='trigger'] > [data-part='indicator'] {
249
+ /**
250
+ * On the first line of the title, by R5, and not on the middle of what the
251
+ * trigger holds. Centred over both rows the mark stood 9.25 to 10.25 pixels
252
+ * under the line it annotates wherever a description was written, and 32
253
+ * pixels under it where the title wrapped to three lines — the disclosure's
254
+ * own version of what AL1 fixed in `alert` and SL7 in `select` (CL1).
255
+ *
256
+ * `1lh` resolves against *this* element's line box, and this element
257
+ * inherits the trigger's font and line-height, so the line it measures is
258
+ * the line the title sets. The mark keeps its own row: spanning both put it
259
+ * in a box the description made taller, which is what centred it there.
260
+ */
261
+ --slotted-icon-size: var(--_icon-size);
262
+ align-self: start;
263
+ block-size: var(--_icon-size);
264
+ color: var(--slotted-collapsible-indicator-color, currentColor);
265
+ display: flex;
266
+ flex: none;
267
+ grid-column: 2;
268
+ grid-row: 1;
269
+ inline-size: var(--_icon-size);
270
+ margin-block-start: calc((1lh - var(--_icon-size)) / 2);
271
+ }
272
+
273
+ [data-ui='collapsible']
274
+ > [data-part='header']
275
+ > [data-part='trigger']
276
+ > [data-part='indicator']
277
+ > [data-ui='icon'] {
278
+ transition: rotate var(--slotted-duration-medium)
279
+ var(--slotted-control-transition-easing, var(--slotted-easing-standard));
280
+ }
281
+
282
+ [data-ui='collapsible'][data-open]
283
+ > [data-part='header']
284
+ > [data-part='trigger']
285
+ > [data-part='indicator']
286
+ > [data-ui='icon'] {
287
+ rotate: 180deg;
288
+ }
289
+
290
+ /**
291
+ * The other pair the scale holds, drawn on one grid: the same bar, with a
292
+ * second crossing it. The binding swaps the glyph with the state, and nothing
293
+ * rotates, because a plus turning into a minus by rotation is a plus with a
294
+ * stroke that vanished.
295
+ */
296
+ [data-ui='collapsible'][data-indicator='plus-minus']
297
+ > [data-part='header']
298
+ > [data-part='trigger']
299
+ > [data-part='indicator']
300
+ > [data-ui='icon'] {
301
+ rotate: none;
302
+ }
303
+
304
+ /**
305
+ * The mark before the words. The two columns swap and nothing else moves,
306
+ * which is what a logical grid is for.
307
+ */
308
+ [data-ui='collapsible'][data-toggle-placement='start']
309
+ > [data-part='header']
310
+ > [data-part='trigger'] {
311
+ grid-template-columns: auto minmax(0, 1fr);
312
+ }
313
+
314
+ [data-ui='collapsible'][data-toggle-placement='start']
315
+ > [data-part='header']
316
+ > [data-part='trigger']
317
+ > [data-part='indicator'] {
318
+ grid-column: 1;
319
+ }
320
+
321
+ [data-ui='collapsible'][data-toggle-placement='start']
322
+ > [data-part='header']
323
+ > [data-part='trigger']
324
+ > [data-part='label'],
325
+ [data-ui='collapsible'][data-toggle-placement='start']
326
+ > [data-part='header']
327
+ > [data-part='trigger']
328
+ > [data-part='description'] {
329
+ grid-column: 2;
330
+ }
331
+
332
+ /**
333
+ * The body lines up with the title rather than with the mark. With the mark
334
+ * at the end the two edges are already the same; with it at the start the
335
+ * title begins a column further in, and a panel left at the box's own inset
336
+ * hangs to the left of the heading it belongs to — which was what the first
337
+ * capture showed.
338
+ */
339
+ [data-ui='collapsible'][data-toggle-placement='start']
340
+ > [data-part='panel']
341
+ > [data-part='content'] {
342
+ padding-inline-start: calc(
343
+ var(--slotted-collapsible-padding-inline, var(--_padding-inline)) + var(--_icon-size) +
344
+ var(--_gap)
345
+ );
346
+ }
347
+
348
+ /* ── The actions beside the header ────────────────────────────────────── */
349
+
350
+ /**
351
+ * A slot on the header's own row, outside the heading and outside the
352
+ * button. What belongs in it is a `toolbar`: one tab stop for however many
353
+ * controls the page puts there, and the reader reaches it after the trigger
354
+ * rather than inside it.
355
+ */
356
+ [data-ui='collapsible'] > [data-part='actions'] {
357
+ align-items: center;
358
+ align-self: center;
359
+ column-gap: var(--_gap);
360
+ display: flex;
361
+ grid-column: 2;
362
+ grid-row: 1;
363
+ padding-inline-end: var(--slotted-collapsible-padding-inline, var(--_padding-inline));
364
+ }
365
+
366
+ /* ── The panel ────────────────────────────────────────────────────────── */
367
+
368
+ /**
369
+ * ── Opening without a measurement ─────────────────────────────────────
370
+ *
371
+ * The panel is a one-row grid whose track runs between `0fr` and `1fr`, and
372
+ * `1fr` is the content's own height at every frame. Radix writes
373
+ * `--radix-collapsible-content-height` from a layout read, Base UI writes
374
+ * `--collapsible-panel-height`, and Ark and Angular Material each measure in
375
+ * their own words; all four are wrong for one frame in a server response and
376
+ * stale until a resize observer fires. Nothing here reads the layout, so the
377
+ * family is right during the first paint and right when the content grows
378
+ * while the panel is open.
379
+ *
380
+ * `::details-content` would have been the platform's answer and is not
381
+ * available: animating it to an intrinsic height needs `interpolate-size`,
382
+ * which is not baseline.
383
+ */
384
+ [data-ui='collapsible'] > [data-part='panel'] {
385
+ display: grid;
386
+ grid-column: 1 / -1;
387
+ grid-row: 2;
388
+ grid-template-rows: 0fr;
389
+ min-inline-size: 0;
390
+ transition: grid-template-rows var(--slotted-duration-medium)
391
+ var(--slotted-control-transition-easing, var(--slotted-easing-standard));
392
+ }
393
+
394
+ [data-ui='collapsible'][data-open] > [data-part='panel'] {
395
+ grid-template-rows: 1fr;
396
+ }
397
+
398
+ /**
399
+ * The box the track clips. `content-visibility` is what takes closed content
400
+ * out of the accessibility tree, out of the tab sequence and out of the
401
+ * browser's page search, and `allow-discrete` is what keeps it visible for
402
+ * the length of the closing transition instead of vanishing at the first
403
+ * frame. The binding writes `inert` alongside it, so a browser without the
404
+ * property still cannot put focus inside a closed panel.
405
+ */
406
+ [data-ui='collapsible'] > [data-part='panel'] > [data-part='content'] {
407
+ color: var(--slotted-collapsible-panel-color, var(--slotted-text, CanvasText));
408
+ content-visibility: hidden;
409
+ font-size: var(--_panel-font-size);
410
+ line-height: var(--slotted-line-height-md, 1.5);
411
+ min-block-size: 0;
412
+ opacity: 0;
413
+ overflow: hidden;
414
+ /**
415
+ * The air under the content belongs to the open panel. A `0fr` track sizes
416
+ * to its item's minimum contribution, and padding is part of that even
417
+ * where the content itself contributes nothing — so a closed panel kept
418
+ * eight pixels of dead space under every header, which the reference page
419
+ * showed as a gap between the last row and the rule that closes the set.
420
+ */
421
+ padding-block-end: 0;
422
+ padding-inline: var(--slotted-collapsible-padding-inline, var(--_padding-inline));
423
+ transition:
424
+ content-visibility var(--slotted-duration-medium) allow-discrete,
425
+ opacity var(--slotted-duration-medium)
426
+ var(--slotted-control-transition-easing, var(--slotted-easing-standard));
427
+ }
428
+
429
+ [data-ui='collapsible'][data-open] > [data-part='panel'] > [data-part='content'] {
430
+ content-visibility: visible;
431
+ opacity: 1;
432
+ padding-block-end: var(--_padding-block);
433
+ }
434
+
435
+ /**
436
+ * A panel whose content has not arrived. The box is held open at a line's
437
+ * height so the reader is not handed an empty frame, and `aria-busy` on the
438
+ * panel is what says the emptiness is temporary. What stands in for the
439
+ * content is `skeleton`'s, composed by the consumer: a second family drawing
440
+ * placeholder geometry would be two answers to one question.
441
+ */
442
+ [data-ui='collapsible'][data-loading][data-open] > [data-part='panel'] > [data-part='content'] {
443
+ min-block-size: calc(var(--_panel-font-size) * var(--slotted-line-height-md, 1.5));
444
+ }
445
+
446
+ /* ── The states a trigger paints ──────────────────────────────────────── */
447
+
448
+ /**
449
+ * Hover raises the ink and lays a wash under the row; press goes one step
450
+ * further. Both hold themselves back for `:disabled`, which the browser has
451
+ * already taken out of action — the library learned that from a defect, and
452
+ * `states.test.mjs` is what keeps it from being relearned the same way.
453
+ */
454
+ [data-ui='collapsible']:not([data-disabled])
455
+ > [data-part='header']
456
+ > [data-part='trigger']:enabled:hover {
457
+ background-color: var(
458
+ --slotted-collapsible-hover-background,
459
+ var(--slotted-tone-secondary-subtle-hover)
460
+ );
461
+ color: var(--slotted-collapsible-hover-color, var(--slotted-text, CanvasText));
462
+ }
463
+
464
+ [data-ui='collapsible']:not([data-disabled])
465
+ > [data-part='header']
466
+ > [data-part='trigger']:enabled:active {
467
+ background-color: var(
468
+ --slotted-collapsible-active-background,
469
+ var(--slotted-tone-secondary-subtle-active)
470
+ );
471
+ }
472
+
473
+ [data-ui='collapsible'] > [data-part='header'] > [data-part='trigger']:disabled {
474
+ color: var(--slotted-disabled-foreground, GrayText);
475
+ cursor: not-allowed;
476
+ }
477
+
478
+ /**
479
+ * A header the group refuses to let close. It is the APG's own
480
+ * `aria-disabled="true"`, so it is still focusable and still announced — the
481
+ * mark simply says the press will do nothing.
482
+ */
483
+ [data-ui='collapsible']
484
+ > [data-part='header']
485
+ > [data-part='trigger'][aria-disabled='true']
486
+ > [data-part='indicator'] {
487
+ opacity: 0.45;
488
+ }
489
+
490
+ [data-ui='collapsible'][data-disabled] {
491
+ color: var(--slotted-disabled-foreground, GrayText);
492
+ }
493
+
494
+ /* ── Appearance ───────────────────────────────────────────────────────── */
495
+
496
+ /**
497
+ * A rule above the header, which is what makes a stack of these read as one
498
+ * list. The group closes the bottom of the stack with a rule of its own, so
499
+ * the item never has to know whether it is the last one.
500
+ */
501
+ [data-ui='collapsible'][data-variant='ruled'] {
502
+ border-block-start: var(--_rule-size) solid
503
+ var(--slotted-collapsible-rule-color, var(--slotted-border-subtle, ButtonBorder));
504
+ }
505
+
506
+ /**
507
+ * Its own card. It is the standalone disclosure's shape, and it is what an
508
+ * accordion hands its items under `separated`.
509
+ */
510
+ [data-ui='collapsible'][data-variant='framed'] {
511
+ background-color: var(--slotted-collapsible-surface, var(--slotted-surface-raised, Canvas));
512
+ border: var(--_rule-size) solid
513
+ var(--slotted-collapsible-rule-color, var(--slotted-border-subtle, ButtonBorder));
514
+ border-radius: var(--slotted-collapsible-radius, var(--slotted-radius-md, 6px));
515
+ /* The trigger's own background is drawn to the frame's edge, so the corner
516
+ it meets has to be the corner the frame draws. */
517
+ overflow: clip;
518
+ }
519
+
520
+ /* ── Density, direction and the narrow container ──────────────────────── */
521
+
522
+ /**
523
+ * Below this the actions leave the header's row and take one of their own.
524
+ * The literal is the rule the foundation states for container conditions:
525
+ * `@container (min-inline-size: var(--x))` is invalid CSS, so a reflowing
526
+ * family owns its container and writes the number.
527
+ */
528
+ [data-ui='collapsible'] {
529
+ container-name: slotted-collapsible;
530
+ container-type: inline-size;
531
+ }
532
+
533
+ @container slotted-collapsible (max-inline-size: 22rem) {
534
+ [data-ui='collapsible'] > [data-part='actions'] {
535
+ grid-column: 1 / -1;
536
+ grid-row: 2;
537
+ justify-content: flex-end;
538
+ padding-block-end: var(--_padding-block);
539
+ padding-inline-start: var(--slotted-collapsible-padding-inline, var(--_padding-inline));
540
+ }
541
+
542
+ [data-ui='collapsible'] > [data-part='panel'] {
543
+ grid-row: 3;
544
+ }
545
+ }
546
+ }
@@ -0,0 +1,55 @@
1
+ [
2
+ "--slotted-border-subtle",
3
+ "--slotted-border-width-thin",
4
+ "--slotted-collapsible-active-background",
5
+ "--slotted-collapsible-background",
6
+ "--slotted-collapsible-color",
7
+ "--slotted-collapsible-description-color",
8
+ "--slotted-collapsible-hover-background",
9
+ "--slotted-collapsible-hover-color",
10
+ "--slotted-collapsible-indicator-color",
11
+ "--slotted-collapsible-padding-inline",
12
+ "--slotted-collapsible-panel-color",
13
+ "--slotted-collapsible-radius",
14
+ "--slotted-collapsible-rule-color",
15
+ "--slotted-collapsible-surface",
16
+ "--slotted-control-font-family",
17
+ "--slotted-control-gap-lg",
18
+ "--slotted-control-gap-md",
19
+ "--slotted-control-gap-sm",
20
+ "--slotted-control-height-lg",
21
+ "--slotted-control-height-md",
22
+ "--slotted-control-height-sm",
23
+ "--slotted-control-icon-size-lg",
24
+ "--slotted-control-icon-size-md",
25
+ "--slotted-control-icon-size-sm",
26
+ "--slotted-control-letter-spacing",
27
+ "--slotted-control-padding-inline-lg",
28
+ "--slotted-control-padding-inline-md",
29
+ "--slotted-control-padding-inline-sm",
30
+ "--slotted-control-transition-duration",
31
+ "--slotted-control-transition-easing",
32
+ "--slotted-disabled-foreground",
33
+ "--slotted-duration-medium",
34
+ "--slotted-duration-short",
35
+ "--slotted-easing-standard",
36
+ "--slotted-focus-ring-color",
37
+ "--slotted-focus-ring-offset",
38
+ "--slotted-focus-ring-width",
39
+ "--slotted-font-size-lg",
40
+ "--slotted-font-size-md",
41
+ "--slotted-font-size-sm",
42
+ "--slotted-font-size-xs",
43
+ "--slotted-font-weight-medium",
44
+ "--slotted-font-weight-regular",
45
+ "--slotted-line-height-md",
46
+ "--slotted-radius-md",
47
+ "--slotted-space-3",
48
+ "--slotted-space-4",
49
+ "--slotted-space-5",
50
+ "--slotted-surface-raised",
51
+ "--slotted-text",
52
+ "--slotted-text-muted",
53
+ "--slotted-tone-secondary-subtle-active",
54
+ "--slotted-tone-secondary-subtle-hover"
55
+ ]