@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
package/src/kbd/kbd.css
ADDED
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
@layer slotted.components {
|
|
2
|
+
/**
|
|
3
|
+
* ── The key cap ────────────────────────────────────────────────────────
|
|
4
|
+
*
|
|
5
|
+
* One key of a keyboard, drawn so a reader can find it on theirs. It is not a
|
|
6
|
+
* control: nothing here is focusable, nothing answers hover, and nothing
|
|
7
|
+
* binds a shortcut.
|
|
8
|
+
*
|
|
9
|
+
* Two attributes on every selector, always. `shortcut` is the part that
|
|
10
|
+
* contains this family's own roots rather than sitting inside one — the shape
|
|
11
|
+
* `badge` proved with `anchor` — so it carries `data-ui` itself and the pair
|
|
12
|
+
* is what tells a whole combination from one key of it.
|
|
13
|
+
*
|
|
14
|
+
* The height is a step of a scale, never a sum of what is inside. A key cap
|
|
15
|
+
* whose height followed its legend drew `⌘` taller than `Esc` (K1), and a
|
|
16
|
+
* cap whose height followed its variant drew a `raised` key one pixel taller
|
|
17
|
+
* than an `outline` one beside it (25.19 against 24.19). Every size states
|
|
18
|
+
* one whole-pixel height, and every legend and every variant fits inside it.
|
|
19
|
+
* The same length is the minimum inline size, which is what makes a
|
|
20
|
+
* one-letter cap square instead of a slot.
|
|
21
|
+
*/
|
|
22
|
+
[data-ui='kbd'] {
|
|
23
|
+
/**
|
|
24
|
+
* The height comes from the space scale — 16, 20, 24, 28 — and not from
|
|
25
|
+
* the control geometry. A cap on its own is a glyph box, not a control,
|
|
26
|
+
* and the inner-size steps (22, 24, 28) leave no room below `sm` for the
|
|
27
|
+
* key a caption or a tooltip needs. The type still comes from the control
|
|
28
|
+
* scale, the one that moves with density, so a dense page draws a smaller
|
|
29
|
+
* legend inside the same box.
|
|
30
|
+
*/
|
|
31
|
+
--_size: var(--slotted-space-8, 1.5rem);
|
|
32
|
+
--_font-size: var(--slotted-control-font-size-md, 13px);
|
|
33
|
+
--_inset-inline: var(--slotted-space-3, 0.375rem);
|
|
34
|
+
--_radius: var(--slotted-kbd-radius, var(--slotted-radius-md, 6px));
|
|
35
|
+
--_gap: var(--slotted-space-2, 0.25rem);
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The rim, and the edge the face sits above.
|
|
39
|
+
*
|
|
40
|
+
* `raised` draws its bottom edge as a thicker border rather than as a
|
|
41
|
+
* shadow. Chrome drops `box-shadow` outright under `forced-colors: active`
|
|
42
|
+
* — measured while `badge` was built — so a key made of a shadow is a flat
|
|
43
|
+
* key exactly where the reader most needs the affordance. A border
|
|
44
|
+
* survives, and a face sitting a pixel above its own bottom edge is what
|
|
45
|
+
* a keycap looks like anyway. The thicker edge sits inside the stated
|
|
46
|
+
* height: it lifts the legend half a pixel and never grows the cap.
|
|
47
|
+
*/
|
|
48
|
+
--_edge-width: var(--slotted-kbd-border-width, var(--slotted-border-width-thin, 1px));
|
|
49
|
+
--_base-width: var(--_edge-width);
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Inside a control — a shortcut hint at the end of a search field — the
|
|
53
|
+
* cap is the height the foundation gives the inside of a control,
|
|
54
|
+
* `--slotted-control-inner-size`, which the field writes on its adornment
|
|
55
|
+
* from its own size step. On its own the cap keeps its size step. A
|
|
56
|
+
* 24-pixel cap sat in a 26-pixel field at dense before this
|
|
57
|
+
* (`docs/token-foundation.md`, Control geometry).
|
|
58
|
+
*/
|
|
59
|
+
--_block-size: var(--slotted-control-inner-size, var(--_size));
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* The ground, the rim and the ink. `raised` is the default: the rim a
|
|
63
|
+
* control draws on three sides, and `--slotted-border-strong` below, the
|
|
64
|
+
* one border token the theme holds to 3:1 against the surface. The strong
|
|
65
|
+
* edge on all four sides was a frame drawn round a word; on the base alone
|
|
66
|
+
* it is the shadow a key casts, and it is still the signal that says the
|
|
67
|
+
* word inside is a key.
|
|
68
|
+
*/
|
|
69
|
+
--_background: var(--slotted-surface-raised, Canvas);
|
|
70
|
+
--_face: none;
|
|
71
|
+
--_border: var(--slotted-control-border-color, ButtonBorder);
|
|
72
|
+
--_base: var(--slotted-border-strong, ButtonBorder);
|
|
73
|
+
--_color: var(--slotted-text, CanvasText);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
[data-ui='kbd'][data-part='root'] {
|
|
77
|
+
background-color: var(--_background);
|
|
78
|
+
background-image: var(--_face);
|
|
79
|
+
/**
|
|
80
|
+
* The height the family states, not the height the legend asks for. A key
|
|
81
|
+
* is a cap of a fixed size with a symbol drawn on it, and a row of caps
|
|
82
|
+
* whose tops disagree by three pixels is a row of caps of different keys.
|
|
83
|
+
*/
|
|
84
|
+
block-size: var(--_block-size);
|
|
85
|
+
border: var(--_edge-width) solid var(--_border);
|
|
86
|
+
border-block-end: var(--_base-width) solid var(--_base);
|
|
87
|
+
border-radius: var(--_radius);
|
|
88
|
+
box-sizing: border-box;
|
|
89
|
+
color: var(--_color);
|
|
90
|
+
/**
|
|
91
|
+
* One cell, and the legend centred in it on both axes. A grid of one cell
|
|
92
|
+
* centres what is inside it against the cell rather than against the line
|
|
93
|
+
* box the text opened, which is the half of the fix that keeps a symbol
|
|
94
|
+
* from sitting low once the box stops following it.
|
|
95
|
+
*/
|
|
96
|
+
display: inline-grid;
|
|
97
|
+
/**
|
|
98
|
+
* The interface face, the one the label beside the key is set in. The
|
|
99
|
+
* monospaced face drew `Backspace` 70.45px wide against the interface
|
|
100
|
+
* face's narrower word, and it does not carry `⌘ ⇧ ⌥ ↩ ⌫`, so every
|
|
101
|
+
* modifier came from a second face and a cap held two typefaces. Equal
|
|
102
|
+
* advance, the one thing a monospaced legend gave, the square minimum
|
|
103
|
+
* width already gives a one-letter key, and `tabular-nums` gives figures.
|
|
104
|
+
*/
|
|
105
|
+
font-family: var(--slotted-kbd-font-family, var(--slotted-control-font-family, sans-serif));
|
|
106
|
+
font-size: var(--_font-size);
|
|
107
|
+
/* A shortcut that counts — `⌘1` to `⌘9` — must not jitter as the figure
|
|
108
|
+
changes, which is the rule `badge` applies to its own count. */
|
|
109
|
+
font-variant-numeric: tabular-nums;
|
|
110
|
+
font-weight: var(--slotted-kbd-font-weight, var(--slotted-font-weight-medium, 500));
|
|
111
|
+
/**
|
|
112
|
+
* The legend's own line box is the em box and nothing more. Leading is what
|
|
113
|
+
* a fallback font varies — the strut and the glyph's own box are aligned on
|
|
114
|
+
* the baseline and each carries half of its font's leading — so a line box
|
|
115
|
+
* that stops at 1 is a line box no substituted glyph can grow. The air
|
|
116
|
+
* around the legend is the stated height less the em box, and it belongs
|
|
117
|
+
* to the cap, not to the legend.
|
|
118
|
+
*/
|
|
119
|
+
line-height: 1;
|
|
120
|
+
min-inline-size: var(--_block-size);
|
|
121
|
+
place-items: center;
|
|
122
|
+
/* The stated height holds the air; the cell centres the legend in it. */
|
|
123
|
+
padding-block: 0;
|
|
124
|
+
padding-inline: var(--_inset-inline);
|
|
125
|
+
/**
|
|
126
|
+
* A key label is never truncated. Half a key name is a wrong instruction,
|
|
127
|
+
* where a wrapped shortcut is only a taller row — so the cap keeps its word
|
|
128
|
+
* whole and the combination around it is what breaks.
|
|
129
|
+
*/
|
|
130
|
+
white-space: nowrap;
|
|
131
|
+
/* Written inside a sentence, a key sits on the text's centre. */
|
|
132
|
+
vertical-align: middle;
|
|
133
|
+
/**
|
|
134
|
+
* The one state pair this family has. A menu row that becomes unavailable
|
|
135
|
+
* fades; a cap inside it that snapped would be the only thing on the row
|
|
136
|
+
* that moved instantly. Nothing else here animates, and there is no looping
|
|
137
|
+
* animation to stop under reduced motion.
|
|
138
|
+
*/
|
|
139
|
+
transition:
|
|
140
|
+
background-color var(--slotted-control-transition-duration)
|
|
141
|
+
var(--slotted-control-transition-easing),
|
|
142
|
+
border-color var(--slotted-control-transition-duration)
|
|
143
|
+
var(--slotted-control-transition-easing),
|
|
144
|
+
color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/* ── The word, and the word behind it ──────────────────────────────────── */
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* The legend has a box of its own, as the words do in `button` and `badge`,
|
|
151
|
+
* and that box is what makes the family's one typographic problem solvable.
|
|
152
|
+
*
|
|
153
|
+
* The cell centres the *line box*, and a line box is not symmetric around the
|
|
154
|
+
* letters inside it: the ascender reaches further above the cap than the
|
|
155
|
+
* descender reaches below the baseline. `text-box` trims the line to
|
|
156
|
+
* the cap and the baseline, so what is centred is the ink rather than the
|
|
157
|
+
* font's metrics, and `K`, `Esc` and `Página` all sit the same way.
|
|
158
|
+
*
|
|
159
|
+
* It is applied here rather than on the root because `text-box-trim` needs a
|
|
160
|
+
* block container and a grid container has none: its own text lives in an
|
|
161
|
+
* anonymous item no selector can reach.
|
|
162
|
+
*
|
|
163
|
+
* No clip region is involved, which is what makes this simpler than the same
|
|
164
|
+
* rule in `badge`: `⌘`, `↑` and a descender all reach outside a box trimmed
|
|
165
|
+
* to the cap and the baseline, and here they paint into the inset instead of
|
|
166
|
+
* being cut off. The block size is still computed from the untrimmed metrics,
|
|
167
|
+
* so the trim moves the ink and never the box.
|
|
168
|
+
*/
|
|
169
|
+
@supports (text-box: trim-both cap alphabetic) {
|
|
170
|
+
[data-ui='kbd'] [data-part='legend'] {
|
|
171
|
+
text-box: trim-both cap alphabetic;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* A mark is not trimmed, and this is the half of the rule that had to be
|
|
176
|
+
* looked at rather than reasoned out. `cap alphabetic` are Latin metrics: a
|
|
177
|
+
* box trimmed to them centres the cap band, and `⌘`, `↩` and `⌫` have no
|
|
178
|
+
* relation to a cap height or an alphabetic baseline — measured here, all
|
|
179
|
+
* three sat visibly high in the cap. Left untrimmed, what gets centred is
|
|
180
|
+
* the em box, which is where a mark is drawn.
|
|
181
|
+
*/
|
|
182
|
+
[data-ui='kbd'] [data-part='legend'][data-legend='symbol'] {
|
|
183
|
+
text-box: normal;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* The interface face for a mark, whatever face the legend is set in. A
|
|
189
|
+
* consumer who sets `--slotted-kbd-font-family` to a monospaced face keeps
|
|
190
|
+
* `⌘ ⇧ ⌥ ↩ ⌫` at the weight of the interface type: measured with the
|
|
191
|
+
* monospaced legend, every mark rendered thinner and smaller than `Esc` in the
|
|
192
|
+
* same cap. A tenth larger than the legend: at 1em `⌘` and `↵` stood
|
|
193
|
+
* below the cap height of `K`, and at 1.15em `⌫` stood wider than the
|
|
194
|
+
* `Esc` beside it.
|
|
195
|
+
*/
|
|
196
|
+
[data-ui='kbd'] [data-part='legend'][data-legend='symbol'] {
|
|
197
|
+
font-family: var(--slotted-kbd-symbol-font-family, var(--slotted-font-family-sans, sans-serif));
|
|
198
|
+
font-size: 1.1em;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* What a reader hears in place of a symbol. It is content rather than a
|
|
203
|
+
* label because ARIA in HTML maps `kbd` to no role and declares it Naming
|
|
204
|
+
* Prohibited, so `aria-label` is not available to this family at all.
|
|
205
|
+
*
|
|
206
|
+
* The rule is `visually-hidden`'s, restated here rather than depended on: a
|
|
207
|
+
* key cap must not reserve a millimetre for a word nobody sees, and a family
|
|
208
|
+
* whose accessible name disappears when a consumer forgets an import has no
|
|
209
|
+
* accessible name.
|
|
210
|
+
*/
|
|
211
|
+
[data-ui='kbd'] [data-part='name'] {
|
|
212
|
+
block-size: 1px;
|
|
213
|
+
border: 0;
|
|
214
|
+
clip-path: inset(50%);
|
|
215
|
+
inline-size: 1px;
|
|
216
|
+
margin: -1px;
|
|
217
|
+
overflow: hidden;
|
|
218
|
+
padding: 0;
|
|
219
|
+
position: absolute;
|
|
220
|
+
white-space: nowrap;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/* ── The whole combination ─────────────────────────────────────────────── */
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* `direction: ltr`, and it is the deliberate part of this rule.
|
|
227
|
+
*
|
|
228
|
+
* A combination is one formula. The bidi algorithm renders `Ctrl + K` inside
|
|
229
|
+
* an Arabic paragraph as a single left-to-right run, which is also what
|
|
230
|
+
* macOS and Windows show in a right-to-left locale, so a mirrored `K + ⌘` is
|
|
231
|
+
* a shortcut no operating system displays. The combination as a whole still
|
|
232
|
+
* sits where the paragraph puts it; only the order of the caps inside it is
|
|
233
|
+
* pinned. A key legend written in Arabic still renders right-to-left within
|
|
234
|
+
* its own cap, because that is a run of its own.
|
|
235
|
+
*/
|
|
236
|
+
[data-ui='kbd'][data-part='shortcut'] {
|
|
237
|
+
align-items: center;
|
|
238
|
+
direction: ltr;
|
|
239
|
+
display: inline-flex;
|
|
240
|
+
/**
|
|
241
|
+
* A shortcut wider than its column wraps between caps and never inside
|
|
242
|
+
* one. The row gets taller; no instruction gets shorter.
|
|
243
|
+
*/
|
|
244
|
+
flex-wrap: wrap;
|
|
245
|
+
gap: var(--_gap);
|
|
246
|
+
/**
|
|
247
|
+
* Without this the wrapping above is only ever a coincidence. An
|
|
248
|
+
* `inline-flex` box is sized by its content, so a five-key combination in a
|
|
249
|
+
* 360-pixel column simply ran out of it — the wrap happened where the
|
|
250
|
+
* container narrowed the box and nowhere else. Read at 1280 in a measured
|
|
251
|
+
* column, `Win + Ctrl + Alt + Shift + Backspace` overflowed its stage on
|
|
252
|
+
* one line.
|
|
253
|
+
*/
|
|
254
|
+
max-inline-size: 100%;
|
|
255
|
+
vertical-align: middle;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* A Mac joins with nothing, so the gap is the only thing holding the
|
|
260
|
+
* combination together — and at the shared step it was exactly the width of
|
|
261
|
+
* the space between two separate shortcuts on the same line, which made
|
|
262
|
+
* `⌥⇧⌘P` and `⌘K` read as one run of six keys. One step tighter is what says
|
|
263
|
+
* these caps are one shortcut. Everywhere else the `+` says it instead.
|
|
264
|
+
*/
|
|
265
|
+
[data-ui='kbd'][data-part='shortcut'][data-platform='mac'] {
|
|
266
|
+
--_gap: var(--slotted-space-1, 0.125rem);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
[data-ui='kbd'][data-part='shortcut'][data-platform='mac'][data-size='inherit'] {
|
|
270
|
+
--_gap: 0.125em;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* `+` between two keys pressed together, and the word between two steps of a
|
|
275
|
+
* sequence. The plus is hidden from assistive technology — it is punctuation
|
|
276
|
+
* joining two caps, and “Command Shift K” is what the operating systems
|
|
277
|
+
* announce for the same shortcut. The word is not hidden: it is the only
|
|
278
|
+
* thing that tells a sequence from a combination.
|
|
279
|
+
*/
|
|
280
|
+
[data-ui='kbd'] [data-part='separator'] {
|
|
281
|
+
color: var(--slotted-text-muted, GrayText);
|
|
282
|
+
flex: none;
|
|
283
|
+
font-family: var(--slotted-kbd-font-family, var(--slotted-control-font-family, sans-serif));
|
|
284
|
+
font-size: var(--_font-size);
|
|
285
|
+
line-height: 1;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
[data-ui='kbd'] [data-part='separator'][data-separator='then'] {
|
|
289
|
+
font-family: var(--slotted-control-font-family, sans-serif);
|
|
290
|
+
/**
|
|
291
|
+
* A step boundary is a bigger break than a key join, so it gets more air
|
|
292
|
+
* than the plus does. Read at the shared gap, `Ctrl + K then Ctrl + S` was
|
|
293
|
+
* four caps in a row with a word somewhere in it.
|
|
294
|
+
*/
|
|
295
|
+
padding-inline: var(--slotted-space-2, 0.25rem);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/* ── Size ──────────────────────────────────────────────────────────────── */
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Four absolute steps, 16 to 28 pixels in steps of four, and one relative
|
|
302
|
+
* step. The radius is a quarter of the height or near it (4/16, 6/20, 6/24,
|
|
303
|
+
* 8/28), so a small cap is as round as a large one and not a pill.
|
|
304
|
+
*
|
|
305
|
+
* `xs` is the cap a caption, a tooltip or a dense table cell needs, where a
|
|
306
|
+
* 20-pixel key stood taller than the 12-pixel line it sat in. The type
|
|
307
|
+
* scale starts at 12px, and 12px in a 16-pixel cap left one pixel of air
|
|
308
|
+
* above an ascender, so this step writes the one size the scale lacks.
|
|
309
|
+
*/
|
|
310
|
+
[data-ui='kbd'][data-size='xs'] {
|
|
311
|
+
--_size: var(--slotted-space-6, 1rem);
|
|
312
|
+
--_font-size: 0.6875rem;
|
|
313
|
+
--_inset-inline: var(--slotted-space-2, 0.25rem);
|
|
314
|
+
--_radius: var(--slotted-kbd-radius, var(--slotted-radius-sm, 4px));
|
|
315
|
+
--_gap: var(--slotted-space-1, 0.125rem);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
[data-ui='kbd'][data-size='sm'] {
|
|
319
|
+
--_size: var(--slotted-space-7, 1.25rem);
|
|
320
|
+
--_font-size: var(--slotted-control-font-size-sm, 12px);
|
|
321
|
+
--_inset-inline: var(--slotted-space-2, 0.25rem);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
[data-ui='kbd'][data-size='lg'] {
|
|
325
|
+
--_size: calc(var(--slotted-space-8, 1.5rem) + var(--slotted-space-2, 0.25rem));
|
|
326
|
+
--_font-size: var(--slotted-control-font-size-lg, 14px);
|
|
327
|
+
--_inset-inline: var(--slotted-space-4, 0.5rem);
|
|
328
|
+
--_radius: var(--slotted-kbd-radius, var(--slotted-radius-lg, 8px));
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* The step no surveyed implementation ships, and the one prose needs. Every
|
|
333
|
+
* absolute size makes a key inside an `h2` a stamp and one in fine print a
|
|
334
|
+
* slab; here the cap is a proportion of the text it interrupts, so it is the
|
|
335
|
+
* right size in both. The insets go with it, in the same relative unit, or a
|
|
336
|
+
* large key would carry a small key's padding.
|
|
337
|
+
*
|
|
338
|
+
* The height is 1.5 of the legend, which is 1.2 of the surrounding text: it
|
|
339
|
+
* stays inside a line box of 1.3 or more, so a key in a paragraph never
|
|
340
|
+
* pushes its line away from the next one. The previous sum, legend line plus
|
|
341
|
+
* insets plus edges, made 25.8px on 16px text set at 24px lines. The radius
|
|
342
|
+
* is a quarter of that height, the proportion of the absolute steps.
|
|
343
|
+
*/
|
|
344
|
+
[data-ui='kbd'][data-size='inherit'] {
|
|
345
|
+
--_size: 1.5em;
|
|
346
|
+
--_font-size: 0.8em;
|
|
347
|
+
--_inset-inline: 0.4em;
|
|
348
|
+
--_radius: var(--slotted-kbd-radius, 0.375em);
|
|
349
|
+
--_gap: 0.25em;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/* A fractional height puts both horizontal edges between pixels. */
|
|
353
|
+
@supports (inline-size: round(nearest, 1.5em, 1px)) {
|
|
354
|
+
[data-ui='kbd'][data-size='inherit'] {
|
|
355
|
+
--_size: round(nearest, 1.5em, 1px);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/* ── Painting ──────────────────────────────────────────────────────────── */
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* The bottom edge is the whole of the difference between a raised key and an
|
|
363
|
+
* outlined one, and it is why `raised` is the default: it is the only value
|
|
364
|
+
* that reads as an object rather than as a box drawn round a word.
|
|
365
|
+
*/
|
|
366
|
+
[data-ui='kbd'][data-variant='raised'] {
|
|
367
|
+
--_base-width: var(--slotted-kbd-base-width, var(--slotted-border-width-thick, 2px));
|
|
368
|
+
/**
|
|
369
|
+
* The skirt. The lower part of the face turns a tenth of the way toward
|
|
370
|
+
* the base colour, so the face runs into the thick edge instead of meeting
|
|
371
|
+
* it at a line: `#ffffff` to `#f1f3f6` in light, `#171719` to `#202023` in
|
|
372
|
+
* dark. The top 40% stays the flat face, which is where the legend's cap
|
|
373
|
+
* band sits. A gradient is an image, so forced colours drop it with the
|
|
374
|
+
* ground and leave the edges, which is the whole key there.
|
|
375
|
+
*/
|
|
376
|
+
--_face: linear-gradient(
|
|
377
|
+
to bottom,
|
|
378
|
+
var(--_background) 40%,
|
|
379
|
+
color-mix(in oklab, var(--_background), var(--_base) 10%)
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* No ground of its own, so it carries over any surface the page puts under
|
|
385
|
+
* it — a card, a sunken panel, a solid banner.
|
|
386
|
+
*
|
|
387
|
+
* And no ink of its own either, which is the half that had to be looked at.
|
|
388
|
+
* Read on `--slotted-surface-inverse`, an outlined key kept `--slotted-text`
|
|
389
|
+
* and was near-black type on a near-black ground: the variant that exists to
|
|
390
|
+
* survive an unknown surface was the one variant that could not. A box that
|
|
391
|
+
* borrows its ground borrows its foreground with it.
|
|
392
|
+
*/
|
|
393
|
+
[data-ui='kbd'][data-variant='outline'] {
|
|
394
|
+
--_background: transparent;
|
|
395
|
+
/* The edge is all this variant draws, so it is the strong one all round. */
|
|
396
|
+
--_border: var(--slotted-border-strong, ButtonBorder);
|
|
397
|
+
--_color: inherit;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* The tinted chip, painted from the neutral tone rather than from a surface
|
|
402
|
+
* token. `--slotted-surface-sunken` is the page's own colour on a sunken
|
|
403
|
+
* panel, where a key painted with it would disappear; the neutral tone's
|
|
404
|
+
* surface is the step `badge` calibrated to read on both.
|
|
405
|
+
*/
|
|
406
|
+
[data-ui='kbd'][data-variant='soft'] {
|
|
407
|
+
--_background: var(--slotted-tone-secondary-surface);
|
|
408
|
+
/**
|
|
409
|
+
* The tinted key draws the tone's own edge, as every `badge` variant does,
|
|
410
|
+
* and it is not decoration here either. In the `high-contrast` scheme the
|
|
411
|
+
* neutral surface is the page's own white: read in that scheme with no
|
|
412
|
+
* edge, the chip was gone outright and `Ctrl + B` was a run of text. The
|
|
413
|
+
* edge is also what carries it through forced colours, where the ground
|
|
414
|
+
* flattens to `Canvas` for the same reason.
|
|
415
|
+
*/
|
|
416
|
+
--_border: var(--slotted-tone-secondary-border);
|
|
417
|
+
--_base: var(--slotted-tone-secondary-border);
|
|
418
|
+
--_color: var(--slotted-tone-secondary-text);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* A key that is only its word. In a dense menu a column of boxes is noise,
|
|
423
|
+
* and the shortcut there is what macOS and VS Code both draw: muted type, no
|
|
424
|
+
* frame, nothing between it and the row it belongs to.
|
|
425
|
+
*/
|
|
426
|
+
/**
|
|
427
|
+
* A key that is only its word, and it takes the colour of the text it sits
|
|
428
|
+
* in rather than choosing one. React Spectrum's `Keyboard` is the surveyed
|
|
429
|
+
* implementation that gets this right — it “provides no specific styling by
|
|
430
|
+
* itself, but receives styling from the parent container” — and inheriting is
|
|
431
|
+
* also what makes the row work: a menu item that dims dims its shortcut with
|
|
432
|
+
* it, with no state to set and nothing left bright at the end of a grey row.
|
|
433
|
+
*/
|
|
434
|
+
[data-ui='kbd'][data-variant='plain'] {
|
|
435
|
+
--_background: transparent;
|
|
436
|
+
--_border: transparent;
|
|
437
|
+
--_base: transparent;
|
|
438
|
+
--_color: inherit;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
[data-ui='kbd'][data-part='root'][data-variant='plain'] {
|
|
442
|
+
min-inline-size: 0;
|
|
443
|
+
padding-inline: 0;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/* ── Disabled ──────────────────────────────────────────────────────────── */
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Presentational only, and the strongest state this family has — there is no
|
|
450
|
+
* hover and no press for it to hold itself back for. The item the shortcut
|
|
451
|
+
* belongs to owns the semantics: `kbd` may carry only the global ARIA
|
|
452
|
+
* attributes, and `aria-disabled` is not one of them.
|
|
453
|
+
*/
|
|
454
|
+
[data-ui='kbd'][data-disabled] {
|
|
455
|
+
--_background: var(--slotted-disabled-background, Canvas);
|
|
456
|
+
--_face: none;
|
|
457
|
+
--_border: var(--slotted-disabled-border, GrayText);
|
|
458
|
+
--_base: var(--slotted-disabled-border, GrayText);
|
|
459
|
+
--_color: var(--slotted-disabled-foreground, GrayText);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
[data-ui='kbd'][data-disabled] [data-part='separator'] {
|
|
463
|
+
color: var(--slotted-disabled-foreground, GrayText);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* The two variants that own no ground keep owning none. A disabled `outline`
|
|
468
|
+
* that filled itself grey would be a grey rectangle on whatever surface it
|
|
469
|
+
* was placed over, which is the one thing the variant exists to avoid.
|
|
470
|
+
*/
|
|
471
|
+
[data-ui='kbd'][data-variant='outline'][data-disabled],
|
|
472
|
+
[data-ui='kbd'][data-variant='plain'][data-disabled] {
|
|
473
|
+
--_background: transparent;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
[data-ui='kbd'][data-variant='plain'][data-disabled] {
|
|
477
|
+
--_border: transparent;
|
|
478
|
+
--_base: transparent;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* This family writes no `forced-colors` rule, and the reason is worth
|
|
483
|
+
* recording because it was nearly written twice. Every ground it paints is a
|
|
484
|
+
* token the theme already remaps — `--slotted-surface-raised` to `Canvas`,
|
|
485
|
+
* the neutral tone's surface to `Canvas` — and every edge it draws is a
|
|
486
|
+
* border token remapped to `CanvasText` or `ButtonBorder`. There is no filled
|
|
487
|
+
* variant whose edge is its own fill, which is the case `badge` had to write
|
|
488
|
+
* a rule for. Nothing here is painted with anything the theme cannot reach.
|
|
489
|
+
*/
|
|
490
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
[
|
|
2
|
+
"--slotted-border-strong",
|
|
3
|
+
"--slotted-border-width-thick",
|
|
4
|
+
"--slotted-border-width-thin",
|
|
5
|
+
"--slotted-control-border-color",
|
|
6
|
+
"--slotted-control-font-family",
|
|
7
|
+
"--slotted-control-font-size-lg",
|
|
8
|
+
"--slotted-control-font-size-md",
|
|
9
|
+
"--slotted-control-font-size-sm",
|
|
10
|
+
"--slotted-control-inner-size",
|
|
11
|
+
"--slotted-control-transition-duration",
|
|
12
|
+
"--slotted-control-transition-easing",
|
|
13
|
+
"--slotted-disabled-background",
|
|
14
|
+
"--slotted-disabled-border",
|
|
15
|
+
"--slotted-disabled-foreground",
|
|
16
|
+
"--slotted-font-family-sans",
|
|
17
|
+
"--slotted-font-weight-medium",
|
|
18
|
+
"--slotted-kbd-base-width",
|
|
19
|
+
"--slotted-kbd-border-width",
|
|
20
|
+
"--slotted-kbd-font-family",
|
|
21
|
+
"--slotted-kbd-font-weight",
|
|
22
|
+
"--slotted-kbd-radius",
|
|
23
|
+
"--slotted-kbd-symbol-font-family",
|
|
24
|
+
"--slotted-radius-lg",
|
|
25
|
+
"--slotted-radius-md",
|
|
26
|
+
"--slotted-radius-sm",
|
|
27
|
+
"--slotted-space-1",
|
|
28
|
+
"--slotted-space-2",
|
|
29
|
+
"--slotted-space-3",
|
|
30
|
+
"--slotted-space-4",
|
|
31
|
+
"--slotted-space-6",
|
|
32
|
+
"--slotted-space-7",
|
|
33
|
+
"--slotted-space-8",
|
|
34
|
+
"--slotted-surface-raised",
|
|
35
|
+
"--slotted-text",
|
|
36
|
+
"--slotted-text-muted",
|
|
37
|
+
"--slotted-tone-secondary-border",
|
|
38
|
+
"--slotted-tone-secondary-surface",
|
|
39
|
+
"--slotted-tone-secondary-text"
|
|
40
|
+
]
|