@slotted/styles 0.0.0-stage → 0.1.0-beta.1
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,1320 @@
|
|
|
1
|
+
@layer slotted.components {
|
|
2
|
+
/**
|
|
3
|
+
* ── A control that picks one place in a hierarchy ───────────────────────
|
|
4
|
+
*
|
|
5
|
+
* Two subtrees, as `select` is built: the **control** where the consumer
|
|
6
|
+
* wrote it, and the **popup** portalled to the end of the document. Both
|
|
7
|
+
* carry `data-ui='cascader'` and every rule states which one it is about
|
|
8
|
+
* through its own `data-part`.
|
|
9
|
+
*
|
|
10
|
+
* ┌─ root ─ the control ───────────────────────────────────────────┐
|
|
11
|
+
* │ ┌─ trigger ─ role="combobox" ────────────────────────────────┐ │
|
|
12
|
+
* │ │ value ▸ segment / segment / segment │ │
|
|
13
|
+
* │ └────────────────────────────────────────────────────────────┘ │
|
|
14
|
+
* │ clear ✕ arrow ⌄ │
|
|
15
|
+
* └────────────────────────────────────────────────────────────────┘
|
|
16
|
+
*
|
|
17
|
+
* ┌─ positioner ─ data-layout ──────────────────────────────────────┐
|
|
18
|
+
* │ ┌─ content ─────────────────────────────────────────────────┐ │
|
|
19
|
+
* │ │ search ▸ search-input (search only) │ │
|
|
20
|
+
* │ │ breadcrumb ▸ crumb › crumb › crumb (drill only) │ │
|
|
21
|
+
* │ │ ┌─ panel ─ role="tree" ─────────────────────────────────┐ │ │
|
|
22
|
+
* │ │ │ column │ column │ column (one in drill/tree) │ │ │
|
|
23
|
+
* │ │ │ node ▸ indicator icon label meta end │ │ │
|
|
24
|
+
* │ │ └──────────────────────────────────────────────────────┘ │ │
|
|
25
|
+
* │ └───────────────────────────────────────────────────────────┘ │
|
|
26
|
+
* └────────────────────────────────────────────────────────────────┘
|
|
27
|
+
*
|
|
28
|
+
* The control is `select`'s control, rule for rule and on the same control
|
|
29
|
+
* tokens: a form holding a select and a cascader is one row of controls.
|
|
30
|
+
*
|
|
31
|
+
* The panel also stands alone, without a control or a layer, as a settings
|
|
32
|
+
* screen or a sidebar holds it. It then carries `data-ui='cascader'` itself,
|
|
33
|
+
* paints its own surface, and reads the same scale the layer states.
|
|
34
|
+
*
|
|
35
|
+
* ── Why each column is a grid and a node a subgrid ────────────────────
|
|
36
|
+
*
|
|
37
|
+
* The same architecture `select` and `menu` use. A column owns five tracks —
|
|
38
|
+
* the box, the icon, the label, the meta, the end — and every node passes
|
|
39
|
+
* through them, so labels line up down a column however many nodes carry
|
|
40
|
+
* artwork, and every count ends on one edge. No track carries a gap; each
|
|
41
|
+
* cell carries its own margin, so a column of plain labels has no gutter.
|
|
42
|
+
*
|
|
43
|
+
* The end track holds the check of a single selection or the chevron of a
|
|
44
|
+
* branch, never both: a branch is opened rather than chosen by default, and
|
|
45
|
+
* a branch that may be chosen says so with its ink.
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
/* ── The control ──────────────────────────────────────────────────────── */
|
|
49
|
+
|
|
50
|
+
[data-ui='cascader'][data-part='root'] {
|
|
51
|
+
--_font-size: var(--slotted-control-font-size-md, 13px);
|
|
52
|
+
--_height: var(--slotted-control-height-md, 34px);
|
|
53
|
+
--_padding-inline: var(--slotted-control-padding-inline-md, 13px);
|
|
54
|
+
--_gap: var(--slotted-control-gap-md, 8px);
|
|
55
|
+
--_icon-floor: var(--slotted-cascader-icon-size-min, 14px);
|
|
56
|
+
--_icon-size: max(var(--_icon-floor), var(--slotted-control-icon-size-md, 16px));
|
|
57
|
+
--_inner-size: var(--slotted-control-inner-size-md, 24px);
|
|
58
|
+
--_action-size: min(
|
|
59
|
+
calc(var(--_icon-size) + 2 * var(--slotted-space-2, 0.25rem)),
|
|
60
|
+
var(--_inner-size)
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
align-items: center;
|
|
64
|
+
background-color: var(--slotted-cascader-background, var(--slotted-control-surface, Field));
|
|
65
|
+
border: var(--slotted-control-border-width, 1px) solid
|
|
66
|
+
var(--slotted-cascader-border-color, var(--slotted-control-border-color, ButtonBorder));
|
|
67
|
+
border-radius: var(--slotted-cascader-radius, var(--slotted-control-radius, 4px));
|
|
68
|
+
box-shadow: var(--slotted-control-shadow, none);
|
|
69
|
+
box-sizing: border-box;
|
|
70
|
+
color: var(--slotted-text, CanvasText);
|
|
71
|
+
column-gap: var(--_gap);
|
|
72
|
+
display: grid;
|
|
73
|
+
font-family: var(--slotted-control-font-family, system-ui, sans-serif);
|
|
74
|
+
font-size: var(--_font-size);
|
|
75
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
76
|
+
inline-size: 100%;
|
|
77
|
+
min-block-size: var(--_height);
|
|
78
|
+
min-inline-size: 0;
|
|
79
|
+
position: relative;
|
|
80
|
+
transition:
|
|
81
|
+
background-color var(--slotted-control-transition-duration)
|
|
82
|
+
var(--slotted-control-transition-easing),
|
|
83
|
+
border-color var(--slotted-control-transition-duration)
|
|
84
|
+
var(--slotted-control-transition-easing),
|
|
85
|
+
box-shadow var(--slotted-control-transition-duration) var(--slotted-control-transition-easing);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
[data-ui='cascader'][data-part='root']:has(> [data-part='clear']) {
|
|
89
|
+
grid-template-columns: minmax(0, 1fr) auto auto;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
[data-ui='cascader'][data-part='root']:not([data-full-width]) {
|
|
93
|
+
inline-size: auto;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/* The trigger fills the frame and the two marks sit over it, for the reason
|
|
97
|
+
`select` writes above its own trigger: the chevron ends the control, and
|
|
98
|
+
the clear button is a sibling of the button rather than a widget in it. */
|
|
99
|
+
[data-ui='cascader'] > [data-part='trigger'] {
|
|
100
|
+
align-items: center;
|
|
101
|
+
appearance: none;
|
|
102
|
+
background-color: transparent;
|
|
103
|
+
border: 0;
|
|
104
|
+
box-sizing: border-box;
|
|
105
|
+
color: inherit;
|
|
106
|
+
cursor: pointer;
|
|
107
|
+
display: flex;
|
|
108
|
+
font: inherit;
|
|
109
|
+
gap: var(--_gap);
|
|
110
|
+
grid-area: 1 / 1 / 2 / -1;
|
|
111
|
+
margin-block: calc(var(--slotted-control-border-width, 1px) * -1);
|
|
112
|
+
min-block-size: var(--_height);
|
|
113
|
+
min-inline-size: 0;
|
|
114
|
+
outline: none;
|
|
115
|
+
padding-block: 0;
|
|
116
|
+
padding-inline-start: var(--_padding-inline);
|
|
117
|
+
padding-inline-end: calc(var(--_padding-inline) + var(--_icon-size) + var(--_gap));
|
|
118
|
+
text-align: start;
|
|
119
|
+
touch-action: manipulation;
|
|
120
|
+
-webkit-tap-highlight-color: transparent;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
[data-ui='cascader'][data-part='root']:has(> [data-part='clear']) > [data-part='trigger'] {
|
|
124
|
+
padding-inline-end: calc(
|
|
125
|
+
var(--_padding-inline) + var(--_icon-size) + var(--_gap) + var(--_action-size) + var(--_gap)
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* The path, on one line. A path that wrapped would change the control's
|
|
131
|
+
* height as the reader chose. The segments give way before the last one: a
|
|
132
|
+
* long path reads "Portugal / Lis… / Alfama", keeping the place itself whole
|
|
133
|
+
* and eliding the middle of the road to it. The whole path stays in the DOM,
|
|
134
|
+
* so the trigger's name is never the ellipsis.
|
|
135
|
+
*/
|
|
136
|
+
[data-ui='cascader'] [data-part='value'] {
|
|
137
|
+
align-items: baseline;
|
|
138
|
+
display: flex;
|
|
139
|
+
flex: 1 1 auto;
|
|
140
|
+
min-inline-size: 0;
|
|
141
|
+
overflow: hidden;
|
|
142
|
+
white-space: nowrap;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
[data-ui='cascader'] [data-part='value-segment'] {
|
|
146
|
+
flex: 0 1 auto;
|
|
147
|
+
/* Two characters and the ellipsis, the least a segment can say. */
|
|
148
|
+
min-inline-size: 2.5ch;
|
|
149
|
+
overflow: hidden;
|
|
150
|
+
text-overflow: ellipsis;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* The segments give way in order: the middle ones first, then the first,
|
|
155
|
+
* and the place itself last — it shrinks only once every other segment is at
|
|
156
|
+
* its floor. Flex freezes a segment at its minimum and hands the rest of the
|
|
157
|
+
* shortfall to the ones still free, so the weights order the giving way. The
|
|
158
|
+
* smallest weight is 1 and not a fraction: once the others are frozen, a
|
|
159
|
+
* free set whose weights sum below one receives only that share of the
|
|
160
|
+
* shortfall, and the last segment overflowed the value unclipped by its own
|
|
161
|
+
* ellipsis at a weight of 0.001.
|
|
162
|
+
*/
|
|
163
|
+
[data-ui='cascader'] [data-part='value-segment'] {
|
|
164
|
+
flex-shrink: 100;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
[data-ui='cascader'] [data-part='value-segment']:first-child {
|
|
168
|
+
flex-shrink: 50;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
[data-ui='cascader'] [data-part='value-segment']:last-child {
|
|
172
|
+
flex-shrink: 1;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
[data-ui='cascader'] [data-part='value-separator'] {
|
|
176
|
+
color: var(--slotted-cascader-separator-color, var(--slotted-text-muted, GrayText));
|
|
177
|
+
flex: none;
|
|
178
|
+
padding-inline: var(--slotted-space-2, 0.25rem);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/* Nothing chosen yet: the same weight, one step quieter. */
|
|
182
|
+
[data-ui='cascader'] [data-part='placeholder'] {
|
|
183
|
+
color: var(--slotted-cascader-placeholder-color, var(--slotted-text-muted, GrayText));
|
|
184
|
+
flex: 1 1 auto;
|
|
185
|
+
min-inline-size: 0;
|
|
186
|
+
overflow: hidden;
|
|
187
|
+
text-overflow: ellipsis;
|
|
188
|
+
white-space: nowrap;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/* A multiple selection shows its chips in the content lane, as `select`'s. */
|
|
192
|
+
[data-ui='cascader'][data-part='root'] > [data-part='tags'] {
|
|
193
|
+
align-items: center;
|
|
194
|
+
display: flex;
|
|
195
|
+
gap: var(--slotted-space-2, 0.25rem);
|
|
196
|
+
grid-area: 1 / 1 / 2 / 2;
|
|
197
|
+
margin-inline-start: var(--_padding-inline);
|
|
198
|
+
min-block-size: var(--slotted-target-min, 24px);
|
|
199
|
+
min-inline-size: 0;
|
|
200
|
+
overflow: hidden;
|
|
201
|
+
pointer-events: none;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
[data-ui='cascader'] > [data-part='tags'] > * {
|
|
205
|
+
pointer-events: auto;
|
|
206
|
+
position: relative;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
[data-ui='cascader'] [data-part='summary'] {
|
|
210
|
+
display: block;
|
|
211
|
+
overflow: hidden;
|
|
212
|
+
text-overflow: ellipsis;
|
|
213
|
+
unicode-bidi: plaintext;
|
|
214
|
+
white-space: nowrap;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
[data-ui='cascader'][data-part='root']:not([data-narrow]) [data-part='summary'] {
|
|
218
|
+
block-size: 1px;
|
|
219
|
+
clip-path: inset(50%);
|
|
220
|
+
inline-size: 1px;
|
|
221
|
+
overflow: hidden;
|
|
222
|
+
white-space: nowrap;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
[data-ui='cascader'][data-part='root'][data-narrow] > [data-part='tags'] {
|
|
226
|
+
display: none;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
[data-ui='cascader'] > [data-part='arrow'] {
|
|
230
|
+
--slotted-icon-size: var(--_icon-size);
|
|
231
|
+
|
|
232
|
+
align-items: center;
|
|
233
|
+
block-size: var(--_icon-size);
|
|
234
|
+
color: var(--slotted-cascader-arrow-color, var(--slotted-text-muted, GrayText));
|
|
235
|
+
display: flex;
|
|
236
|
+
grid-area: 1 / -2 / 2 / -1;
|
|
237
|
+
inline-size: var(--_icon-size);
|
|
238
|
+
justify-content: center;
|
|
239
|
+
margin-inline-end: var(--_padding-inline);
|
|
240
|
+
pointer-events: none;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
[data-ui='cascader'] > [data-part='arrow'] > [data-ui='icon'] {
|
|
244
|
+
transition: rotate var(--slotted-control-transition-duration)
|
|
245
|
+
var(--slotted-control-transition-easing);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
[data-ui='cascader'][data-open] > [data-part='arrow'] > [data-ui='icon'] {
|
|
249
|
+
rotate: 180deg;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/* The ring where the chevron stands, while the value's path is resolving. */
|
|
253
|
+
[data-ui='cascader'] > [data-part='busy'] {
|
|
254
|
+
--slotted-spinner-size: var(--_icon-size);
|
|
255
|
+
|
|
256
|
+
color: var(--slotted-cascader-arrow-color, var(--slotted-text-muted, GrayText));
|
|
257
|
+
grid-area: 1 / -2 / 2 / -1;
|
|
258
|
+
margin-inline-end: var(--_padding-inline);
|
|
259
|
+
pointer-events: none;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
[data-ui='cascader'] > [data-part='clear'] {
|
|
263
|
+
--slotted-icon-size: var(--_icon-size);
|
|
264
|
+
|
|
265
|
+
align-items: center;
|
|
266
|
+
appearance: none;
|
|
267
|
+
background-color: transparent;
|
|
268
|
+
block-size: var(--_action-size);
|
|
269
|
+
border: 0;
|
|
270
|
+
border-radius: var(--slotted-cascader-radius, var(--slotted-control-radius, 4px));
|
|
271
|
+
color: var(--slotted-text-muted, GrayText);
|
|
272
|
+
cursor: pointer;
|
|
273
|
+
display: inline-flex;
|
|
274
|
+
grid-area: 1 / 2 / 2 / 3;
|
|
275
|
+
inline-size: var(--_action-size);
|
|
276
|
+
justify-content: center;
|
|
277
|
+
margin-inline: calc((var(--_icon-size) - var(--_action-size)) / 2);
|
|
278
|
+
padding: 0;
|
|
279
|
+
position: relative;
|
|
280
|
+
touch-action: manipulation;
|
|
281
|
+
transition:
|
|
282
|
+
background-color var(--slotted-control-transition-duration)
|
|
283
|
+
var(--slotted-control-transition-easing),
|
|
284
|
+
color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing);
|
|
285
|
+
-webkit-tap-highlight-color: transparent;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/* The hit area recovered outside the paint, as `select`'s. */
|
|
289
|
+
[data-ui='cascader'] > [data-part='clear']::after {
|
|
290
|
+
content: '';
|
|
291
|
+
inset: min(0px, calc((100% - var(--slotted-target-min, 24px)) / 2));
|
|
292
|
+
position: absolute;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
@media (pointer: coarse) {
|
|
296
|
+
[data-ui='cascader'] > [data-part='clear']::after {
|
|
297
|
+
inset: min(0px, calc((100% - var(--slotted-target-comfortable, 44px)) / 2));
|
|
298
|
+
inset-inline-end: 0;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/* ── Size ─────────────────────────────────────────────────────────────── */
|
|
303
|
+
|
|
304
|
+
[data-ui='cascader'][data-part='root'][data-size='sm'] {
|
|
305
|
+
--_font-size: var(--slotted-control-font-size-sm, 12px);
|
|
306
|
+
--_height: var(--slotted-control-height-sm, 30px);
|
|
307
|
+
--_padding-inline: var(--slotted-control-padding-inline-sm, 10px);
|
|
308
|
+
--_gap: var(--slotted-control-gap-sm, 6px);
|
|
309
|
+
--_icon-size: max(var(--_icon-floor), var(--slotted-control-icon-size-sm, 14px));
|
|
310
|
+
--_inner-size: var(--slotted-control-inner-size-sm, 22px);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
[data-ui='cascader'][data-part='root'][data-size='lg'] {
|
|
314
|
+
--_font-size: var(--slotted-control-font-size-lg, 14px);
|
|
315
|
+
--_height: var(--slotted-control-height-lg, 38px);
|
|
316
|
+
--_padding-inline: var(--slotted-control-padding-inline-lg, 16px);
|
|
317
|
+
--_gap: var(--slotted-control-gap-lg, 8px);
|
|
318
|
+
--_icon-size: max(var(--_icon-floor), var(--slotted-control-icon-size-lg, 18px));
|
|
319
|
+
--_inner-size: var(--slotted-control-inner-size-lg, 28px);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/* ── Variant ──────────────────────────────────────────────────────────── */
|
|
323
|
+
|
|
324
|
+
[data-ui='cascader'][data-part='root'][data-variant='subtle'] {
|
|
325
|
+
background-color: var(--slotted-surface-sunken, Canvas);
|
|
326
|
+
border-color: var(--slotted-border-subtle, ButtonBorder);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
[data-ui='cascader'][data-part='root'][data-variant='plain'] {
|
|
330
|
+
background-color: transparent;
|
|
331
|
+
border-color: transparent;
|
|
332
|
+
border-radius: var(--slotted-radius-none, 0px);
|
|
333
|
+
box-shadow: none;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
@media (forced-colors: active) {
|
|
337
|
+
[data-ui='cascader'][data-part='root'][data-variant='plain'] {
|
|
338
|
+
border-color: ButtonBorder;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/* ── States on the control ────────────────────────────────────────────── */
|
|
343
|
+
|
|
344
|
+
[data-ui='cascader'][data-part='root']:hover:not([data-disabled]):not([data-readonly]):not(
|
|
345
|
+
[data-invalid]
|
|
346
|
+
) {
|
|
347
|
+
border-color: var(--slotted-cascader-hover-border-color, var(--slotted-tone-accent-border));
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
[data-ui='cascader'][data-part='root'][data-variant='subtle']:hover:not([data-disabled]):not(
|
|
351
|
+
[data-readonly]
|
|
352
|
+
):not([data-invalid]) {
|
|
353
|
+
background-color: var(--slotted-tone-secondary-subtle-hover);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
[data-ui='cascader'][data-part='root'][data-variant='plain']:hover:not([data-disabled]):not(
|
|
357
|
+
[data-readonly]
|
|
358
|
+
):not([data-invalid]) {
|
|
359
|
+
background-color: var(--slotted-tone-secondary-subtle-hover);
|
|
360
|
+
border-color: transparent;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
[data-ui='cascader'][data-part='root']:has(> [data-part='trigger']:focus-visible) {
|
|
364
|
+
box-shadow: var(--slotted-control-shadow-focus-geometry, 0 1px 4px -1px)
|
|
365
|
+
var(--slotted-focus-ring-color, Highlight);
|
|
366
|
+
outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
|
|
367
|
+
outline-offset: var(--slotted-focus-ring-offset, 2px);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
[data-ui='cascader'][data-part='root'][data-variant='plain']:has(
|
|
371
|
+
> [data-part='trigger']:focus-visible
|
|
372
|
+
) {
|
|
373
|
+
box-shadow: none;
|
|
374
|
+
outline-offset: calc(var(--slotted-focus-ring-offset, 2px) * -1);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
[data-ui='cascader'][data-part='root'][data-open]:not([data-disabled]) {
|
|
378
|
+
border-color: var(--slotted-cascader-open-border-color, var(--slotted-tone-accent-border));
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
[data-ui='cascader'][data-part='root'][data-invalid] {
|
|
382
|
+
--slotted-focus-ring-color: var(--slotted-focus-ring-color-invalid, Highlight);
|
|
383
|
+
--_invalid-edge-width: var(
|
|
384
|
+
--slotted-cascader-invalid-edge-width,
|
|
385
|
+
var(--slotted-control-invalid-edge-width, 1px)
|
|
386
|
+
);
|
|
387
|
+
--_invalid-edge-color: var(
|
|
388
|
+
--slotted-cascader-invalid-border-color,
|
|
389
|
+
var(--slotted-tone-danger-border)
|
|
390
|
+
);
|
|
391
|
+
--_invalid-edge: inset 0 0 0 var(--_invalid-edge-width) var(--_invalid-edge-color);
|
|
392
|
+
|
|
393
|
+
border-color: var(--slotted-cascader-invalid-border-color, var(--slotted-tone-danger-border));
|
|
394
|
+
/*
|
|
395
|
+
* Width as well as colour (WCAG 1.4.1), the edge `text-field` draws: in
|
|
396
|
+
* `high-contrast` the danger border is the resting edge's black. The line
|
|
397
|
+
* is a shadow inside the border, so neither box nor text moves, and it
|
|
398
|
+
* takes the resting lift's place.
|
|
399
|
+
*/
|
|
400
|
+
box-shadow: var(--_invalid-edge);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
[data-ui='cascader'][data-part='root'][data-invalid]:has(> [data-part='trigger']:focus-visible) {
|
|
404
|
+
box-shadow:
|
|
405
|
+
var(--_invalid-edge),
|
|
406
|
+
var(--slotted-control-shadow-focus-geometry, 0 1px 4px -1px)
|
|
407
|
+
var(--slotted-focus-ring-color, Highlight);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
[data-ui='cascader'][data-part='root'][data-variant='plain'][data-invalid]:has(
|
|
411
|
+
> [data-part='trigger']:focus-visible
|
|
412
|
+
) {
|
|
413
|
+
/* The ring lies inside the box here, over the border and an edge as wide as
|
|
414
|
+
it; the edge reaches past the ring. */
|
|
415
|
+
box-shadow: inset 0 0 0
|
|
416
|
+
calc(
|
|
417
|
+
var(--slotted-focus-ring-offset, 2px) - var(--slotted-control-border-width, 1px) +
|
|
418
|
+
var(--_invalid-edge-width)
|
|
419
|
+
)
|
|
420
|
+
var(--_invalid-edge-color);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/*
|
|
424
|
+
* Forced colours remove every box shadow, and the edge with them. The
|
|
425
|
+
* width comes back as an outline inside the border, and a focused invalid
|
|
426
|
+
* control draws its ring double, which a valid ring is not.
|
|
427
|
+
*/
|
|
428
|
+
@media (forced-colors: active) {
|
|
429
|
+
[data-ui='cascader'][data-part='root'][data-invalid] {
|
|
430
|
+
outline: var(--_invalid-edge-width) solid CanvasText;
|
|
431
|
+
outline-offset: calc(
|
|
432
|
+
-1 * (var(--slotted-control-border-width, 1px) + var(--_invalid-edge-width))
|
|
433
|
+
);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
[data-ui='cascader'][data-part='root'][data-invalid]:has(
|
|
437
|
+
> [data-part='trigger']:focus-visible
|
|
438
|
+
) {
|
|
439
|
+
outline: calc(var(--slotted-focus-ring-width, 2px) + var(--_invalid-edge-width)) double
|
|
440
|
+
var(--slotted-focus-ring-color, Highlight);
|
|
441
|
+
outline-offset: var(--slotted-focus-ring-offset, 2px);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
[data-ui='cascader'][data-part='root'][data-variant='plain'][data-invalid]:has(
|
|
445
|
+
> [data-part='trigger']:focus-visible
|
|
446
|
+
) {
|
|
447
|
+
outline: calc(var(--slotted-focus-ring-width, 2px) + var(--_invalid-edge-width)) double
|
|
448
|
+
var(--slotted-focus-ring-color, Highlight);
|
|
449
|
+
outline-offset: calc(
|
|
450
|
+
-1 * (var(--slotted-focus-ring-width, 2px) + var(--_invalid-edge-width))
|
|
451
|
+
);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
[data-ui='cascader'][data-part='root'][data-readonly] {
|
|
456
|
+
background-color: var(--slotted-tone-secondary-subtle-hover);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/* The chevron of a control nobody may open steps down to the muted ink it
|
|
460
|
+
already has plus the disabled one, rather than fading by opacity. */
|
|
461
|
+
[data-ui='cascader'][data-part='root'][data-readonly] > [data-part='arrow'] {
|
|
462
|
+
color: var(--slotted-disabled-foreground);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
[data-ui='cascader'][data-part='root'][data-disabled],
|
|
466
|
+
[data-ui='cascader'][data-part='root']:has(> [data-part='trigger']:disabled) {
|
|
467
|
+
background-color: var(--slotted-disabled-background);
|
|
468
|
+
border-color: var(--slotted-disabled-border);
|
|
469
|
+
box-shadow: none;
|
|
470
|
+
color: var(--slotted-disabled-foreground);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
[data-ui='cascader'][data-part='root'][data-disabled] > [data-part='trigger'],
|
|
474
|
+
[data-ui='cascader'][data-part='root'] > [data-part='trigger']:disabled {
|
|
475
|
+
cursor: not-allowed;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
[data-ui='cascader'] > [data-part='clear']:hover:not(:disabled):not([data-disabled]) {
|
|
479
|
+
background-color: var(--slotted-tone-secondary-subtle-hover);
|
|
480
|
+
color: var(--slotted-text, CanvasText);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
[data-ui='cascader'] > [data-part='clear']:active:not(:disabled):not([data-disabled]) {
|
|
484
|
+
background-color: var(--slotted-tone-secondary-subtle-active);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
[data-ui='cascader'] > [data-part='clear']:focus-visible {
|
|
488
|
+
outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
|
|
489
|
+
outline-offset: calc(var(--slotted-focus-ring-offset, 2px) * -1);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
/* ── The layer ────────────────────────────────────────────────────────── */
|
|
493
|
+
|
|
494
|
+
[data-ui='cascader']:is([data-part='positioner'], [data-part='content']) {
|
|
495
|
+
--_surface: var(--slotted-cascader-surface, var(--slotted-surface-raised, #ffffff));
|
|
496
|
+
--_text: var(--slotted-text, #0f172a);
|
|
497
|
+
--_muted: var(--slotted-text-muted, #5b6b7f);
|
|
498
|
+
--_border-color: var(--slotted-cascader-border-subtle, var(--slotted-border-subtle, #e2e8f0));
|
|
499
|
+
--_border-width: var(--slotted-border-width-thin, 1px);
|
|
500
|
+
--_radius: var(--slotted-cascader-content-radius, var(--slotted-radius-lg, 8px));
|
|
501
|
+
--_shadow: var(--slotted-cascader-content-shadow, var(--slotted-shadow-md));
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* The cursor, the path and the press. The cursor is `select`'s stronger
|
|
505
|
+
* neutral step, which lifts in all three schemes where the weaker one sank
|
|
506
|
+
* in the dark (the measurement `select` records). The path — the nodes whose
|
|
507
|
+
* columns are open — takes the weaker step of the same pair only in the
|
|
508
|
+
* light schemes; in the dark it would sink, so the path is carried by the
|
|
509
|
+
* ink and the chevron as well, never by the ground alone.
|
|
510
|
+
*/
|
|
511
|
+
--_highlight: var(--slotted-cascader-highlight, var(--slotted-tone-secondary-subtle-active));
|
|
512
|
+
--_highlight-active: var(
|
|
513
|
+
--slotted-cascader-highlight-active,
|
|
514
|
+
var(--slotted-tone-accent-surface)
|
|
515
|
+
);
|
|
516
|
+
--_path: var(--slotted-cascader-path, var(--slotted-tone-secondary-surface));
|
|
517
|
+
--_selected-color: var(--slotted-cascader-selected-color, var(--slotted-tone-accent-text));
|
|
518
|
+
|
|
519
|
+
--_inset-block: var(--slotted-space-2, 0.25rem);
|
|
520
|
+
--_inset-inline: var(--slotted-space-2, 0.25rem);
|
|
521
|
+
--_item-inset: calc(var(--slotted-control-padding-inline-md, 0.8125rem) - var(--_inset-inline));
|
|
522
|
+
--_item-height: var(--slotted-control-height-md, 34px);
|
|
523
|
+
--_item-radius: var(--slotted-control-radius);
|
|
524
|
+
--_content-font-size: var(--slotted-control-font-size-md, 13px);
|
|
525
|
+
--_secondary-font-size: var(--slotted-control-font-size-sm, 12px);
|
|
526
|
+
--_content-icon-size: var(--slotted-control-icon-size-md, 16px);
|
|
527
|
+
--_check-size: var(--slotted-selection-size-md, 16px);
|
|
528
|
+
--_column-gap: var(--slotted-control-gap-md, 0.5rem);
|
|
529
|
+
--_column-measure: var(--slotted-cascader-column-measure, 12rem);
|
|
530
|
+
--_indent: var(--slotted-cascader-indent, var(--slotted-space-6, 1rem));
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* Line boxes on whole pixels, so a column of nodes with descriptions sums
|
|
534
|
+
* to a whole number and the surface's bottom border sits on a pixel row.
|
|
535
|
+
* The same rounding `menu` and `attachment` apply to the same ratios.
|
|
536
|
+
*/
|
|
537
|
+
--_leading: round(
|
|
538
|
+
up,
|
|
539
|
+
calc(var(--_content-font-size) * var(--slotted-line-height-md, 1.5)),
|
|
540
|
+
1px
|
|
541
|
+
);
|
|
542
|
+
--_secondary-leading: round(
|
|
543
|
+
up,
|
|
544
|
+
calc(var(--_secondary-font-size) * var(--slotted-line-height-sm, 1.45)),
|
|
545
|
+
1px
|
|
546
|
+
);
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
[data-ui='cascader'][data-part='positioner'] {
|
|
550
|
+
position: absolute;
|
|
551
|
+
inset-block-start: 0;
|
|
552
|
+
z-index: calc(var(--slotted-z-index-popover, 1100) + var(--slotted-layer-depth, 0));
|
|
553
|
+
isolation: isolate;
|
|
554
|
+
box-sizing: border-box;
|
|
555
|
+
pointer-events: none;
|
|
556
|
+
|
|
557
|
+
opacity: 0;
|
|
558
|
+
--_enter-distance: var(--slotted-space-2, 0.25rem);
|
|
559
|
+
translate: 0 calc(-1 * var(--_enter-distance));
|
|
560
|
+
transition:
|
|
561
|
+
opacity var(--slotted-duration-short) var(--slotted-easing-exit),
|
|
562
|
+
translate var(--slotted-duration-short) var(--slotted-easing-exit);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
[data-ui='cascader'][data-part='positioner'][data-side='top'] {
|
|
566
|
+
translate: 0 var(--_enter-distance);
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
[data-ui='cascader'][data-part='positioner']:is([data-side='left'], [data-side='right']) {
|
|
570
|
+
translate: 0 0;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
/* The entrance is a keyframe, the exit a transition: `select`'s reasoning. */
|
|
574
|
+
[data-ui='cascader'][data-part='positioner'][data-open] {
|
|
575
|
+
opacity: 1;
|
|
576
|
+
translate: 0 0;
|
|
577
|
+
transition: none;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
[data-ui='cascader'][data-part='positioner'][data-open][data-positioned] {
|
|
581
|
+
animation: slotted-cascader-enter-down var(--slotted-duration-medium)
|
|
582
|
+
var(--slotted-easing-enter);
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
[data-ui='cascader'][data-part='positioner'][data-open][data-positioned][data-side='top'] {
|
|
586
|
+
animation-name: slotted-cascader-enter-up;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
@keyframes slotted-cascader-enter-down {
|
|
590
|
+
from {
|
|
591
|
+
opacity: 0;
|
|
592
|
+
translate: 0 calc(-1 * var(--_enter-distance));
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
@keyframes slotted-cascader-enter-up {
|
|
597
|
+
from {
|
|
598
|
+
opacity: 0;
|
|
599
|
+
translate: 0 var(--_enter-distance);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
@keyframes slotted-cascader-fade {
|
|
604
|
+
from {
|
|
605
|
+
opacity: 0;
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
@media (prefers-reduced-motion: reduce) {
|
|
610
|
+
[data-ui='cascader'][data-part='positioner'],
|
|
611
|
+
[data-ui='cascader'][data-part='positioner'][data-side='top'] {
|
|
612
|
+
translate: 0 0;
|
|
613
|
+
transition: opacity var(--slotted-duration-short) var(--slotted-easing-exit);
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
[data-ui='cascader'][data-part='positioner'][data-open][data-positioned],
|
|
617
|
+
[data-ui='cascader'][data-part='positioner'][data-open][data-positioned][data-side='top'] {
|
|
618
|
+
animation-name: slotted-cascader-fade;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
[data-ui='cascader'][data-part='positioner'][data-detached] {
|
|
623
|
+
visibility: hidden;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
/**
|
|
627
|
+
* The width follows the layout. Columns take their own sum, as wide as the
|
|
628
|
+
* path is deep, up to the room the positioner reports; one level at a time
|
|
629
|
+
* takes the control's width, and never less than one column.
|
|
630
|
+
*/
|
|
631
|
+
[data-ui='cascader'][data-part='positioner'][data-layout='columns'] {
|
|
632
|
+
inline-size: max-content;
|
|
633
|
+
max-inline-size: var(--slotted-positioner-available-width, 100vw);
|
|
634
|
+
min-inline-size: var(--slotted-positioner-anchor-width, auto);
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
/**
|
|
638
|
+
* The layer reserves the widest width the window can reach and the surface
|
|
639
|
+
* inside it is only as wide as the columns on show, never narrower than the
|
|
640
|
+
* control it hangs from. The reserved strip beside it is the layer's, which
|
|
641
|
+
* takes no pointer.
|
|
642
|
+
*/
|
|
643
|
+
[data-ui='cascader'][data-part='positioner'][data-layout='columns'] > [data-part='content'] {
|
|
644
|
+
inline-size: max-content;
|
|
645
|
+
max-inline-size: 100%;
|
|
646
|
+
min-inline-size: min(var(--slotted-positioner-anchor-width, 0px), 100%);
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
[data-ui='cascader'][data-part='positioner']:is([data-layout='drill'], [data-layout='tree']) {
|
|
650
|
+
inline-size: max(var(--slotted-positioner-anchor-width, 0px), var(--_column-measure));
|
|
651
|
+
max-inline-size: var(--slotted-positioner-available-width, 100vw);
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
[data-ui='cascader']:is([data-part='positioner'], [data-part='content'])[data-size='sm'] {
|
|
655
|
+
--_item-inset: calc(var(--slotted-control-padding-inline-sm, 0.625rem) - var(--_inset-inline));
|
|
656
|
+
--_item-height: var(--slotted-control-height-sm, 30px);
|
|
657
|
+
--_content-font-size: var(--slotted-control-font-size-sm, 12px);
|
|
658
|
+
--_secondary-font-size: var(--slotted-font-size-xs, 0.75rem);
|
|
659
|
+
--_content-icon-size: var(--slotted-control-icon-size-sm, 14px);
|
|
660
|
+
--_check-size: var(--slotted-selection-size-sm, 14px);
|
|
661
|
+
--_column-gap: var(--slotted-control-gap-sm, 0.375rem);
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
[data-ui='cascader']:is([data-part='positioner'], [data-part='content'])[data-size='lg'] {
|
|
665
|
+
--_item-inset: calc(var(--slotted-control-padding-inline-lg, 1rem) - var(--_inset-inline));
|
|
666
|
+
--_item-height: var(--slotted-control-height-lg, 38px);
|
|
667
|
+
--_content-font-size: var(--slotted-control-font-size-lg, 14px);
|
|
668
|
+
--_secondary-font-size: var(--slotted-control-font-size-sm, 12px);
|
|
669
|
+
--_content-icon-size: var(--slotted-control-icon-size-lg, 18px);
|
|
670
|
+
--_check-size: var(--slotted-selection-size-lg, 18px);
|
|
671
|
+
--_column-gap: var(--slotted-control-gap-lg, 0.5rem);
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
/* ── The surface ──────────────────────────────────────────────────────── */
|
|
675
|
+
|
|
676
|
+
/**
|
|
677
|
+
* A column of up to three rows — the search field, the breadcrumb, the
|
|
678
|
+
* panel — bounded by the height the positioner reports. The panel is the one
|
|
679
|
+
* that gives, and inside it each column scrolls on its own.
|
|
680
|
+
*/
|
|
681
|
+
[data-ui='cascader'] > [data-part='content'] {
|
|
682
|
+
background: var(--_surface);
|
|
683
|
+
border: var(--_border-width) solid var(--_border-color);
|
|
684
|
+
border-radius: var(--_radius);
|
|
685
|
+
box-shadow: var(--_shadow);
|
|
686
|
+
box-sizing: border-box;
|
|
687
|
+
color: var(--_text);
|
|
688
|
+
display: flex;
|
|
689
|
+
flex-direction: column;
|
|
690
|
+
font-family: var(--slotted-font-family-sans);
|
|
691
|
+
font-size: var(--_content-font-size);
|
|
692
|
+
line-height: var(--_leading);
|
|
693
|
+
max-block-size: calc(
|
|
694
|
+
var(--slotted-positioner-available-height, 100vh) - var(--slotted-space-5, 0.75rem)
|
|
695
|
+
);
|
|
696
|
+
/* The columns' own rules meet the rounded edge rather than crossing it. */
|
|
697
|
+
overflow: hidden;
|
|
698
|
+
outline: none;
|
|
699
|
+
pointer-events: auto;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
[data-ui='cascader'] > [data-part='content']:focus-visible {
|
|
703
|
+
outline: none;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
/**
|
|
707
|
+
* The surface on its own, without a control or a layer — a settings screen,
|
|
708
|
+
* a sidebar. It carries `data-ui` itself, paints what the layer's surface
|
|
709
|
+
* paints minus the shadow, because it lies on the page rather than over it,
|
|
710
|
+
* and is as wide as its columns up to its container. The tree inside it
|
|
711
|
+
* takes focus here, and the surface draws the ring for it.
|
|
712
|
+
*/
|
|
713
|
+
[data-ui='cascader'][data-part='content'] {
|
|
714
|
+
background: var(--_surface);
|
|
715
|
+
border: var(--_border-width) solid var(--_border-color);
|
|
716
|
+
border-radius: var(--_radius);
|
|
717
|
+
box-sizing: border-box;
|
|
718
|
+
color: var(--_text);
|
|
719
|
+
display: flex;
|
|
720
|
+
flex-direction: column;
|
|
721
|
+
font-family: var(--slotted-font-family-sans);
|
|
722
|
+
font-size: var(--_content-font-size);
|
|
723
|
+
inline-size: fit-content;
|
|
724
|
+
line-height: var(--_leading);
|
|
725
|
+
max-inline-size: 100%;
|
|
726
|
+
overflow: hidden;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
[data-ui='cascader'][data-part='content']:has(> [data-part='panel']:focus-visible) {
|
|
730
|
+
outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
|
|
731
|
+
outline-offset: var(--slotted-focus-ring-offset, 2px);
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
/* ── The search field ─────────────────────────────────────────────────── */
|
|
735
|
+
|
|
736
|
+
[data-ui='cascader'] [data-part='search'] {
|
|
737
|
+
align-items: center;
|
|
738
|
+
border-block-end: var(--_border-width) solid var(--_border-color);
|
|
739
|
+
box-sizing: border-box;
|
|
740
|
+
display: flex;
|
|
741
|
+
flex: 0 0 auto;
|
|
742
|
+
gap: var(--_column-gap);
|
|
743
|
+
min-block-size: var(--_item-height);
|
|
744
|
+
padding-block: var(--slotted-space-2, 0.25rem);
|
|
745
|
+
padding-inline: calc(var(--_inset-inline) + var(--_item-inset));
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
[data-ui='cascader'] [data-part='search'] > [data-ui='icon'] {
|
|
749
|
+
--slotted-icon-size: var(--_content-icon-size);
|
|
750
|
+
|
|
751
|
+
color: var(--_muted);
|
|
752
|
+
flex: none;
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
/* No ring: the field holds focus for as long as the popup is open, so a
|
|
756
|
+
ring would be a border, not a state. The caret says where focus is. */
|
|
757
|
+
[data-ui='cascader'] [data-part='search-input'] {
|
|
758
|
+
background-color: transparent;
|
|
759
|
+
border: 0;
|
|
760
|
+
color: inherit;
|
|
761
|
+
flex: 1 1 auto;
|
|
762
|
+
font: inherit;
|
|
763
|
+
min-inline-size: 0;
|
|
764
|
+
outline: none;
|
|
765
|
+
padding: 0;
|
|
766
|
+
text-overflow: ellipsis;
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
[data-ui='cascader'] [data-part='search-input']::placeholder {
|
|
770
|
+
color: var(--_muted);
|
|
771
|
+
text-overflow: ellipsis;
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
/* ── The breadcrumb ───────────────────────────────────────────────────── */
|
|
775
|
+
|
|
776
|
+
/**
|
|
777
|
+
* Where the levels on show sit: the ones before them, each a press away. It
|
|
778
|
+
* is the way back by pointer in `drill`, which shows one level, and in
|
|
779
|
+
* `columns` once the window has slid past a level. Each crumb is a real
|
|
780
|
+
* control with the target minimum, and the row shares the column's inset so
|
|
781
|
+
* the first crumb starts where the labels under it start.
|
|
782
|
+
*
|
|
783
|
+
* One line, never wrapped: a deep trail folds its middle into one crumb
|
|
784
|
+
* (`cascaderCrumbs`), so the row is as tall at the tenth level as at the
|
|
785
|
+
* second and the list under it does not move down as the reader drills.
|
|
786
|
+
*/
|
|
787
|
+
[data-ui='cascader'] [data-part='breadcrumb'] {
|
|
788
|
+
align-items: center;
|
|
789
|
+
border-block-end: var(--_border-width) solid var(--_border-color);
|
|
790
|
+
color: var(--_muted);
|
|
791
|
+
display: flex;
|
|
792
|
+
flex: 0 0 auto;
|
|
793
|
+
font-size: var(--_secondary-font-size);
|
|
794
|
+
gap: var(--slotted-space-1, 0.125rem);
|
|
795
|
+
line-height: var(--_secondary-leading);
|
|
796
|
+
min-inline-size: 0;
|
|
797
|
+
overflow: hidden;
|
|
798
|
+
padding-block: var(--slotted-space-2, 0.25rem);
|
|
799
|
+
padding-inline: calc(
|
|
800
|
+
var(--_inset-inline) + var(--_item-inset) - var(--slotted-space-2, 0.25rem)
|
|
801
|
+
);
|
|
802
|
+
white-space: nowrap;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
[data-ui='cascader'] [data-part='breadcrumb'] > [data-ui='icon'] {
|
|
806
|
+
--slotted-icon-size: var(--_secondary-font-size);
|
|
807
|
+
|
|
808
|
+
flex: none;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
[data-ui='cascader'] [data-part='crumb'] {
|
|
812
|
+
appearance: none;
|
|
813
|
+
background-color: transparent;
|
|
814
|
+
border: 0;
|
|
815
|
+
border-radius: var(--slotted-radius-sm, 4px);
|
|
816
|
+
color: inherit;
|
|
817
|
+
cursor: pointer;
|
|
818
|
+
font: inherit;
|
|
819
|
+
/* The crumbs before the current one give way first; weights rather than a
|
|
820
|
+
zero, for the reason the value's segments state. */
|
|
821
|
+
flex: 0 100 auto;
|
|
822
|
+
max-inline-size: 12ch;
|
|
823
|
+
min-block-size: var(--slotted-target-min, 24px);
|
|
824
|
+
min-inline-size: 3ch;
|
|
825
|
+
overflow: hidden;
|
|
826
|
+
padding-block: 0;
|
|
827
|
+
padding-inline: var(--slotted-space-2, 0.25rem);
|
|
828
|
+
text-overflow: ellipsis;
|
|
829
|
+
white-space: nowrap;
|
|
830
|
+
transition:
|
|
831
|
+
background-color var(--slotted-control-transition-duration)
|
|
832
|
+
var(--slotted-control-transition-easing),
|
|
833
|
+
color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing);
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
[data-ui='cascader'] [data-part='crumb']:hover:not([aria-current]):not(:disabled) {
|
|
837
|
+
background-color: var(--_highlight);
|
|
838
|
+
color: var(--_text);
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
[data-ui='cascader'] [data-part='crumb']:active:not([aria-current]):not(:disabled) {
|
|
842
|
+
background-color: var(--_highlight-active);
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
/* Outside the crumb: an inset ring sat on the first letter of a label the
|
|
846
|
+
crumb's own padding barely clears. The row's block padding holds it. */
|
|
847
|
+
[data-ui='cascader'] [data-part='crumb']:focus-visible {
|
|
848
|
+
outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
|
|
849
|
+
outline-offset: 0;
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
/* The level on show: where the reader is, and not a place to go. */
|
|
853
|
+
[data-ui='cascader'] [data-part='crumb'][aria-current] {
|
|
854
|
+
color: var(--_text);
|
|
855
|
+
cursor: default;
|
|
856
|
+
flex-shrink: 1;
|
|
857
|
+
font-weight: var(--slotted-font-weight-semibold, 600);
|
|
858
|
+
max-inline-size: none;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
/* The fold: the middle of a deep trail as one crumb, its ellipsis whole. */
|
|
862
|
+
[data-ui='cascader'] [data-part='crumb'][data-collapsed] {
|
|
863
|
+
flex: none;
|
|
864
|
+
min-inline-size: var(--slotted-target-min, 24px);
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
/* ── The panel and its columns ────────────────────────────────────────── */
|
|
868
|
+
|
|
869
|
+
/**
|
|
870
|
+
* The panel never scrolls sideways. A path deeper than the room holds
|
|
871
|
+
* slides the window of columns the binding renders (`cascaderWindow`), and
|
|
872
|
+
* the levels left behind go to the breadcrumb above. The first capture
|
|
873
|
+
* scrolled them instead, and at 420 pixels the third column sat under the
|
|
874
|
+
* rounded edge with nothing on a touch screen saying there was more.
|
|
875
|
+
*/
|
|
876
|
+
[data-ui='cascader'] [data-part='panel'] {
|
|
877
|
+
display: flex;
|
|
878
|
+
flex: 1 1 auto;
|
|
879
|
+
min-block-size: 0;
|
|
880
|
+
min-inline-size: 0;
|
|
881
|
+
outline: none;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
/**
|
|
885
|
+
* One level. A grid of five tracks every node passes through, one measure
|
|
886
|
+
* wide, scrolling on its own. Columns after the first are ruled off from the
|
|
887
|
+
* one before by a hairline from the border scale — the edge a reader follows
|
|
888
|
+
* from a branch to its children.
|
|
889
|
+
*/
|
|
890
|
+
[data-ui='cascader'] [data-part='column'] {
|
|
891
|
+
align-content: start;
|
|
892
|
+
box-sizing: border-box;
|
|
893
|
+
display: grid;
|
|
894
|
+
/**
|
|
895
|
+
* One measure each, and they give way together rather than spilling past
|
|
896
|
+
* the surface: the binding sizes the window to what fits, and this is the
|
|
897
|
+
* floor under it for the frames between a resize and the next measurement,
|
|
898
|
+
* when the room has shrunk and the window has not yet slid.
|
|
899
|
+
*/
|
|
900
|
+
flex: 0 1 auto;
|
|
901
|
+
grid-template-columns: auto auto minmax(0, 1fr) auto auto;
|
|
902
|
+
/* A size and not a basis: the layer is `max-content`, and a flex basis
|
|
903
|
+
does not enter an item's max-content contribution, so with a basis alone
|
|
904
|
+
every column measured its longest label and broke words inside it. */
|
|
905
|
+
inline-size: var(--_column-measure);
|
|
906
|
+
min-inline-size: 0;
|
|
907
|
+
max-block-size: 100%;
|
|
908
|
+
overflow-y: auto;
|
|
909
|
+
overscroll-behavior: contain;
|
|
910
|
+
padding-block: var(--_inset-block);
|
|
911
|
+
padding-inline: var(--_inset-inline);
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
[data-ui='cascader'] [data-part='column'] + [data-part='column'] {
|
|
915
|
+
border-inline-start: var(--_border-width) solid var(--_border-color);
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
/* One level at a time, or every level in one run: the column is the panel. */
|
|
919
|
+
[data-ui='cascader']:is([data-layout='drill'], [data-layout='tree']) [data-part='column'] {
|
|
920
|
+
flex: 1 1 auto;
|
|
921
|
+
inline-size: auto;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
/* A level still loading says so to a reader while its rows wait. */
|
|
925
|
+
[data-ui='cascader'] [data-part='column'][aria-busy='true'] {
|
|
926
|
+
cursor: progress;
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
/* ── Nodes ────────────────────────────────────────────────────────────── */
|
|
930
|
+
|
|
931
|
+
/**
|
|
932
|
+
* `role="treeitem"` on a `div`: DOM focus stays on the control and the
|
|
933
|
+
* cursor is `aria-activedescendant`, so a node is neither focusable nor a
|
|
934
|
+
* button, as `select`'s option is not.
|
|
935
|
+
*/
|
|
936
|
+
[data-ui='cascader'] [data-part='node'] {
|
|
937
|
+
align-content: center;
|
|
938
|
+
border-radius: var(--_item-radius);
|
|
939
|
+
box-sizing: border-box;
|
|
940
|
+
cursor: pointer;
|
|
941
|
+
display: grid;
|
|
942
|
+
grid-column: 1 / -1;
|
|
943
|
+
grid-template-columns: subgrid;
|
|
944
|
+
line-height: var(--_leading);
|
|
945
|
+
min-block-size: var(--_item-height);
|
|
946
|
+
padding-block: var(--slotted-space-2, 0.25rem);
|
|
947
|
+
padding-inline: var(--_item-inset);
|
|
948
|
+
row-gap: var(--slotted-space-1, 0.125rem);
|
|
949
|
+
user-select: none;
|
|
950
|
+
transition:
|
|
951
|
+
background-color var(--slotted-control-transition-duration, var(--slotted-duration-short))
|
|
952
|
+
var(--slotted-control-transition-easing, var(--slotted-easing-standard)),
|
|
953
|
+
box-shadow var(--slotted-control-transition-duration, var(--slotted-duration-short))
|
|
954
|
+
var(--slotted-control-transition-easing, var(--slotted-easing-standard)),
|
|
955
|
+
color var(--slotted-control-transition-duration, var(--slotted-duration-short))
|
|
956
|
+
var(--slotted-control-transition-easing, var(--slotted-easing-standard));
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
/**
|
|
960
|
+
* The tree layout indents each node by its depth, which the binding writes
|
|
961
|
+
* as a runtime property: the visible nodes are one flat run of treeitems
|
|
962
|
+
* carrying `aria-level`, because a node that held its children would paint
|
|
963
|
+
* its highlight over them.
|
|
964
|
+
*/
|
|
965
|
+
[data-ui='cascader'][data-layout='tree'] [data-part='node'] {
|
|
966
|
+
/* Its own tracks rather than the column's: a subgrid gives every row the
|
|
967
|
+
widest padding among them, so the first capture drew every level at the
|
|
968
|
+
deepest indent. The end tracks still line up, because every node ends in
|
|
969
|
+
a cell of the same width. */
|
|
970
|
+
grid-template-columns: auto auto minmax(0, 1fr) auto auto;
|
|
971
|
+
padding-inline-start: calc(
|
|
972
|
+
var(--_item-inset) + var(--slotted-cascader-depth, 0) * var(--_indent)
|
|
973
|
+
);
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
/**
|
|
977
|
+
* On the path: a branch whose level is open to its inline end. The ground is
|
|
978
|
+
* the quieter neutral step, and the chevron takes the label's ink, so the
|
|
979
|
+
* road from the first column to the cursor reads as one line — and in the
|
|
980
|
+
* dark scheme, where no neutral ground below the cursor lifts, the ink
|
|
981
|
+
* carries it alone.
|
|
982
|
+
*/
|
|
983
|
+
[data-ui='cascader'] [data-part='node'][data-expanded] {
|
|
984
|
+
background-color: var(--_path);
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
/* And a weight, which is what carries the road where no ground does: the
|
|
988
|
+
high-contrast scheme draws the path ground as its own surface. */
|
|
989
|
+
[data-ui='cascader'] [data-part='node'][data-expanded] > [data-part='label'] {
|
|
990
|
+
font-weight: var(--slotted-font-weight-semibold, 600);
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
[data-ui='cascader'][data-layout='tree'] [data-part='node'][data-expanded] {
|
|
994
|
+
background-color: transparent;
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
/* The cursor, a ground and a one-pixel ring, for the reason `select` gives. */
|
|
998
|
+
[data-ui='cascader'] [data-part='node'][data-current] {
|
|
999
|
+
background-color: var(--_highlight);
|
|
1000
|
+
box-shadow: inset 0 0 0 var(--slotted-border-width-thin, 1px)
|
|
1001
|
+
var(--slotted-cascader-highlight-ring, var(--slotted-tone-accent-border));
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
[data-ui='cascader'] [data-part='node']:not([data-disabled]):active {
|
|
1005
|
+
background-color: var(--_highlight-active);
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
[data-ui='cascader'] [data-part='node'][data-selected] {
|
|
1009
|
+
color: var(--_selected-color);
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
[data-ui='cascader'] [data-part='node'][data-selected] > [data-part='label'] {
|
|
1013
|
+
font-weight: var(--slotted-font-weight-medium, 500);
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
[data-ui='cascader'] [data-part='node'][data-disabled] {
|
|
1017
|
+
color: var(--slotted-disabled-foreground, #64748b);
|
|
1018
|
+
cursor: not-allowed;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
/* The cursor lifts on a disabled node too; the ink and the ring step down. */
|
|
1022
|
+
[data-ui='cascader'] [data-part='node'][data-disabled][data-current] {
|
|
1023
|
+
box-shadow: inset 0 0 0 var(--slotted-border-width-thin, 1px)
|
|
1024
|
+
var(--slotted-disabled-border, #cbd5e1);
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
/* ── The cells ────────────────────────────────────────────────────────── */
|
|
1028
|
+
|
|
1029
|
+
[data-ui='cascader']
|
|
1030
|
+
[data-part='node']
|
|
1031
|
+
> :is([data-part='indicator'], [data-part='icon'], [data-part='expander']) {
|
|
1032
|
+
block-size: 1lh;
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
/**
|
|
1036
|
+
* Track two: the node's own picture, content the consumer supplies and the
|
|
1037
|
+
* column sizes. No stylesheet fills it.
|
|
1038
|
+
*/
|
|
1039
|
+
[data-ui='cascader'] [data-part='node'] > [data-part='icon'] {
|
|
1040
|
+
--slotted-icon-size: var(--_content-icon-size);
|
|
1041
|
+
|
|
1042
|
+
align-items: center;
|
|
1043
|
+
display: flex;
|
|
1044
|
+
grid-column: 2;
|
|
1045
|
+
grid-row: 1;
|
|
1046
|
+
inline-size: var(--_content-icon-size);
|
|
1047
|
+
justify-content: center;
|
|
1048
|
+
margin-inline-end: var(--_column-gap);
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
[data-ui='cascader'] [data-part='node'] > [data-part='icon'] > * {
|
|
1052
|
+
font-size: var(--_content-icon-size);
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
/* Track three, the only one that gives way: two lines, then an ellipsis. */
|
|
1056
|
+
[data-ui='cascader'] [data-part='node'] > [data-part='label'] {
|
|
1057
|
+
display: -webkit-box;
|
|
1058
|
+
grid-column: 3;
|
|
1059
|
+
grid-row: 1;
|
|
1060
|
+
min-inline-size: 0;
|
|
1061
|
+
overflow: hidden;
|
|
1062
|
+
overflow-wrap: anywhere;
|
|
1063
|
+
-webkit-box-orient: vertical;
|
|
1064
|
+
-webkit-line-clamp: 2;
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
/**
|
|
1068
|
+
* The path of a search hit, or the line under a label. Quieter by the
|
|
1069
|
+
* secondary step and never in the way of the label above it.
|
|
1070
|
+
*/
|
|
1071
|
+
[data-ui='cascader'] [data-part='node'] > [data-part='description'] {
|
|
1072
|
+
color: var(--_muted);
|
|
1073
|
+
font-size: var(--_secondary-font-size);
|
|
1074
|
+
grid-column: 3;
|
|
1075
|
+
grid-row: 2;
|
|
1076
|
+
line-height: var(--_secondary-leading);
|
|
1077
|
+
min-inline-size: 0;
|
|
1078
|
+
overflow: hidden;
|
|
1079
|
+
text-overflow: ellipsis;
|
|
1080
|
+
white-space: nowrap;
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
[data-ui='cascader'] [data-part='node'][data-disabled] > [data-part='description'] {
|
|
1084
|
+
color: inherit;
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
/* Track four: the count of a branch, or how many inside it are chosen. */
|
|
1088
|
+
[data-ui='cascader'] [data-part='node'] > [data-part='meta'] {
|
|
1089
|
+
color: var(--_muted);
|
|
1090
|
+
font-size: var(--_secondary-font-size);
|
|
1091
|
+
font-variant-numeric: tabular-nums;
|
|
1092
|
+
grid-column: 4;
|
|
1093
|
+
grid-row: 1;
|
|
1094
|
+
justify-self: end;
|
|
1095
|
+
margin-inline-start: var(--_column-gap);
|
|
1096
|
+
white-space: nowrap;
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
[data-ui='cascader'] [data-part='node'][data-selected] > [data-part='meta'],
|
|
1100
|
+
[data-ui='cascader'] [data-part='node'][data-indeterminate] > [data-part='meta'] {
|
|
1101
|
+
color: var(--_selected-color);
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
/**
|
|
1105
|
+
* Track five: the chevron of a branch. It points along the reading
|
|
1106
|
+
* direction, from the `directional` icon box the binding draws, and takes
|
|
1107
|
+
* the label's ink on the path.
|
|
1108
|
+
*/
|
|
1109
|
+
[data-ui='cascader'] [data-part='node'] > [data-part='expander'] {
|
|
1110
|
+
--slotted-icon-size: var(--_content-icon-size);
|
|
1111
|
+
|
|
1112
|
+
align-items: center;
|
|
1113
|
+
color: var(--_muted);
|
|
1114
|
+
display: flex;
|
|
1115
|
+
grid-column: 5;
|
|
1116
|
+
grid-row: 1;
|
|
1117
|
+
inline-size: var(--_content-icon-size);
|
|
1118
|
+
justify-content: center;
|
|
1119
|
+
justify-self: end;
|
|
1120
|
+
margin-inline-start: var(--_column-gap);
|
|
1121
|
+
transition: color var(--slotted-control-transition-duration)
|
|
1122
|
+
var(--slotted-control-transition-easing);
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
[data-ui='cascader']
|
|
1126
|
+
[data-part='node']:is([data-expanded], [data-current])
|
|
1127
|
+
> [data-part='expander'] {
|
|
1128
|
+
color: inherit;
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
[data-ui='cascader'] [data-part='node'] > [data-part='expander'] > [data-ui='icon'] {
|
|
1132
|
+
transition: rotate var(--slotted-control-transition-duration)
|
|
1133
|
+
var(--slotted-control-transition-easing);
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
/* In the tree the level opens under the node, so the chevron turns down. */
|
|
1137
|
+
[data-ui='cascader'][data-layout='tree']
|
|
1138
|
+
[data-part='node'][data-expanded]
|
|
1139
|
+
> [data-part='expander']
|
|
1140
|
+
> [data-ui='icon'] {
|
|
1141
|
+
rotate: 90deg;
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
/* A branch whose level is on its way: the ring stands where the chevron stood. */
|
|
1145
|
+
[data-ui='cascader'] [data-part='expander'] > [data-ui='spinner'] {
|
|
1146
|
+
--slotted-spinner-size: var(--_content-icon-size);
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
/**
|
|
1150
|
+
* The mark of a single selection: the check at the end, in the chevron's
|
|
1151
|
+
* track, because only a node that is not a branch — or a branch the consumer
|
|
1152
|
+
* made selectable — carries it.
|
|
1153
|
+
*/
|
|
1154
|
+
[data-ui='cascader'] [data-part='node'] > [data-part='indicator'] {
|
|
1155
|
+
--slotted-icon-size: var(--_content-icon-size);
|
|
1156
|
+
|
|
1157
|
+
align-items: center;
|
|
1158
|
+
display: flex;
|
|
1159
|
+
grid-column: 5;
|
|
1160
|
+
grid-row: 1;
|
|
1161
|
+
inline-size: var(--_content-icon-size);
|
|
1162
|
+
justify-content: center;
|
|
1163
|
+
justify-self: end;
|
|
1164
|
+
margin-inline-start: var(--_column-gap);
|
|
1165
|
+
opacity: 0;
|
|
1166
|
+
scale: 0.8;
|
|
1167
|
+
transition:
|
|
1168
|
+
opacity var(--slotted-duration-short) var(--slotted-easing-exit),
|
|
1169
|
+
scale var(--slotted-duration-short) var(--slotted-easing-exit);
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
[data-ui='cascader'] [data-part='node'][data-selected] > [data-part='indicator'] {
|
|
1173
|
+
opacity: 1;
|
|
1174
|
+
scale: 1;
|
|
1175
|
+
transition:
|
|
1176
|
+
opacity var(--slotted-duration-short) var(--slotted-easing-enter),
|
|
1177
|
+
scale var(--slotted-duration-short) var(--slotted-easing-enter);
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
/**
|
|
1181
|
+
* A multiple selection draws `checkbox`'s box in track one, as `tree` draws
|
|
1182
|
+
* it: the same square from the selection scale, the same medium edge, the
|
|
1183
|
+
* same solid ground when chosen, and the mark — a check, or the dash while
|
|
1184
|
+
* part of the branch is chosen — revealed along its stroke.
|
|
1185
|
+
*/
|
|
1186
|
+
[data-ui='cascader'][data-selection='multiple'] [data-part='node'] > [data-part='indicator'] {
|
|
1187
|
+
--_mark-inset: var(--slotted-cascader-mark-inset, 2px);
|
|
1188
|
+
--_check-border: var(--slotted-border-width-medium, 1.5px);
|
|
1189
|
+
--slotted-icon-size: calc(var(--_check-size) - 2 * var(--_mark-inset));
|
|
1190
|
+
|
|
1191
|
+
align-self: center;
|
|
1192
|
+
background-color: var(--_surface);
|
|
1193
|
+
block-size: var(--_check-size);
|
|
1194
|
+
border: var(--_check-border) solid var(--slotted-border-strong);
|
|
1195
|
+
border-radius: var(--slotted-radius-xs, 2px);
|
|
1196
|
+
box-sizing: border-box;
|
|
1197
|
+
grid-column: 1;
|
|
1198
|
+
inline-size: var(--_check-size);
|
|
1199
|
+
justify-self: start;
|
|
1200
|
+
margin-inline-end: var(--_column-gap);
|
|
1201
|
+
margin-inline-start: 0;
|
|
1202
|
+
opacity: 1;
|
|
1203
|
+
position: relative;
|
|
1204
|
+
scale: 1;
|
|
1205
|
+
transition:
|
|
1206
|
+
background-color var(--slotted-control-transition-duration)
|
|
1207
|
+
var(--slotted-control-transition-easing),
|
|
1208
|
+
border-color var(--slotted-control-transition-duration)
|
|
1209
|
+
var(--slotted-control-transition-easing);
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
[data-ui='cascader'][data-selection='multiple']
|
|
1213
|
+
[data-part='node']
|
|
1214
|
+
> [data-part='indicator']
|
|
1215
|
+
> [data-ui='icon'] {
|
|
1216
|
+
clip-path: inset(0% 100% 0% 0%);
|
|
1217
|
+
color: var(--slotted-tone-accent-on-solid);
|
|
1218
|
+
inset-block-start: calc(var(--_mark-inset) - var(--_check-border));
|
|
1219
|
+
inset-inline-start: calc(var(--_mark-inset) - var(--_check-border));
|
|
1220
|
+
opacity: 0;
|
|
1221
|
+
pointer-events: none;
|
|
1222
|
+
position: absolute;
|
|
1223
|
+
transition:
|
|
1224
|
+
clip-path var(--slotted-duration-medium) var(--slotted-control-transition-easing),
|
|
1225
|
+
opacity var(--slotted-duration-medium) var(--slotted-control-transition-easing);
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1228
|
+
[data-ui='cascader'][data-selection='multiple']
|
|
1229
|
+
[data-part='node']:is([data-selected], [data-indeterminate])
|
|
1230
|
+
> [data-part='indicator'] {
|
|
1231
|
+
background-color: var(--slotted-tone-accent-solid);
|
|
1232
|
+
border-color: var(--slotted-tone-accent-solid);
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
[data-ui='cascader'][data-selection='multiple']
|
|
1236
|
+
[data-part='node']:is([data-selected], [data-indeterminate])
|
|
1237
|
+
> [data-part='indicator']
|
|
1238
|
+
> [data-ui='icon'] {
|
|
1239
|
+
clip-path: inset(0% 0% 0% 0%);
|
|
1240
|
+
opacity: 1;
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
[data-ui='cascader'][data-selection='multiple']
|
|
1244
|
+
[data-part='node'][data-disabled]
|
|
1245
|
+
> [data-part='indicator'] {
|
|
1246
|
+
background-color: var(--slotted-disabled-background, Canvas);
|
|
1247
|
+
border-color: var(--slotted-disabled-border, GrayText);
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
/* ── Waiting, empty, status ───────────────────────────────────────────── */
|
|
1251
|
+
|
|
1252
|
+
/**
|
|
1253
|
+
* A level on its way, as the shape of the rows that are coming: three bars
|
|
1254
|
+
* the height of a node, descending in width, from `skeleton`'s sheet. The
|
|
1255
|
+
* column's `aria-busy` is what a reader hears.
|
|
1256
|
+
*/
|
|
1257
|
+
[data-ui='cascader'] [data-part='loader'] {
|
|
1258
|
+
align-items: center;
|
|
1259
|
+
display: flex;
|
|
1260
|
+
grid-column: 1 / -1;
|
|
1261
|
+
min-block-size: var(--_item-height);
|
|
1262
|
+
padding-inline: var(--_item-inset);
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
[data-ui='cascader'] [data-part='loader'] > [data-ui='skeleton'] {
|
|
1266
|
+
flex: 1 1 auto;
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
[data-ui='cascader'] [data-part='loader']:nth-child(3n + 2) > [data-ui='skeleton'] {
|
|
1270
|
+
flex: 0 1 78%;
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
[data-ui='cascader'] [data-part='loader']:nth-child(3n) > [data-ui='skeleton'] {
|
|
1274
|
+
flex: 0 1 56%;
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
/**
|
|
1278
|
+
* A level with nothing in it, a query with no answer, and a level that failed
|
|
1279
|
+
* with its retry. Centred sentences in their own bidi run, as `select`'s are,
|
|
1280
|
+
* and never narrower than a word.
|
|
1281
|
+
*/
|
|
1282
|
+
[data-ui='cascader'] :is([data-part='empty'], [data-part='status']) {
|
|
1283
|
+
align-items: center;
|
|
1284
|
+
color: var(--_muted);
|
|
1285
|
+
display: flex;
|
|
1286
|
+
flex-direction: column;
|
|
1287
|
+
gap: var(--slotted-space-2, 0.25rem);
|
|
1288
|
+
grid-column: 1 / -1;
|
|
1289
|
+
min-inline-size: min(10rem, 100%);
|
|
1290
|
+
padding-block: var(--slotted-space-5, 0.75rem);
|
|
1291
|
+
padding-inline: var(--_item-inset);
|
|
1292
|
+
text-align: center;
|
|
1293
|
+
unicode-bidi: plaintext;
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
[data-ui='cascader'] [data-part='status']:empty {
|
|
1297
|
+
display: none;
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
/* ── Forced colours ───────────────────────────────────────────────────── */
|
|
1301
|
+
|
|
1302
|
+
@media (forced-colors: active) {
|
|
1303
|
+
[data-ui='cascader'] [data-part='node'][data-current] {
|
|
1304
|
+
background-color: Highlight;
|
|
1305
|
+
color: HighlightText;
|
|
1306
|
+
forced-color-adjust: none;
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
[data-ui='cascader'] [data-part='node'][data-disabled][data-current] {
|
|
1310
|
+
background-color: Highlight;
|
|
1311
|
+
color: GrayText;
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
/* The path would lose its ground to Canvas: an outline keeps the road. */
|
|
1315
|
+
[data-ui='cascader'] [data-part='node'][data-expanded]:not([data-current]) {
|
|
1316
|
+
outline: 1px solid CanvasText;
|
|
1317
|
+
outline-offset: -1px;
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
}
|