@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.
- package/LICENSE +21 -0
- package/README.md +10 -2
- package/package.json +276 -3
- package/src/accordion/accordion.css +96 -0
- package/src/accordion/accordion.tokens.json +14 -0
- package/src/action-bar/action-bar.css +455 -0
- package/src/action-bar/action-bar.tokens.json +50 -0
- package/src/action-sheet/action-sheet.css +462 -0
- package/src/action-sheet/action-sheet.tokens.json +59 -0
- package/src/alert/alert.css +764 -0
- package/src/alert/alert.tokens.json +77 -0
- package/src/app-shell/app-shell.css +1899 -0
- package/src/app-shell/app-shell.tokens.json +88 -0
- package/src/aspect-ratio/aspect-ratio.css +131 -0
- package/src/aspect-ratio/aspect-ratio.tokens.json +1 -0
- package/src/attachment/attachment.css +906 -0
- package/src/attachment/attachment.tokens.json +85 -0
- package/src/avatar/avatar.css +598 -0
- package/src/avatar/avatar.tokens.json +64 -0
- package/src/avatar-group/avatar-group.css +268 -0
- package/src/avatar-group/avatar-group.tokens.json +16 -0
- package/src/badge/badge.css +462 -0
- package/src/badge/badge.tokens.json +58 -0
- package/src/breadcrumb/breadcrumb.css +441 -0
- package/src/breadcrumb/breadcrumb.tokens.json +50 -0
- package/src/button/button.css +754 -0
- package/src/button/button.tokens.json +72 -0
- package/src/button-group/button-group.css +455 -0
- package/src/button-group/button-group.tokens.json +11 -0
- package/src/calendar/calendar.css +846 -0
- package/src/calendar/calendar.tokens.json +67 -0
- package/src/card/card.css +602 -0
- package/src/card/card.tokens.json +68 -0
- package/src/carousel/carousel.css +860 -0
- package/src/carousel/carousel.tokens.json +62 -0
- package/src/cascader/cascader.css +1320 -0
- package/src/cascader/cascader.tokens.json +103 -0
- package/src/chart/chart.css +1473 -0
- package/src/chart/chart.tokens.json +107 -0
- package/src/checkbox/checkbox.css +1011 -0
- package/src/checkbox/checkbox.tokens.json +102 -0
- package/src/checkbox-group/checkbox-group.css +70 -0
- package/src/checkbox-group/checkbox-group.tokens.json +6 -0
- package/src/code-block/code-block.css +555 -0
- package/src/code-block/code-block.tokens.json +69 -0
- package/src/collapsible/collapsible.css +546 -0
- package/src/collapsible/collapsible.tokens.json +55 -0
- package/src/color-picker/color-picker.css +607 -0
- package/src/color-picker/color-picker.tokens.json +58 -0
- package/src/column-manager/column-manager.css +452 -0
- package/src/column-manager/column-manager.tokens.json +43 -0
- package/src/combobox/combobox.css +1048 -0
- package/src/combobox/combobox.tokens.json +112 -0
- package/src/command-palette/command-palette.css +1000 -0
- package/src/command-palette/command-palette.tokens.json +75 -0
- package/src/container/container.css +198 -0
- package/src/container/container.tokens.json +18 -0
- package/src/context-menu/context-menu.css +104 -0
- package/src/context-menu/context-menu.tokens.json +11 -0
- package/src/currency-field/currency-field.css +787 -0
- package/src/currency-field/currency-field.tokens.json +80 -0
- package/src/dashboard-grid/dashboard-grid.css +748 -0
- package/src/dashboard-grid/dashboard-grid.tokens.json +67 -0
- package/src/data-grid/data-grid.css +2484 -0
- package/src/data-grid/data-grid.tokens.json +100 -0
- package/src/data-list/data-list.css +455 -0
- package/src/data-list/data-list.tokens.json +35 -0
- package/src/date-field/date-field.css +560 -0
- package/src/date-field/date-field.tokens.json +80 -0
- package/src/date-picker/date-picker.css +420 -0
- package/src/date-picker/date-picker.tokens.json +49 -0
- package/src/date-range-picker/date-range-picker.css +983 -0
- package/src/date-range-picker/date-range-picker.tokens.json +109 -0
- package/src/datetime-field/datetime-field.css +850 -0
- package/src/datetime-field/datetime-field.tokens.json +91 -0
- package/src/datetime-picker/datetime-picker.css +843 -0
- package/src/datetime-picker/datetime-picker.tokens.json +78 -0
- package/src/datetime-range-picker/datetime-range-picker.css +1375 -0
- package/src/datetime-range-picker/datetime-range-picker.tokens.json +135 -0
- package/src/description-list/description-list.css +675 -0
- package/src/description-list/description-list.tokens.json +66 -0
- package/src/detail-panel/detail-panel.css +329 -0
- package/src/detail-panel/detail-panel.tokens.json +33 -0
- package/src/dialog/dialog.css +968 -0
- package/src/dialog/dialog.tokens.json +66 -0
- package/src/divider/divider.css +131 -0
- package/src/divider/divider.tokens.json +18 -0
- package/src/drawer/drawer.css +1303 -0
- package/src/drawer/drawer.tokens.json +75 -0
- package/src/entity-picker/entity-picker.css +1367 -0
- package/src/entity-picker/entity-picker.tokens.json +118 -0
- package/src/event-calendar/event-calendar.css +2148 -0
- package/src/event-calendar/event-calendar.tokens.json +87 -0
- package/src/field/field.css +707 -0
- package/src/field/field.tokens.json +58 -0
- package/src/field-group/field-group.css +226 -0
- package/src/field-group/field-group.tokens.json +33 -0
- package/src/filter-bar/filter-bar.css +1306 -0
- package/src/filter-bar/filter-bar.tokens.json +78 -0
- package/src/form/form.css +218 -0
- package/src/form/form.tokens.json +32 -0
- package/src/fullscreen/fullscreen.css +376 -0
- package/src/fullscreen/fullscreen.tokens.json +50 -0
- package/src/grid/grid.css +173 -0
- package/src/grid/grid.tokens.json +20 -0
- package/src/highlight/highlight.css +135 -0
- package/src/highlight/highlight.tokens.json +16 -0
- package/src/hover-card/hover-card.css +93 -0
- package/src/hover-card/hover-card.tokens.json +17 -0
- package/src/icon/icon.css +136 -0
- package/src/icon/icon.tokens.json +14 -0
- package/src/image/image.css +449 -0
- package/src/image/image.tokens.json +27 -0
- package/src/import-export-center/import-export-center.css +1175 -0
- package/src/import-export-center/import-export-center.tokens.json +84 -0
- package/src/inline/inline.css +149 -0
- package/src/inline/inline.tokens.json +14 -0
- package/src/inline-message/inline-message.css +396 -0
- package/src/inline-message/inline-message.tokens.json +19 -0
- package/src/kbd/kbd.css +490 -0
- package/src/kbd/kbd.tokens.json +40 -0
- package/src/link/link.css +237 -0
- package/src/link/link.tokens.json +25 -0
- package/src/list/list.css +240 -0
- package/src/list/list.tokens.json +42 -0
- package/src/list-item/list-item.css +937 -0
- package/src/list-item/list-item.tokens.json +114 -0
- package/src/listbox/listbox.css +674 -0
- package/src/listbox/listbox.tokens.json +72 -0
- package/src/loading-overlay/loading-overlay.css +730 -0
- package/src/loading-overlay/loading-overlay.tokens.json +48 -0
- package/src/markdown/markdown.css +168 -0
- package/src/markdown/markdown.tokens.json +18 -0
- package/src/menu/menu.css +817 -0
- package/src/menu/menu.tokens.json +78 -0
- package/src/menubar/menubar.css +170 -0
- package/src/menubar/menubar.tokens.json +32 -0
- package/src/message/message.css +1453 -0
- package/src/message/message.tokens.json +85 -0
- package/src/message-scroller/message-scroller.css +371 -0
- package/src/message-scroller/message-scroller.tokens.json +47 -0
- package/src/multi-select/multi-select.css +1427 -0
- package/src/multi-select/multi-select.tokens.json +114 -0
- package/src/navigation-menu/navigation-menu.css +1029 -0
- package/src/navigation-menu/navigation-menu.tokens.json +70 -0
- package/src/notification-center/notification-center.css +856 -0
- package/src/notification-center/notification-center.tokens.json +84 -0
- package/src/number-field/number-field.css +794 -0
- package/src/number-field/number-field.tokens.json +80 -0
- package/src/otp-input/otp-input.css +525 -0
- package/src/otp-input/otp-input.tokens.json +69 -0
- package/src/page/page.css +179 -0
- package/src/page/page.tokens.json +20 -0
- package/src/page-header/page-header.css +1181 -0
- package/src/page-header/page-header.tokens.json +71 -0
- package/src/pagination/pagination.css +500 -0
- package/src/pagination/pagination.tokens.json +56 -0
- package/src/popover/popover.css +526 -0
- package/src/popover/popover.tokens.json +60 -0
- package/src/progress-indicator/progress-indicator.css +1584 -0
- package/src/progress-indicator/progress-indicator.tokens.json +50 -0
- package/src/prompt-composer/prompt-composer.css +680 -0
- package/src/prompt-composer/prompt-composer.tokens.json +99 -0
- package/src/prose/prose.css +733 -0
- package/src/prose/prose.tokens.json +79 -0
- package/src/radio-group/radio-group.css +778 -0
- package/src/radio-group/radio-group.tokens.json +103 -0
- package/src/rating/rating.css +1071 -0
- package/src/rating/rating.tokens.json +88 -0
- package/src/result-state/result-state.css +980 -0
- package/src/result-state/result-state.tokens.json +63 -0
- package/src/runtime-properties.mjs +321 -0
- package/src/saved-views/saved-views.css +394 -0
- package/src/saved-views/saved-views.tokens.json +41 -0
- package/src/scroll-area/scroll-area.css +481 -0
- package/src/scroll-area/scroll-area.tokens.json +15 -0
- package/src/section/section.css +177 -0
- package/src/section/section.tokens.json +39 -0
- package/src/segmented-control/segmented-control.css +564 -0
- package/src/segmented-control/segmented-control.tokens.json +67 -0
- package/src/select/select.css +1593 -0
- package/src/select/select.tokens.json +110 -0
- package/src/side-navigation/side-navigation.css +1096 -0
- package/src/side-navigation/side-navigation.tokens.json +87 -0
- package/src/skeleton/skeleton.css +431 -0
- package/src/skeleton/skeleton.tokens.json +29 -0
- package/src/slider/slider.css +792 -0
- package/src/slider/slider.tokens.json +75 -0
- package/src/sparkline/sparkline.css +282 -0
- package/src/sparkline/sparkline.tokens.json +45 -0
- package/src/spinner/spinner.css +224 -0
- package/src/spinner/spinner.tokens.json +8 -0
- package/src/split-button/split-button.css +253 -0
- package/src/split-button/split-button.tokens.json +12 -0
- package/src/splitter/splitter.css +336 -0
- package/src/splitter/splitter.tokens.json +24 -0
- package/src/stack/stack.css +128 -0
- package/src/stack/stack.tokens.json +14 -0
- package/src/stat-card/stat-card.css +641 -0
- package/src/stat-card/stat-card.tokens.json +95 -0
- package/src/status-indicator/status-indicator.css +481 -0
- package/src/status-indicator/status-indicator.tokens.json +38 -0
- package/src/stepper/stepper.css +629 -0
- package/src/stepper/stepper.tokens.json +72 -0
- package/src/switch/switch.css +703 -0
- package/src/switch/switch.tokens.json +75 -0
- package/src/table/table.css +1482 -0
- package/src/table/table.tokens.json +69 -0
- package/src/table-of-contents/table-of-contents.css +533 -0
- package/src/table-of-contents/table-of-contents.tokens.json +53 -0
- package/src/tabs/tabs.css +998 -0
- package/src/tabs/tabs.tokens.json +82 -0
- package/src/tag/tag.css +768 -0
- package/src/tag/tag.tokens.json +85 -0
- package/src/tags-input/tags-input.css +757 -0
- package/src/tags-input/tags-input.tokens.json +84 -0
- package/src/text-field/text-field.css +900 -0
- package/src/text-field/text-field.tokens.json +87 -0
- package/src/textarea/textarea.css +365 -0
- package/src/textarea/textarea.tokens.json +59 -0
- package/src/time-field/time-field.css +719 -0
- package/src/time-field/time-field.tokens.json +86 -0
- package/src/time-picker/time-picker.css +665 -0
- package/src/time-picker/time-picker.tokens.json +66 -0
- package/src/time-range-picker/time-range-picker.css +1287 -0
- package/src/time-range-picker/time-range-picker.tokens.json +134 -0
- package/src/timeline/timeline.css +1596 -0
- package/src/timeline/timeline.tokens.json +96 -0
- package/src/toast/toast.css +943 -0
- package/src/toast/toast.tokens.json +90 -0
- package/src/toggle/toggle.css +290 -0
- package/src/toggle/toggle.tokens.json +54 -0
- package/src/toggle-group/toggle-group.css +463 -0
- package/src/toggle-group/toggle-group.tokens.json +54 -0
- package/src/toolbar/toolbar.css +434 -0
- package/src/toolbar/toolbar.tokens.json +49 -0
- package/src/tooltip/tooltip.css +368 -0
- package/src/tooltip/tooltip.tokens.json +39 -0
- package/src/top-navigation/top-navigation.css +1287 -0
- package/src/top-navigation/top-navigation.tokens.json +91 -0
- package/src/tour/tour.css +680 -0
- package/src/tour/tour.tokens.json +67 -0
- package/src/transfer/transfer.css +571 -0
- package/src/transfer/transfer.tokens.json +49 -0
- package/src/tree/tree.css +1000 -0
- package/src/tree/tree.tokens.json +80 -0
- package/src/typography/typography.css +211 -0
- package/src/typography/typography.tokens.json +31 -0
- package/src/upload/upload.css +1706 -0
- package/src/upload/upload.tokens.json +123 -0
- package/src/visually-hidden/visually-hidden.css +52 -0
- package/src/visually-hidden/visually-hidden.tokens.json +1 -0
- package/src/wizard/wizard.css +740 -0
- package/src/wizard/wizard.tokens.json +63 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
@layer slotted.components {
|
|
2
|
+
/**
|
|
3
|
+
* ── The span a query found ─────────────────────────────────────────────
|
|
4
|
+
*
|
|
5
|
+
* One mark, drawn once. Every list a reader types into says the same thing
|
|
6
|
+
* about the same span — this is the part of the label your query matched —
|
|
7
|
+
* and `combobox` drew it in its own sheet, so `select` with a filter,
|
|
8
|
+
* `multi-select` and `command-palette` would each have drawn it again, with
|
|
9
|
+
* their own answers (R6). Until wave 10 it was a shared sheet those hosts
|
|
10
|
+
* wore as `data-ui='highlight'` on the mark itself; it is now a family, and
|
|
11
|
+
* the host's label holds one root of it.
|
|
12
|
+
*
|
|
13
|
+
* The root is the element that holds the text. It has no rule: it is inline,
|
|
14
|
+
* it inherits everything, and the whole of what the family paints is the
|
|
15
|
+
* `mark` inside it. The element is a `mark`, so a reader whose browser
|
|
16
|
+
* exposes the role hears the emphasis as well as sees it.
|
|
17
|
+
*
|
|
18
|
+
* **The mark changes no metric.** A mark that is heavier, padded, or spaced
|
|
19
|
+
* differently from the text around it makes the word wider than the same
|
|
20
|
+
* word unmarked, and a filter that marks a different span on every keystroke
|
|
21
|
+
* reflows the label under the reader's eyes: at 600 weight and 0.1em of
|
|
22
|
+
* inline padding, `Blueberry` measured 70.03px marked against 63.17px plain,
|
|
23
|
+
* and the run moved 6.86px as the query grew (CB6). Weight, spacing and
|
|
24
|
+
* padding are therefore the label's own, and the mark is carried entirely by
|
|
25
|
+
* colour: the accent's text tone over a band mixed from that same tone, with
|
|
26
|
+
* a rule of the accent's border tone under it.
|
|
27
|
+
*
|
|
28
|
+
* The rule is `text-decoration` rather than a shadow, so it follows the
|
|
29
|
+
* letters across a line break and is drawn by the same machinery that draws
|
|
30
|
+
* every other underline the reader has met.
|
|
31
|
+
*
|
|
32
|
+
* **The band is not a `*-surface` tone.** `accent-surface` is a ground, and
|
|
33
|
+
* a ground is calibrated to sit under text on the page rather than to
|
|
34
|
+
* separate from it: it measured 1.220 | 1.014 | 1.000:1 against the panel in
|
|
35
|
+
* `light` | `dark` | `high-contrast`, so in two schemes out of three the band
|
|
36
|
+
* did not exist and the mark was carried by its colour and its rule alone
|
|
37
|
+
* (CB10, the same fact CK7 found under the pointer halo). The band is mixed
|
|
38
|
+
* from `accent-text` instead — the one role every scheme keeps legible over
|
|
39
|
+
* the surface — so one share gives one gesture in all three: 1.120 | 1.165 |
|
|
40
|
+
* 1.140:1 against the panel, and 1.115 to 1.165 across every ground a marked
|
|
41
|
+
* label can land on.
|
|
42
|
+
*
|
|
43
|
+
* The share is 0.075 and not the halo's 0.12 because a band is read through
|
|
44
|
+
* and a halo is not. The mark's own text has to keep the ratio its scheme
|
|
45
|
+
* promises while sitting on the band, and in `high-contrast` — 7:1, over a
|
|
46
|
+
* highlighted row — that caps the share: 0.075 leaves 7.078:1, 0.08 leaves
|
|
47
|
+
* 7.001:1, and 0.12 leaves 6.540:1.
|
|
48
|
+
*/
|
|
49
|
+
[data-ui='highlight'] [data-part='match'] {
|
|
50
|
+
background-color: var(
|
|
51
|
+
--slotted-highlight-background,
|
|
52
|
+
color-mix(
|
|
53
|
+
in oklab,
|
|
54
|
+
var(--slotted-tone-accent-text) calc(var(--slotted-highlight-tint-opacity, 0.075) * 100%),
|
|
55
|
+
transparent
|
|
56
|
+
)
|
|
57
|
+
);
|
|
58
|
+
/**
|
|
59
|
+
* A run that wraps is two boxes, and each of them carries the ground and
|
|
60
|
+
* the rule: without this the tint runs to the end of the first line and
|
|
61
|
+
* stops, and the second half of the word is unmarked.
|
|
62
|
+
*/
|
|
63
|
+
-webkit-box-decoration-break: clone;
|
|
64
|
+
box-decoration-break: clone;
|
|
65
|
+
/* No corner: a radius is a box around the letters, and the mark is a band
|
|
66
|
+
behind them. */
|
|
67
|
+
border-radius: var(--slotted-radius-none, 0px);
|
|
68
|
+
color: var(--slotted-highlight-color, var(--slotted-tone-accent-text));
|
|
69
|
+
font-weight: inherit;
|
|
70
|
+
letter-spacing: inherit;
|
|
71
|
+
padding: 0;
|
|
72
|
+
text-decoration-color: var(--slotted-highlight-rule-color, var(--slotted-tone-accent-border));
|
|
73
|
+
text-decoration-line: underline;
|
|
74
|
+
text-decoration-thickness: var(--slotted-border-width-thin, 1px);
|
|
75
|
+
/* One step of the space scale between the letters and the rule, which is
|
|
76
|
+
the smallest the scale holds. */
|
|
77
|
+
text-underline-offset: var(--slotted-space-1, 0.125rem);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* The match a find bar is standing on. Every browser's own find draws the
|
|
82
|
+
* active match apart from the others, and it does so by filling it: the band
|
|
83
|
+
* cannot be made stronger by degrees — 0.075 is the cap the 7:1 promise sets
|
|
84
|
+
* in `high-contrast`, and doubling it leaves 6.5:1 — so the current mark
|
|
85
|
+
* takes the accent's solid ground and the ink the theme pairs with it, which
|
|
86
|
+
* is a ratio the theme already promises. The rule goes: drawn in the ink it
|
|
87
|
+
* sits inside the fill and reads as nothing, which the capture showed. An
|
|
88
|
+
* outline is not used: R3 reserves it for the focus ring.
|
|
89
|
+
*/
|
|
90
|
+
[data-ui='highlight'] [data-part='match'][data-current] {
|
|
91
|
+
background-color: var(--slotted-highlight-current-background, var(--slotted-tone-accent-solid));
|
|
92
|
+
color: var(--slotted-highlight-current-color, var(--slotted-tone-accent-on-solid));
|
|
93
|
+
text-decoration-line: none;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* A disabled row's mark steps down with the rest of it. The mark says "this
|
|
98
|
+
* is why the option is here", and saying it in the accent tone on a row that
|
|
99
|
+
* answers nothing puts the loudest thing on the surface on the one option a
|
|
100
|
+
* reader cannot take. The rule stays: the reader still has to see which span
|
|
101
|
+
* matched, and it is the part of the mark that costs no colour.
|
|
102
|
+
*
|
|
103
|
+
* The state is the root's own, or any row's above it: the host's option
|
|
104
|
+
* already carries `data-disabled`, and the family reads it from there rather
|
|
105
|
+
* than asking the host to say it twice.
|
|
106
|
+
*/
|
|
107
|
+
[data-ui='highlight']:is([data-disabled], [data-disabled] *) [data-part='match'] {
|
|
108
|
+
background-color: var(--slotted-highlight-disabled-background, transparent);
|
|
109
|
+
color: inherit;
|
|
110
|
+
/* Restated for the current match, which gave the rule up for its fill. */
|
|
111
|
+
text-decoration-line: underline;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Under forced colours the accent ground becomes `Canvas` and the mark would
|
|
116
|
+
* vanish. `Mark` and `MarkText` are the system pair for exactly this element,
|
|
117
|
+
* and they are the one case where this sheet names a system colour because
|
|
118
|
+
* the theme has no token that maps to it. The current match takes
|
|
119
|
+
* `Highlight` and `HighlightText`, the pair the user agent draws its own
|
|
120
|
+
* active find match in.
|
|
121
|
+
*/
|
|
122
|
+
@media (forced-colors: active) {
|
|
123
|
+
[data-ui='highlight'] [data-part='match'],
|
|
124
|
+
[data-ui='highlight']:is([data-disabled], [data-disabled] *) [data-part='match'] {
|
|
125
|
+
background-color: Mark;
|
|
126
|
+
color: MarkText;
|
|
127
|
+
forced-color-adjust: none;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
[data-ui='highlight'] [data-part='match'][data-current] {
|
|
131
|
+
background-color: Highlight;
|
|
132
|
+
color: HighlightText;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
[
|
|
2
|
+
"--slotted-border-width-thin",
|
|
3
|
+
"--slotted-highlight-background",
|
|
4
|
+
"--slotted-highlight-color",
|
|
5
|
+
"--slotted-highlight-current-background",
|
|
6
|
+
"--slotted-highlight-current-color",
|
|
7
|
+
"--slotted-highlight-disabled-background",
|
|
8
|
+
"--slotted-highlight-rule-color",
|
|
9
|
+
"--slotted-highlight-tint-opacity",
|
|
10
|
+
"--slotted-radius-none",
|
|
11
|
+
"--slotted-space-1",
|
|
12
|
+
"--slotted-tone-accent-border",
|
|
13
|
+
"--slotted-tone-accent-on-solid",
|
|
14
|
+
"--slotted-tone-accent-solid",
|
|
15
|
+
"--slotted-tone-accent-text"
|
|
16
|
+
]
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
@layer slotted.components {
|
|
2
|
+
/**
|
|
3
|
+
* The trigger of a hover card: the link a reader hovers or focuses to see a
|
|
4
|
+
* preview of where it goes, or of who it names.
|
|
5
|
+
*
|
|
6
|
+
* root ─ the trigger ─ <a> ─ data-open
|
|
7
|
+
* └─ [data-ui='popover'] ─ unchanged, autoFocus off ─┐
|
|
8
|
+
* │ header / body / footer — the consumer's │
|
|
9
|
+
* │ arrow │
|
|
10
|
+
* └───────────────────────────────────────────────┘
|
|
11
|
+
*
|
|
12
|
+
* The family owns this one part and no surface: the card is `popover`,
|
|
13
|
+
* imported as it is, the way `menubar` holds `menu`. Radix's `HoverCard`
|
|
14
|
+
* restates `Popover.Content` under a second name, and two copies drift.
|
|
15
|
+
*
|
|
16
|
+
* ── Why the trigger is painted at all ────────────────────────────────
|
|
17
|
+
*
|
|
18
|
+
* A bare `<a>` is the browser's blue. When the consumer renders the trigger
|
|
19
|
+
* onto `link`, that family's paint wins and these rules never match; when
|
|
20
|
+
* the family renders its own anchor, it owes the reader a link that reads as
|
|
21
|
+
* one and says, while the card shows, which word the card is about.
|
|
22
|
+
*/
|
|
23
|
+
[data-ui='hover-card'] {
|
|
24
|
+
--_text: var(--slotted-hover-card-color, var(--slotted-tone-accent-text, LinkText));
|
|
25
|
+
/* The underline at rest is the text at less than half strength, as
|
|
26
|
+
`link` draws it: present enough to say "link", quiet enough that a
|
|
27
|
+
paragraph of mentions is not a paragraph of bars. */
|
|
28
|
+
--_underline: var(
|
|
29
|
+
--slotted-hover-card-underline-color,
|
|
30
|
+
color-mix(in oklab, var(--_text) 40%, transparent)
|
|
31
|
+
);
|
|
32
|
+
/* The ground behind the word while its card is open. A band with no edge
|
|
33
|
+
to pair with is mixed from the tone's text at the share `highlight` uses
|
|
34
|
+
for the band behind a matched span (`docs/token-foundation.md`,
|
|
35
|
+
Highlight), rather than taken from the tone's surface: the surface is
|
|
36
|
+
painted the page's own white in `high-contrast`, where a state that has
|
|
37
|
+
to be seen would then not be. */
|
|
38
|
+
--_tint: var(
|
|
39
|
+
--slotted-hover-card-tint,
|
|
40
|
+
color-mix(
|
|
41
|
+
in oklab,
|
|
42
|
+
var(--_text) calc(var(--slotted-highlight-tint-opacity, 0.075) * 100%),
|
|
43
|
+
transparent
|
|
44
|
+
)
|
|
45
|
+
);
|
|
46
|
+
--_halo: var(--slotted-hover-card-halo, var(--slotted-space-1, 0.125rem));
|
|
47
|
+
|
|
48
|
+
border-radius: var(--slotted-hover-card-radius, var(--slotted-radius-xs, 2px));
|
|
49
|
+
color: var(--_text);
|
|
50
|
+
text-decoration-color: var(--_underline);
|
|
51
|
+
text-decoration-line: underline;
|
|
52
|
+
text-decoration-thickness: from-font;
|
|
53
|
+
text-underline-offset: 0.15em;
|
|
54
|
+
transition:
|
|
55
|
+
background-color var(--slotted-duration-short) var(--slotted-easing-standard),
|
|
56
|
+
box-shadow var(--slotted-duration-short) var(--slotted-easing-standard),
|
|
57
|
+
text-decoration-color var(--slotted-duration-short) var(--slotted-easing-standard);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* Hover fills the underline. The card itself waits for `openDelay`, so this
|
|
61
|
+
is the only thing that answers the pointer at once. */
|
|
62
|
+
[data-ui='hover-card']:not([data-disabled]):hover {
|
|
63
|
+
text-decoration-color: currentColor;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* While the card shows, the word it is about is marked: the tint behind it
|
|
68
|
+
* and a halo of the same colour drawn as a spread shadow, so the inline box
|
|
69
|
+
* grows by one step of space without moving the line it sits on. A padding
|
|
70
|
+
* would have reflowed the paragraph on every open.
|
|
71
|
+
*/
|
|
72
|
+
[data-ui='hover-card'][data-open] {
|
|
73
|
+
background-color: var(--_tint);
|
|
74
|
+
box-shadow: 0 0 0 var(--_halo) var(--_tint);
|
|
75
|
+
text-decoration-color: currentColor;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
[data-ui='hover-card']:focus-visible {
|
|
79
|
+
outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
|
|
80
|
+
outline-offset: var(--slotted-focus-ring-offset, 2px);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Forced colours remove backgrounds, so the open mark would vanish with them;
|
|
85
|
+
* a link the reader is looking at is underlined in the system's own link
|
|
86
|
+
* colour instead, which is the one thing forced colours keep.
|
|
87
|
+
*/
|
|
88
|
+
@media (forced-colors: active) {
|
|
89
|
+
[data-ui='hover-card'][data-open] {
|
|
90
|
+
text-decoration-thickness: var(--slotted-border-width-thick, 2px);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
[
|
|
2
|
+
"--slotted-border-width-thick",
|
|
3
|
+
"--slotted-duration-short",
|
|
4
|
+
"--slotted-easing-standard",
|
|
5
|
+
"--slotted-focus-ring-color",
|
|
6
|
+
"--slotted-focus-ring-offset",
|
|
7
|
+
"--slotted-focus-ring-width",
|
|
8
|
+
"--slotted-highlight-tint-opacity",
|
|
9
|
+
"--slotted-hover-card-color",
|
|
10
|
+
"--slotted-hover-card-halo",
|
|
11
|
+
"--slotted-hover-card-radius",
|
|
12
|
+
"--slotted-hover-card-tint",
|
|
13
|
+
"--slotted-hover-card-underline-color",
|
|
14
|
+
"--slotted-radius-xs",
|
|
15
|
+
"--slotted-space-1",
|
|
16
|
+
"--slotted-tone-accent-text"
|
|
17
|
+
]
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
@layer slotted.components {
|
|
2
|
+
/**
|
|
3
|
+
* Icon is the box a glyph is drawn in, not the glyph. The library ships no
|
|
4
|
+
* catalogue: the artwork is the consumer's, and this family owns the size it
|
|
5
|
+
* is drawn at, the colour it inherits, where it sits against a line of text,
|
|
6
|
+
* and whether it mirrors in a right-to-left document.
|
|
7
|
+
*
|
|
8
|
+
* The size is read through the family token rather than stated, so a
|
|
9
|
+
* container — a button, a table row, a tag — sizes every icon inside it by
|
|
10
|
+
* setting `--slotted-icon-size` once and needs to know nothing else about
|
|
11
|
+
* this family. An instance overrides that container through `data-size`,
|
|
12
|
+
* which sets the same token on the element itself.
|
|
13
|
+
*/
|
|
14
|
+
[data-ui='icon'] {
|
|
15
|
+
--_size: var(--slotted-icon-size, var(--slotted-control-icon-size-md, 16px));
|
|
16
|
+
|
|
17
|
+
align-items: center;
|
|
18
|
+
block-size: var(--_size);
|
|
19
|
+
display: inline-flex;
|
|
20
|
+
/* A box that shrinks is not a box: an icon keeps its size in a flex row. */
|
|
21
|
+
flex: none;
|
|
22
|
+
inline-size: var(--_size);
|
|
23
|
+
justify-content: center;
|
|
24
|
+
line-height: 1;
|
|
25
|
+
/**
|
|
26
|
+
* An inline box sits with its bottom edge on the baseline, which puts its
|
|
27
|
+
* centre half its own height above the line while text reads centred
|
|
28
|
+
* between the baseline and the cap height. The icon reads high without a
|
|
29
|
+
* correction, and by more the larger it is relative to the type around it:
|
|
30
|
+
* a constant shift is right at one ratio and wrong at every other, which a
|
|
31
|
+
* large step inside small text shows plainly.
|
|
32
|
+
*
|
|
33
|
+
* The default is therefore computed rather than stated. `cap` is the cap
|
|
34
|
+
* height of the font the icon inherits and `--_size` is the box, so the
|
|
35
|
+
* expression puts the box's centre on the text's optical centre at every
|
|
36
|
+
* combination of the two. At `1em` it resolves near the `-0.125em` this
|
|
37
|
+
* family used to state, which is why that constant looked right until the
|
|
38
|
+
* ratio changed. A theme still overrides the whole thing through the token.
|
|
39
|
+
*
|
|
40
|
+
* It is inert inside a flex or grid container, where alignment is the
|
|
41
|
+
* parent's decision.
|
|
42
|
+
*/
|
|
43
|
+
vertical-align: var(--slotted-icon-baseline-shift, calc(0.5cap - 0.5 * var(--_size)));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The artwork fills the box rather than deciding it. The descendant form is
|
|
48
|
+
* needed as well as the child form because a glyph component renders its own
|
|
49
|
+
* host in between, as `<ng-icon><svg/></ng-icon>` does. This reaches into
|
|
50
|
+
* markup the consumer wrote, deliberately: a box whose content sets its own
|
|
51
|
+
* size is not a box.
|
|
52
|
+
*
|
|
53
|
+
* Such a host sizes itself at `1em` from a stylesheet outside any layer,
|
|
54
|
+
* and an unlayered declaration outranks a layered one whatever its
|
|
55
|
+
* specificity: the two lengths below never reach it. The box does not fight
|
|
56
|
+
* that host. It gives the host a font-size equal to the box, and `1em` is
|
|
57
|
+
* then the box — 14 pixels at `sm`, the type's size at `text`. The font-size
|
|
58
|
+
* is on the child and not on the box, because `vertical-align` above reads
|
|
59
|
+
* `cap` from the text the box sits in.
|
|
60
|
+
*/
|
|
61
|
+
[data-ui='icon'] > *,
|
|
62
|
+
[data-ui='icon'] svg {
|
|
63
|
+
block-size: 100%;
|
|
64
|
+
display: block;
|
|
65
|
+
font-size: var(--_size);
|
|
66
|
+
inline-size: 100%;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Three steps read the control icon scale, which the theme restates per
|
|
71
|
+
* density, so an icon shrinks with the control beside it. The fourth follows
|
|
72
|
+
* the type it sits in, because sixteen pixels inside a display heading is
|
|
73
|
+
* not an icon.
|
|
74
|
+
*/
|
|
75
|
+
[data-ui='icon'][data-size='text'] {
|
|
76
|
+
--slotted-icon-size: 1em;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
[data-ui='icon'][data-size='sm'] {
|
|
80
|
+
--slotted-icon-size: var(--slotted-control-icon-size-sm, 14px);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
[data-ui='icon'][data-size='md'] {
|
|
84
|
+
--slotted-icon-size: var(--slotted-control-icon-size-md, 16px);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
[data-ui='icon'][data-size='lg'] {
|
|
88
|
+
--slotted-icon-size: var(--slotted-control-icon-size-lg, 18px);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Colour is inherited rather than painted, so an icon beside a label is the
|
|
93
|
+
* colour of that label without anyone deciding it. The family sets `color`
|
|
94
|
+
* and never `fill` or `stroke`: stroked artwork declares
|
|
95
|
+
* `stroke="currentColor"` and filled artwork declares `fill="currentColor"`,
|
|
96
|
+
* and imposing either would break the other.
|
|
97
|
+
*/
|
|
98
|
+
[data-ui='icon'][data-tone='default'] {
|
|
99
|
+
color: var(--slotted-text, CanvasText);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
[data-ui='icon'][data-tone='muted'] {
|
|
103
|
+
color: var(--slotted-text-muted, GrayText);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
[data-ui='icon'][data-tone='accent'] {
|
|
107
|
+
color: var(--slotted-tone-accent-text, LinkText);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
[data-ui='icon'][data-tone='success'] {
|
|
111
|
+
color: var(--slotted-tone-success-text, CanvasText);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
[data-ui='icon'][data-tone='warning'] {
|
|
115
|
+
color: var(--slotted-tone-warning-text, CanvasText);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
[data-ui='icon'][data-tone='danger'] {
|
|
119
|
+
color: var(--slotted-tone-danger-text, CanvasText);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
[data-ui='icon'][data-tone='inverse'] {
|
|
123
|
+
color: var(--slotted-text-inverse, Canvas);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Only artwork that points somewhere mirrors, and only the consumer knows
|
|
128
|
+
* which artwork that is. `:dir()` rather than an ancestor `[dir]` selector,
|
|
129
|
+
* because a mirrored icon inside a left-to-right island inside a
|
|
130
|
+
* right-to-left page has to read the directionality that actually applies to
|
|
131
|
+
* it.
|
|
132
|
+
*/
|
|
133
|
+
[data-ui='icon'][data-directional]:dir(rtl) {
|
|
134
|
+
scale: -1 1;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
[
|
|
2
|
+
"--slotted-control-icon-size-lg",
|
|
3
|
+
"--slotted-control-icon-size-md",
|
|
4
|
+
"--slotted-control-icon-size-sm",
|
|
5
|
+
"--slotted-icon-baseline-shift",
|
|
6
|
+
"--slotted-icon-size",
|
|
7
|
+
"--slotted-text",
|
|
8
|
+
"--slotted-text-inverse",
|
|
9
|
+
"--slotted-text-muted",
|
|
10
|
+
"--slotted-tone-accent-text",
|
|
11
|
+
"--slotted-tone-danger-text",
|
|
12
|
+
"--slotted-tone-success-text",
|
|
13
|
+
"--slotted-tone-warning-text"
|
|
14
|
+
]
|