@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,730 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every selector below the root is written with child combinators, and that is
|
|
3
|
+
* not a stylistic preference.
|
|
4
|
+
*
|
|
5
|
+
* This family renders another family inside itself: the mark in the panel is a
|
|
6
|
+
* `progress-indicator`, and `progress-indicator` has parts called `indicator`,
|
|
7
|
+
* `label` and `root` — the same three words this family uses. A descendant
|
|
8
|
+
* selector would reach into the nested family and restyle its insides, and the
|
|
9
|
+
* defect would be invisible in the source and obvious only in the picture.
|
|
10
|
+
*
|
|
11
|
+
* The chain is `root > scrim > panel > *`, which is also the anatomy, so the
|
|
12
|
+
* selectors document the tree they depend on.
|
|
13
|
+
*/
|
|
14
|
+
@layer slotted.components {
|
|
15
|
+
/* ── The region ─────────────────────────────────────────────────────────
|
|
16
|
+
*
|
|
17
|
+
* The element the consumer's content already lives in, plus a containing
|
|
18
|
+
* block for the layer that covers it. Nothing else: the geometry on screen
|
|
19
|
+
* is the covered content's own, which is the whole difference between this
|
|
20
|
+
* family and `skeleton`. A region that changed size when it was covered
|
|
21
|
+
* would move everything below it, twice per load.
|
|
22
|
+
*
|
|
23
|
+
* `position: relative` and no `container-type`. Containment is applied to
|
|
24
|
+
* the layer instead — see the scrim — because `container-type` would apply
|
|
25
|
+
* it to the consumer's own content, and a family that covers a box has no
|
|
26
|
+
* business changing how that box lays itself out.
|
|
27
|
+
*/
|
|
28
|
+
[data-ui='loading-overlay'][data-part='root'] {
|
|
29
|
+
/**
|
|
30
|
+
* The distance the panel keeps from the region's edges. It is the panel's
|
|
31
|
+
* own margin rather than the layer's padding, and the difference is not
|
|
32
|
+
* cosmetic: the layer is the query container, container query units measure
|
|
33
|
+
* its content box, and padding on it would make every `cqb` in this sheet
|
|
34
|
+
* smaller than the region it is asking about. A margin on the panel moves
|
|
35
|
+
* the panel and leaves the measurement alone.
|
|
36
|
+
*/
|
|
37
|
+
--_inset: var(--slotted-loading-overlay-inset, var(--slotted-space-4, 0.5rem));
|
|
38
|
+
|
|
39
|
+
position: relative;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Page scope. The layer is the whole viewport and there is no region: what
|
|
44
|
+
* is covered is the application, which this family does not own. The stack
|
|
45
|
+
* position is the overlay step, below `popover` and `toast`, because a
|
|
46
|
+
* message about a wait has to stay readable over anything the wait raises.
|
|
47
|
+
*/
|
|
48
|
+
[data-ui='loading-overlay'][data-part='root'][data-scope='page'] {
|
|
49
|
+
inset: 0;
|
|
50
|
+
position: fixed;
|
|
51
|
+
z-index: var(--slotted-z-index-overlay, 1000);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* ── The covered content ────────────────────────────────────────────────
|
|
55
|
+
*
|
|
56
|
+
* The part that exists so `inert` has somewhere to go, and the reason it
|
|
57
|
+
* generates no box.
|
|
58
|
+
*
|
|
59
|
+
* `inert` is inherited by every flat-tree descendant and only a modal
|
|
60
|
+
* `dialog` escapes it, so the attribute cannot go on the root: it would take
|
|
61
|
+
* the announcement out of the accessibility tree — an inert live region says
|
|
62
|
+
* nothing — and it would make the cancel control unpressable. It needs an
|
|
63
|
+
* element that wraps the content and excludes the layer.
|
|
64
|
+
*
|
|
65
|
+
* `display: contents` is what makes that element free. It generates no box,
|
|
66
|
+
* so the consumer's children stay the root's own layout children: a covered
|
|
67
|
+
* grid keeps its tracks, a covered flex row keeps its line. Inertness is a
|
|
68
|
+
* property of the flat tree and not of the box, so the two compose.
|
|
69
|
+
*
|
|
70
|
+
* The cost, recorded here rather than discovered later: this part can never
|
|
71
|
+
* be painted, because it has no box to paint. Any future rule that needs a
|
|
72
|
+
* ground, a padding or an edge here reopens the decision. And a root that is
|
|
73
|
+
* a `table` or a `tbody` cannot legally hold this `div`, so a family covering
|
|
74
|
+
* table internals covers the table instead.
|
|
75
|
+
*/
|
|
76
|
+
[data-ui='loading-overlay'] > [data-part='content'] {
|
|
77
|
+
display: contents;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* ── The wash ───────────────────────────────────────────────────────────
|
|
81
|
+
*
|
|
82
|
+
* One element doing two jobs, and they belong together: it paints what says
|
|
83
|
+
* the content is out of reach, and it is the one-cell grid that centres the
|
|
84
|
+
* panel in the region. `dialog` splits the two because its viewport scrolls
|
|
85
|
+
* and a scrim inside a scrolling box scrolls away with it; nothing here
|
|
86
|
+
* scrolls, so nothing here is split.
|
|
87
|
+
*
|
|
88
|
+
* It is the query container rather than the root, which is the opposite of
|
|
89
|
+
* the split `docs/build-briefing.md` records and is right for a reason that
|
|
90
|
+
* split does not cover: `container-type` applies containment, and the root's
|
|
91
|
+
* other child is the consumer's content. Absolutely positioned to the root's
|
|
92
|
+
* padding box, the scrim measures the inline size the root does and contains
|
|
93
|
+
* nothing but the panel.
|
|
94
|
+
*/
|
|
95
|
+
[data-ui='loading-overlay'] > [data-part='scrim'] {
|
|
96
|
+
align-items: center;
|
|
97
|
+
container-name: slotted-loading-overlay;
|
|
98
|
+
container-type: size;
|
|
99
|
+
display: grid;
|
|
100
|
+
inset: 0;
|
|
101
|
+
justify-items: center;
|
|
102
|
+
position: absolute;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* The wash itself. `--slotted-scrim` is the foundation token the theme
|
|
107
|
+
* restates per scheme and turns opaque under forced colours, and it is what
|
|
108
|
+
* `dialog` and `drawer` already read: three families dimming a surface in
|
|
109
|
+
* three tints would be three answers to one question.
|
|
110
|
+
*/
|
|
111
|
+
[data-ui='loading-overlay'][data-veil='wash'] > [data-part='scrim'],
|
|
112
|
+
[data-ui='loading-overlay'][data-veil='blur'] > [data-part='scrim'] {
|
|
113
|
+
background: var(--slotted-loading-overlay-scrim, var(--slotted-scrim, Canvas));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* The blur is a second signal for the same fact, and it is the one that
|
|
118
|
+
* still reads when the wash is faint: text under it stops being legible
|
|
119
|
+
* before it stops being visible, which is exactly the message.
|
|
120
|
+
*
|
|
121
|
+
* The radius is a literal in the fallback because no scale in the foundation
|
|
122
|
+
* measures a blur, and adding one for a single declaration would be the
|
|
123
|
+
* parallel scale `docs/token-foundation.md` refuses. A theme retunes the
|
|
124
|
+
* hook instead.
|
|
125
|
+
*/
|
|
126
|
+
[data-ui='loading-overlay'][data-veil='blur'] > [data-part='scrim'] {
|
|
127
|
+
backdrop-filter: blur(var(--slotted-loading-overlay-blur, 3px));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/* ── Appearing, and leaving ─────────────────────────────────────────────
|
|
131
|
+
*
|
|
132
|
+
* The wash fades and nothing moves. A panel that slid or scaled would be a
|
|
133
|
+
* dialog's entrance, and this layer is not something the reader asked for:
|
|
134
|
+
* it arrives while they are looking at the thing it covers, so the eye
|
|
135
|
+
* should find it rather than follow it.
|
|
136
|
+
*
|
|
137
|
+
* Both directions are transitions, and the scrim is in the document from the
|
|
138
|
+
* moment the family is, which is what makes that possible: a transition
|
|
139
|
+
* starts from the style the browser computed last, and an element that has
|
|
140
|
+
* just been mounted has no last style to start from. `menu` solves the same
|
|
141
|
+
* problem with a keyframe because its layer is mounted at the moment it
|
|
142
|
+
* opens; this one has no reason to be.
|
|
143
|
+
*
|
|
144
|
+
* The first capture of this family is why it is written this way. A keyframe
|
|
145
|
+
* on the open rule runs on every first paint, including a layer that was
|
|
146
|
+
* already blocking when the page loaded — so the shutter caught a
|
|
147
|
+
* half-faded wash with the covered text reading straight through the panel.
|
|
148
|
+
* A transition does not fire on an initial style, which is exactly the rule
|
|
149
|
+
* a layer already open on first mount needs.
|
|
150
|
+
*
|
|
151
|
+
* What the scrim does not hold at rest is its panel: the binding mounts that
|
|
152
|
+
* one through `@slotted/core/presence`, so nothing animates a mark nobody is
|
|
153
|
+
* looking at, and the resting layer holds no control for Tab to find.
|
|
154
|
+
*
|
|
155
|
+
* `pointer-events` is dropped on the way out. The covered content stops
|
|
156
|
+
* being `inert` the moment the wait ends rather than when the fade finishes,
|
|
157
|
+
* so a click during those hundred and twenty milliseconds has somewhere to
|
|
158
|
+
* land.
|
|
159
|
+
*/
|
|
160
|
+
[data-ui='loading-overlay'] > [data-part='scrim'] {
|
|
161
|
+
opacity: 0;
|
|
162
|
+
pointer-events: none;
|
|
163
|
+
transition: opacity var(--slotted-duration-short) var(--slotted-easing-exit, ease);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
[data-ui='loading-overlay'] > [data-part='scrim'][data-loading] {
|
|
167
|
+
opacity: 1;
|
|
168
|
+
pointer-events: auto;
|
|
169
|
+
transition-duration: var(--slotted-duration-medium);
|
|
170
|
+
transition-timing-function: var(--slotted-easing-enter, ease);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/* ── The panel ──────────────────────────────────────────────────────────
|
|
174
|
+
*
|
|
175
|
+
* A surface, not a bare mark on the wash, and the reason is measurable. The
|
|
176
|
+
* wash is a translucent tint over content this family cannot know, so the
|
|
177
|
+
* composite behind a label is whatever the covered page happens to be: a
|
|
178
|
+
* label painted straight onto it holds no contrast ratio anybody can state.
|
|
179
|
+
* On its own ground it holds the theme's, in all three schemes, over any
|
|
180
|
+
* content. None of the surveyed implementations draws one, and none of them
|
|
181
|
+
* can say what its text contrasts against.
|
|
182
|
+
*
|
|
183
|
+
* The lift is `dialog`'s and `drawer`'s, one step above a card's. Every
|
|
184
|
+
* surface in this library that floats over a scrim takes that step, and a
|
|
185
|
+
* panel that took a smaller one read as part of the wash rather than as
|
|
186
|
+
* something standing in front of it.
|
|
187
|
+
*
|
|
188
|
+
* The edge is not decoration. In `high-contrast` and under forced colours
|
|
189
|
+
* the shadow is dropped and the scrim goes opaque, so the edge is the only
|
|
190
|
+
* thing left separating the panel from what is behind it.
|
|
191
|
+
*/
|
|
192
|
+
[data-ui='loading-overlay'] > [data-part='scrim'] > [data-part='panel'] {
|
|
193
|
+
align-items: center;
|
|
194
|
+
background: var(--slotted-loading-overlay-surface, var(--slotted-surface-raised, Canvas));
|
|
195
|
+
border: var(--slotted-border-width-thin, 1px) solid var(--slotted-border-subtle, CanvasText);
|
|
196
|
+
border-radius: var(--slotted-loading-overlay-radius, var(--slotted-radius-md, 6px));
|
|
197
|
+
box-shadow: var(--slotted-shadow-lg);
|
|
198
|
+
color: var(--slotted-text, CanvasText);
|
|
199
|
+
display: grid;
|
|
200
|
+
gap: var(--_gap);
|
|
201
|
+
justify-items: center;
|
|
202
|
+
margin: var(--_inset);
|
|
203
|
+
max-block-size: calc(100% - 2 * var(--_inset));
|
|
204
|
+
/**
|
|
205
|
+
* A floor under the panel's width, three marks across, so a one-word
|
|
206
|
+
* label does not produce a portrait card taller than it is wide. It is
|
|
207
|
+
* derived from the mark's own scale rather than stated, and `min()` keeps
|
|
208
|
+
* it inside a region narrower than the floor.
|
|
209
|
+
*/
|
|
210
|
+
min-inline-size: var(--_floor);
|
|
211
|
+
max-inline-size: min(
|
|
212
|
+
var(--slotted-loading-overlay-measure, 18rem),
|
|
213
|
+
calc(100% - 2 * var(--_inset))
|
|
214
|
+
);
|
|
215
|
+
overflow: clip;
|
|
216
|
+
padding-block: var(--_padding-block);
|
|
217
|
+
padding-inline: var(--_padding-inline);
|
|
218
|
+
text-align: center;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Three sizes, and each of them moves three things: the panel's padding and
|
|
223
|
+
* gap on the space scale, the two lines on the type scale, and the mark on
|
|
224
|
+
* `progress-indicator`'s own control-height scale.
|
|
225
|
+
*
|
|
226
|
+
* The type had to join them. With the geometry alone the three steps were
|
|
227
|
+
* four pixels of padding and four of mark apart, and the captures of `sm`,
|
|
228
|
+
* `md` and `lg` side by side were three pictures nobody could tell apart —
|
|
229
|
+
* an axis a reader cannot see is an axis that does not exist.
|
|
230
|
+
*
|
|
231
|
+
* It is the **control** font-size scale and not the general one, for two
|
|
232
|
+
* reasons. That is the scale the theme restates per density, so it is what
|
|
233
|
+
* carries `dense` into the panel — the general type scale is stated once and
|
|
234
|
+
* would leave the panel's words the same size at every density while its
|
|
235
|
+
* mark and its control shrank around them. And the panel is chrome rather
|
|
236
|
+
* than prose: it says what a control says.
|
|
237
|
+
*
|
|
238
|
+
* Both lines take the same step, which is what `alert` does with its own
|
|
239
|
+
* title and description. They are told apart by weight and colour, which
|
|
240
|
+
* holds at every step; a second, smaller step would have run out of scale
|
|
241
|
+
* under `sm`.
|
|
242
|
+
*/
|
|
243
|
+
[data-ui='loading-overlay'][data-size='sm'] > [data-part='scrim'] > [data-part='panel'] {
|
|
244
|
+
--_floor: min(100%, calc(3 * var(--slotted-control-height-sm, 30px)));
|
|
245
|
+
--_line-height: var(--slotted-line-height-sm, 1.35);
|
|
246
|
+
--_text-size: var(--slotted-control-font-size-sm, 12px);
|
|
247
|
+
--_gap: var(--slotted-space-3, 0.375rem);
|
|
248
|
+
--_padding-block: var(--slotted-space-4, 0.5rem);
|
|
249
|
+
--_padding-inline: var(--slotted-space-5, 0.75rem);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
[data-ui='loading-overlay'][data-size='md'] > [data-part='scrim'] > [data-part='panel'] {
|
|
253
|
+
--_floor: min(100%, calc(3 * var(--slotted-control-height-md, 34px)));
|
|
254
|
+
--_line-height: var(--slotted-line-height-md, 1.4);
|
|
255
|
+
--_text-size: var(--slotted-control-font-size-md, 13px);
|
|
256
|
+
--_gap: var(--slotted-space-4, 0.5rem);
|
|
257
|
+
--_padding-block: var(--slotted-space-5, 0.75rem);
|
|
258
|
+
--_padding-inline: var(--slotted-space-6, 1rem);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
[data-ui='loading-overlay'][data-size='lg'] > [data-part='scrim'] > [data-part='panel'] {
|
|
262
|
+
--_floor: min(100%, calc(3 * var(--slotted-control-height-lg, 38px)));
|
|
263
|
+
--_line-height: var(--slotted-line-height-lg, 1.45);
|
|
264
|
+
--_text-size: var(--slotted-control-font-size-lg, 14px);
|
|
265
|
+
--_gap: var(--slotted-space-5, 0.75rem);
|
|
266
|
+
--_padding-block: var(--slotted-space-6, 1rem);
|
|
267
|
+
--_padding-inline: var(--slotted-space-7, 1.25rem);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/* ── The mark ───────────────────────────────────────────────────────────
|
|
271
|
+
*
|
|
272
|
+
* A place, and nothing else. The shape, its turn and its reduced-motion rule
|
|
273
|
+
* belong to `progress-indicator`, which is what renders here by default and
|
|
274
|
+
* what a consumer substitutes when the wait is determinate. A mark drawn
|
|
275
|
+
* again in this sheet would be a second answer to one wait, drifting from
|
|
276
|
+
* the first the moment either is retuned.
|
|
277
|
+
*
|
|
278
|
+
* What this family does decide is that the default mark is **contained** —
|
|
279
|
+
* `progress-indicator`'s own axis, which is M3's 38-in-48 ratio — and it
|
|
280
|
+
* decides it for two reasons the first captures found.
|
|
281
|
+
*
|
|
282
|
+
* The shape turns, and a turning box overflows the box that holds it: a
|
|
283
|
+
* square 27 pixels across sweeps a 38-pixel diagonal, and every one of those
|
|
284
|
+
* eleven pixels is scrollable overflow contributed to each ancestor in turn.
|
|
285
|
+
* Measured on the page rather than reasoned about — 2 to 9 pixels, rising
|
|
286
|
+
* and falling on the beat of the animation — and an ancestor that scrolls
|
|
287
|
+
* answers it with a scrollbar that flickers for as long as the wait lasts.
|
|
288
|
+
*
|
|
289
|
+
* `contained` is M3's own ratio and takes most of that excess out by
|
|
290
|
+
* shrinking the shape to 0.79 of its container. What is left — four or five
|
|
291
|
+
* pixels at each edge — is absorbed by the panel: its own padding is wider
|
|
292
|
+
* than the excursion, so the ink never reaches the panel's edge, and the
|
|
293
|
+
* panel clips rather than scrolls. The panel opens its clip again in the one
|
|
294
|
+
* arrangement where it has no padding to spare, which is the rule for the
|
|
295
|
+
* smallest regions below.
|
|
296
|
+
*
|
|
297
|
+
* The clip is not written on the mark itself. That sheet belongs to another
|
|
298
|
+
* family and is not this one's to edit, and a family that clipped a mark it
|
|
299
|
+
* did not draw would be deciding how much of somebody else's artwork is
|
|
300
|
+
* allowed to show.
|
|
301
|
+
*
|
|
302
|
+
* And the mark is the one thing that sits directly on the wash, in the
|
|
303
|
+
* smallest regions, where the panel has given up its ground. On a dark
|
|
304
|
+
* scheme that reads: the wash is near black and the accent is a light blue.
|
|
305
|
+
* On a light one it does not — the wash is a dark tint and the accent is a
|
|
306
|
+
* dark blue laid over it. `contained` gives the mark the ground the panel
|
|
307
|
+
* gave up, at the 3:1 `progress-indicator` holds between a contained shape
|
|
308
|
+
* and its container, in every scheme rather than in one.
|
|
309
|
+
*/
|
|
310
|
+
[data-ui='loading-overlay']
|
|
311
|
+
> [data-part='scrim']
|
|
312
|
+
> [data-part='panel']
|
|
313
|
+
> [data-part='indicator'] {
|
|
314
|
+
display: grid;
|
|
315
|
+
justify-items: stretch;
|
|
316
|
+
justify-self: stretch;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* The family's own mark is centred; a mark the consumer put here fills the
|
|
321
|
+
* slot. `data-default` is what tells them apart, and the binding writes it —
|
|
322
|
+
* asking the question in CSS would mean selecting on the nested family's own
|
|
323
|
+
* attributes, which is the reach this sheet refuses everywhere else.
|
|
324
|
+
*
|
|
325
|
+
* The first reference page is why the two cases are split. A determinate
|
|
326
|
+
* `ProgressBar` in a centred, content-sized slot drew a two-pixel dash at
|
|
327
|
+
* the left of the panel: a bar has no intrinsic width to be centred at.
|
|
328
|
+
*/
|
|
329
|
+
[data-ui='loading-overlay']
|
|
330
|
+
> [data-part='scrim']
|
|
331
|
+
> [data-part='panel']
|
|
332
|
+
> [data-part='indicator'][data-default] {
|
|
333
|
+
justify-items: center;
|
|
334
|
+
justify-self: center;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/* ── The two lines ──────────────────────────────────────────────────────
|
|
338
|
+
*
|
|
339
|
+
* The first says what is happening and the second says what the first could
|
|
340
|
+
* not. Both wrap: a translated string is longer than the English one that
|
|
341
|
+
* was measured, and the panel is bounded by the region it is centred in.
|
|
342
|
+
*
|
|
343
|
+
* `overflow-wrap` rather than a truncation, because there is nowhere for
|
|
344
|
+
* truncated text to be read from — and the announcement holds the same
|
|
345
|
+
* sentence whole for the one reader who would otherwise lose it.
|
|
346
|
+
*
|
|
347
|
+
* The panel clips and never scrolls. A scroll container is what it was
|
|
348
|
+
* first, and the mark inside it turns: the rotation put a pixel or two of
|
|
349
|
+
* scrollable overflow into the box on every beat, and the box answered with
|
|
350
|
+
* a scrollbar that flickered in and out for as long as the wait lasted. A
|
|
351
|
+
* scrollbar nobody can reach for is not worth a defect that visible.
|
|
352
|
+
*/
|
|
353
|
+
[data-ui='loading-overlay'] > [data-part='scrim'] > [data-part='panel'] > [data-part='label'] {
|
|
354
|
+
font-size: var(--_text-size);
|
|
355
|
+
font-weight: var(--slotted-font-weight-medium, 500);
|
|
356
|
+
line-height: var(--_line-height);
|
|
357
|
+
overflow-wrap: anywhere;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
[data-ui='loading-overlay']
|
|
361
|
+
> [data-part='scrim']
|
|
362
|
+
> [data-part='panel']
|
|
363
|
+
> [data-part='description'] {
|
|
364
|
+
color: var(--slotted-text-muted, GrayText);
|
|
365
|
+
font-size: var(--_text-size);
|
|
366
|
+
line-height: var(--_line-height);
|
|
367
|
+
/**
|
|
368
|
+
* The two lines are one block and the panel's gap is not for use inside
|
|
369
|
+
* it. With one gap everywhere the panel read as four objects evenly
|
|
370
|
+
* spaced — mark, line, line, control — and the second line looked as far
|
|
371
|
+
* from the first as the control did from both.
|
|
372
|
+
*
|
|
373
|
+
* The gap between them is taken back to nothing, and what is left between
|
|
374
|
+
* the words is the leading the two line boxes already carry. That scales
|
|
375
|
+
* with the type at every step, where a fixed step would be tight at `lg`
|
|
376
|
+
* and loose at `sm`, and it leaves the panel's own gap to separate the
|
|
377
|
+
* three things that are actually separate.
|
|
378
|
+
*/
|
|
379
|
+
margin-block-start: calc(-1 * var(--_gap));
|
|
380
|
+
overflow-wrap: anywhere;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/* ── The control ────────────────────────────────────────────────────────
|
|
384
|
+
*
|
|
385
|
+
* The one thing in the layer that takes focus, and the only escape a reader
|
|
386
|
+
* has from a wait that has gone wrong. None of the seven surveyed
|
|
387
|
+
* implementations offers one, which is why a stuck overlay is a page reload
|
|
388
|
+
* in all of them.
|
|
389
|
+
*
|
|
390
|
+
* It reads the control scale rather than a scale of its own, so it is the
|
|
391
|
+
* size every other control at the same density is, and the theme's own
|
|
392
|
+
* validation keeps that above the WCAG target minimum.
|
|
393
|
+
*
|
|
394
|
+
* `:not([data-ui])` on every rule that paints it. A consumer who puts this
|
|
395
|
+
* library's own Button in the slot brings a control that is already painted,
|
|
396
|
+
* and two families painting one element is a button wearing a second set of
|
|
397
|
+
* clothes. The part is still the part — the panel's own layout, the focus
|
|
398
|
+
* move and the tight-region rules all still find it — and only the paint
|
|
399
|
+
* steps back.
|
|
400
|
+
*/
|
|
401
|
+
[data-ui='loading-overlay']
|
|
402
|
+
> [data-part='scrim']
|
|
403
|
+
> [data-part='panel']
|
|
404
|
+
> [data-part='cancel']:not([data-ui]) {
|
|
405
|
+
align-items: center;
|
|
406
|
+
background: transparent;
|
|
407
|
+
border: var(--slotted-control-border-width, 1px) solid
|
|
408
|
+
var(--slotted-control-border-color, ButtonBorder);
|
|
409
|
+
border-radius: var(--slotted-control-radius, 6px);
|
|
410
|
+
color: inherit;
|
|
411
|
+
cursor: pointer;
|
|
412
|
+
display: inline-flex;
|
|
413
|
+
font: inherit;
|
|
414
|
+
font-size: var(--slotted-control-font-size-sm, 0.8125rem);
|
|
415
|
+
justify-content: center;
|
|
416
|
+
min-block-size: var(--slotted-control-height-sm, 30px);
|
|
417
|
+
padding-inline: var(--slotted-control-padding-inline-sm, 0.5rem);
|
|
418
|
+
transition: background-color var(--slotted-duration-short) var(--slotted-easing-standard, ease);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* The neutral subtle pair, which is the ground every other unfilled control
|
|
423
|
+
* in the library answers hover and press with. The first capture used the
|
|
424
|
+
* sunken surface instead and the hover was invisible: on a raised panel that
|
|
425
|
+
* token is one or two per cent away from the ground it is drawn on, so the
|
|
426
|
+
* control looked inert while the pointer was on it.
|
|
427
|
+
*
|
|
428
|
+
* Both hold themselves back for `disabled`, which is the precedence
|
|
429
|
+
* `specs/contract.schema.mjs` declares and
|
|
430
|
+
* `packages/styles/src/states.test.mjs` enforces. A control the browser has
|
|
431
|
+
* already switched off must not look operable.
|
|
432
|
+
*/
|
|
433
|
+
[data-ui='loading-overlay']
|
|
434
|
+
> [data-part='scrim']
|
|
435
|
+
> [data-part='panel']
|
|
436
|
+
> [data-part='cancel']:not([data-ui]):hover:not(:disabled) {
|
|
437
|
+
background: var(--slotted-tone-secondary-subtle-hover);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
[data-ui='loading-overlay']
|
|
441
|
+
> [data-part='scrim']
|
|
442
|
+
> [data-part='panel']
|
|
443
|
+
> [data-part='cancel']:not([data-ui]):active:not(:disabled) {
|
|
444
|
+
background: var(--slotted-tone-secondary-subtle-active);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
[data-ui='loading-overlay']
|
|
448
|
+
> [data-part='scrim']
|
|
449
|
+
> [data-part='panel']
|
|
450
|
+
> [data-part='cancel']:not([data-ui]):disabled {
|
|
451
|
+
border-color: var(--slotted-disabled-border);
|
|
452
|
+
color: var(--slotted-disabled-foreground);
|
|
453
|
+
cursor: default;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
[data-ui='loading-overlay']
|
|
457
|
+
> [data-part='scrim']
|
|
458
|
+
> [data-part='panel']
|
|
459
|
+
> [data-part='cancel']:not([data-ui]):focus-visible {
|
|
460
|
+
outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
|
|
461
|
+
outline-offset: var(--slotted-focus-ring-offset, 2px);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* The panel takes focus when there is no control to take it — the
|
|
466
|
+
* `'container'` destination the APG advises for content that has to be read
|
|
467
|
+
* before it is operated. Script puts focus there and Tab never does, so the
|
|
468
|
+
* ring is the only thing the part needs.
|
|
469
|
+
*/
|
|
470
|
+
[data-ui='loading-overlay'] > [data-part='scrim'] > [data-part='panel']:focus-visible {
|
|
471
|
+
outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
|
|
472
|
+
outline-offset: var(--slotted-focus-ring-offset, 2px);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/* ── A region with no room for a column ─────────────────────────────────
|
|
476
|
+
*
|
|
477
|
+
* The panel is a column and a column is taller than most regions are. A card
|
|
478
|
+
* is a hundred and fifty pixels; a stacked mark, line, second line and
|
|
479
|
+
* control is a hundred and sixty. The first capture of this family showed
|
|
480
|
+
* exactly that: a panel taller than the box it was centred in, spilling over
|
|
481
|
+
* both edges with its control clipped.
|
|
482
|
+
*
|
|
483
|
+
* So the panel turns on its side rather than scrolling. The mark moves
|
|
484
|
+
* beside the text, the two lines stack next to it, and the control goes to
|
|
485
|
+
* the end of the row — a shape sixty pixels tall carrying everything the
|
|
486
|
+
* column carried. Nothing is dropped, which is what separates this from the
|
|
487
|
+
* next rule.
|
|
488
|
+
*
|
|
489
|
+
* `container-type: size` is what makes a block-size condition legal, and the
|
|
490
|
+
* scrim is the one element in the family that can carry it: its size comes
|
|
491
|
+
* from `inset: 0` rather than from its contents, so size containment costs
|
|
492
|
+
* nothing. The root could not — its block size is the covered content's.
|
|
493
|
+
*
|
|
494
|
+
* A row needs width the way a column needs height, and the second condition
|
|
495
|
+
* is what the capture at 240 pixels added: below 260 the row was a sentence
|
|
496
|
+
* broken into two-word lines beside a control, which is a worse answer than
|
|
497
|
+
* the mark alone. The rule below takes that case.
|
|
498
|
+
*/
|
|
499
|
+
@container slotted-loading-overlay ((height <= 168px) and (width > 260px)) {
|
|
500
|
+
/**
|
|
501
|
+
* The measure goes with the column. A card has a reading measure because a
|
|
502
|
+
* card is read; a bar across a short region has the region's own width, and
|
|
503
|
+
* holding it to eighteen rem is what squeezed a sentence into one word per
|
|
504
|
+
* line beside a control that then had nowhere to sit.
|
|
505
|
+
*/
|
|
506
|
+
[data-ui='loading-overlay'] > [data-part='scrim'] > [data-part='panel'] {
|
|
507
|
+
grid-template-columns: auto minmax(0, 1fr) auto;
|
|
508
|
+
justify-items: stretch;
|
|
509
|
+
max-inline-size: calc(100% - 2 * var(--_inset));
|
|
510
|
+
/**
|
|
511
|
+
* A bar takes a bar's width. Shrink-wrapped, the text column resolved
|
|
512
|
+
* narrower than the sentence in it and broke "Importing 4 812 rows"
|
|
513
|
+
* across two lines beside a control with room to spare on both sides —
|
|
514
|
+
* a panel a third the width of the region it covers, in a form chosen
|
|
515
|
+
* precisely because the region is wide.
|
|
516
|
+
*
|
|
517
|
+
* The floor is the column form's own measure, capped by the region, so
|
|
518
|
+
* the two arrangements agree about how wide a panel wants to be and the
|
|
519
|
+
* region still decides how wide it may be. The text track is `1fr` and
|
|
520
|
+
* takes everything the floor opened up: `auto` left the slack beside the
|
|
521
|
+
* control instead, and the sentence went on breaking in a panel with
|
|
522
|
+
* room for it.
|
|
523
|
+
*/
|
|
524
|
+
min-inline-size: min(
|
|
525
|
+
calc(100% - 2 * var(--_inset)),
|
|
526
|
+
var(--slotted-loading-overlay-measure, 18rem)
|
|
527
|
+
);
|
|
528
|
+
text-align: start;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* A mark the consumer supplied gets a track that can hold it. The family's
|
|
533
|
+
* own is a square and sizes itself; a determinate bar has no intrinsic
|
|
534
|
+
* width at all, and in an `auto` track it resolved to eight pixels — a
|
|
535
|
+
* dash at the left of the panel, which is what the first reference page
|
|
536
|
+
* showed.
|
|
537
|
+
*/
|
|
538
|
+
[data-ui='loading-overlay']
|
|
539
|
+
> [data-part='scrim']
|
|
540
|
+
> [data-part='panel']:not(:has(> [data-part='indicator'][data-default])) {
|
|
541
|
+
grid-template-columns: minmax(6rem, 2fr) minmax(0, 3fr) auto;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
[data-ui='loading-overlay']
|
|
545
|
+
> [data-part='scrim']
|
|
546
|
+
> [data-part='panel']
|
|
547
|
+
> [data-part='indicator'] {
|
|
548
|
+
align-self: center;
|
|
549
|
+
grid-column: 1;
|
|
550
|
+
grid-row: 1 / span 2;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
[data-ui='loading-overlay'] > [data-part='scrim'] > [data-part='panel'] > [data-part='label'] {
|
|
554
|
+
align-self: end;
|
|
555
|
+
grid-column: 2;
|
|
556
|
+
grid-row: 1;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
/**
|
|
560
|
+
* One line, and it takes both rows.
|
|
561
|
+
*
|
|
562
|
+
* The mark is taller than a single line, and a grid distributes a spanning
|
|
563
|
+
* item's excess height across the tracks it spans — so with the label in
|
|
564
|
+
* row 1 and row 2 left empty, the words sat at the top of a 34-pixel block
|
|
565
|
+
* with six pixels of nothing under them. The reviewer read it as text
|
|
566
|
+
* pinned to the ceiling of the bar, which is exactly what it was.
|
|
567
|
+
*/
|
|
568
|
+
[data-ui='loading-overlay']
|
|
569
|
+
> [data-part='scrim']
|
|
570
|
+
> [data-part='panel']:not(:has(> [data-part='description']))
|
|
571
|
+
> [data-part='label'] {
|
|
572
|
+
align-self: center;
|
|
573
|
+
grid-row: 1 / span 2;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
[data-ui='loading-overlay']
|
|
577
|
+
> [data-part='scrim']
|
|
578
|
+
> [data-part='panel']
|
|
579
|
+
> [data-part='description'] {
|
|
580
|
+
align-self: start;
|
|
581
|
+
grid-column: 2;
|
|
582
|
+
grid-row: 2;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
[data-ui='loading-overlay']
|
|
586
|
+
> [data-part='scrim']
|
|
587
|
+
> [data-part='panel']
|
|
588
|
+
> [data-part='cancel']:not([data-ui]) {
|
|
589
|
+
align-self: center;
|
|
590
|
+
grid-column: 3;
|
|
591
|
+
grid-row: 1 / span 2;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
/* ── A region too small to hold a sentence ──────────────────────────────
|
|
596
|
+
*
|
|
597
|
+
* Three ways for a region to have no room for words: it is narrower than 220
|
|
598
|
+
* pixels, it is shorter than 88, or it is short enough to want the row and
|
|
599
|
+
* too narrow to hold one. In all three the two lines go and the mark stays,
|
|
600
|
+
* centred in the region.
|
|
601
|
+
*
|
|
602
|
+
* They have not been taken away from anybody. They are in the announcement,
|
|
603
|
+
* which is where they were carrying meaning to a screen reader all along —
|
|
604
|
+
* so the smallest case loses paint and nothing else. Every surveyed
|
|
605
|
+
* implementation centres a fixed panel here and lets it spill out of the
|
|
606
|
+
* region instead.
|
|
607
|
+
*
|
|
608
|
+
* The ground goes only when the mark is all that is left. A control on no
|
|
609
|
+
* ground is a control floating over the content it is meant to be separate
|
|
610
|
+
* from, which is what the first capture of this rule showed: a Cancel
|
|
611
|
+
* sitting on a paragraph, unpainted and unreadable. `:has()` is what lets
|
|
612
|
+
* one rule ask whether the panel still holds a control.
|
|
613
|
+
*
|
|
614
|
+
* The numbers are literals because a container condition cannot hold a
|
|
615
|
+
* custom property.
|
|
616
|
+
*/
|
|
617
|
+
@container slotted-loading-overlay (
|
|
618
|
+
(width <= 220px) or (height <= 88px) or ((height <= 168px) and (width <= 260px))
|
|
619
|
+
) {
|
|
620
|
+
/**
|
|
621
|
+
* The one place the panel is allowed out of its region. Everywhere else it
|
|
622
|
+
* is capped at the region's own block size and scrolls, which is the right
|
|
623
|
+
* last resort for a pathological string; here there is no string, and what
|
|
624
|
+
* would be scrolled out of sight is a control. A 36-pixel table row cannot
|
|
625
|
+
* hold a mark and a Cancel, so a 58-pixel pill overhangs it by eleven
|
|
626
|
+
* pixels at each end — visible, pressable, and the lesser of the two.
|
|
627
|
+
*/
|
|
628
|
+
[data-ui='loading-overlay'] > [data-part='scrim'] > [data-part='panel'] {
|
|
629
|
+
--_floor: auto;
|
|
630
|
+
--_inset: 0px;
|
|
631
|
+
|
|
632
|
+
grid-template-columns: auto;
|
|
633
|
+
justify-items: center;
|
|
634
|
+
overflow: visible;
|
|
635
|
+
text-align: center;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
/**
|
|
639
|
+
* The mark is capped at what the region actually has. `cqb` measures the
|
|
640
|
+
* query container's content box, so the cap is the region's own height
|
|
641
|
+
* less the layer's inset — a 30-pixel table row gets a 14-pixel mark
|
|
642
|
+
* instead of a 30-pixel one hanging over both its edges.
|
|
643
|
+
*
|
|
644
|
+
* Three rules rather than one, because the cap has to be the step this
|
|
645
|
+
* overlay's own size axis asked for. A single rule capping at the largest
|
|
646
|
+
* step would grow an `sm` overlay's mark in a region that is narrow and
|
|
647
|
+
* tall, which is the other half of this query's condition.
|
|
648
|
+
*
|
|
649
|
+
* It applies only where the panel has given up its ground. A panel still
|
|
650
|
+
* holding a control keeps its padding and overhangs the region anyway, and
|
|
651
|
+
* a mark shrunk to the region's height beside a control that was not is
|
|
652
|
+
* two objects at two scales in one pill.
|
|
653
|
+
*/
|
|
654
|
+
[data-ui='loading-overlay'][data-size='sm']
|
|
655
|
+
> [data-part='scrim']
|
|
656
|
+
> [data-part='panel']:not(:has(> [data-part='cancel']))
|
|
657
|
+
> [data-part='indicator'] {
|
|
658
|
+
--slotted-progress-indicator-size: min(var(--slotted-control-height-sm, 30px), 100cqb);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
[data-ui='loading-overlay'][data-size='md']
|
|
662
|
+
> [data-part='scrim']
|
|
663
|
+
> [data-part='panel']:not(:has(> [data-part='cancel']))
|
|
664
|
+
> [data-part='indicator'] {
|
|
665
|
+
--slotted-progress-indicator-size: min(var(--slotted-control-height-md, 34px), 100cqb);
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
[data-ui='loading-overlay'][data-size='lg']
|
|
669
|
+
> [data-part='scrim']
|
|
670
|
+
> [data-part='panel']:not(:has(> [data-part='cancel']))
|
|
671
|
+
> [data-part='indicator'] {
|
|
672
|
+
--slotted-progress-indicator-size: min(var(--slotted-control-height-lg, 38px), 100cqb);
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
/**
|
|
676
|
+
* Mark and control side by side rather than stacked: the same two objects
|
|
677
|
+
* are 58 pixels tall in a row and 96 in a column, and the region that
|
|
678
|
+
* reached this rule has neither to spare.
|
|
679
|
+
*
|
|
680
|
+
* The block padding is what is left to give, and it is given in proportion
|
|
681
|
+
* rather than dropped: `clamp` spends it down to nothing as the region
|
|
682
|
+
* approaches the height of the control itself, so a 30-pixel table row
|
|
683
|
+
* gets a 30-pixel pill that fits inside it, and a narrow 180-pixel card
|
|
684
|
+
* keeps the padding it has room for.
|
|
685
|
+
*
|
|
686
|
+
* The cap is lifted here alone. Below the height of one control there is
|
|
687
|
+
* no arrangement that fits, and a pill overhanging a very short row by a
|
|
688
|
+
* few pixels is better than a control clipped out of reach — which is the
|
|
689
|
+
* one thing this family exists to avoid doing to a reader.
|
|
690
|
+
*/
|
|
691
|
+
[data-ui='loading-overlay']
|
|
692
|
+
> [data-part='scrim']
|
|
693
|
+
> [data-part='panel']:has(> [data-part='cancel']) {
|
|
694
|
+
align-items: center;
|
|
695
|
+
grid-auto-flow: column;
|
|
696
|
+
grid-template-columns: none;
|
|
697
|
+
max-block-size: none;
|
|
698
|
+
overflow: visible;
|
|
699
|
+
padding-block: clamp(
|
|
700
|
+
0px,
|
|
701
|
+
calc(
|
|
702
|
+
(
|
|
703
|
+
100cqb - var(--slotted-control-height-sm, 30px) - 2 *
|
|
704
|
+
var(--slotted-border-width-thin, 1px)
|
|
705
|
+
) /
|
|
706
|
+
2
|
|
707
|
+
),
|
|
708
|
+
var(--slotted-space-4, 0.5rem)
|
|
709
|
+
);
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
[data-ui='loading-overlay']
|
|
713
|
+
> [data-part='scrim']
|
|
714
|
+
> [data-part='panel']:not(:has(> [data-part='cancel'])) {
|
|
715
|
+
background: none;
|
|
716
|
+
border: 0;
|
|
717
|
+
box-shadow: none;
|
|
718
|
+
padding-block: 0;
|
|
719
|
+
padding-inline: 0;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
[data-ui='loading-overlay'] > [data-part='scrim'] > [data-part='panel'] > [data-part='label'],
|
|
723
|
+
[data-ui='loading-overlay']
|
|
724
|
+
> [data-part='scrim']
|
|
725
|
+
> [data-part='panel']
|
|
726
|
+
> [data-part='description'] {
|
|
727
|
+
display: none;
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
}
|