@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,71 @@
1
+ [
2
+ "--slotted-border-subtle",
3
+ "--slotted-border-width-thin",
4
+ "--slotted-control-gap-md",
5
+ "--slotted-control-gap-sm",
6
+ "--slotted-control-height-md",
7
+ "--slotted-control-height-sm",
8
+ "--slotted-control-icon-size-md",
9
+ "--slotted-control-icon-size-sm",
10
+ "--slotted-control-radius",
11
+ "--slotted-disabled-foreground",
12
+ "--slotted-duration-medium",
13
+ "--slotted-duration-short",
14
+ "--slotted-easing-standard",
15
+ "--slotted-focus-ring-color",
16
+ "--slotted-focus-ring-offset",
17
+ "--slotted-focus-ring-width",
18
+ "--slotted-font-family-heading",
19
+ "--slotted-font-family-sans",
20
+ "--slotted-font-size-2xl",
21
+ "--slotted-font-size-3xl",
22
+ "--slotted-font-size-lg",
23
+ "--slotted-font-size-md",
24
+ "--slotted-font-size-sm",
25
+ "--slotted-font-size-xl",
26
+ "--slotted-font-weight-medium",
27
+ "--slotted-font-weight-semibold",
28
+ "--slotted-line-height-2xl",
29
+ "--slotted-line-height-3xl",
30
+ "--slotted-line-height-lg",
31
+ "--slotted-line-height-md",
32
+ "--slotted-line-height-sm",
33
+ "--slotted-line-height-xl",
34
+ "--slotted-page-header-background",
35
+ "--slotted-page-header-border",
36
+ "--slotted-page-header-control-size",
37
+ "--slotted-page-header-description-measure",
38
+ "--slotted-page-header-gap",
39
+ "--slotted-page-header-heading-size-lg",
40
+ "--slotted-page-header-heading-size-md",
41
+ "--slotted-page-header-heading-size-sm",
42
+ "--slotted-page-header-inset",
43
+ "--slotted-page-header-padding-block",
44
+ "--slotted-page-header-radius",
45
+ "--slotted-page-header-shadow",
46
+ "--slotted-page-header-snapped-heading-size-lg",
47
+ "--slotted-page-header-snapped-heading-size-md",
48
+ "--slotted-page-header-snapped-heading-size-sm",
49
+ "--slotted-radius-full",
50
+ "--slotted-radius-lg",
51
+ "--slotted-radius-sm",
52
+ "--slotted-shadow-sm",
53
+ "--slotted-space-1",
54
+ "--slotted-space-2",
55
+ "--slotted-space-3",
56
+ "--slotted-space-4",
57
+ "--slotted-space-5",
58
+ "--slotted-space-6",
59
+ "--slotted-surface",
60
+ "--slotted-target-comfortable",
61
+ "--slotted-target-min",
62
+ "--slotted-text",
63
+ "--slotted-text-muted",
64
+ "--slotted-tone-accent-subtle-hover",
65
+ "--slotted-tone-accent-surface",
66
+ "--slotted-tone-accent-text",
67
+ "--slotted-tone-secondary-subtle-active",
68
+ "--slotted-tone-secondary-subtle-hover",
69
+ "--slotted-toolbar-inset",
70
+ "--slotted-z-index-sticky"
71
+ ]
@@ -0,0 +1,500 @@
1
+ @layer slotted.components {
2
+ /**
3
+ * Moving between pages of a collection. Thirteen parts, twelve of them
4
+ * optional, and the arrangement is the consumer's: a numbered paginator is
5
+ * the row between two triggers, and a table's paginator bar is a page size,
6
+ * a range and two triggers. The field ships those as two components — MUI
7
+ * `Pagination` and Angular Material `mat-paginator` — and the difference
8
+ * between them is which parts were placed, not which stylesheet was loaded.
9
+ *
10
+ * The root is the container every part measures itself against. It declares
11
+ * its own `container-name`, so a paginator nested inside another family's
12
+ * container answers its own inline size and not that one's.
13
+ */
14
+ [data-ui='pagination'] {
15
+ --_target: var(--slotted-pagination-target, var(--slotted-control-height-md, 34px));
16
+ --_radius: var(--slotted-pagination-radius, var(--slotted-control-radius, 4px));
17
+ --_muted: var(--slotted-pagination-color-muted, var(--slotted-text-muted, GrayText));
18
+ --_strong: var(--slotted-pagination-color, var(--slotted-text, CanvasText));
19
+ --_glyph: var(--slotted-pagination-glyph-size, var(--slotted-control-icon-size-md, 16px));
20
+ --_hover-surface: var(
21
+ --slotted-pagination-surface-hover,
22
+ var(--slotted-tone-accent-subtle-hover, ButtonFace)
23
+ );
24
+ --_active-surface: var(
25
+ --slotted-pagination-surface-active,
26
+ var(--slotted-tone-accent-subtle-active, ButtonFace)
27
+ );
28
+
29
+ align-items: center;
30
+ color: var(--_strong);
31
+ /**
32
+ * The controls sit as tightly together as the numbers do, so the four
33
+ * triggers and the row read as one track rather than as six things spaced
34
+ * apart. The air goes around the two sentences instead, which is where the
35
+ * eye actually needs a break; a single gap on the root gave the same
36
+ * distance to "Next" and to "Rows per page", and the track fell apart.
37
+ */
38
+ column-gap: var(--slotted-pagination-gap, var(--slotted-space-1, 0.125rem));
39
+ container-name: slotted-pagination;
40
+ container-type: inline-size;
41
+ display: flex;
42
+ flex-wrap: wrap;
43
+ font-family: var(--slotted-pagination-font-family, var(--slotted-font-family-sans, inherit));
44
+ font-size: var(--slotted-pagination-font-size, var(--slotted-control-font-size-md, 13px));
45
+ row-gap: var(--slotted-pagination-row-gap, var(--slotted-space-4, 0.5rem));
46
+ }
47
+
48
+ /* ── The row of pages ───────────────────────────────────────────────────
49
+ *
50
+ * `@slotted/core/pagination` keeps the row a constant number of items at
51
+ * every page, so nothing here has to defend against a row that grows. What
52
+ * this stylesheet defends against is the digits: page 9 and page 1000 are
53
+ * the same target, because the box is at least as wide as it is tall and the
54
+ * figures are tabular.
55
+ */
56
+
57
+ [data-ui='pagination'] [data-part='list'] {
58
+ align-items: center;
59
+ column-gap: var(--slotted-pagination-item-gap, var(--slotted-space-1, 0.125rem));
60
+ display: flex;
61
+ list-style: none;
62
+ margin: 0;
63
+ padding: 0;
64
+ }
65
+
66
+ [data-ui='pagination'] [data-part='item'] {
67
+ display: flex;
68
+ }
69
+
70
+ [data-ui='pagination']
71
+ :is([data-part='status'], [data-part='summary'], [data-part='page-size-label']) {
72
+ margin-inline: var(--slotted-pagination-text-gap, var(--slotted-space-4, 0.5rem));
73
+ }
74
+
75
+ /* The air belongs between things, never against the family's own edge. */
76
+ [data-ui='pagination']
77
+ :is([data-part='status'], [data-part='summary'], [data-part='page-size-label']):first-child {
78
+ margin-inline-start: 0;
79
+ }
80
+
81
+ [data-ui='pagination']
82
+ :is([data-part='status'], [data-part='summary'], [data-part='page-size-label']):last-child {
83
+ margin-inline-end: 0;
84
+ }
85
+
86
+ /* Two sentences side by side share one step of air, not two: the page
87
+ size's label and the range read eighteen pixels apart while the range
88
+ and the trigger read ten. */
89
+ [data-ui='pagination']
90
+ :is([data-part='status'], [data-part='summary'], [data-part='page-size-label'])
91
+ + :is([data-part='status'], [data-part='summary'], [data-part='page-size-label']) {
92
+ margin-inline-start: 0;
93
+ }
94
+
95
+ [data-ui='pagination']
96
+ :is(
97
+ [data-part='page'],
98
+ [data-part='first'],
99
+ [data-part='previous'],
100
+ [data-part='next'],
101
+ [data-part='last']
102
+ ) {
103
+ align-items: center;
104
+ appearance: none;
105
+ background-color: transparent;
106
+ block-size: var(--_target);
107
+ border: var(--slotted-control-border-width, 1px) solid transparent;
108
+ border-radius: var(--_radius);
109
+ color: var(--_strong);
110
+ cursor: pointer;
111
+ display: inline-flex;
112
+ font: inherit;
113
+ /**
114
+ * Proportional figures give every digit its own width, so a row walking
115
+ * from page 8 to page 9 to page 10 shifts every item beside it. Tabular
116
+ * figures cost nothing and the row stops moving.
117
+ */
118
+ font-variant-numeric: tabular-nums;
119
+ font-weight: var(--slotted-pagination-item-weight, var(--slotted-font-weight-medium, 500));
120
+ justify-content: center;
121
+ /** Square at one digit, and wider only when the digits demand it. */
122
+ min-inline-size: var(--_target);
123
+ padding-inline: var(--slotted-pagination-item-padding, var(--slotted-space-2, 0.25rem));
124
+ text-decoration: none;
125
+ transition:
126
+ background-color var(--slotted-control-transition-duration)
127
+ var(--slotted-control-transition-easing),
128
+ border-color var(--slotted-control-transition-duration)
129
+ var(--slotted-control-transition-easing),
130
+ color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing);
131
+ }
132
+
133
+ /**
134
+ * A page number rests one step back from the four triggers. A row of eight
135
+ * numbers at full strength competes with the one that is filled, and the
136
+ * triggers are glyphs rather than words: a chevron at the muted step reads
137
+ * as unavailable, which is the difference this family needs to keep for the
138
+ * trigger that actually is.
139
+ */
140
+ [data-ui='pagination'] [data-part='page']:not([aria-current]:not([aria-current='false'])) {
141
+ color: var(--_muted);
142
+ }
143
+
144
+ /**
145
+ * The page the reader is on. It is a solid fill rather than a heavier weight
146
+ * or a border, for the reason the breadcrumb gives its last crumb the
147
+ * strongest colour: a row of numbers is scanned rather than read, and a fill
148
+ * is the only difference visible at a glance. `aria-current="page"` is what
149
+ * paints it — the value the ARIA specification names for a link inside a set
150
+ * of pagination links — so what a screen reader announces and what the eye
151
+ * sees are one fact rather than two.
152
+ */
153
+ [data-ui='pagination'] [data-part='page'][aria-current]:not([aria-current='false']) {
154
+ background-color: var(
155
+ --slotted-pagination-current-surface,
156
+ var(--slotted-tone-accent-solid, Highlight)
157
+ );
158
+ color: var(
159
+ --slotted-pagination-current-color,
160
+ var(--slotted-tone-accent-on-solid, HighlightText)
161
+ );
162
+ }
163
+
164
+ /* ── Hover, press, and the states that outrank them ─────────────────────
165
+ *
166
+ * `[data-loading]` guards as well as `[data-disabled]`, which is what stops a
167
+ * reader pressing Next four times while one request is in flight: a
168
+ * paginator waiting for the page it already asked for answers the pointer
169
+ * with nothing. The current page is guarded too — it is where the reader
170
+ * already is, and a fill that lightens under the pointer would read as a
171
+ * different page.
172
+ */
173
+
174
+ [data-ui='pagination']
175
+ :is(
176
+ [data-part='page'],
177
+ [data-part='first'],
178
+ [data-part='previous'],
179
+ [data-part='next'],
180
+ [data-part='last']
181
+ ):not([data-disabled], [data-loading], [aria-current]:not([aria-current='false'])):hover {
182
+ background-color: var(--_hover-surface);
183
+ color: var(--_strong);
184
+ }
185
+
186
+ [data-ui='pagination']
187
+ :is(
188
+ [data-part='page'],
189
+ [data-part='first'],
190
+ [data-part='previous'],
191
+ [data-part='next'],
192
+ [data-part='last']
193
+ ):not([data-disabled], [data-loading], [aria-current]:not([aria-current='false'])):active {
194
+ background-color: var(--_active-surface);
195
+ color: var(--_strong);
196
+ }
197
+
198
+ [data-ui='pagination']
199
+ :is(
200
+ [data-part='page'],
201
+ [data-part='first'],
202
+ [data-part='previous'],
203
+ [data-part='next'],
204
+ [data-part='last'],
205
+ [data-part='page-size']
206
+ ):focus-visible {
207
+ outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
208
+ outline-offset: var(--slotted-focus-ring-offset, 2px);
209
+ }
210
+
211
+ /**
212
+ * A trigger at a bound, and every control while the whole family is
213
+ * unavailable. `data-disabled` rather than `:disabled`, because in link mode
214
+ * the control is an anchor: what makes an anchor unavailable is the
215
+ * destination the binding did not render, which is the shape `link` already
216
+ * ships and the only one that stops a middle click as well as a left one.
217
+ */
218
+ [data-ui='pagination'] :is([data-disabled], [data-loading]) {
219
+ color: var(--slotted-pagination-color-disabled, var(--slotted-disabled-foreground, GrayText));
220
+ }
221
+
222
+ [data-ui='pagination'] [data-disabled] {
223
+ cursor: not-allowed;
224
+ }
225
+
226
+ /**
227
+ * The current page while the row is inert. The chip keeps its shape, because
228
+ * the reader still needs to know which page they are on, and loses its
229
+ * accent, because `disabled` and `loading` both outrank `current` in
230
+ * `STATE_PRECEDENCE` — a saturated chip inside a grey row reads as the one
231
+ * thing still operable, which is exactly backwards.
232
+ */
233
+ [data-ui='pagination']
234
+ [data-part='page'][aria-current]:not([aria-current='false']):is(
235
+ [data-disabled],
236
+ [data-loading]
237
+ ) {
238
+ background-color: var(--slotted-disabled-background, Canvas);
239
+ color: var(--slotted-disabled-foreground, GrayText);
240
+ }
241
+
242
+ /**
243
+ * A page change in flight. The row keeps its size and its text, because a
244
+ * paginator that emptied itself while loading would move the control the
245
+ * reader is about to press again.
246
+ */
247
+ [data-ui='pagination'] [data-loading] {
248
+ cursor: progress;
249
+ }
250
+
251
+ /**
252
+ * The pages the row does not draw. The mark is the character U+2026 as text,
253
+ * for the reason the breadcrumb's ellipsis is: rule 3 of
254
+ * `docs/token-foundation.md` forbids drawing an *icon* from a character, and
255
+ * this one stands in for nothing — it is the typographic mark for omitted
256
+ * content, and omitted content is exactly what it holds. It is announced to
257
+ * nobody, which is what Zag, MUI and Primer all ship.
258
+ */
259
+ [data-ui='pagination'] [data-part='ellipsis'] {
260
+ align-items: center;
261
+ block-size: var(--_target);
262
+ color: var(--_muted);
263
+ display: inline-flex;
264
+ justify-content: center;
265
+ letter-spacing: var(--slotted-pagination-ellipsis-tracking, 0.05em);
266
+ line-height: 1;
267
+ min-inline-size: var(--_target);
268
+ /**
269
+ * The ink of an ellipsis sits on the baseline, and a centred line box puts
270
+ * the baseline below the middle of the box. Half a cap height is the
271
+ * distance from the baseline to the optical centre of Latin text.
272
+ */
273
+ translate: 0 calc(-1 * var(--slotted-pagination-ellipsis-lift, 0.5cap));
274
+ }
275
+
276
+ /* ── The four triggers ──────────────────────────────────────────────────
277
+ *
278
+ * One chevron for a step and two for an end: the `chevron-right` and
279
+ * `chevrons-right` Glyph elements the bindings render in each trigger, both
280
+ * stroked with `currentColor` so each follows the state its button is in —
281
+ * including the muted colour a disabled trigger takes, which is why neither
282
+ * needs a rule of its own.
283
+ *
284
+ * Mirroring is stated twice rather than once, because there are two facts:
285
+ * a chevron points along the reading direction, which the icon box's own
286
+ * `directional` mirror answers in a right-to-left document; and `previous`
287
+ * and `first` point against it, which the half turn below answers. A turn
288
+ * rather than a second `scale`, which the box's mirror holds: the two
289
+ * compose, and a chevron turned half a turn is the chevron flipped.
290
+ */
291
+
292
+ [data-ui='pagination']
293
+ :is([data-part='first'], [data-part='previous'], [data-part='next'], [data-part='last']) {
294
+ --slotted-icon-size: var(--_glyph);
295
+ }
296
+
297
+ [data-ui='pagination'] :is([data-part='first'], [data-part='previous']) > [data-ui='icon'] {
298
+ rotate: 0.5turn;
299
+ }
300
+
301
+ /* ── The two sentences ──────────────────────────────────────────────────
302
+ *
303
+ * `status` is "21–40 of 482", and it is the polite live region: the numbers
304
+ * are what a reader who cannot see the row needs after a page change, and
305
+ * one region announcing one sentence is the whole of the announcement.
306
+ * `summary` is "Page 3 of 24", which is what the row itself becomes below
307
+ * the breakpoint.
308
+ */
309
+
310
+ [data-ui='pagination'] :is([data-part='status'], [data-part='summary']) {
311
+ color: var(--_muted);
312
+ font-variant-numeric: tabular-nums;
313
+ /* Only the paragraph's own block margin: the inline air between the
314
+ sentences and the triggers is stated above and stays. Read live, a
315
+ `margin: 0` here came after that rule and won, and "1–8 of 50" stood
316
+ two pixels from the previous-page trigger. */
317
+ margin-block: 0;
318
+ }
319
+
320
+ /**
321
+ * The summary is three words and never breaks; the range may be a sentence a
322
+ * consumer wrote, and forbidding it to wrap pushed the trigger after it onto
323
+ * a line of its own at 240 pixels.
324
+ */
325
+ [data-ui='pagination'] [data-part='summary'] {
326
+ white-space: nowrap;
327
+ }
328
+
329
+ [data-ui='pagination'] [data-part='summary'] {
330
+ align-items: center;
331
+ block-size: var(--_target);
332
+ display: none;
333
+ }
334
+
335
+ /* ── The page size ──────────────────────────────────────────────────────
336
+ *
337
+ * A native `select`, painted from the control tokens every other control in
338
+ * the library reads. `select` in a later wave owns the styled listbox; a
339
+ * paginator that could not change its page size until then is not one a
340
+ * table can use, and the native control is what section 2.8 of
341
+ * `docs/component-features.md` asks for first. Its popup follows the
342
+ * `color-scheme` the theme already emits, so neither scheme needs a rule.
343
+ *
344
+ * The label wraps the select rather than pointing at it, which gives the
345
+ * control its accessible name from the platform and gives the bindings
346
+ * somewhere to put the chevron: the `chevron-down` Glyph element after the
347
+ * select, laid over its end. A `select` takes no children of its own, and a
348
+ * chevron drawn as a `background-image` would be one fixed colour in a
349
+ * family that has three schemes.
350
+ */
351
+
352
+ [data-ui='pagination'] [data-part='page-size-label'] {
353
+ align-items: center;
354
+ color: var(--_muted);
355
+ column-gap: var(--slotted-pagination-page-size-gap, var(--slotted-space-3, 0.375rem));
356
+ display: inline-flex;
357
+ position: relative;
358
+ white-space: nowrap;
359
+ }
360
+
361
+ [data-ui='pagination'] [data-part='page-size-label'] > [data-ui='icon'] {
362
+ --slotted-icon-size: var(--_glyph);
363
+
364
+ inset-block-start: 50%;
365
+ inset-inline-end: var(--slotted-pagination-page-size-inset, var(--slotted-space-3, 0.375rem));
366
+ /* The chevron belongs to the select underneath it, and never takes a click. */
367
+ pointer-events: none;
368
+ position: absolute;
369
+ translate: 0 -50%;
370
+ }
371
+
372
+ [data-ui='pagination'] [data-part='page-size'] {
373
+ appearance: none;
374
+ background-color: var(
375
+ --slotted-pagination-page-size-surface,
376
+ var(--slotted-control-surface, Field)
377
+ );
378
+ block-size: var(--_target);
379
+ border: var(--slotted-control-border-width, 1px) solid
380
+ var(--slotted-control-border-color, ButtonBorder);
381
+ border-radius: var(--_radius);
382
+ box-shadow: var(--slotted-control-shadow);
383
+ color: var(--_strong);
384
+ cursor: pointer;
385
+ font: inherit;
386
+ font-variant-numeric: tabular-nums;
387
+ padding-inline: var(--slotted-control-padding-inline-sm, 10px)
388
+ calc(var(--_glyph) + var(--slotted-space-6, 1rem));
389
+ transition: border-color var(--slotted-control-transition-duration)
390
+ var(--slotted-control-transition-easing);
391
+ }
392
+
393
+ [data-ui='pagination'] [data-part='page-size']:not(:disabled):hover {
394
+ border-color: var(--slotted-border-strong, ButtonBorder);
395
+ }
396
+
397
+ [data-ui='pagination'] [data-part='page-size']:disabled {
398
+ background-color: var(--slotted-disabled-background, Canvas);
399
+ border-color: var(--slotted-disabled-border, GrayText);
400
+ color: var(--slotted-disabled-foreground, GrayText);
401
+ cursor: not-allowed;
402
+ }
403
+
404
+ /* ── Compaction ─────────────────────────────────────────────────────────
405
+ *
406
+ * Below the breakpoint the numbered row gives way to the sentence that says
407
+ * the same thing in less space, and the triggers stay. Both are always
408
+ * rendered and exactly one is displayed, so neither is announced twice.
409
+ *
410
+ * It is a container query and not a viewport query, so a paginator under a
411
+ * table in a split pane compacts while the same paginator on a full page
412
+ * does not. The breakpoint is a literal because
413
+ * `@container (min-width: var(--x))` is invalid CSS, which rule 4 of
414
+ * `docs/token-foundation.md` states.
415
+ */
416
+
417
+ @container slotted-pagination (max-width: 22rem) {
418
+ [data-ui='pagination'] [data-part='list'] {
419
+ display: none;
420
+ }
421
+
422
+ [data-ui='pagination'] [data-part='summary'] {
423
+ display: flex;
424
+ }
425
+
426
+ /**
427
+ * The range and the summary say overlapping things, and at this width
428
+ * there is room for one. The summary wins because it names the page the
429
+ * triggers move; the range names items the reader cannot act on.
430
+ *
431
+ * Only where a summary exists to replace it. A paginator over a collection
432
+ * whose total the server does not know has no page numbers and therefore
433
+ * no summary, and hiding its range left two chevrons and no sentence at
434
+ * all — which the 240-pixel capture showed and no test could have.
435
+ */
436
+ [data-ui='pagination']:has([data-part='summary']) [data-part='status'] {
437
+ display: none;
438
+ }
439
+
440
+ /**
441
+ * The page size takes the whole line, so the controls beside it are not
442
+ * split across two. At this width the label and its select are most of the
443
+ * row, and the trigger that did not fit landed alone underneath.
444
+ */
445
+ [data-ui='pagination'] [data-part='page-size-label'] {
446
+ flex-basis: 100%;
447
+ margin-inline: 0;
448
+ }
449
+
450
+ /**
451
+ * And the select fills the line with it. The chevron is drawn at the
452
+ * label's own inline end, so a label stretched to the full width with a
453
+ * select still sized to its content left the mark floating in the gap
454
+ * between the two.
455
+ */
456
+ [data-ui='pagination'] [data-part='page-size'] {
457
+ flex: 1;
458
+ }
459
+
460
+ /**
461
+ * A sentence claims its full length before a flex row decides where to
462
+ * break, so a range of any length pushed the trigger after it onto a line
463
+ * of its own. Basing it at nought lets the row keep every control on one
464
+ * line and gives the sentence whatever is left.
465
+ */
466
+ [data-ui='pagination'] [data-part='status'] {
467
+ flex: 1 1 0;
468
+ }
469
+ }
470
+
471
+ /* ── Forced colours ─────────────────────────────────────────────────────
472
+ *
473
+ * The system replaces every painted surface with the page's own background,
474
+ * which would take two things with it: the fill that is the only mark on
475
+ * the current page, and the fill that answers the pointer.
476
+ *
477
+ * The chevrons need nothing: they are stroked with `currentColor`, the
478
+ * button's own colour, which the system has already forced to the right
479
+ * value — including the grey a disabled trigger takes.
480
+ */
481
+
482
+ @media (forced-colors: active) {
483
+ [data-ui='pagination'] [data-part='page'][aria-current]:not([aria-current='false']) {
484
+ background-color: Highlight;
485
+ color: HighlightText;
486
+ forced-color-adjust: none;
487
+ }
488
+
489
+ [data-ui='pagination']
490
+ :is(
491
+ [data-part='page'],
492
+ [data-part='first'],
493
+ [data-part='previous'],
494
+ [data-part='next'],
495
+ [data-part='last']
496
+ ):not([data-disabled], [data-loading], [aria-current]:not([aria-current='false'])):hover {
497
+ border-color: ButtonBorder;
498
+ }
499
+ }
500
+ }
@@ -0,0 +1,56 @@
1
+ [
2
+ "--slotted-border-strong",
3
+ "--slotted-control-border-color",
4
+ "--slotted-control-border-width",
5
+ "--slotted-control-font-size-md",
6
+ "--slotted-control-height-md",
7
+ "--slotted-control-icon-size-md",
8
+ "--slotted-control-padding-inline-sm",
9
+ "--slotted-control-radius",
10
+ "--slotted-control-shadow",
11
+ "--slotted-control-surface",
12
+ "--slotted-control-transition-duration",
13
+ "--slotted-control-transition-easing",
14
+ "--slotted-disabled-background",
15
+ "--slotted-disabled-border",
16
+ "--slotted-disabled-foreground",
17
+ "--slotted-focus-ring-color",
18
+ "--slotted-focus-ring-offset",
19
+ "--slotted-focus-ring-width",
20
+ "--slotted-font-family-sans",
21
+ "--slotted-font-weight-medium",
22
+ "--slotted-pagination-color",
23
+ "--slotted-pagination-color-disabled",
24
+ "--slotted-pagination-color-muted",
25
+ "--slotted-pagination-current-color",
26
+ "--slotted-pagination-current-surface",
27
+ "--slotted-pagination-ellipsis-lift",
28
+ "--slotted-pagination-ellipsis-tracking",
29
+ "--slotted-pagination-font-family",
30
+ "--slotted-pagination-font-size",
31
+ "--slotted-pagination-gap",
32
+ "--slotted-pagination-glyph-size",
33
+ "--slotted-pagination-item-gap",
34
+ "--slotted-pagination-item-padding",
35
+ "--slotted-pagination-item-weight",
36
+ "--slotted-pagination-page-size-gap",
37
+ "--slotted-pagination-page-size-inset",
38
+ "--slotted-pagination-page-size-surface",
39
+ "--slotted-pagination-radius",
40
+ "--slotted-pagination-row-gap",
41
+ "--slotted-pagination-surface-active",
42
+ "--slotted-pagination-surface-hover",
43
+ "--slotted-pagination-target",
44
+ "--slotted-pagination-text-gap",
45
+ "--slotted-space-1",
46
+ "--slotted-space-2",
47
+ "--slotted-space-3",
48
+ "--slotted-space-4",
49
+ "--slotted-space-6",
50
+ "--slotted-text",
51
+ "--slotted-text-muted",
52
+ "--slotted-tone-accent-on-solid",
53
+ "--slotted-tone-accent-solid",
54
+ "--slotted-tone-accent-subtle-active",
55
+ "--slotted-tone-accent-subtle-hover"
56
+ ]