@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,526 @@
1
+ @layer slotted.components {
2
+ /**
3
+ * Interactive, non-modal content anchored to the control that opened it.
4
+ *
5
+ * The same two boxes `tooltip` is built from, and the same reasons: the
6
+ * **layer** is what `packages/core/src/positioner` writes `position`, `left`
7
+ * and `top` onto and what slides and fades, because the module leaves
8
+ * `transform` alone on purpose; the **content** is the painted panel; the
9
+ * arrow is the layer's other child, behind the panel. The gap between the
10
+ * trigger and the panel is the layer's own padding rather than the
11
+ * positioner's offset, so the arrow has a band to stand in and the pointer
12
+ * never crosses empty page.
13
+ *
14
+ * ┌─ root ─ the layer ────────────────────────────────┐
15
+ * │ ▪ focus-guard │
16
+ * │ ┌─ content ─ role="dialog" ─────────────────┐ │
17
+ * │ │ header ▸ title · description │ close │ │
18
+ * │ ├────────────────────────────────────────────┤ │
19
+ * │ │ body ▸ the only part that scrolls │ │
20
+ * │ ├────────────────────────────────────────────┤ │
21
+ * │ │ footer ▸ the actions │ │
22
+ * │ └────────────────────────────────────────────┘ │
23
+ * │ ▪ focus-guard ◆ arrow │
24
+ * └───────────────────────────────────────────────────┘
25
+ *
26
+ * ── Why the panel is a grid of three rows ────────────────────────────
27
+ *
28
+ * Radix, Base UI and React Aria each publish the remaining height as a custom
29
+ * property and none of them uses it. Bounding the whole panel scrolls the
30
+ * title out of sight, which is the wrong answer for a panel whose name is how
31
+ * a reader knows what they are in. The middle row takes the height that is
32
+ * left and scrolls; the header and the footer keep theirs.
33
+ *
34
+ * ── Density ─────────────────────────────────────────────────────────
35
+ *
36
+ * A panel's own inset is on the space scale, as `card`'s and `alert`'s are.
37
+ * Density moves what a panel holds — the close control, the buttons in the
38
+ * footer, the fields in the body — all of which read control geometry. The
39
+ * gaps inside the header and the footer read it too, so a dense popover is a
40
+ * tighter popover rather than a smaller one.
41
+ */
42
+ [data-ui='popover'] {
43
+ --_gap: var(--slotted-popover-gap, var(--slotted-space-4, 0.5rem));
44
+
45
+ --_surface: var(--slotted-popover-surface, var(--slotted-surface-raised, #ffffff));
46
+ --_text: var(--slotted-popover-text, var(--slotted-text, #0f172a));
47
+ --_border-color: var(--slotted-popover-border-color, var(--slotted-border-subtle, #e2e8f0));
48
+ --_border-width: var(--slotted-border-width-thin, 1px);
49
+ --_radius: var(--slotted-popover-radius, var(--slotted-radius-lg, 8px));
50
+ --_shadow: var(--slotted-popover-shadow, var(--slotted-shadow-md));
51
+ --_arrow-size: var(--slotted-popover-arrow-size, 0.625rem);
52
+ /* The point, softened to the same degree the surface's own corners are.
53
+ A 90-degree tip beside a rounded panel reads as a different object. */
54
+ --_arrow-tip-radius: var(--slotted-popover-arrow-tip-radius, var(--slotted-radius-xs, 2px));
55
+
56
+ --_inset-block: var(--slotted-popover-padding-block, var(--slotted-space-5, 0.75rem));
57
+ --_inset-inline: var(--slotted-popover-padding-inline, var(--slotted-space-6, 1rem));
58
+ --_row-gap: var(--slotted-control-gap-md, 0.5rem);
59
+ --_title-font-size: var(--slotted-font-size-lg, 1rem);
60
+ --_font-size: var(--slotted-font-size-md, 0.875rem);
61
+ /**
62
+ * The cap, for the reason `tooltip` records: measure belongs to
63
+ * `container`, so the family offers no axis for it and still has to stop a
64
+ * `max-content` layer from setting one line the width of the page. Three
65
+ * steps, and `width="anchor"` replaces all three with the anchor's own.
66
+ */
67
+ --_measure: var(--slotted-popover-measure, 20rem);
68
+
69
+ /* Only the block inset, for the reason `tooltip.css` sets out: the
70
+ positioner writes `left` and never `right`, and `inset-inline-start`
71
+ resolves to `right` in a right-to-left document, where it would win over
72
+ the measured `left` and pin every layer to the far edge. */
73
+ position: absolute;
74
+ inset-block-start: 0;
75
+
76
+ z-index: calc(var(--slotted-z-index-popover, 1100) + var(--slotted-layer-depth, 0));
77
+ isolation: isolate;
78
+
79
+ box-sizing: border-box;
80
+ padding: var(--_gap);
81
+ inline-size: max-content;
82
+ max-inline-size: min(var(--_measure), var(--slotted-positioner-available-width, 100vw));
83
+
84
+ /* The layer is only a frame around the panel; the panel takes the pointer. */
85
+ pointer-events: none;
86
+
87
+ opacity: 0;
88
+ /**
89
+ * R7: the layer arrives along the axis it opens on — from one space step
90
+ * above its place when it opens downward, from one step below when it
91
+ * opens upward — and never along the inline axis. A `scale` from the
92
+ * corner the positioner named as origin moved the far edge by four per
93
+ * cent of the width, which read as an entrance from the left.
94
+ */
95
+ --_enter-distance: var(--slotted-space-2, 0.25rem);
96
+ translate: 0 calc(-1 * var(--_enter-distance));
97
+ transition:
98
+ opacity var(--slotted-duration-short) var(--slotted-easing-exit),
99
+ translate var(--slotted-duration-short) var(--slotted-easing-exit);
100
+ }
101
+
102
+ [data-ui='popover'][data-side='top'] {
103
+ translate: 0 var(--_enter-distance);
104
+ }
105
+
106
+ /* A lateral side has no block direction to arrive from, so it only fades. */
107
+ [data-ui='popover']:is([data-side='left'], [data-side='right']) {
108
+ translate: 0 0;
109
+ }
110
+
111
+ /**
112
+ * The entrance is a keyframe animation and not a transition. A transition
113
+ * starts from the style the browser computed last, and the positioner
114
+ * writes `data-side` in the same style update as the family opens the
115
+ * layer, so a transition set out from the closed style of the side the
116
+ * layer had before it had one — the bottom's — whatever side it opens on.
117
+ * A keyframe states where it starts. The exit stays a transition: it
118
+ * leaves from wherever the layer is, on the closed rule's durations.
119
+ */
120
+ [data-ui='popover'][data-open] {
121
+ opacity: 1;
122
+ translate: 0 0;
123
+ transition: none;
124
+ }
125
+
126
+ /**
127
+ * Only a layer the positioner placed arrives: it writes `data-positioned`
128
+ * with the side, and a layer written open in static markup — the harness,
129
+ * a docs snippet — is simply there, and is photographed where it stands.
130
+ */
131
+ [data-ui='popover'][data-open][data-positioned] {
132
+ animation: slotted-popover-enter-down var(--slotted-duration-medium) var(--slotted-easing-enter);
133
+ }
134
+
135
+ [data-ui='popover'][data-open][data-positioned][data-side='top'] {
136
+ animation-name: slotted-popover-enter-up;
137
+ }
138
+
139
+ [data-ui='popover'][data-open][data-positioned]:is([data-side='left'], [data-side='right']) {
140
+ animation-name: slotted-popover-fade;
141
+ }
142
+
143
+ @keyframes slotted-popover-enter-down {
144
+ from {
145
+ opacity: 0;
146
+ translate: 0 calc(-1 * var(--_enter-distance));
147
+ }
148
+ }
149
+
150
+ @keyframes slotted-popover-enter-up {
151
+ from {
152
+ opacity: 0;
153
+ translate: 0 var(--_enter-distance);
154
+ }
155
+ }
156
+
157
+ @keyframes slotted-popover-fade {
158
+ from {
159
+ opacity: 0;
160
+ }
161
+ }
162
+
163
+ /* Stillness keeps the fade and drops the movement (R7). */
164
+ @media (prefers-reduced-motion: reduce) {
165
+ [data-ui='popover'],
166
+ [data-ui='popover'][data-side='top'],
167
+ [data-ui='popover'][data-side='left'],
168
+ [data-ui='popover'][data-side='right'] {
169
+ translate: 0 0;
170
+ transition: opacity var(--slotted-duration-short) var(--slotted-easing-exit);
171
+ }
172
+
173
+ [data-ui='popover'][data-open][data-positioned],
174
+ [data-ui='popover'][data-open][data-positioned][data-side='top'],
175
+ [data-ui='popover'][data-open][data-positioned][data-side='left'],
176
+ [data-ui='popover'][data-open][data-positioned][data-side='right'] {
177
+ animation-name: slotted-popover-fade;
178
+ }
179
+ }
180
+
181
+ [data-ui='popover'][data-detached] {
182
+ visibility: hidden;
183
+ }
184
+
185
+ [data-ui='popover'][data-size='sm'] {
186
+ --_inset-block: var(--slotted-popover-padding-block-sm, var(--slotted-space-4, 0.5rem));
187
+ --_inset-inline: var(--slotted-popover-padding-inline-sm, var(--slotted-space-5, 0.75rem));
188
+ --_title-font-size: var(--slotted-font-size-md, 0.875rem);
189
+ --_font-size: var(--slotted-font-size-sm, 0.8125rem);
190
+ --_measure: var(--slotted-popover-measure-sm, 16rem);
191
+ }
192
+
193
+ [data-ui='popover'][data-size='lg'] {
194
+ --_inset-block: var(--slotted-popover-padding-block-lg, var(--slotted-space-6, 1rem));
195
+ --_inset-inline: var(--slotted-popover-padding-inline-lg, var(--slotted-space-7, 1.25rem));
196
+ --_title-font-size: var(--slotted-font-size-xl, 1.125rem);
197
+ --_measure: var(--slotted-popover-measure-lg, 24rem);
198
+ }
199
+
200
+ /**
201
+ * The panel is exactly as wide as the control it hangs from — a filter panel
202
+ * under a search field, which is the one case Radix documents a custom
203
+ * property for. The layer's own padding is added back, so the panel and the
204
+ * anchor share an edge rather than being inset from one another.
205
+ */
206
+ [data-ui='popover'][data-width='anchor'] {
207
+ inline-size: calc(var(--slotted-positioner-anchor-width, 0px) + 2 * var(--_gap));
208
+ max-inline-size: var(--slotted-positioner-available-width, 100vw);
209
+ }
210
+
211
+ /**
212
+ * Zero-sized, focusable and hidden from assistive technology. Focus reaching
213
+ * one of them arrived by `Tab` at the edge of a layer that lives at the end
214
+ * of the document, so the family closes the popover and puts focus back on
215
+ * the trigger, from which the next `Tab` continues down the page.
216
+ */
217
+ [data-ui='popover'] > [data-part='focus-guard'] {
218
+ position: absolute;
219
+ inline-size: 1px;
220
+ block-size: 1px;
221
+ padding: 0;
222
+ overflow: hidden;
223
+ opacity: 0;
224
+ outline: none;
225
+ pointer-events: none;
226
+ }
227
+
228
+ [data-ui='popover'] > [data-part='content'] {
229
+ box-sizing: border-box;
230
+ display: grid;
231
+ grid-template-rows: auto minmax(0, 1fr) auto;
232
+ max-inline-size: 100%;
233
+ /**
234
+ * The room the positioner says is left, less the layer's own padding at
235
+ * both ends. Only the body scrolls inside it.
236
+ */
237
+ max-block-size: calc(var(--slotted-positioner-available-height, 100vh) - 2 * var(--_gap));
238
+
239
+ border: var(--_border-width) solid var(--_border-color);
240
+ border-radius: var(--_radius);
241
+ background: var(--_surface);
242
+ color: var(--_text);
243
+ box-shadow: var(--_shadow);
244
+ /**
245
+ * The radius clips what the rows paint. The body's scroll shadow is two
246
+ * opaque covers in the panel's own ground, and a child's background runs
247
+ * square through a parent's rounded corner unless the parent clips: a
248
+ * panel with no footer stood rounded at the top and square at the bottom.
249
+ * `clip` and not `hidden`, so the panel is no scroll container of its own
250
+ * and a focus moving inside the body cannot scroll the panel off its frame.
251
+ */
252
+ overflow: clip;
253
+
254
+ font-family: var(--slotted-font-family-sans, ui-sans-serif, system-ui, sans-serif);
255
+ font-size: var(--_font-size);
256
+ line-height: var(--slotted-line-height-md, 1.5);
257
+ text-align: start;
258
+
259
+ pointer-events: auto;
260
+ /* The panel takes focus on open and is not a tab stop of its own. */
261
+ outline: none;
262
+ }
263
+
264
+ /**
265
+ * The three rows are the header's, the body's and the footer's, and the
266
+ * body's alone is bounded. A consumer's own composition — the notification
267
+ * centre under a bell, an inline command palette — stands as the panel's
268
+ * one child, and as an auto row it grew past the room the positioner
269
+ * reported: clipped at the panel's edge, its own footer out of sight. The
270
+ * one child takes the body's row instead, and the family inside it scrolls
271
+ * what it owns. Two children or more are the consumer's own layout and keep
272
+ * their auto rows.
273
+ */
274
+ [data-ui='popover']
275
+ > [data-part='content']
276
+ > :only-child:not([data-part='header'], [data-part='body'], [data-part='footer']) {
277
+ grid-row: 2;
278
+ min-block-size: 0;
279
+ }
280
+
281
+ [data-ui='popover'] > [data-part='content']:focus-visible {
282
+ outline: var(--slotted-focus-ring-width, 2px) solid
283
+ var(--slotted-focus-ring-color, currentColor);
284
+ outline-offset: calc(-1 * var(--slotted-focus-ring-width, 2px));
285
+ }
286
+
287
+ /**
288
+ * Title and description in the first column, the close control in the second,
289
+ * on the first row so it stays level with the title rather than centring
290
+ * itself against a description the title may not have.
291
+ */
292
+ [data-ui='popover'] > [data-part='content'] > [data-part='header'] {
293
+ display: grid;
294
+ grid-template-columns: minmax(0, 1fr) auto;
295
+ column-gap: var(--_row-gap);
296
+ row-gap: var(--slotted-space-2, 0.25rem);
297
+ align-items: start;
298
+ padding-block: var(--_inset-block);
299
+ padding-inline: var(--_inset-inline);
300
+ }
301
+
302
+ [data-ui='popover'] > [data-part='content'] > [data-part='header'] > [data-part='title'] {
303
+ grid-column: 1;
304
+ margin: 0;
305
+ font-family: var(
306
+ --slotted-font-family-heading,
307
+ var(--slotted-font-family-sans, ui-sans-serif, system-ui, sans-serif)
308
+ );
309
+ font-size: var(--_title-font-size);
310
+ font-weight: var(--slotted-font-weight-semibold, 600);
311
+ line-height: var(--slotted-line-height-lg, 1.5);
312
+ color: var(--_text);
313
+ overflow-wrap: anywhere;
314
+ unicode-bidi: plaintext;
315
+ }
316
+
317
+ [data-ui='popover'] > [data-part='content'] > [data-part='header'] > [data-part='description'] {
318
+ grid-column: 1;
319
+ margin: 0;
320
+ font-size: var(--slotted-font-size-sm, 0.8125rem);
321
+ line-height: var(--slotted-line-height-sm, 1.45);
322
+ color: var(--slotted-text-muted, #5b6b7f);
323
+ overflow-wrap: anywhere;
324
+ unicode-bidi: plaintext;
325
+ }
326
+
327
+ /**
328
+ * A square on control geometry, so it holds the WCAG minimum target at every
329
+ * density, and the mark is the library's own `Glyph` — an `<svg>` the binding
330
+ * draws inside an `icon` box at `sm` — rather than a character or a mask. It
331
+ * is pulled level with the title's cap height by the negative
332
+ * block margin rather than by stretching the row.
333
+ */
334
+ [data-ui='popover'] > [data-part='content'] > [data-part='header'] > [data-part='close'] {
335
+ grid-column: 2;
336
+ grid-row: 1;
337
+ display: inline-flex;
338
+ align-items: center;
339
+ justify-content: center;
340
+ box-sizing: border-box;
341
+ inline-size: var(--slotted-control-height-sm, 30px);
342
+ block-size: var(--slotted-control-height-sm, 30px);
343
+ margin-block-start: calc(-1 * var(--slotted-space-2, 0.25rem));
344
+ margin-inline-end: calc(-1 * var(--slotted-space-3, 0.375rem));
345
+ padding: 0;
346
+
347
+ border: 0;
348
+ border-radius: var(--slotted-control-radius, var(--slotted-radius-sm, 4px));
349
+ background: transparent;
350
+ color: var(--slotted-text-muted, #5b6b7f);
351
+ cursor: pointer;
352
+
353
+ transition:
354
+ background-color var(--slotted-control-transition-duration, var(--slotted-duration-short))
355
+ var(--slotted-control-transition-easing, var(--slotted-easing-standard)),
356
+ color var(--slotted-control-transition-duration, var(--slotted-duration-short))
357
+ var(--slotted-control-transition-easing, var(--slotted-easing-standard));
358
+ }
359
+
360
+ [data-ui='popover']
361
+ > [data-part='content']
362
+ > [data-part='header']
363
+ > [data-part='close']:enabled:hover {
364
+ background: var(--slotted-tone-secondary-subtle-hover, rgb(15 23 42 / 0.06));
365
+ color: var(--_text);
366
+ }
367
+
368
+ [data-ui='popover']
369
+ > [data-part='content']
370
+ > [data-part='header']
371
+ > [data-part='close']:enabled:active {
372
+ background: var(--slotted-tone-secondary-subtle-active, rgb(15 23 42 / 0.1));
373
+ }
374
+
375
+ [data-ui='popover']
376
+ > [data-part='content']
377
+ > [data-part='header']
378
+ > [data-part='close']:focus-visible {
379
+ outline: var(--slotted-focus-ring-width, 2px) solid
380
+ var(--slotted-focus-ring-color, currentColor);
381
+ outline-offset: var(--slotted-focus-ring-offset, 2px);
382
+ }
383
+
384
+ /**
385
+ * The only part that scrolls. It absorbs the header's block padding when
386
+ * there is no header, so a popover holding one sentence is not inset twice at
387
+ * the top and once at the bottom.
388
+ */
389
+ [data-ui='popover'] > [data-part='content'] > [data-part='body'] {
390
+ grid-row: 2;
391
+ min-block-size: 0;
392
+ overflow-x: hidden;
393
+ overflow-y: auto;
394
+ overflow-inline: hidden;
395
+ overflow-block: auto;
396
+ overscroll-behavior: contain;
397
+ /* The first capture put an unbroken 45-character token out through the
398
+ right edge of the panel and left the body scrolling sideways to reach it.
399
+ `plaintext` here for the reason the title takes it: the body is the
400
+ consumer's own prose, in whatever language they wrote it. */
401
+ overflow-wrap: anywhere;
402
+ unicode-bidi: plaintext;
403
+ padding-inline: var(--_inset-inline);
404
+ padding-block-end: var(--_inset-block);
405
+
406
+ /**
407
+ * ── The scroll shadow ────────────────────────────────────────────────
408
+ *
409
+ * A body that overflows cuts its last line in half against the footer's
410
+ * rule, and the capture read as a rendering fault rather than as "there is
411
+ * more below". The four layers are the standard pair of pairs: two solid
412
+ * covers that scroll **with** the content (`local`) and two shadows that
413
+ * stay **with** the box (`scroll`). At the top and bottom of the scroll
414
+ * range the cover sits over the shadow and hides it, so each edge shades
415
+ * only while there is something past it, and a body that fits shows
416
+ * neither.
417
+ *
418
+ * The ink is the panel's own text colour at eight per cent rather than a
419
+ * literal, so it follows every scheme without a rule of its own.
420
+ */
421
+ background:
422
+ linear-gradient(var(--_surface) 30%, transparent) center top / 100% var(--_inset-block)
423
+ no-repeat local,
424
+ linear-gradient(transparent, var(--_surface) 70%) center bottom / 100% var(--_inset-block)
425
+ no-repeat local,
426
+ radial-gradient(
427
+ farthest-side at 50% 0,
428
+ color-mix(in oklab, var(--_text) 12%, transparent),
429
+ transparent
430
+ )
431
+ center top / 100% var(--slotted-space-3, 0.375rem) no-repeat scroll,
432
+ radial-gradient(
433
+ farthest-side at 50% 100%,
434
+ color-mix(in oklab, var(--_text) 12%, transparent),
435
+ transparent
436
+ )
437
+ center bottom / 100% var(--slotted-space-3, 0.375rem) no-repeat scroll;
438
+ }
439
+
440
+ [data-ui='popover'] > [data-part='content'] > [data-part='body']:first-child {
441
+ padding-block-start: var(--_inset-block);
442
+ }
443
+
444
+ [data-ui='popover'] > [data-part='content'] > [data-part='footer'] {
445
+ grid-row: 3;
446
+ display: flex;
447
+ flex-wrap: wrap;
448
+ align-items: center;
449
+ justify-content: flex-end;
450
+ gap: var(--_row-gap);
451
+ padding-block: var(--_inset-block);
452
+ padding-inline: var(--_inset-inline);
453
+ border-block-start: var(--_border-width) solid var(--_border-color);
454
+ }
455
+
456
+ /**
457
+ * Written in physical properties, and painted over the panel rather than
458
+ * behind it, for the two reasons `tooltip.css` sets out at length: the engine
459
+ * measures the arrow from the layer's own left and top and `data-side` names
460
+ * a physical edge, and an arrow behind a bordered panel leaves the panel's own
461
+ * border running straight across its base.
462
+ *
463
+ * Where the arrow may stand is the straight run of the panel's edge. The
464
+ * positioner keeps it `arrowPadding` from the edge of the **layer**, and
465
+ * the panel stands a `gap` inside the layer, so beside an anchor near a
466
+ * corner the arrow landed on the panel's rounded corner, and the half of
467
+ * the rotated square the panel normally hides showed outside it as a point
468
+ * of a diamond. Clamped here, the arrow meets a straight edge whatever
469
+ * padding, gap or radius a theme sets.
470
+ */
471
+ [data-ui='popover'] > [data-part='arrow'] {
472
+ --_arrow-x: clamp(
473
+ calc(var(--_gap) + var(--_radius)),
474
+ var(--slotted-positioner-arrow-x, 0px),
475
+ calc(100% - var(--_gap) - var(--_radius) - var(--_arrow-size))
476
+ );
477
+ --_arrow-y: clamp(
478
+ calc(var(--_gap) + var(--_radius)),
479
+ var(--slotted-positioner-arrow-y, 0px),
480
+ calc(100% - var(--_gap) - var(--_radius) - var(--_arrow-size))
481
+ );
482
+ position: absolute;
483
+ z-index: 1;
484
+ inline-size: var(--_arrow-size);
485
+ block-size: var(--_arrow-size);
486
+ rotate: 45deg;
487
+ background: var(--_surface);
488
+ border: 0 solid var(--_border-color);
489
+ }
490
+
491
+ [data-ui='popover'][data-side='top'] > [data-part='arrow'] {
492
+ left: var(--_arrow-x);
493
+ top: auto;
494
+ bottom: calc(var(--_gap) - var(--_arrow-size) / 2);
495
+ border-right-width: var(--_border-width);
496
+ border-bottom-width: var(--_border-width);
497
+ border-bottom-right-radius: var(--_arrow-tip-radius);
498
+ }
499
+
500
+ [data-ui='popover'][data-side='bottom'] > [data-part='arrow'] {
501
+ left: var(--_arrow-x);
502
+ top: calc(var(--_gap) - var(--_arrow-size) / 2);
503
+ bottom: auto;
504
+ border-top-width: var(--_border-width);
505
+ border-left-width: var(--_border-width);
506
+ border-top-left-radius: var(--_arrow-tip-radius);
507
+ }
508
+
509
+ [data-ui='popover'][data-side='left'] > [data-part='arrow'] {
510
+ top: var(--_arrow-y);
511
+ left: auto;
512
+ right: calc(var(--_gap) - var(--_arrow-size) / 2);
513
+ border-top-width: var(--_border-width);
514
+ border-right-width: var(--_border-width);
515
+ border-top-right-radius: var(--_arrow-tip-radius);
516
+ }
517
+
518
+ [data-ui='popover'][data-side='right'] > [data-part='arrow'] {
519
+ top: var(--_arrow-y);
520
+ left: calc(var(--_gap) - var(--_arrow-size) / 2);
521
+ right: auto;
522
+ border-bottom-width: var(--_border-width);
523
+ border-left-width: var(--_border-width);
524
+ border-bottom-left-radius: var(--_arrow-tip-radius);
525
+ }
526
+ }
@@ -0,0 +1,60 @@
1
+ [
2
+ "--slotted-border-subtle",
3
+ "--slotted-border-width-thin",
4
+ "--slotted-control-gap-md",
5
+ "--slotted-control-height-sm",
6
+ "--slotted-control-radius",
7
+ "--slotted-control-transition-duration",
8
+ "--slotted-control-transition-easing",
9
+ "--slotted-duration-medium",
10
+ "--slotted-duration-short",
11
+ "--slotted-easing-enter",
12
+ "--slotted-easing-exit",
13
+ "--slotted-easing-standard",
14
+ "--slotted-focus-ring-color",
15
+ "--slotted-focus-ring-offset",
16
+ "--slotted-focus-ring-width",
17
+ "--slotted-font-family-heading",
18
+ "--slotted-font-family-sans",
19
+ "--slotted-font-size-lg",
20
+ "--slotted-font-size-md",
21
+ "--slotted-font-size-sm",
22
+ "--slotted-font-size-xl",
23
+ "--slotted-font-weight-semibold",
24
+ "--slotted-line-height-lg",
25
+ "--slotted-line-height-md",
26
+ "--slotted-line-height-sm",
27
+ "--slotted-popover-arrow-size",
28
+ "--slotted-popover-arrow-tip-radius",
29
+ "--slotted-popover-border-color",
30
+ "--slotted-popover-gap",
31
+ "--slotted-popover-measure",
32
+ "--slotted-popover-measure-lg",
33
+ "--slotted-popover-measure-sm",
34
+ "--slotted-popover-padding-block",
35
+ "--slotted-popover-padding-block-lg",
36
+ "--slotted-popover-padding-block-sm",
37
+ "--slotted-popover-padding-inline",
38
+ "--slotted-popover-padding-inline-lg",
39
+ "--slotted-popover-padding-inline-sm",
40
+ "--slotted-popover-radius",
41
+ "--slotted-popover-shadow",
42
+ "--slotted-popover-surface",
43
+ "--slotted-popover-text",
44
+ "--slotted-radius-lg",
45
+ "--slotted-radius-sm",
46
+ "--slotted-radius-xs",
47
+ "--slotted-shadow-md",
48
+ "--slotted-space-2",
49
+ "--slotted-space-3",
50
+ "--slotted-space-4",
51
+ "--slotted-space-5",
52
+ "--slotted-space-6",
53
+ "--slotted-space-7",
54
+ "--slotted-surface-raised",
55
+ "--slotted-text",
56
+ "--slotted-text-muted",
57
+ "--slotted-tone-secondary-subtle-active",
58
+ "--slotted-tone-secondary-subtle-hover",
59
+ "--slotted-z-index-popover"
60
+ ]