@slotted/styles 0.1.0-beta.1 → 0.1.0-beta.11
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/package.json +1 -1
- package/src/accordion/accordion.css +10 -10
- package/src/action-bar/action-bar.css +35 -42
- package/src/action-sheet/action-sheet.css +36 -36
- package/src/alert/alert.css +43 -35
- package/src/alert/alert.tokens.json +5 -0
- package/src/app-shell/app-shell.css +356 -301
- package/src/aspect-ratio/aspect-ratio.css +9 -9
- package/src/attachment/attachment.css +91 -99
- package/src/avatar/avatar.css +71 -41
- package/src/avatar/avatar.tokens.json +7 -0
- package/src/avatar-group/avatar-group.css +21 -22
- package/src/badge/badge.css +45 -37
- package/src/badge/badge.tokens.json +5 -0
- package/src/breadcrumb/breadcrumb.css +37 -37
- package/src/button/button.css +149 -68
- package/src/button/button.tokens.json +10 -0
- package/src/button-group/button-group.css +79 -74
- package/src/button-group/button-group.tokens.json +2 -0
- package/src/calendar/calendar.css +93 -103
- package/src/card/card.css +54 -61
- package/src/carousel/carousel.css +150 -161
- package/src/cascader/cascader.css +152 -153
- package/src/cascader/cascader.tokens.json +1 -0
- package/src/chart/chart.css +242 -239
- package/src/chart/chart.tokens.json +1 -0
- package/src/checkbox/checkbox.css +119 -124
- package/src/checkbox-group/checkbox-group.css +7 -7
- package/src/code-block/code-block.css +81 -85
- package/src/collapsible/collapsible.css +69 -76
- package/src/color-picker/color-picker.css +83 -91
- package/src/column-manager/column-manager.css +106 -114
- package/src/combobox/combobox.css +132 -107
- package/src/combobox/combobox.tokens.json +1 -0
- package/src/command-palette/command-palette.css +103 -90
- package/src/command-palette/command-palette.tokens.json +1 -0
- package/src/container/container.css +24 -24
- package/src/context-menu/context-menu.css +8 -8
- package/src/currency-field/currency-field.css +210 -88
- package/src/currency-field/currency-field.tokens.json +13 -0
- package/src/dashboard-grid/dashboard-grid.css +148 -116
- package/src/data-grid/data-grid.css +535 -470
- package/src/data-grid/data-grid.tokens.json +4 -0
- package/src/data-list/data-list.css +81 -70
- package/src/data-list/data-list.tokens.json +2 -1
- package/src/date-field/date-field.css +55 -52
- package/src/date-field/date-field.tokens.json +1 -0
- package/src/date-picker/date-picker.css +40 -42
- package/src/date-range-picker/date-range-picker.css +114 -118
- package/src/datetime-field/datetime-field.css +78 -80
- package/src/datetime-field/datetime-field.tokens.json +1 -0
- package/src/datetime-picker/datetime-picker.css +61 -63
- package/src/datetime-range-picker/datetime-range-picker.css +149 -156
- package/src/description-list/description-list.css +61 -64
- package/src/detail-panel/detail-panel.css +86 -71
- package/src/detail-panel/detail-panel.tokens.json +2 -0
- package/src/dialog/dialog.css +372 -153
- package/src/dialog/dialog.tokens.json +6 -0
- package/src/divider/divider.css +18 -18
- package/src/drawer/drawer.css +205 -210
- package/src/drawer/drawer.tokens.json +1 -0
- package/src/entity-picker/entity-picker.css +238 -241
- package/src/entity-picker/entity-picker.tokens.json +1 -0
- package/src/event-calendar/event-calendar.css +343 -385
- package/src/field/field.css +74 -78
- package/src/field-group/field-group.css +22 -25
- package/src/filter-bar/filter-bar.css +193 -209
- package/src/form/form.css +34 -24
- package/src/form/form.tokens.json +1 -0
- package/src/fullscreen/fullscreen.css +24 -25
- package/src/grid/grid.css +28 -28
- package/src/highlight/highlight.css +6 -6
- package/src/hover-card/hover-card.css +6 -6
- package/src/icon/icon.css +19 -15
- package/src/icon/icon.tokens.json +1 -0
- package/src/image/image.css +39 -39
- package/src/import-export-center/import-export-center.css +135 -156
- package/src/inline/inline.css +27 -27
- package/src/inline-message/inline-message.css +52 -28
- package/src/inline-message/inline-message.tokens.json +4 -0
- package/src/kbd/kbd.css +30 -26
- package/src/link/link.css +15 -15
- package/src/list/list.css +44 -17
- package/src/list/list.tokens.json +4 -0
- package/src/list-item/list-item.css +80 -66
- package/src/list-item/list-item.tokens.json +7 -0
- package/src/listbox/listbox.css +56 -59
- package/src/loading-overlay/loading-overlay.css +75 -92
- package/src/markdown/markdown.css +17 -17
- package/src/menu/menu.css +83 -63
- package/src/menubar/menubar.css +13 -13
- package/src/message/message.css +182 -202
- package/src/message/message.tokens.json +5 -0
- package/src/message-scroller/message-scroller.css +41 -42
- package/src/multi-select/multi-select.css +152 -145
- package/src/multi-select/multi-select.tokens.json +1 -0
- package/src/navigation-menu/navigation-menu.css +167 -188
- package/src/notification-center/notification-center.css +140 -148
- package/src/notification-center/notification-center.tokens.json +3 -0
- package/src/number-field/number-field.css +84 -83
- package/src/number-field/number-field.tokens.json +1 -0
- package/src/otp-input/otp-input.css +67 -57
- package/src/otp-input/otp-input.tokens.json +1 -0
- package/src/page/page.css +39 -23
- package/src/page/page.tokens.json +1 -0
- package/src/page-header/page-header.css +323 -283
- package/src/page-header/page-header.tokens.json +5 -0
- package/src/pagination/pagination.css +68 -72
- package/src/popover/popover.css +40 -49
- package/src/progress-indicator/progress-indicator.css +177 -120
- package/src/progress-indicator/progress-indicator.tokens.json +1 -1
- package/src/prompt-composer/prompt-composer.css +221 -102
- package/src/prompt-composer/prompt-composer.tokens.json +15 -0
- package/src/prose/prose.css +71 -75
- package/src/radio-group/radio-group.css +98 -103
- package/src/rating/rating.css +136 -132
- package/src/rating/rating.tokens.json +1 -0
- package/src/result-state/result-state.css +74 -77
- package/src/runtime-properties.mjs +2 -0
- package/src/saved-views/saved-views.css +41 -47
- package/src/scroll-area/scroll-area.css +39 -32
- package/src/section/section.css +161 -41
- package/src/section/section.tokens.json +7 -2
- package/src/segmented-control/segmented-control.css +254 -97
- package/src/segmented-control/segmented-control.tokens.json +15 -11
- package/src/select/select.css +118 -117
- package/src/select/select.tokens.json +1 -0
- package/src/side-navigation/side-navigation.css +179 -182
- package/src/side-navigation/side-navigation.tokens.json +1 -0
- package/src/skeleton/skeleton.css +47 -48
- package/src/slider/slider.css +86 -88
- package/src/sparkline/sparkline.css +62 -40
- package/src/sparkline/sparkline.tokens.json +2 -0
- package/src/spinner/spinner.css +83 -180
- package/src/spinner/spinner.tokens.json +0 -1
- package/src/split-button/split-button.css +30 -31
- package/src/split-button/split-button.tokens.json +1 -0
- package/src/splitter/splitter.css +35 -35
- package/src/stack/stack.css +24 -24
- package/src/stat-card/stat-card.css +341 -224
- package/src/stat-card/stat-card.tokens.json +3 -0
- package/src/status-indicator/status-indicator.css +28 -28
- package/src/stepper/stepper.css +58 -62
- package/src/switch/switch.css +86 -92
- package/src/table/table.css +310 -165
- package/src/table/table.tokens.json +6 -0
- package/src/table-of-contents/table-of-contents.css +51 -54
- package/src/tabs/tabs.css +337 -302
- package/src/tabs/tabs.tokens.json +8 -5
- package/src/tag/tag.css +79 -71
- package/src/tag/tag.tokens.json +9 -0
- package/src/tags-input/tags-input.css +145 -82
- package/src/tags-input/tags-input.tokens.json +7 -1
- package/src/text-field/text-field.css +132 -136
- package/src/text-field/text-field.tokens.json +1 -0
- package/src/textarea/textarea.css +31 -28
- package/src/textarea/textarea.tokens.json +1 -0
- package/src/time-field/time-field.css +72 -69
- package/src/time-field/time-field.tokens.json +1 -0
- package/src/time-picker/time-picker.css +56 -58
- package/src/time-range-picker/time-range-picker.css +126 -133
- package/src/timeline/timeline.css +254 -266
- package/src/timeline/timeline.tokens.json +5 -0
- package/src/toast/toast.css +108 -90
- package/src/toast/toast.tokens.json +6 -0
- package/src/toggle/toggle.css +62 -25
- package/src/toggle/toggle.tokens.json +8 -0
- package/src/toggle-group/toggle-group.css +106 -60
- package/src/toggle-group/toggle-group.tokens.json +10 -0
- package/src/toolbar/toolbar.css +30 -35
- package/src/tooltip/tooltip.css +26 -26
- package/src/top-navigation/top-navigation.css +243 -259
- package/src/tour/tour.css +51 -60
- package/src/transfer/transfer.css +160 -164
- package/src/tree/tree.css +103 -111
- package/src/typography/typography.css +40 -36
- package/src/typography/typography.tokens.json +1 -0
- package/src/upload/upload.css +224 -224
- package/src/visually-hidden/visually-hidden.css +1 -1
- package/src/wizard/wizard.css +185 -197
package/src/tabs/tabs.css
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* │ panel │
|
|
17
17
|
* └──────────────────────────────────────────────────┘
|
|
18
18
|
*/
|
|
19
|
-
[data-ui
|
|
19
|
+
[data-ui-tabs] {
|
|
20
20
|
/**
|
|
21
21
|
* The control scales, read once at the root, so `size` and the three
|
|
22
22
|
* densities are one decision each rather than one per rule.
|
|
@@ -47,23 +47,35 @@
|
|
|
47
47
|
min(calc(var(--_icon-size) + 2 * var(--slotted-space-2, 0.25rem)), var(--_inner-size))
|
|
48
48
|
);
|
|
49
49
|
--_dismiss-overhang: calc((var(--_dismiss-size) - var(--_icon-size)) / 2);
|
|
50
|
-
|
|
50
|
+
/**
|
|
51
|
+
* The marker: one bar the list draws under the selected tab, and the hover
|
|
52
|
+
* bar under the tab the pointer is on, in the same geometry — the tab's
|
|
53
|
+
* content box, a pill just above the list's edge. It is never thinner than the
|
|
54
|
+
* thick border width, the floor the high-contrast scheme keeps for a mark
|
|
55
|
+
* that carries state, and its thickness, its rounding and its inset are
|
|
56
|
+
* tokens of their own: tied to the thick border width, a theme could not
|
|
57
|
+
* thicken the marker without thickening sixty other rules.
|
|
58
|
+
*/
|
|
59
|
+
--_marker-size: max(
|
|
60
|
+
var(--slotted-tabs-marker-size, 3px),
|
|
61
|
+
var(--slotted-border-width-thick, 2px)
|
|
62
|
+
);
|
|
63
|
+
--_marker-radius: var(--slotted-tabs-marker-radius, var(--slotted-radius-full, 9999px));
|
|
64
|
+
--_marker-inset: var(--slotted-tabs-marker-inset, var(--_padding-inline));
|
|
65
|
+
/**
|
|
66
|
+
* The gap between the bars and the list's edge: the selected marker and the
|
|
67
|
+
* hover bar stand this far above the track, so the line reads as a line and
|
|
68
|
+
* the bar as a mark on it. An inset rather than a transform, because the
|
|
69
|
+
* marker's `translate` is its slide between tabs.
|
|
70
|
+
*/
|
|
71
|
+
--_marker-offset: var(--slotted-tabs-marker-offset, 1px);
|
|
72
|
+
--_track-color: var(--slotted-tabs-track-color, var(--slotted-border-subtle, ButtonBorder));
|
|
51
73
|
/**
|
|
52
74
|
* The length of the fade a scrolling list takes at an edge that has more
|
|
53
75
|
* behind it, read once here so the five mask gradients below state a
|
|
54
76
|
* length and no public property of their own.
|
|
55
77
|
*/
|
|
56
78
|
--_fade: var(--slotted-tabs-fade-size, var(--slotted-space-6, 1rem));
|
|
57
|
-
/**
|
|
58
|
-
* Which way the selection travelled, resolved into a transform origin. The
|
|
59
|
-
* marker of the tab being left collapses toward the direction of travel
|
|
60
|
-
* and the marker of the tab being entered grows from the side the reader
|
|
61
|
-
* came from, so the pair reads as one bar moving. Nothing is measured:
|
|
62
|
-
* every surveyed indicator reads the active tab's box, which is why Base UI
|
|
63
|
-
* ships `renderBeforeHydration` and Ark UI a `setIndicatorRect`.
|
|
64
|
-
*/
|
|
65
|
-
--_marker-origin: 50%;
|
|
66
|
-
--_marker-origin-selected: 50%;
|
|
67
79
|
|
|
68
80
|
/**
|
|
69
81
|
* No column gap on the grid itself: three gaps stood around two empty
|
|
@@ -83,7 +95,7 @@
|
|
|
83
95
|
row-gap: var(--slotted-tabs-gap, var(--slotted-space-6, 1rem));
|
|
84
96
|
}
|
|
85
97
|
|
|
86
|
-
[data-ui
|
|
98
|
+
[data-ui-tabs][data-size='sm'] {
|
|
87
99
|
--_height: var(--slotted-control-height-sm, 30px);
|
|
88
100
|
--_font-size: var(--slotted-control-font-size-sm, 0.8125rem);
|
|
89
101
|
--_padding-inline: var(--slotted-control-padding-inline-sm, 0.625rem);
|
|
@@ -92,7 +104,7 @@
|
|
|
92
104
|
--_inner-size: var(--slotted-control-inner-size-sm, 22px);
|
|
93
105
|
}
|
|
94
106
|
|
|
95
|
-
[data-ui
|
|
107
|
+
[data-ui-tabs][data-size='lg'] {
|
|
96
108
|
--_height: var(--slotted-control-height-lg, 40px);
|
|
97
109
|
--_font-size: var(--slotted-control-font-size-lg, 1rem);
|
|
98
110
|
--_padding-inline: var(--slotted-control-padding-inline-lg, 1rem);
|
|
@@ -111,7 +123,10 @@
|
|
|
111
123
|
* the panel: the distance the row gap keeps in a horizontal family. Without
|
|
112
124
|
* it the panel's first letter touched the track on the list's end edge.
|
|
113
125
|
*/
|
|
114
|
-
[data-ui
|
|
126
|
+
[data-ui-tabs][data-orientation='vertical'] {
|
|
127
|
+
/* The inset runs along the block axis, where a tab has no padding. */
|
|
128
|
+
--_marker-inset: var(--slotted-tabs-marker-inset, 0px);
|
|
129
|
+
|
|
115
130
|
column-gap: var(--slotted-tabs-gap, var(--slotted-space-6, 1rem));
|
|
116
131
|
grid-template-columns: auto minmax(0, 1fr);
|
|
117
132
|
grid-template-rows: auto auto;
|
|
@@ -124,7 +139,7 @@
|
|
|
124
139
|
* which is on the border box and therefore does not scroll with the tabs —
|
|
125
140
|
* a track drawn on the content would slide away with the first tab.
|
|
126
141
|
*/
|
|
127
|
-
[data-ui
|
|
142
|
+
[data-ui-tabs] > [data-part-list] {
|
|
128
143
|
align-items: stretch;
|
|
129
144
|
display: flex;
|
|
130
145
|
gap: var(--slotted-tabs-list-gap, var(--_list-gap));
|
|
@@ -140,6 +155,8 @@
|
|
|
140
155
|
overflow-x: auto;
|
|
141
156
|
overflow-y: hidden;
|
|
142
157
|
overscroll-behavior-inline: contain;
|
|
158
|
+
/* The containing block of the marker, which scrolls with the tabs. */
|
|
159
|
+
position: relative;
|
|
143
160
|
/**
|
|
144
161
|
* The platform's scrollbar is the affordance until the family draws its
|
|
145
162
|
* own. It is hidden only once `data-overflowing` says the paging controls
|
|
@@ -149,13 +166,23 @@
|
|
|
149
166
|
scrollbar-width: thin;
|
|
150
167
|
}
|
|
151
168
|
|
|
152
|
-
[data-ui
|
|
169
|
+
[data-ui-tabs][data-overflowing] > [data-part-list] {
|
|
153
170
|
scrollbar-width: none;
|
|
154
171
|
}
|
|
155
172
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
173
|
+
/**
|
|
174
|
+
* The track is an inset shadow on the list's own padding rather than its
|
|
175
|
+
* border. The list is a scroll container, which clips what it draws to its
|
|
176
|
+
* padding box, so a marker standing over a border was cut along it; inside
|
|
177
|
+
* the padding the marker lies over the line, flush with the list's edge. The
|
|
178
|
+
* shadow is the box's, so the line does not scroll with the tabs.
|
|
179
|
+
*/
|
|
180
|
+
[data-ui-tabs][data-variant='line'][data-track='line'] > [data-part-list] {
|
|
181
|
+
/* How far the hover bar reaches past an item to stand on the track. */
|
|
182
|
+
--_track-reach: var(--_track-size);
|
|
183
|
+
|
|
184
|
+
box-shadow: inset 0 calc(-1 * var(--_track-size)) 0 var(--_track-color);
|
|
185
|
+
padding-block-end: var(--_track-size);
|
|
159
186
|
}
|
|
160
187
|
|
|
161
188
|
/**
|
|
@@ -169,39 +196,25 @@
|
|
|
169
196
|
* variant for the same case, which is a second family's worth of paint to
|
|
170
197
|
* remove one line.
|
|
171
198
|
*
|
|
172
|
-
* The marker then sits on the
|
|
173
|
-
*
|
|
174
|
-
*
|
|
199
|
+
* The marker then sits on the list's own edge, which is the items' edge, so
|
|
200
|
+
* it lands on the line the page already drew. Where that line is is the
|
|
201
|
+
* page's business: the family stops at its own box.
|
|
175
202
|
*/
|
|
176
|
-
[data-ui='tabs'][data-track='none'] > :where([data-part='list']) > [data-part='item']::before,
|
|
177
|
-
[data-ui='tabs'][data-track='none'] > :where([data-part='list']) > [data-part='item']::after {
|
|
178
|
-
inset-block-end: 0;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
[data-ui='tabs'][data-track='none'][data-orientation='vertical']
|
|
182
|
-
> :where([data-part='list'])
|
|
183
|
-
> [data-part='item']::before,
|
|
184
|
-
[data-ui='tabs'][data-track='none'][data-orientation='vertical']
|
|
185
|
-
> :where([data-part='list'])
|
|
186
|
-
> [data-part='item']::after {
|
|
187
|
-
inset-block-end: auto;
|
|
188
|
-
inset-inline-end: 0;
|
|
189
|
-
}
|
|
190
203
|
|
|
191
204
|
/**
|
|
192
205
|
* A column of labels reads down its own start edge. Centring them is what the
|
|
193
206
|
* horizontal rule wants — a row of equal shares has a middle — and in a
|
|
194
207
|
* column it produces a ragged left edge nobody can scan.
|
|
195
208
|
*/
|
|
196
|
-
[data-ui
|
|
197
|
-
> :where([data-part
|
|
198
|
-
> :where([data-part
|
|
199
|
-
> [data-part
|
|
209
|
+
[data-ui-tabs][data-orientation='vertical']
|
|
210
|
+
> :where([data-part-list])
|
|
211
|
+
> :where([data-part-item])
|
|
212
|
+
> [data-part-tab] {
|
|
200
213
|
justify-content: start;
|
|
201
214
|
text-align: start;
|
|
202
215
|
}
|
|
203
216
|
|
|
204
|
-
[data-ui
|
|
217
|
+
[data-ui-tabs][data-orientation='vertical'] > [data-part-list] {
|
|
205
218
|
flex-direction: column;
|
|
206
219
|
grid-column: 1;
|
|
207
220
|
grid-row: 1;
|
|
@@ -209,11 +222,17 @@
|
|
|
209
222
|
overflow-y: auto;
|
|
210
223
|
}
|
|
211
224
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
225
|
+
/* A shadow takes no logical offset, so the line's side is mirrored by hand. */
|
|
226
|
+
[data-ui-tabs][data-orientation='vertical'][data-variant='line'][data-track='line']
|
|
227
|
+
> [data-part-list] {
|
|
228
|
+
box-shadow: inset calc(-1 * var(--_track-size)) 0 0 var(--_track-color);
|
|
229
|
+
padding-block-end: 0;
|
|
230
|
+
padding-inline-end: var(--_track-size);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
[data-ui-tabs][data-orientation='vertical'][data-variant='line'][data-track='line']:dir(rtl)
|
|
234
|
+
> [data-part-list] {
|
|
235
|
+
box-shadow: inset var(--_track-size) 0 0 var(--_track-color);
|
|
217
236
|
}
|
|
218
237
|
|
|
219
238
|
/**
|
|
@@ -225,7 +244,7 @@
|
|
|
225
244
|
* label is what gives way, and it is the only place a horizontal label ever
|
|
226
245
|
* truncates.
|
|
227
246
|
*/
|
|
228
|
-
[data-ui
|
|
247
|
+
[data-ui-tabs][data-fit='equal'] > [data-part-list] {
|
|
229
248
|
display: grid;
|
|
230
249
|
grid-auto-columns: minmax(0, 1fr);
|
|
231
250
|
grid-auto-flow: column;
|
|
@@ -234,15 +253,15 @@
|
|
|
234
253
|
}
|
|
235
254
|
|
|
236
255
|
/** Equal shares are shares of the line, so each item takes the one it is given. */
|
|
237
|
-
[data-ui
|
|
256
|
+
[data-ui-tabs][data-fit='equal'] > :where([data-part-list]) > [data-part-item] {
|
|
238
257
|
min-inline-size: 0;
|
|
239
258
|
}
|
|
240
259
|
|
|
241
|
-
[data-ui
|
|
242
|
-
> :where([data-part
|
|
243
|
-
> :where([data-part
|
|
244
|
-
> :where([data-part
|
|
245
|
-
> [data-part
|
|
260
|
+
[data-ui-tabs][data-fit='equal']
|
|
261
|
+
> :where([data-part-list])
|
|
262
|
+
> :where([data-part-item])
|
|
263
|
+
> :where([data-part-tab])
|
|
264
|
+
> [data-part-label] {
|
|
246
265
|
overflow: hidden;
|
|
247
266
|
text-overflow: ellipsis;
|
|
248
267
|
white-space: nowrap;
|
|
@@ -251,12 +270,11 @@
|
|
|
251
270
|
/* ── One tab, and the box that holds it ───────────────────────────────── */
|
|
252
271
|
|
|
253
272
|
/**
|
|
254
|
-
* The item is presentational, and it exists
|
|
255
|
-
*
|
|
256
|
-
*
|
|
257
|
-
* rather than only the label.
|
|
273
|
+
* The item is presentational, and it exists because a `button` may not
|
|
274
|
+
* contain a `button`: a dismissible tab needs a box for its second control.
|
|
275
|
+
* It also carries the hover bar, under the tab and not the control.
|
|
258
276
|
*/
|
|
259
|
-
[data-ui
|
|
277
|
+
[data-ui-tabs] > :where([data-part-list]) > [data-part-item] {
|
|
260
278
|
align-items: stretch;
|
|
261
279
|
display: grid;
|
|
262
280
|
grid-auto-flow: column;
|
|
@@ -270,7 +288,7 @@
|
|
|
270
288
|
position: relative;
|
|
271
289
|
}
|
|
272
290
|
|
|
273
|
-
[data-ui
|
|
291
|
+
[data-ui-tabs] > :where([data-part-list]) > :where([data-part-item]) > [data-part-tab] {
|
|
274
292
|
align-items: center;
|
|
275
293
|
appearance: none;
|
|
276
294
|
background-color: transparent;
|
|
@@ -302,10 +320,10 @@
|
|
|
302
320
|
* inset there: the control carries it instead, measured from the mark rather
|
|
303
321
|
* than from the box.
|
|
304
322
|
*/
|
|
305
|
-
[data-ui
|
|
306
|
-
> :where([data-part
|
|
307
|
-
> [data-part
|
|
308
|
-
> [data-part
|
|
323
|
+
[data-ui-tabs]
|
|
324
|
+
> :where([data-part-list])
|
|
325
|
+
> [data-part-item]:has(> [data-part-dismiss])
|
|
326
|
+
> [data-part-tab] {
|
|
309
327
|
padding-inline-end: 0;
|
|
310
328
|
}
|
|
311
329
|
|
|
@@ -315,11 +333,11 @@
|
|
|
315
333
|
* needs something to be aligned against, and a label in another script needs
|
|
316
334
|
* to read its own way inside a page that reads the other.
|
|
317
335
|
*/
|
|
318
|
-
[data-ui
|
|
319
|
-
> :where([data-part
|
|
320
|
-
> :where([data-part
|
|
321
|
-
> :where([data-part
|
|
322
|
-
> [data-part
|
|
336
|
+
[data-ui-tabs]
|
|
337
|
+
> :where([data-part-list])
|
|
338
|
+
> :where([data-part-item])
|
|
339
|
+
> :where([data-part-tab])
|
|
340
|
+
> [data-part-label] {
|
|
323
341
|
min-inline-size: 0;
|
|
324
342
|
unicode-bidi: plaintext;
|
|
325
343
|
}
|
|
@@ -331,11 +349,11 @@
|
|
|
331
349
|
* gives way. An icon box reads `--slotted-icon-size` from the slot, so it
|
|
332
350
|
* takes the tab's icon step.
|
|
333
351
|
*/
|
|
334
|
-
[data-ui
|
|
335
|
-
> :where([data-part
|
|
336
|
-
> :where([data-part
|
|
337
|
-
> :where([data-part
|
|
338
|
-
> :is([data-part
|
|
352
|
+
[data-ui-tabs]
|
|
353
|
+
> :where([data-part-list])
|
|
354
|
+
> :where([data-part-item])
|
|
355
|
+
> :where([data-part-tab])
|
|
356
|
+
> :is([data-part-start], [data-part-end]) {
|
|
339
357
|
--slotted-icon-size: var(--_icon-size);
|
|
340
358
|
|
|
341
359
|
align-items: center;
|
|
@@ -354,10 +372,10 @@
|
|
|
354
372
|
* meeting a line that runs under all of them. What that variant says on
|
|
355
373
|
* hover is where the mark would go, and it says it on the item, below.
|
|
356
374
|
*/
|
|
357
|
-
[data-ui
|
|
358
|
-
> :where([data-part
|
|
359
|
-
> :where([data-part
|
|
360
|
-
> [data-part
|
|
375
|
+
[data-ui-tabs]
|
|
376
|
+
> :where([data-part-list])
|
|
377
|
+
> :where([data-part-item])
|
|
378
|
+
> [data-part-tab]:not(:disabled):not([aria-selected='true']):hover {
|
|
361
379
|
color: var(--slotted-tabs-hover-color, var(--slotted-text, CanvasText));
|
|
362
380
|
}
|
|
363
381
|
|
|
@@ -367,20 +385,20 @@
|
|
|
367
385
|
* and goes one step further on press is what a segmented control does —
|
|
368
386
|
* the fill has a box to belong to and no line to meet.
|
|
369
387
|
*/
|
|
370
|
-
[data-ui
|
|
371
|
-
> :where([data-part
|
|
372
|
-
> :where([data-part
|
|
373
|
-
> [data-part
|
|
388
|
+
[data-ui-tabs][data-variant='contained']
|
|
389
|
+
> :where([data-part-list])
|
|
390
|
+
> :where([data-part-item])
|
|
391
|
+
> [data-part-tab]:not(:disabled):not([aria-selected='true']):hover {
|
|
374
392
|
background-color: var(
|
|
375
393
|
--slotted-tabs-hover-background,
|
|
376
394
|
var(--slotted-tone-secondary-subtle-hover)
|
|
377
395
|
);
|
|
378
396
|
}
|
|
379
397
|
|
|
380
|
-
[data-ui
|
|
381
|
-
> :where([data-part
|
|
382
|
-
> :where([data-part
|
|
383
|
-
> [data-part
|
|
398
|
+
[data-ui-tabs][data-variant='contained']
|
|
399
|
+
> :where([data-part-list])
|
|
400
|
+
> :where([data-part-item])
|
|
401
|
+
> [data-part-tab]:not(:disabled):active {
|
|
384
402
|
background-color: var(
|
|
385
403
|
--slotted-tabs-active-background,
|
|
386
404
|
var(--slotted-tone-secondary-subtle-active)
|
|
@@ -398,10 +416,10 @@
|
|
|
398
416
|
* focus became one blue shape that said neither of the two things — the
|
|
399
417
|
* capture is what showed it.
|
|
400
418
|
*/
|
|
401
|
-
[data-ui
|
|
402
|
-
> :where([data-part
|
|
403
|
-
> :where([data-part
|
|
404
|
-
> [data-part
|
|
419
|
+
[data-ui-tabs]
|
|
420
|
+
> :where([data-part-list])
|
|
421
|
+
> :where([data-part-item])
|
|
422
|
+
> [data-part-tab]:focus-visible {
|
|
405
423
|
outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
|
|
406
424
|
outline-offset: calc(-1 * (var(--slotted-focus-ring-offset, 2px) + var(--_marker-size)));
|
|
407
425
|
}
|
|
@@ -412,25 +430,19 @@
|
|
|
412
430
|
* and nothing about it reaches the edge the scroller clips at — and an inset
|
|
413
431
|
* ring on a twenty-four pixel box would be drawn through the mark.
|
|
414
432
|
*/
|
|
415
|
-
[data-ui
|
|
416
|
-
> :where([data-part
|
|
417
|
-
> :where([data-part
|
|
418
|
-
> [data-part
|
|
433
|
+
[data-ui-tabs]
|
|
434
|
+
> :where([data-part-list])
|
|
435
|
+
> :where([data-part-item])
|
|
436
|
+
> [data-part-dismiss]:focus-visible {
|
|
419
437
|
outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
|
|
420
438
|
outline-offset: var(--slotted-focus-ring-offset, 2px);
|
|
421
439
|
}
|
|
422
440
|
|
|
423
|
-
[data-ui
|
|
424
|
-
> :where([data-part='list'])
|
|
425
|
-
> [data-part='item'][data-selected]
|
|
426
|
-
> [data-part='tab'] {
|
|
441
|
+
[data-ui-tabs] > :where([data-part-list]) > [data-part-item][data-selected] > [data-part-tab] {
|
|
427
442
|
color: var(--slotted-tabs-selected-color, var(--slotted-tone-accent-text));
|
|
428
443
|
}
|
|
429
444
|
|
|
430
|
-
[data-ui
|
|
431
|
-
> :where([data-part='list'])
|
|
432
|
-
> :where([data-part='item'])
|
|
433
|
-
> [data-part='tab']:disabled {
|
|
445
|
+
[data-ui-tabs] > :where([data-part-list]) > :where([data-part-item]) > [data-part-tab]:disabled {
|
|
434
446
|
color: var(--slotted-disabled-foreground, GrayText);
|
|
435
447
|
cursor: not-allowed;
|
|
436
448
|
}
|
|
@@ -438,132 +450,160 @@
|
|
|
438
450
|
/* ── The marker ───────────────────────────────────────────────────────── */
|
|
439
451
|
|
|
440
452
|
/**
|
|
441
|
-
*
|
|
442
|
-
*
|
|
443
|
-
*
|
|
444
|
-
*
|
|
445
|
-
*
|
|
446
|
-
*
|
|
447
|
-
* lines are one line rather than a hairline with a thicker line beside it.
|
|
453
|
+
* One bar, drawn by the list rather than by each item, that slides from the
|
|
454
|
+
* tab being left to the tab being entered: a mark per item can only appear
|
|
455
|
+
* or scale from an edge, and one mark moving is what says the selection
|
|
456
|
+
* moved. The binding creates it with `createIndicator` from
|
|
457
|
+
* `@slotted/core/measure`, which writes the selected tab's start and length
|
|
458
|
+
* in the list's scroll coordinates; everything else is decided here.
|
|
448
459
|
*
|
|
449
|
-
*
|
|
450
|
-
*
|
|
451
|
-
*
|
|
452
|
-
*
|
|
453
|
-
*
|
|
454
|
-
*
|
|
455
|
-
*
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
460
|
+
* It spans the tab's content box — the icon and the label — through
|
|
461
|
+
* `--slotted-tabs-marker-inset`, which defaults to the tab's own inline
|
|
462
|
+
* padding, and never the closing control: a tab followed by one gives up its
|
|
463
|
+
* end padding, so the end inset is nought there. Below the width of a short
|
|
464
|
+
* label it keeps a minimum length, centred on the content. It stands
|
|
465
|
+
* `--slotted-tabs-marker-offset` above the list's edge, over the track, and the axes are physical in this one rule
|
|
466
|
+
* because the measurement is: the position is from the list's left edge.
|
|
467
|
+
* At rest the bar is laid out by `left` and `inline-size`, so its ends keep
|
|
468
|
+
* their radius; it slides by `translate` and `scale` together, both on the
|
|
469
|
+
* compositor, so both edges advance in the same frame. A composited
|
|
470
|
+
* `translate` beside a main-thread `inline-size` drifted apart while the
|
|
471
|
+
* panel rendered, and a slide of `left` and `inline-size` lost every frame
|
|
472
|
+
* to a panel rendering on the same thread.
|
|
473
|
+
*/
|
|
474
|
+
[data-ui-tabs] > :where([data-part-list]) > [data-part-marker] {
|
|
475
|
+
--_start-inset: var(--_marker-inset);
|
|
476
|
+
--_end-inset: var(--_marker-inset);
|
|
477
|
+
--_left-inset: var(--_start-inset);
|
|
478
|
+
--_span: calc(var(--_indicator-length, 0px) - var(--_start-inset) - var(--_end-inset));
|
|
479
|
+
--_length: max(var(--slotted-space-6, 1rem), var(--_span));
|
|
480
|
+
|
|
481
|
+
background-color: var(--slotted-tabs-marker-color, var(--slotted-tone-accent-solid));
|
|
461
482
|
block-size: var(--_marker-size);
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
inset-
|
|
465
|
-
|
|
483
|
+
border-radius: var(--_marker-radius);
|
|
484
|
+
inline-size: var(--_length);
|
|
485
|
+
inset-block-end: calc(var(--_marker-lift, 0px) + var(--_marker-offset));
|
|
486
|
+
left: calc(
|
|
487
|
+
var(--_indicator-start, 0px) + var(--_left-inset) + (var(--_span) - var(--_length)) / 2
|
|
488
|
+
);
|
|
466
489
|
pointer-events: none;
|
|
467
490
|
position: absolute;
|
|
468
491
|
}
|
|
469
492
|
|
|
470
|
-
[data-ui
|
|
471
|
-
|
|
472
|
-
than shouts, as the mark beside it already does. */
|
|
473
|
-
background-color: var(--slotted-tabs-hover-marker-color, var(--slotted-border-strong));
|
|
474
|
-
transition:
|
|
475
|
-
background-color var(--slotted-control-transition-duration)
|
|
476
|
-
var(--slotted-control-transition-easing),
|
|
477
|
-
opacity var(--slotted-control-transition-duration) var(--slotted-control-transition-easing);
|
|
493
|
+
[data-ui-tabs]:dir(rtl) > :where([data-part-list]) > [data-part-marker] {
|
|
494
|
+
--_left-inset: var(--_end-inset);
|
|
478
495
|
}
|
|
479
496
|
|
|
480
|
-
[data-ui
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
transition:
|
|
485
|
-
opacity var(--slotted-control-transition-duration) var(--slotted-control-transition-easing),
|
|
486
|
-
transform var(--slotted-control-transition-duration) var(--slotted-control-transition-easing);
|
|
497
|
+
[data-ui-tabs]:not([data-orientation='vertical'])
|
|
498
|
+
> [data-part-list]:has(> [data-part-item][data-selected] > [data-part-dismiss])
|
|
499
|
+
> [data-part-marker] {
|
|
500
|
+
--_end-inset: 0px;
|
|
487
501
|
}
|
|
488
502
|
|
|
489
|
-
[data-ui
|
|
490
|
-
|
|
491
|
-
> [data-part='item']:not([data-selected]):has(
|
|
492
|
-
> [data-part='tab']:not(:disabled):hover
|
|
493
|
-
)::before {
|
|
494
|
-
opacity: 1;
|
|
503
|
+
[data-ui-tabs] > :where([data-part-list]) > [data-part-marker][hidden] {
|
|
504
|
+
display: none;
|
|
495
505
|
}
|
|
496
506
|
|
|
497
|
-
/**
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
507
|
+
/**
|
|
508
|
+
* It slides only when the selection moves: `createIndicator` places the bar
|
|
509
|
+
* on the new tab, writes the shift and the scale from the box it was drawn
|
|
510
|
+
* in, and raises `data-moving`, which starts the slide from there back to
|
|
511
|
+
* nought; a re-measurement of the same tab drops it, so the first position,
|
|
512
|
+
* a font arriving and a resized list place the bar without motion. The slide
|
|
513
|
+
* takes the medium duration on a curve that starts and ends slowly,
|
|
514
|
+
* `--slotted-tabs-marker-easing`: the control duration on the theme's
|
|
515
|
+
* decelerating curve covered a third of the distance in its first frame and
|
|
516
|
+
* read as a jump. Under reduced motion it jumps.
|
|
517
|
+
*/
|
|
518
|
+
[data-ui-tabs] > :where([data-part-list]) > [data-part-marker][data-moving] {
|
|
519
|
+
--_marker-easing: var(--slotted-tabs-marker-easing, cubic-bezier(0.4, 0, 0.2, 1));
|
|
520
|
+
|
|
521
|
+
animation: slotted-tabs-marker-slide var(--slotted-duration-medium) var(--_marker-easing);
|
|
522
|
+
transform-origin: 0 0;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
@keyframes slotted-tabs-marker-slide {
|
|
526
|
+
from {
|
|
527
|
+
translate: var(--_indicator-shift, 0px 0px);
|
|
528
|
+
scale: var(--_indicator-scale, 1 1);
|
|
529
|
+
}
|
|
504
530
|
}
|
|
505
531
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
532
|
+
@media (prefers-reduced-motion: reduce) {
|
|
533
|
+
[data-ui-tabs] > :where([data-part-list]) > [data-part-marker][data-moving] {
|
|
534
|
+
animation: none;
|
|
535
|
+
}
|
|
510
536
|
}
|
|
511
537
|
|
|
512
538
|
/**
|
|
513
|
-
*
|
|
514
|
-
*
|
|
515
|
-
*
|
|
516
|
-
*
|
|
517
|
-
*
|
|
539
|
+
* The hover bar: the marker's geometry under the tab the pointer is on, in a
|
|
540
|
+
* neutral at a reduced opacity, saying where the mark would go. It is drawn
|
|
541
|
+
* on the item, and it fades rather than slides — a bar that travelled on
|
|
542
|
+
* every pass of the pointer would be the selection's motion with nothing
|
|
543
|
+
* selected. It reaches past the item by the track's width to lie on it, and
|
|
544
|
+
* stops at the tab where a closing control follows: that control is the
|
|
545
|
+
* tab's inline padding on either side of the glyph.
|
|
518
546
|
*/
|
|
519
|
-
[data-ui
|
|
520
|
-
|
|
521
|
-
--_marker-
|
|
547
|
+
[data-ui-tabs] > :where([data-part-list]) > [data-part-item]::before {
|
|
548
|
+
background-color: var(--slotted-tabs-hover-marker-color, var(--slotted-border-strong));
|
|
549
|
+
block-size: var(--_marker-size);
|
|
550
|
+
border-radius: var(--_marker-radius);
|
|
551
|
+
content: '';
|
|
552
|
+
inset-block-end: calc(var(--_marker-offset) - var(--_track-reach, 0px));
|
|
553
|
+
inset-inline: var(--_marker-inset);
|
|
554
|
+
min-inline-size: var(--slotted-space-6, 1rem);
|
|
555
|
+
opacity: 0;
|
|
556
|
+
pointer-events: none;
|
|
557
|
+
position: absolute;
|
|
558
|
+
transition:
|
|
559
|
+
background-color var(--slotted-control-transition-duration)
|
|
560
|
+
var(--slotted-control-transition-easing),
|
|
561
|
+
opacity var(--slotted-control-transition-duration) var(--slotted-control-transition-easing);
|
|
522
562
|
}
|
|
523
563
|
|
|
524
|
-
[data-ui
|
|
525
|
-
|
|
526
|
-
|
|
564
|
+
[data-ui-tabs]:not([data-orientation='vertical'])
|
|
565
|
+
> :where([data-part-list])
|
|
566
|
+
> [data-part-item]:has(> [data-part-dismiss])::before {
|
|
567
|
+
inset-inline-end: calc(2 * var(--_padding-inline) + var(--_icon-size));
|
|
527
568
|
}
|
|
528
569
|
|
|
529
|
-
[data-ui
|
|
530
|
-
|
|
531
|
-
|
|
570
|
+
[data-ui-tabs][data-variant='line']
|
|
571
|
+
> :where([data-part-list])
|
|
572
|
+
> [data-part-item]:not([data-selected]):has(> [data-part-tab]:not(:disabled):hover)::before {
|
|
573
|
+
opacity: var(--slotted-tabs-hover-marker-opacity, 0.5);
|
|
532
574
|
}
|
|
533
575
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
576
|
+
/** Press takes the bar to the label's own ink: the two say one thing. */
|
|
577
|
+
[data-ui-tabs][data-variant='line']
|
|
578
|
+
> :where([data-part-list])
|
|
579
|
+
> [data-part-item]:not([data-selected]):has(> [data-part-tab]:not(:disabled):active)::before {
|
|
580
|
+
background-color: var(--slotted-tabs-active-marker-color, var(--slotted-text));
|
|
537
581
|
}
|
|
538
582
|
|
|
539
|
-
/**
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
block-size: auto;
|
|
547
|
-
border-start-end-radius: var(--slotted-radius-xs, 2px);
|
|
548
|
-
border-start-start-radius: 0;
|
|
549
|
-
border-end-end-radius: var(--slotted-radius-xs, 2px);
|
|
583
|
+
/**
|
|
584
|
+
* A quarter turn: both bars stand on the list's inline-end edge and run along
|
|
585
|
+
* the block axis, where the inset defaults to nought because a tab has no
|
|
586
|
+
* block padding.
|
|
587
|
+
*/
|
|
588
|
+
[data-ui-tabs][data-orientation='vertical'] > :where([data-part-list]) > [data-part-marker] {
|
|
589
|
+
block-size: var(--_length);
|
|
550
590
|
inline-size: var(--_marker-size);
|
|
551
|
-
inset-block:
|
|
552
|
-
|
|
591
|
+
inset-block: calc(
|
|
592
|
+
var(--_indicator-start, 0px) + var(--_start-inset) + (var(--_span) - var(--_length)) / 2
|
|
593
|
+
)
|
|
594
|
+
auto;
|
|
595
|
+
inset-inline: auto calc(var(--_marker-lift, 0px) + var(--_marker-offset));
|
|
553
596
|
}
|
|
554
597
|
|
|
555
|
-
[data-ui
|
|
556
|
-
> :where([data-part
|
|
557
|
-
> [data-part
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
> [data-part='item'][data-selected]::after {
|
|
565
|
-
transform: scale(1, 1);
|
|
566
|
-
transform-origin: 50% var(--_marker-origin-selected);
|
|
598
|
+
[data-ui-tabs][data-orientation='vertical']
|
|
599
|
+
> :where([data-part-list])
|
|
600
|
+
> [data-part-item]::before {
|
|
601
|
+
block-size: auto;
|
|
602
|
+
inline-size: var(--_marker-size);
|
|
603
|
+
inset-block: var(--_marker-inset);
|
|
604
|
+
inset-inline: auto calc(var(--_marker-offset) - var(--_track-reach, 0px));
|
|
605
|
+
min-block-size: var(--slotted-space-6, 1rem);
|
|
606
|
+
min-inline-size: 0;
|
|
567
607
|
}
|
|
568
608
|
|
|
569
609
|
/* ── Contained ────────────────────────────────────────────────────────── */
|
|
@@ -581,7 +621,10 @@
|
|
|
581
621
|
* the first capture showed; the `line` variant keeps the full width, because
|
|
582
622
|
* there the track is the edge of the panel below it.
|
|
583
623
|
*/
|
|
584
|
-
[data-ui
|
|
624
|
+
[data-ui-tabs][data-variant='contained'] > [data-part-list] {
|
|
625
|
+
/* The marker underlines the label inside the selected surface, a step above its edge. */
|
|
626
|
+
--_marker-lift: calc(2 * var(--slotted-space-1, 0.125rem));
|
|
627
|
+
|
|
585
628
|
background-color: var(--slotted-tabs-contained-background, var(--slotted-surface-sunken));
|
|
586
629
|
border-radius: var(--slotted-radius-md, 6px);
|
|
587
630
|
justify-self: start;
|
|
@@ -589,39 +632,19 @@
|
|
|
589
632
|
padding: var(--slotted-space-1, 0.125rem);
|
|
590
633
|
}
|
|
591
634
|
|
|
592
|
-
[data-ui
|
|
635
|
+
[data-ui-tabs][data-variant='contained'] > :where([data-part-list]) > [data-part-item] {
|
|
593
636
|
border-radius: var(--slotted-radius-sm, 4px);
|
|
594
637
|
transition: background-color var(--slotted-control-transition-duration)
|
|
595
638
|
var(--slotted-control-transition-easing);
|
|
596
639
|
}
|
|
597
640
|
|
|
598
|
-
[data-ui
|
|
599
|
-
> :where([data-part
|
|
600
|
-
> [data-part
|
|
641
|
+
[data-ui-tabs][data-variant='contained']
|
|
642
|
+
> :where([data-part-list])
|
|
643
|
+
> [data-part-item][data-selected] {
|
|
601
644
|
background-color: var(--slotted-tabs-contained-selected-background, var(--slotted-surface));
|
|
602
645
|
box-shadow: var(--slotted-shadow-xs);
|
|
603
646
|
}
|
|
604
647
|
|
|
605
|
-
/**
|
|
606
|
-
* Inset from the corners by the radius, so the bar underlines the label
|
|
607
|
-
* instead of tracing the edge of the surface it sits on. Sitting on the
|
|
608
|
-
* edge, it read as a second border of a different colour, and the capture
|
|
609
|
-
* showed a pill with one blue side.
|
|
610
|
-
*/
|
|
611
|
-
[data-ui='tabs'][data-variant='contained']
|
|
612
|
-
> :where([data-part='list'])
|
|
613
|
-
> [data-part='item']::after {
|
|
614
|
-
inset-block-end: var(--slotted-space-1, 0.125rem);
|
|
615
|
-
inset-inline: var(--slotted-radius-sm, 4px);
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
[data-ui='tabs'][data-variant='contained'][data-orientation='vertical']
|
|
619
|
-
> :where([data-part='list'])
|
|
620
|
-
> [data-part='item']::after {
|
|
621
|
-
inset-block: var(--slotted-radius-sm, 4px);
|
|
622
|
-
inset-inline: auto var(--slotted-space-1, 0.125rem);
|
|
623
|
-
}
|
|
624
|
-
|
|
625
648
|
/* ── The dismiss control ──────────────────────────────────────────────── */
|
|
626
649
|
|
|
627
650
|
/**
|
|
@@ -631,17 +654,16 @@
|
|
|
631
654
|
* through `aria-keyshortcuts`.
|
|
632
655
|
*
|
|
633
656
|
* It is aligned by its mark rather than by its box. The box overhangs the X
|
|
634
|
-
* on every side,
|
|
635
|
-
*
|
|
636
|
-
* inner gap
|
|
637
|
-
*
|
|
638
|
-
*
|
|
639
|
-
*
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
> [data-part='dismiss'] {
|
|
657
|
+
* on every side, and both margins take the overhang back, which puts the mark
|
|
658
|
+
* the tab's own inset from the last letter and from the end of the item. An
|
|
659
|
+
* inner gap before the mark left the round ground of the hover touching the
|
|
660
|
+
* words; the first capture showed a square the height of the control, hard
|
|
661
|
+
* against the words, with the whole tab's padding on the far side of it.
|
|
662
|
+
*
|
|
663
|
+
* Neutral, as the dialog's close and the paging controls: removing a tab
|
|
664
|
+
* closes a view and destroys nothing, so the danger tone overstated it.
|
|
665
|
+
*/
|
|
666
|
+
[data-ui-tabs] > :where([data-part-list]) > :where([data-part-item]) > [data-part-dismiss] {
|
|
645
667
|
--slotted-icon-size: var(--_icon-size);
|
|
646
668
|
|
|
647
669
|
align-items: center;
|
|
@@ -650,7 +672,7 @@
|
|
|
650
672
|
background-color: transparent;
|
|
651
673
|
block-size: var(--_dismiss-size);
|
|
652
674
|
border: 0;
|
|
653
|
-
border-radius: var(--slotted-
|
|
675
|
+
border-radius: var(--slotted-radius-full, 9999px);
|
|
654
676
|
color: var(--slotted-tabs-dismiss-color, var(--slotted-text-muted, GrayText));
|
|
655
677
|
cursor: pointer;
|
|
656
678
|
display: inline-flex;
|
|
@@ -658,7 +680,7 @@
|
|
|
658
680
|
inline-size: var(--_dismiss-size);
|
|
659
681
|
justify-content: center;
|
|
660
682
|
margin-inline-end: calc(var(--_padding-inline) - var(--_dismiss-overhang));
|
|
661
|
-
margin-inline-start:
|
|
683
|
+
margin-inline-start: calc(var(--_padding-inline) - var(--_dismiss-overhang));
|
|
662
684
|
padding: 0;
|
|
663
685
|
transition:
|
|
664
686
|
background-color var(--slotted-control-transition-duration)
|
|
@@ -670,49 +692,46 @@
|
|
|
670
692
|
is the one a mouse sees: a transparent box centred on the control reaches
|
|
671
693
|
44 pixels, and the ground and the ring stay square. */
|
|
672
694
|
@media (pointer: coarse) {
|
|
673
|
-
[data-ui
|
|
674
|
-
> :where([data-part='list'])
|
|
675
|
-
> :where([data-part='item'])
|
|
676
|
-
> [data-part='dismiss'] {
|
|
695
|
+
[data-ui-tabs] > :where([data-part-list]) > :where([data-part-item]) > [data-part-dismiss] {
|
|
677
696
|
position: relative;
|
|
678
697
|
}
|
|
679
698
|
|
|
680
|
-
[data-ui
|
|
681
|
-
> :where([data-part
|
|
682
|
-
> :where([data-part
|
|
683
|
-
> [data-part
|
|
699
|
+
[data-ui-tabs]
|
|
700
|
+
> :where([data-part-list])
|
|
701
|
+
> :where([data-part-item])
|
|
702
|
+
> [data-part-dismiss]::after {
|
|
684
703
|
content: '';
|
|
685
704
|
inset: min(0px, calc((100% - var(--slotted-target-comfortable, 44px)) / 2));
|
|
686
705
|
position: absolute;
|
|
687
706
|
}
|
|
688
707
|
}
|
|
689
708
|
|
|
690
|
-
[data-ui
|
|
691
|
-
> :where([data-part
|
|
692
|
-
> :where([data-part
|
|
693
|
-
> [data-part
|
|
709
|
+
[data-ui-tabs]
|
|
710
|
+
> :where([data-part-list])
|
|
711
|
+
> :where([data-part-item])
|
|
712
|
+
> [data-part-dismiss]:not(:disabled):hover {
|
|
694
713
|
background-color: var(
|
|
695
714
|
--slotted-tabs-dismiss-hover-background,
|
|
696
|
-
var(--slotted-tone-
|
|
715
|
+
var(--slotted-tone-secondary-subtle-hover)
|
|
697
716
|
);
|
|
698
|
-
color: var(--slotted-tabs-dismiss-hover-color, var(--slotted-
|
|
717
|
+
color: var(--slotted-tabs-dismiss-hover-color, var(--slotted-text, CanvasText));
|
|
699
718
|
}
|
|
700
719
|
|
|
701
|
-
[data-ui
|
|
702
|
-
> :where([data-part
|
|
703
|
-
> :where([data-part
|
|
704
|
-
> [data-part
|
|
720
|
+
[data-ui-tabs]
|
|
721
|
+
> :where([data-part-list])
|
|
722
|
+
> :where([data-part-item])
|
|
723
|
+
> [data-part-dismiss]:not(:disabled):active {
|
|
705
724
|
background-color: var(
|
|
706
725
|
--slotted-tabs-dismiss-active-background,
|
|
707
|
-
var(--slotted-tone-
|
|
726
|
+
var(--slotted-tone-secondary-subtle-active)
|
|
708
727
|
);
|
|
709
|
-
color: var(--slotted-tabs-dismiss-active-color, var(--slotted-text
|
|
728
|
+
color: var(--slotted-tabs-dismiss-active-color, var(--slotted-text, CanvasText));
|
|
710
729
|
}
|
|
711
730
|
|
|
712
|
-
[data-ui
|
|
713
|
-
> :where([data-part
|
|
714
|
-
> :where([data-part
|
|
715
|
-
> [data-part
|
|
731
|
+
[data-ui-tabs]
|
|
732
|
+
> :where([data-part-list])
|
|
733
|
+
> :where([data-part-item])
|
|
734
|
+
> [data-part-dismiss]:disabled {
|
|
716
735
|
color: var(--slotted-disabled-foreground, GrayText);
|
|
717
736
|
cursor: not-allowed;
|
|
718
737
|
}
|
|
@@ -735,7 +754,7 @@
|
|
|
735
754
|
* list as they move, and Cloudscape's own guidance warns against extra
|
|
736
755
|
* stops before a tab list.
|
|
737
756
|
*/
|
|
738
|
-
[data-ui
|
|
757
|
+
[data-ui-tabs] > [data-part-scroll] {
|
|
739
758
|
--slotted-icon-size: var(--_icon-size);
|
|
740
759
|
|
|
741
760
|
align-items: center;
|
|
@@ -767,31 +786,30 @@
|
|
|
767
786
|
* is read from the control itself — a paging control at its end is
|
|
768
787
|
* disabled — so the family needs no second signal for it.
|
|
769
788
|
*/
|
|
770
|
-
[data-ui
|
|
771
|
-
> [data-part
|
|
789
|
+
[data-ui-tabs]:has(> [data-part-scroll][data-direction='start']:not(:disabled))
|
|
790
|
+
> [data-part-list] {
|
|
772
791
|
mask-image: linear-gradient(to right, transparent, black var(--_fade));
|
|
773
792
|
}
|
|
774
793
|
|
|
775
|
-
[data-ui
|
|
776
|
-
> [data-part='list'] {
|
|
794
|
+
[data-ui-tabs]:has(> [data-part-scroll][data-direction='end']:not(:disabled)) > [data-part-list] {
|
|
777
795
|
mask-image: linear-gradient(to left, transparent, black var(--_fade));
|
|
778
796
|
}
|
|
779
797
|
|
|
780
798
|
/* The start edge is the right one in a right-to-left document. */
|
|
781
|
-
[data-ui
|
|
782
|
-
> [data-part
|
|
799
|
+
[data-ui-tabs]:dir(rtl):has(> [data-part-scroll][data-direction='start']:not(:disabled))
|
|
800
|
+
> [data-part-list] {
|
|
783
801
|
mask-image: linear-gradient(to left, transparent, black var(--_fade));
|
|
784
802
|
}
|
|
785
803
|
|
|
786
|
-
[data-ui
|
|
787
|
-
> [data-part
|
|
804
|
+
[data-ui-tabs]:dir(rtl):has(> [data-part-scroll][data-direction='end']:not(:disabled))
|
|
805
|
+
> [data-part-list] {
|
|
788
806
|
mask-image: linear-gradient(to right, transparent, black var(--_fade));
|
|
789
807
|
}
|
|
790
808
|
|
|
791
|
-
[data-ui
|
|
792
|
-
> [data-part
|
|
809
|
+
[data-ui-tabs]:has(> [data-part-scroll][data-direction='start']:not(:disabled)):has(
|
|
810
|
+
> [data-part-scroll][data-direction='end']:not(:disabled)
|
|
793
811
|
)
|
|
794
|
-
> [data-part
|
|
812
|
+
> [data-part-list] {
|
|
795
813
|
mask-image: linear-gradient(
|
|
796
814
|
to right,
|
|
797
815
|
transparent,
|
|
@@ -805,19 +823,19 @@
|
|
|
805
823
|
for both axes. As wide as its glyph and as tall as the row, it stood 24
|
|
806
824
|
wide and 44 tall beside tabs grown to the comfortable height. */
|
|
807
825
|
@media (pointer: coarse) {
|
|
808
|
-
[data-ui
|
|
826
|
+
[data-ui-tabs] > [data-part-scroll] {
|
|
809
827
|
min-block-size: max(var(--slotted-target-comfortable, 44px), var(--_height));
|
|
810
828
|
min-inline-size: max(var(--slotted-target-comfortable, 44px), var(--_height));
|
|
811
829
|
}
|
|
812
830
|
}
|
|
813
831
|
|
|
814
|
-
[data-ui
|
|
832
|
+
[data-ui-tabs] > [data-part-scroll][data-direction='start'] {
|
|
815
833
|
grid-column: 1;
|
|
816
834
|
grid-row: 1;
|
|
817
835
|
margin-inline-end: var(--slotted-tabs-actions-gap, var(--slotted-space-4, 0.5rem));
|
|
818
836
|
}
|
|
819
837
|
|
|
820
|
-
[data-ui
|
|
838
|
+
[data-ui-tabs] > [data-part-scroll][data-direction='end'] {
|
|
821
839
|
grid-column: 3;
|
|
822
840
|
margin-inline-start: var(--slotted-tabs-actions-gap, var(--slotted-space-4, 0.5rem));
|
|
823
841
|
grid-row: 1;
|
|
@@ -832,26 +850,26 @@
|
|
|
832
850
|
* own mirror holds: the two compose, so the start control points back in
|
|
833
851
|
* both directions.
|
|
834
852
|
*/
|
|
835
|
-
[data-ui
|
|
853
|
+
[data-ui-tabs] > [data-part-scroll][data-direction='start'] > [data-ui-icon] {
|
|
836
854
|
rotate: 0.5turn;
|
|
837
855
|
}
|
|
838
856
|
|
|
839
857
|
/* The ground moves under the pointer and nothing else does (R2). */
|
|
840
|
-
[data-ui
|
|
858
|
+
[data-ui-tabs] > [data-part-scroll]:not(:disabled):hover {
|
|
841
859
|
background-color: var(
|
|
842
860
|
--slotted-tabs-hover-background,
|
|
843
861
|
var(--slotted-tone-secondary-subtle-hover)
|
|
844
862
|
);
|
|
845
863
|
}
|
|
846
864
|
|
|
847
|
-
[data-ui
|
|
865
|
+
[data-ui-tabs] > [data-part-scroll]:not(:disabled):active {
|
|
848
866
|
background-color: var(
|
|
849
867
|
--slotted-tabs-active-background,
|
|
850
868
|
var(--slotted-tone-secondary-subtle-active)
|
|
851
869
|
);
|
|
852
870
|
}
|
|
853
871
|
|
|
854
|
-
[data-ui
|
|
872
|
+
[data-ui-tabs] > [data-part-scroll]:focus-visible {
|
|
855
873
|
outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
|
|
856
874
|
outline-offset: calc(-1 * var(--slotted-focus-ring-width, 2px));
|
|
857
875
|
}
|
|
@@ -862,18 +880,18 @@
|
|
|
862
880
|
* not removed — so the list never moves under the pointer that is using
|
|
863
881
|
* the other one.
|
|
864
882
|
*/
|
|
865
|
-
[data-ui
|
|
883
|
+
[data-ui-tabs] > [data-part-scroll]:disabled {
|
|
866
884
|
cursor: default;
|
|
867
885
|
visibility: hidden;
|
|
868
886
|
}
|
|
869
887
|
|
|
870
|
-
[data-ui
|
|
888
|
+
[data-ui-tabs][data-orientation='vertical'] > [data-part-scroll] {
|
|
871
889
|
display: none;
|
|
872
890
|
}
|
|
873
891
|
|
|
874
892
|
/* ── Actions, and the panels ──────────────────────────────────────────── */
|
|
875
893
|
|
|
876
|
-
[data-ui
|
|
894
|
+
[data-ui-tabs] > [data-part-actions] {
|
|
877
895
|
align-items: center;
|
|
878
896
|
align-self: center;
|
|
879
897
|
display: flex;
|
|
@@ -883,7 +901,7 @@
|
|
|
883
901
|
min-inline-size: 0;
|
|
884
902
|
}
|
|
885
903
|
|
|
886
|
-
[data-ui
|
|
904
|
+
[data-ui-tabs][data-orientation='vertical'] > [data-part-actions] {
|
|
887
905
|
grid-column: 1;
|
|
888
906
|
grid-row: 2;
|
|
889
907
|
}
|
|
@@ -902,14 +920,14 @@
|
|
|
902
920
|
* their own element, which is one declaration against a layout that
|
|
903
921
|
* otherwise breaks for every reader on a narrow screen.
|
|
904
922
|
*/
|
|
905
|
-
[data-ui
|
|
923
|
+
[data-ui-tabs] > [data-part-panel] {
|
|
906
924
|
grid-column: 1 / -1;
|
|
907
925
|
grid-row: 2;
|
|
908
926
|
min-inline-size: 0;
|
|
909
927
|
overflow-wrap: anywhere;
|
|
910
928
|
}
|
|
911
929
|
|
|
912
|
-
[data-ui
|
|
930
|
+
[data-ui-tabs][data-orientation='vertical'] > [data-part-panel] {
|
|
913
931
|
grid-column: 2;
|
|
914
932
|
grid-row: 1 / -1;
|
|
915
933
|
}
|
|
@@ -920,7 +938,7 @@
|
|
|
920
938
|
* than relied on. It is the attribute and not a class because a screen
|
|
921
939
|
* reader, find-in-page and `:target` all already understand it.
|
|
922
940
|
*/
|
|
923
|
-
[data-ui
|
|
941
|
+
[data-ui-tabs] > [data-part-panel][hidden] {
|
|
924
942
|
display: none;
|
|
925
943
|
}
|
|
926
944
|
|
|
@@ -930,7 +948,7 @@
|
|
|
930
948
|
* own content and has no padding of its own, so an inset ring is drawn
|
|
931
949
|
* through the first line of it.
|
|
932
950
|
*/
|
|
933
|
-
[data-ui
|
|
951
|
+
[data-ui-tabs] > [data-part-panel]:focus-visible {
|
|
934
952
|
outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
|
|
935
953
|
outline-offset: var(--slotted-focus-ring-offset, 2px);
|
|
936
954
|
}
|
|
@@ -943,7 +961,7 @@
|
|
|
943
961
|
* panel instead, which needs a clipping viewport that traps horizontal
|
|
944
962
|
* scrolling and fights the list's own scroll.
|
|
945
963
|
*/
|
|
946
|
-
[data-ui
|
|
964
|
+
[data-ui-tabs] > [data-part-panel]:not([hidden]) {
|
|
947
965
|
animation: slotted-tabs-panel-in var(--slotted-duration-short) var(--slotted-easing-enter);
|
|
948
966
|
}
|
|
949
967
|
|
|
@@ -961,11 +979,11 @@
|
|
|
961
979
|
* adds is the track: a disabled family should not read as a live one with
|
|
962
980
|
* grey labels.
|
|
963
981
|
*/
|
|
964
|
-
[data-ui
|
|
965
|
-
|
|
982
|
+
[data-ui-tabs][data-disabled] {
|
|
983
|
+
--_track-color: var(--slotted-disabled-border, GrayText);
|
|
966
984
|
}
|
|
967
985
|
|
|
968
|
-
[data-ui
|
|
986
|
+
[data-ui-tabs][data-disabled][data-variant='contained'] > [data-part-list] {
|
|
969
987
|
background-color: var(--slotted-disabled-background, Canvas);
|
|
970
988
|
}
|
|
971
989
|
|
|
@@ -974,24 +992,41 @@
|
|
|
974
992
|
* decoration in an unthemed page should disappear rather than shout, and a
|
|
975
993
|
* marker painted `GrayText` with no theme would be the loudest thing on it.
|
|
976
994
|
*/
|
|
977
|
-
[data-ui
|
|
978
|
-
> :where([data-part='list'])
|
|
979
|
-
> [data-part='item'][data-selected]::after {
|
|
995
|
+
[data-ui-tabs][data-disabled] > :where([data-part-list]) > [data-part-marker] {
|
|
980
996
|
background-color: var(--slotted-disabled-border);
|
|
981
997
|
}
|
|
982
998
|
|
|
983
999
|
/* ── Forced colours ──────────────────────────────────────────────────── */
|
|
984
1000
|
|
|
985
1001
|
/**
|
|
986
|
-
* The theme maps every scheme token to a system colour, so the
|
|
987
|
-
*
|
|
988
|
-
*
|
|
989
|
-
* track it stands in.
|
|
1002
|
+
* The theme maps every scheme token to a system colour, so the rules here
|
|
1003
|
+
* are about paint the theme cannot reach: the track drawn as a shadow, the
|
|
1004
|
+
* marker's ground, and a selected tab in the contained variant, whose fill
|
|
1005
|
+
* flattens to `Canvas` along with the track it stands in.
|
|
990
1006
|
*/
|
|
991
1007
|
@media (forced-colors: active) {
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
1008
|
+
/* A shadow is not drawn under forced colours: the track is a border again. */
|
|
1009
|
+
[data-ui-tabs][data-variant='line'][data-track='line'] > [data-part-list] {
|
|
1010
|
+
border-block-end: var(--_track-size) solid CanvasText;
|
|
1011
|
+
padding-block-end: 0;
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
[data-ui-tabs][data-orientation='vertical'][data-variant='line'][data-track='line']
|
|
1015
|
+
> [data-part-list] {
|
|
1016
|
+
border-block-end: 0;
|
|
1017
|
+
border-inline-end: var(--_track-size) solid CanvasText;
|
|
1018
|
+
padding-inline-end: 0;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
/* The marker's ground would flatten to Canvas with every other ground. */
|
|
1022
|
+
[data-ui-tabs] > :where([data-part-list]) > [data-part-marker] {
|
|
1023
|
+
background-color: Highlight;
|
|
1024
|
+
forced-color-adjust: none;
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
[data-ui-tabs][data-variant='contained']
|
|
1028
|
+
> :where([data-part-list])
|
|
1029
|
+
> [data-part-item][data-selected] {
|
|
995
1030
|
border: var(--slotted-border-width-thin, 1px) solid Highlight;
|
|
996
1031
|
}
|
|
997
1032
|
}
|