@slotted/styles 0.0.0-stage → 0.1.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +10 -2
- package/package.json +276 -3
- package/src/accordion/accordion.css +96 -0
- package/src/accordion/accordion.tokens.json +14 -0
- package/src/action-bar/action-bar.css +455 -0
- package/src/action-bar/action-bar.tokens.json +50 -0
- package/src/action-sheet/action-sheet.css +462 -0
- package/src/action-sheet/action-sheet.tokens.json +59 -0
- package/src/alert/alert.css +764 -0
- package/src/alert/alert.tokens.json +77 -0
- package/src/app-shell/app-shell.css +1899 -0
- package/src/app-shell/app-shell.tokens.json +88 -0
- package/src/aspect-ratio/aspect-ratio.css +131 -0
- package/src/aspect-ratio/aspect-ratio.tokens.json +1 -0
- package/src/attachment/attachment.css +906 -0
- package/src/attachment/attachment.tokens.json +85 -0
- package/src/avatar/avatar.css +598 -0
- package/src/avatar/avatar.tokens.json +64 -0
- package/src/avatar-group/avatar-group.css +268 -0
- package/src/avatar-group/avatar-group.tokens.json +16 -0
- package/src/badge/badge.css +462 -0
- package/src/badge/badge.tokens.json +58 -0
- package/src/breadcrumb/breadcrumb.css +441 -0
- package/src/breadcrumb/breadcrumb.tokens.json +50 -0
- package/src/button/button.css +754 -0
- package/src/button/button.tokens.json +72 -0
- package/src/button-group/button-group.css +455 -0
- package/src/button-group/button-group.tokens.json +11 -0
- package/src/calendar/calendar.css +846 -0
- package/src/calendar/calendar.tokens.json +67 -0
- package/src/card/card.css +602 -0
- package/src/card/card.tokens.json +68 -0
- package/src/carousel/carousel.css +860 -0
- package/src/carousel/carousel.tokens.json +62 -0
- package/src/cascader/cascader.css +1320 -0
- package/src/cascader/cascader.tokens.json +103 -0
- package/src/chart/chart.css +1473 -0
- package/src/chart/chart.tokens.json +107 -0
- package/src/checkbox/checkbox.css +1011 -0
- package/src/checkbox/checkbox.tokens.json +102 -0
- package/src/checkbox-group/checkbox-group.css +70 -0
- package/src/checkbox-group/checkbox-group.tokens.json +6 -0
- package/src/code-block/code-block.css +555 -0
- package/src/code-block/code-block.tokens.json +69 -0
- package/src/collapsible/collapsible.css +546 -0
- package/src/collapsible/collapsible.tokens.json +55 -0
- package/src/color-picker/color-picker.css +607 -0
- package/src/color-picker/color-picker.tokens.json +58 -0
- package/src/column-manager/column-manager.css +452 -0
- package/src/column-manager/column-manager.tokens.json +43 -0
- package/src/combobox/combobox.css +1048 -0
- package/src/combobox/combobox.tokens.json +112 -0
- package/src/command-palette/command-palette.css +1000 -0
- package/src/command-palette/command-palette.tokens.json +75 -0
- package/src/container/container.css +198 -0
- package/src/container/container.tokens.json +18 -0
- package/src/context-menu/context-menu.css +104 -0
- package/src/context-menu/context-menu.tokens.json +11 -0
- package/src/currency-field/currency-field.css +787 -0
- package/src/currency-field/currency-field.tokens.json +80 -0
- package/src/dashboard-grid/dashboard-grid.css +748 -0
- package/src/dashboard-grid/dashboard-grid.tokens.json +67 -0
- package/src/data-grid/data-grid.css +2484 -0
- package/src/data-grid/data-grid.tokens.json +100 -0
- package/src/data-list/data-list.css +455 -0
- package/src/data-list/data-list.tokens.json +35 -0
- package/src/date-field/date-field.css +560 -0
- package/src/date-field/date-field.tokens.json +80 -0
- package/src/date-picker/date-picker.css +420 -0
- package/src/date-picker/date-picker.tokens.json +49 -0
- package/src/date-range-picker/date-range-picker.css +983 -0
- package/src/date-range-picker/date-range-picker.tokens.json +109 -0
- package/src/datetime-field/datetime-field.css +850 -0
- package/src/datetime-field/datetime-field.tokens.json +91 -0
- package/src/datetime-picker/datetime-picker.css +843 -0
- package/src/datetime-picker/datetime-picker.tokens.json +78 -0
- package/src/datetime-range-picker/datetime-range-picker.css +1375 -0
- package/src/datetime-range-picker/datetime-range-picker.tokens.json +135 -0
- package/src/description-list/description-list.css +675 -0
- package/src/description-list/description-list.tokens.json +66 -0
- package/src/detail-panel/detail-panel.css +329 -0
- package/src/detail-panel/detail-panel.tokens.json +33 -0
- package/src/dialog/dialog.css +968 -0
- package/src/dialog/dialog.tokens.json +66 -0
- package/src/divider/divider.css +131 -0
- package/src/divider/divider.tokens.json +18 -0
- package/src/drawer/drawer.css +1303 -0
- package/src/drawer/drawer.tokens.json +75 -0
- package/src/entity-picker/entity-picker.css +1367 -0
- package/src/entity-picker/entity-picker.tokens.json +118 -0
- package/src/event-calendar/event-calendar.css +2148 -0
- package/src/event-calendar/event-calendar.tokens.json +87 -0
- package/src/field/field.css +707 -0
- package/src/field/field.tokens.json +58 -0
- package/src/field-group/field-group.css +226 -0
- package/src/field-group/field-group.tokens.json +33 -0
- package/src/filter-bar/filter-bar.css +1306 -0
- package/src/filter-bar/filter-bar.tokens.json +78 -0
- package/src/form/form.css +218 -0
- package/src/form/form.tokens.json +32 -0
- package/src/fullscreen/fullscreen.css +376 -0
- package/src/fullscreen/fullscreen.tokens.json +50 -0
- package/src/grid/grid.css +173 -0
- package/src/grid/grid.tokens.json +20 -0
- package/src/highlight/highlight.css +135 -0
- package/src/highlight/highlight.tokens.json +16 -0
- package/src/hover-card/hover-card.css +93 -0
- package/src/hover-card/hover-card.tokens.json +17 -0
- package/src/icon/icon.css +136 -0
- package/src/icon/icon.tokens.json +14 -0
- package/src/image/image.css +449 -0
- package/src/image/image.tokens.json +27 -0
- package/src/import-export-center/import-export-center.css +1175 -0
- package/src/import-export-center/import-export-center.tokens.json +84 -0
- package/src/inline/inline.css +149 -0
- package/src/inline/inline.tokens.json +14 -0
- package/src/inline-message/inline-message.css +396 -0
- package/src/inline-message/inline-message.tokens.json +19 -0
- package/src/kbd/kbd.css +490 -0
- package/src/kbd/kbd.tokens.json +40 -0
- package/src/link/link.css +237 -0
- package/src/link/link.tokens.json +25 -0
- package/src/list/list.css +240 -0
- package/src/list/list.tokens.json +42 -0
- package/src/list-item/list-item.css +937 -0
- package/src/list-item/list-item.tokens.json +114 -0
- package/src/listbox/listbox.css +674 -0
- package/src/listbox/listbox.tokens.json +72 -0
- package/src/loading-overlay/loading-overlay.css +730 -0
- package/src/loading-overlay/loading-overlay.tokens.json +48 -0
- package/src/markdown/markdown.css +168 -0
- package/src/markdown/markdown.tokens.json +18 -0
- package/src/menu/menu.css +817 -0
- package/src/menu/menu.tokens.json +78 -0
- package/src/menubar/menubar.css +170 -0
- package/src/menubar/menubar.tokens.json +32 -0
- package/src/message/message.css +1453 -0
- package/src/message/message.tokens.json +85 -0
- package/src/message-scroller/message-scroller.css +371 -0
- package/src/message-scroller/message-scroller.tokens.json +47 -0
- package/src/multi-select/multi-select.css +1427 -0
- package/src/multi-select/multi-select.tokens.json +114 -0
- package/src/navigation-menu/navigation-menu.css +1029 -0
- package/src/navigation-menu/navigation-menu.tokens.json +70 -0
- package/src/notification-center/notification-center.css +856 -0
- package/src/notification-center/notification-center.tokens.json +84 -0
- package/src/number-field/number-field.css +794 -0
- package/src/number-field/number-field.tokens.json +80 -0
- package/src/otp-input/otp-input.css +525 -0
- package/src/otp-input/otp-input.tokens.json +69 -0
- package/src/page/page.css +179 -0
- package/src/page/page.tokens.json +20 -0
- package/src/page-header/page-header.css +1181 -0
- package/src/page-header/page-header.tokens.json +71 -0
- package/src/pagination/pagination.css +500 -0
- package/src/pagination/pagination.tokens.json +56 -0
- package/src/popover/popover.css +526 -0
- package/src/popover/popover.tokens.json +60 -0
- package/src/progress-indicator/progress-indicator.css +1584 -0
- package/src/progress-indicator/progress-indicator.tokens.json +50 -0
- package/src/prompt-composer/prompt-composer.css +680 -0
- package/src/prompt-composer/prompt-composer.tokens.json +99 -0
- package/src/prose/prose.css +733 -0
- package/src/prose/prose.tokens.json +79 -0
- package/src/radio-group/radio-group.css +778 -0
- package/src/radio-group/radio-group.tokens.json +103 -0
- package/src/rating/rating.css +1071 -0
- package/src/rating/rating.tokens.json +88 -0
- package/src/result-state/result-state.css +980 -0
- package/src/result-state/result-state.tokens.json +63 -0
- package/src/runtime-properties.mjs +321 -0
- package/src/saved-views/saved-views.css +394 -0
- package/src/saved-views/saved-views.tokens.json +41 -0
- package/src/scroll-area/scroll-area.css +481 -0
- package/src/scroll-area/scroll-area.tokens.json +15 -0
- package/src/section/section.css +177 -0
- package/src/section/section.tokens.json +39 -0
- package/src/segmented-control/segmented-control.css +564 -0
- package/src/segmented-control/segmented-control.tokens.json +67 -0
- package/src/select/select.css +1593 -0
- package/src/select/select.tokens.json +110 -0
- package/src/side-navigation/side-navigation.css +1096 -0
- package/src/side-navigation/side-navigation.tokens.json +87 -0
- package/src/skeleton/skeleton.css +431 -0
- package/src/skeleton/skeleton.tokens.json +29 -0
- package/src/slider/slider.css +792 -0
- package/src/slider/slider.tokens.json +75 -0
- package/src/sparkline/sparkline.css +282 -0
- package/src/sparkline/sparkline.tokens.json +45 -0
- package/src/spinner/spinner.css +224 -0
- package/src/spinner/spinner.tokens.json +8 -0
- package/src/split-button/split-button.css +253 -0
- package/src/split-button/split-button.tokens.json +12 -0
- package/src/splitter/splitter.css +336 -0
- package/src/splitter/splitter.tokens.json +24 -0
- package/src/stack/stack.css +128 -0
- package/src/stack/stack.tokens.json +14 -0
- package/src/stat-card/stat-card.css +641 -0
- package/src/stat-card/stat-card.tokens.json +95 -0
- package/src/status-indicator/status-indicator.css +481 -0
- package/src/status-indicator/status-indicator.tokens.json +38 -0
- package/src/stepper/stepper.css +629 -0
- package/src/stepper/stepper.tokens.json +72 -0
- package/src/switch/switch.css +703 -0
- package/src/switch/switch.tokens.json +75 -0
- package/src/table/table.css +1482 -0
- package/src/table/table.tokens.json +69 -0
- package/src/table-of-contents/table-of-contents.css +533 -0
- package/src/table-of-contents/table-of-contents.tokens.json +53 -0
- package/src/tabs/tabs.css +998 -0
- package/src/tabs/tabs.tokens.json +82 -0
- package/src/tag/tag.css +768 -0
- package/src/tag/tag.tokens.json +85 -0
- package/src/tags-input/tags-input.css +757 -0
- package/src/tags-input/tags-input.tokens.json +84 -0
- package/src/text-field/text-field.css +900 -0
- package/src/text-field/text-field.tokens.json +87 -0
- package/src/textarea/textarea.css +365 -0
- package/src/textarea/textarea.tokens.json +59 -0
- package/src/time-field/time-field.css +719 -0
- package/src/time-field/time-field.tokens.json +86 -0
- package/src/time-picker/time-picker.css +665 -0
- package/src/time-picker/time-picker.tokens.json +66 -0
- package/src/time-range-picker/time-range-picker.css +1287 -0
- package/src/time-range-picker/time-range-picker.tokens.json +134 -0
- package/src/timeline/timeline.css +1596 -0
- package/src/timeline/timeline.tokens.json +96 -0
- package/src/toast/toast.css +943 -0
- package/src/toast/toast.tokens.json +90 -0
- package/src/toggle/toggle.css +290 -0
- package/src/toggle/toggle.tokens.json +54 -0
- package/src/toggle-group/toggle-group.css +463 -0
- package/src/toggle-group/toggle-group.tokens.json +54 -0
- package/src/toolbar/toolbar.css +434 -0
- package/src/toolbar/toolbar.tokens.json +49 -0
- package/src/tooltip/tooltip.css +368 -0
- package/src/tooltip/tooltip.tokens.json +39 -0
- package/src/top-navigation/top-navigation.css +1287 -0
- package/src/top-navigation/top-navigation.tokens.json +91 -0
- package/src/tour/tour.css +680 -0
- package/src/tour/tour.tokens.json +67 -0
- package/src/transfer/transfer.css +571 -0
- package/src/transfer/transfer.tokens.json +49 -0
- package/src/tree/tree.css +1000 -0
- package/src/tree/tree.tokens.json +80 -0
- package/src/typography/typography.css +211 -0
- package/src/typography/typography.tokens.json +31 -0
- package/src/upload/upload.css +1706 -0
- package/src/upload/upload.tokens.json +123 -0
- package/src/visually-hidden/visually-hidden.css +52 -0
- package/src/visually-hidden/visually-hidden.tokens.json +1 -0
- package/src/wizard/wizard.css +740 -0
- package/src/wizard/wizard.tokens.json +63 -0
|
@@ -0,0 +1,843 @@
|
|
|
1
|
+
@layer slotted.components {
|
|
2
|
+
/**
|
|
3
|
+
* ── A datetime field, a trigger, and two surfaces behind them ──────────
|
|
4
|
+
*
|
|
5
|
+
* ┌─ root ──────────────────────────────────────────────────────────┐
|
|
6
|
+
* │ ┌─ control ─────────────────────────────────────────────────┐ │
|
|
7
|
+
* │ │ datetime-field ┌ trigger ┐ │ │
|
|
8
|
+
* │ └───────────────────────────────────────────────────────────┘ │
|
|
9
|
+
* └─────────────────────────────────────────────────────────────────┘
|
|
10
|
+
* ┌─ positioner ─ the layer ────────────────────────────────┐
|
|
11
|
+
* │ ┌─ content ─ role="dialog" ────────────────────────┐ │
|
|
12
|
+
* │ │ head: now │ presets │ │
|
|
13
|
+
* │ │ ┌─ panels ────────────────────────────────────┐ │ │
|
|
14
|
+
* │ │ │ date-panel ─ calendar │ time-panel ─ list │ │ │
|
|
15
|
+
* │ │ └─────────────────────────────────────────────┘ │ │
|
|
16
|
+
* │ │ footer │ │
|
|
17
|
+
* │ └──────────────────────────────────────────────────┘ │
|
|
18
|
+
* └────────────────────────────────────────────────────────┘
|
|
19
|
+
*
|
|
20
|
+
* **The only family in the library holding two surfaces.** One layer, one
|
|
21
|
+
* dialog, and inside it a `grid` that `calendar` draws and a `listbox` that
|
|
22
|
+
* this family draws. Both are in the DOM at every width: a `tablist` that
|
|
23
|
+
* exists on a narrow container and not on a wide one tells assistive
|
|
24
|
+
* technology two different stories about the same component, and Kendo's tabs
|
|
25
|
+
* and MUI's mobile tabs are what that decline is against.
|
|
26
|
+
*
|
|
27
|
+
* `datetime-field` and `calendar` inside keep their own `data-ui`, so nothing
|
|
28
|
+
* here restyles a segment or a day cell. This stylesheet owns the box the
|
|
29
|
+
* positioner measures, the trigger inside the field, the layer, and the list.
|
|
30
|
+
*/
|
|
31
|
+
[data-ui='datetime-picker'][data-part='root'] {
|
|
32
|
+
display: block;
|
|
33
|
+
/* The anchor the positioner measures is the control, and a block root lets
|
|
34
|
+
the frame take the width the form gave it. */
|
|
35
|
+
inline-size: 100%;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* The box the positioner measures, and nothing else.
|
|
40
|
+
*
|
|
41
|
+
* It draws no frame: the `datetime-field` inside it draws its own, and the
|
|
42
|
+
* trigger is handed to that field's `end` slot by the binding.
|
|
43
|
+
*/
|
|
44
|
+
[data-ui='datetime-picker'] [data-part='control'] {
|
|
45
|
+
--_icon-size: var(--slotted-control-icon-size-md, 16px);
|
|
46
|
+
--_height: var(--slotted-control-height-md, 34px);
|
|
47
|
+
|
|
48
|
+
align-items: center;
|
|
49
|
+
display: flex;
|
|
50
|
+
inline-size: 100%;
|
|
51
|
+
min-inline-size: 0;
|
|
52
|
+
position: relative;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
[data-ui='datetime-picker'][data-part='root'][data-size='sm'] [data-part='control'] {
|
|
56
|
+
--_icon-size: var(--slotted-control-icon-size-sm, 14px);
|
|
57
|
+
--_height: var(--slotted-control-height-sm, 30px);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
[data-ui='datetime-picker'][data-part='root'][data-size='lg'] [data-part='control'] {
|
|
61
|
+
--_icon-size: var(--slotted-control-icon-size-lg, 18px);
|
|
62
|
+
--_height: var(--slotted-control-height-lg, 38px);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* The button that opens the panel.
|
|
67
|
+
*
|
|
68
|
+
* Its mark is a calendar, which is the mark `input[type=datetime-local]`
|
|
69
|
+
* draws for the same control and the one `date-picker` already uses. The
|
|
70
|
+
* panel holds two surfaces and each names itself inside; the trigger names
|
|
71
|
+
* the kind of value the control holds, which is the one thing about it that
|
|
72
|
+
* never changes — so it does not turn while the panel is open either. It is
|
|
73
|
+
* a `Glyph` the binding draws inside an `icon` box, at the field's icon step.
|
|
74
|
+
*
|
|
75
|
+
* It is always drawn. Angular Material records why: ChromeOS turns
|
|
76
|
+
* `Alt`+`ArrowDown` into `PageDown` before the browser sees it, so the chord
|
|
77
|
+
* cannot be the only way in.
|
|
78
|
+
*/
|
|
79
|
+
[data-ui='datetime-picker'] [data-part='trigger'] {
|
|
80
|
+
--slotted-icon-size: var(--_icon-size);
|
|
81
|
+
|
|
82
|
+
align-items: center;
|
|
83
|
+
appearance: none;
|
|
84
|
+
background-color: transparent;
|
|
85
|
+
block-size: var(
|
|
86
|
+
--slotted-datetime-picker-trigger-size,
|
|
87
|
+
min(
|
|
88
|
+
calc(var(--_icon-size) + 2 * var(--slotted-space-2, 0.25rem)),
|
|
89
|
+
calc(
|
|
90
|
+
var(--_height) - var(--slotted-control-border-width, 1px) * 2 -
|
|
91
|
+
var(--slotted-space-2, 0.25rem)
|
|
92
|
+
)
|
|
93
|
+
)
|
|
94
|
+
);
|
|
95
|
+
border: 0;
|
|
96
|
+
border-radius: var(--slotted-datetime-picker-radius, var(--slotted-control-radius, 4px));
|
|
97
|
+
color: var(--slotted-datetime-picker-trigger-color, var(--slotted-text-muted, GrayText));
|
|
98
|
+
cursor: pointer;
|
|
99
|
+
display: inline-flex;
|
|
100
|
+
flex: 0 0 auto;
|
|
101
|
+
inline-size: var(
|
|
102
|
+
--slotted-datetime-picker-trigger-size,
|
|
103
|
+
min(
|
|
104
|
+
calc(var(--_icon-size) + 2 * var(--slotted-space-2, 0.25rem)),
|
|
105
|
+
calc(
|
|
106
|
+
var(--_height) - var(--slotted-control-border-width, 1px) * 2 -
|
|
107
|
+
var(--slotted-space-2, 0.25rem)
|
|
108
|
+
)
|
|
109
|
+
)
|
|
110
|
+
);
|
|
111
|
+
justify-content: center;
|
|
112
|
+
padding: 0;
|
|
113
|
+
position: relative;
|
|
114
|
+
touch-action: manipulation;
|
|
115
|
+
transition:
|
|
116
|
+
background-color var(--slotted-control-transition-duration)
|
|
117
|
+
var(--slotted-control-transition-easing),
|
|
118
|
+
color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing);
|
|
119
|
+
-webkit-tap-highlight-color: transparent;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/* The hit area, recovered outside the paint, exactly as every other inner
|
|
123
|
+
control in the library recovers it. */
|
|
124
|
+
[data-ui='datetime-picker'] [data-part='trigger']::after {
|
|
125
|
+
content: '';
|
|
126
|
+
inset: min(0px, calc((100% - var(--slotted-target-min, 24px)) / 2));
|
|
127
|
+
position: absolute;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/* On a finger the target is the comfortable size in both axes and the box
|
|
131
|
+
is the one a mouse sees: the ground and the focus ring stay square, and
|
|
132
|
+
the hit area above grows to 44 pixels around them. Before the field's
|
|
133
|
+
clear it does not reach across it. */
|
|
134
|
+
@media (pointer: coarse) {
|
|
135
|
+
[data-ui='datetime-picker'] [data-part='trigger']::after {
|
|
136
|
+
inset: min(0px, calc((100% - var(--slotted-target-comfortable, 44px)) / 2));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
[data-ui='datetime-picker']
|
|
140
|
+
[data-part='end']:has(+ [data-part='clear']:not([hidden]))
|
|
141
|
+
> [data-part='trigger']::after {
|
|
142
|
+
inset-inline-end: 0;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
[data-ui='datetime-picker'] [data-part='trigger']:hover:not(:disabled):not([data-disabled]) {
|
|
147
|
+
background-color: var(
|
|
148
|
+
--slotted-datetime-picker-trigger-hover-background,
|
|
149
|
+
var(--slotted-tone-secondary-subtle-hover)
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
[data-ui='datetime-picker'] [data-part='trigger']:active:not(:disabled):not([data-disabled]) {
|
|
154
|
+
background-color: var(
|
|
155
|
+
--slotted-datetime-picker-trigger-active-background,
|
|
156
|
+
var(--slotted-tone-secondary-subtle-active)
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/* Its own ring: tabbing from the last segment to the trigger has to move
|
|
161
|
+
something visible, and the frame's ring would sit still. */
|
|
162
|
+
[data-ui='datetime-picker'] [data-part='trigger']:focus-visible {
|
|
163
|
+
outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
|
|
164
|
+
outline-offset: calc(var(--slotted-focus-ring-offset, 2px) * -1);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
[data-ui='datetime-picker'][data-part='root'][data-invalid] {
|
|
168
|
+
--slotted-focus-ring-color: var(
|
|
169
|
+
--slotted-datetime-picker-invalid-focus-ring-color,
|
|
170
|
+
var(--slotted-focus-ring-color-invalid, Highlight)
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
[data-ui='datetime-picker'] [data-part='trigger']:disabled {
|
|
175
|
+
color: var(--slotted-disabled-foreground);
|
|
176
|
+
cursor: not-allowed;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/* ── The layer ────────────────────────────────────────────────────────
|
|
180
|
+
*
|
|
181
|
+
* What `packages/core/src/positioner` writes `position`, `left` and `top`
|
|
182
|
+
* onto. The painted surface is one element in, as every anchored family in
|
|
183
|
+
* the library is built.
|
|
184
|
+
*/
|
|
185
|
+
[data-ui='datetime-picker'][data-part='positioner'] {
|
|
186
|
+
/* Only the block inset: the positioner writes `left` and never `right`,
|
|
187
|
+
and `inset-inline-start` would resolve to `right` in a right-to-left
|
|
188
|
+
document and win over the measured value. */
|
|
189
|
+
position: absolute;
|
|
190
|
+
inset-block-start: 0;
|
|
191
|
+
|
|
192
|
+
box-sizing: border-box;
|
|
193
|
+
isolation: isolate;
|
|
194
|
+
/* The layer is only a frame around the surface; the surface takes the
|
|
195
|
+
pointer, and the frame must not swallow a press meant for the page. */
|
|
196
|
+
pointer-events: none;
|
|
197
|
+
z-index: calc(var(--slotted-z-index-popover, 1100) + var(--slotted-layer-depth, 0));
|
|
198
|
+
|
|
199
|
+
/* The layer arrives along the axis it opens on and never along the inline
|
|
200
|
+
one, which is the rule `select` records. */
|
|
201
|
+
--_enter-distance: var(--slotted-space-2, 0.25rem);
|
|
202
|
+
opacity: 0;
|
|
203
|
+
translate: 0 calc(-1 * var(--_enter-distance));
|
|
204
|
+
transition:
|
|
205
|
+
opacity var(--slotted-duration-short) var(--slotted-easing-exit),
|
|
206
|
+
translate var(--slotted-duration-short) var(--slotted-easing-exit);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
[data-ui='datetime-picker'][data-part='positioner'][data-side='top'] {
|
|
210
|
+
translate: 0 var(--_enter-distance);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/* A lateral side has no block direction to arrive from, so it only fades. */
|
|
214
|
+
[data-ui='datetime-picker'][data-part='positioner']:is([data-side='left'], [data-side='right']) {
|
|
215
|
+
translate: 0 0;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
[data-ui='datetime-picker'][data-part='positioner'][data-open] {
|
|
219
|
+
opacity: 1;
|
|
220
|
+
translate: 0 0;
|
|
221
|
+
transition: none;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* The entrance is a keyframe animation and not a transition, for the reason
|
|
226
|
+
* `select` records: a transition starts from the style the browser computed
|
|
227
|
+
* last, and the positioner writes `data-side` in the same style update as the
|
|
228
|
+
* family opens the layer. A layer written open in static markup — the
|
|
229
|
+
* harness, a docs snippet — is simply there, and is photographed where it
|
|
230
|
+
* stands.
|
|
231
|
+
*/
|
|
232
|
+
[data-ui='datetime-picker'][data-part='positioner'][data-open][data-positioned] {
|
|
233
|
+
animation: slotted-datetime-picker-enter-down var(--slotted-duration-medium)
|
|
234
|
+
var(--slotted-easing-enter);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
[data-ui='datetime-picker'][data-part='positioner'][data-open][data-positioned][data-side='top'] {
|
|
238
|
+
animation-name: slotted-datetime-picker-enter-up;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
[data-ui='datetime-picker'][data-part='positioner'][data-open][data-positioned]:is(
|
|
242
|
+
[data-side='left'],
|
|
243
|
+
[data-side='right']
|
|
244
|
+
) {
|
|
245
|
+
animation-name: slotted-datetime-picker-fade;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
@keyframes slotted-datetime-picker-enter-down {
|
|
249
|
+
from {
|
|
250
|
+
opacity: 0;
|
|
251
|
+
translate: 0 calc(-1 * var(--_enter-distance));
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
@keyframes slotted-datetime-picker-enter-up {
|
|
256
|
+
from {
|
|
257
|
+
opacity: 0;
|
|
258
|
+
translate: 0 var(--_enter-distance);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
@keyframes slotted-datetime-picker-fade {
|
|
263
|
+
from {
|
|
264
|
+
opacity: 0;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/* Stillness keeps the fade and drops the movement. */
|
|
269
|
+
@media (prefers-reduced-motion: reduce) {
|
|
270
|
+
[data-ui='datetime-picker'][data-part='positioner'],
|
|
271
|
+
[data-ui='datetime-picker'][data-part='positioner'][data-side='top'],
|
|
272
|
+
[data-ui='datetime-picker'][data-part='positioner'][data-side='left'],
|
|
273
|
+
[data-ui='datetime-picker'][data-part='positioner'][data-side='right'] {
|
|
274
|
+
translate: 0 0;
|
|
275
|
+
transition: opacity var(--slotted-duration-short) var(--slotted-easing-exit);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
[data-ui='datetime-picker'][data-part='positioner'][data-open][data-positioned],
|
|
279
|
+
[data-ui='datetime-picker'][data-part='positioner'][data-open][data-positioned][data-side='top'],
|
|
280
|
+
[data-ui='datetime-picker'][data-part='positioner'][data-open][data-positioned][data-side='left'],
|
|
281
|
+
[data-ui='datetime-picker'][data-part='positioner'][data-open][data-positioned][data-side='right'] {
|
|
282
|
+
animation-name: slotted-datetime-picker-fade;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/* The anchor scrolled out of its own clipper. The panel is still open and
|
|
287
|
+
still belongs to a control the reader can no longer see. */
|
|
288
|
+
[data-ui='datetime-picker'][data-part='positioner'][data-detached] {
|
|
289
|
+
visibility: hidden;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* The surface.
|
|
294
|
+
*
|
|
295
|
+
* It is shrink-wrapped from the two panels and capped by the room the
|
|
296
|
+
* positioner measured, rather than sized to the anchor: a calendar has a
|
|
297
|
+
* width of its own and a field narrower than one would squeeze the month
|
|
298
|
+
* rather than the panel. That is also why there is **no container query
|
|
299
|
+
* here**. `container-type: inline-size` would make the surface's inline size
|
|
300
|
+
* independent of its contents, which is the opposite of what a panel sized to
|
|
301
|
+
* a calendar needs; the two panels wrap instead, which needs no threshold to
|
|
302
|
+
* guess at and cannot be wrong at a width nobody tested.
|
|
303
|
+
*/
|
|
304
|
+
[data-ui='datetime-picker'] [data-part='content'] {
|
|
305
|
+
background-color: var(--slotted-datetime-picker-surface, var(--slotted-surface-raised, Canvas));
|
|
306
|
+
border: var(--slotted-border-width-thin, 1px) solid
|
|
307
|
+
var(
|
|
308
|
+
--slotted-datetime-picker-content-border-color,
|
|
309
|
+
var(--slotted-border-subtle, ButtonBorder)
|
|
310
|
+
);
|
|
311
|
+
border-radius: var(--slotted-datetime-picker-content-radius, var(--slotted-radius-lg, 8px));
|
|
312
|
+
box-shadow: var(--slotted-datetime-picker-content-shadow, var(--slotted-shadow-md));
|
|
313
|
+
box-sizing: border-box;
|
|
314
|
+
color: var(--slotted-datetime-picker-content-color, var(--slotted-text, CanvasText));
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* One row's height, stated once, because the list's cap is counted in rows
|
|
318
|
+
* at every density. Read from the control scale rather than from the target
|
|
319
|
+
* floor alone, so a dense panel shrinks its rows and its cap together — the
|
|
320
|
+
* alternative shrinks only the cap and shows fewer options, which is
|
|
321
|
+
* density changing what a reader can see rather than how much room it
|
|
322
|
+
* takes.
|
|
323
|
+
*/
|
|
324
|
+
--_row: max(var(--slotted-target-min, 24px), var(--slotted-control-height-sm, 30px));
|
|
325
|
+
--_row-pitch: calc(var(--_row) + var(--slotted-space-1, 0.125rem));
|
|
326
|
+
|
|
327
|
+
display: grid;
|
|
328
|
+
gap: var(--slotted-space-2, 0.25rem);
|
|
329
|
+
grid-template-areas: 'head' 'panels' 'footer';
|
|
330
|
+
grid-template-columns: minmax(0, 1fr);
|
|
331
|
+
inline-size: auto;
|
|
332
|
+
max-inline-size: min(34rem, var(--slotted-positioner-available-width, 34rem));
|
|
333
|
+
padding: var(--slotted-datetime-picker-content-padding, var(--slotted-space-3, 0.375rem));
|
|
334
|
+
/* The layer above gave up the pointer; the surface takes it back. */
|
|
335
|
+
pointer-events: auto;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* The head band.
|
|
340
|
+
*
|
|
341
|
+
* It says what the reader has chosen **so far**, which is the one thing
|
|
342
|
+
* neither surface can show: a month grid says which day is chosen and a
|
|
343
|
+
* column of times says which time is, and a reader who chose a day and is now
|
|
344
|
+
* reading a column of times has nothing telling them which day those times
|
|
345
|
+
* belong to. No surveyed panel says it at all.
|
|
346
|
+
*
|
|
347
|
+
* It replaces a pair of labels — `Data` and `Hora`, each with a mark small
|
|
348
|
+
* enough to sit in eleven-pixel text — that were decoration twice over: a
|
|
349
|
+
* month grid is a date and a column of times is times, which is why none of
|
|
350
|
+
* the four surveyed panels labels either, and a mark that small is a mark
|
|
351
|
+
* nobody can read. The listbox's name is written in `aria-label` instead,
|
|
352
|
+
* where a name belongs when the thing it names says what it is.
|
|
353
|
+
*
|
|
354
|
+
* The rule under it is what makes this a band rather than a line of text
|
|
355
|
+
* floating over two columns.
|
|
356
|
+
*/
|
|
357
|
+
[data-ui='datetime-picker'] [data-part='head'] {
|
|
358
|
+
/**
|
|
359
|
+
* The band renders at the panel's width and contributes nothing to it.
|
|
360
|
+
*
|
|
361
|
+
* A grid track sizes to the widest thing in it, so a row of the consumer's
|
|
362
|
+
* own shortcuts stretched the whole panel — and with it the column of
|
|
363
|
+
* times, which then ran the width of a page. `inline-size: 0` takes the
|
|
364
|
+
* band out of that measurement and `min-inline-size: 100%` puts it back at
|
|
365
|
+
* the track's own width, so the two surfaces decide how wide the panel is
|
|
366
|
+
* and the band wraps inside whatever they decide.
|
|
367
|
+
*/
|
|
368
|
+
/* `border-box`, and it is load-bearing: under `content-box` the percentage
|
|
369
|
+
resolves to the content box and the padding is added on top, so the band
|
|
370
|
+
came out twelve pixels wider than the area it sits in and pushed the
|
|
371
|
+
control at its end six pixels past the panel's own edge. */
|
|
372
|
+
box-sizing: border-box;
|
|
373
|
+
inline-size: 0;
|
|
374
|
+
min-inline-size: 100%;
|
|
375
|
+
|
|
376
|
+
align-items: center;
|
|
377
|
+
border-block-end: var(--slotted-border-width-thin, 1px) solid
|
|
378
|
+
var(
|
|
379
|
+
--slotted-datetime-picker-content-border-color,
|
|
380
|
+
var(--slotted-border-subtle, ButtonBorder)
|
|
381
|
+
);
|
|
382
|
+
column-gap: var(--slotted-space-4, 0.5rem);
|
|
383
|
+
display: flex;
|
|
384
|
+
flex-wrap: wrap;
|
|
385
|
+
grid-area: head;
|
|
386
|
+
justify-content: space-between;
|
|
387
|
+
/**
|
|
388
|
+
* No inline padding of its own. The surface's own padding is the panel's
|
|
389
|
+
* one gutter, and every box under this band starts and ends on it: the
|
|
390
|
+
* month's column, the page trigger inside it, the list's column and the
|
|
391
|
+
* ground of every row in it. With six pixels more here the title stood six
|
|
392
|
+
* pixels inside the month below it and the control at the end stopped six
|
|
393
|
+
* pixels short of the rows below *it* — two edges that almost line up,
|
|
394
|
+
* which reads worse than two that plainly do not.
|
|
395
|
+
*
|
|
396
|
+
* Measured on the default theme at `comfortable`, 720 pixels: the surface's
|
|
397
|
+
* inner edges are 32 and 405.4, and the month's column, the list's column
|
|
398
|
+
* and this band now all begin and end there.
|
|
399
|
+
*/
|
|
400
|
+
/**
|
|
401
|
+
* Air under the controls before the rule — the same step the footer keeps
|
|
402
|
+
* between its own rule and its buttons, so the two bands hold the surface
|
|
403
|
+
* symmetrically. With none, the rule read as an underline on `now` and on
|
|
404
|
+
* the consumer's shortcuts rather than as the bottom of the band they
|
|
405
|
+
* stand in.
|
|
406
|
+
*/
|
|
407
|
+
padding-block-end: var(--slotted-space-3, 0.375rem);
|
|
408
|
+
row-gap: var(--slotted-space-2, 0.25rem);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* The value as it stands. It is the panel's own title, so it takes the
|
|
413
|
+
* surface's ink and a step of weight, and its digits line up with the list's
|
|
414
|
+
* below it.
|
|
415
|
+
*/
|
|
416
|
+
[data-ui='datetime-picker'] [data-part='head-value'] {
|
|
417
|
+
color: var(--slotted-datetime-picker-content-color, var(--slotted-text, CanvasText));
|
|
418
|
+
font-size: var(--slotted-font-size-sm, 13px);
|
|
419
|
+
font-variant-numeric: tabular-nums;
|
|
420
|
+
font-weight: var(--slotted-font-weight-medium, 500);
|
|
421
|
+
min-inline-size: 0;
|
|
422
|
+
/* A datetime in words is a mixed run — a month name beside two numbers — so
|
|
423
|
+
it is laid out by its own content rather than by the paragraph, which is
|
|
424
|
+
the rule the field's own preview records. */
|
|
425
|
+
unicode-bidi: plaintext;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* The half the reader has not written yet, drawn as its placeholder beside
|
|
430
|
+
* the half they have. It is the family's own answer to a value that is not
|
|
431
|
+
* whole, said where the reader is looking rather than only in the field.
|
|
432
|
+
*/
|
|
433
|
+
[data-ui='datetime-picker'] [data-part='head-value'] [data-placeholder] {
|
|
434
|
+
color: var(--slotted-datetime-picker-label-color, var(--slotted-text-muted, GrayText));
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* One press for the current datetime — what a reader who never discovers that
|
|
439
|
+
* `+` opens an expression still has.
|
|
440
|
+
*
|
|
441
|
+
* It is drawn as a control and not as a link. `time-picker` writes its own
|
|
442
|
+
* `now` as accent text, and alone at the head of a single list that reads
|
|
443
|
+
* correctly; here it stands at the end of a band opposite a title, where bare
|
|
444
|
+
* coloured text is a third register beside the panel's plain ink and its one
|
|
445
|
+
* solid accent block — it read as a stray link rather than as the shortcut it
|
|
446
|
+
* is. A quiet bordered control at the small step is the shape the library
|
|
447
|
+
* already gives an action of this weight, and the divergence from the sibling
|
|
448
|
+
* is the band around it.
|
|
449
|
+
*
|
|
450
|
+
* It carries the clock, which is the second of the family's two marks and the
|
|
451
|
+
* only place one earns its keep: this is the control that writes a time, so
|
|
452
|
+
* the mark names what it does, and at the control glyph size inside a control
|
|
453
|
+
* it is legible rather than a speck beside a word.
|
|
454
|
+
*/
|
|
455
|
+
[data-ui='datetime-picker'] [data-part='now'] {
|
|
456
|
+
align-items: center;
|
|
457
|
+
appearance: none;
|
|
458
|
+
background-color: var(--slotted-datetime-picker-now-background, transparent);
|
|
459
|
+
/* The control's own border token rather than the surface's subtle one: this
|
|
460
|
+
button stands *on* the raised surface, where `--slotted-border-subtle` is
|
|
461
|
+
within a shade of the ground and the dark capture showed no edge at all. */
|
|
462
|
+
border: var(--slotted-control-border-width, 1px) solid
|
|
463
|
+
var(
|
|
464
|
+
--slotted-datetime-picker-now-border-color,
|
|
465
|
+
var(--slotted-control-border-color, ButtonBorder)
|
|
466
|
+
);
|
|
467
|
+
border-radius: var(--slotted-datetime-picker-radius, var(--slotted-control-radius, 4px));
|
|
468
|
+
color: var(--slotted-datetime-picker-now-color, var(--slotted-text, CanvasText));
|
|
469
|
+
cursor: pointer;
|
|
470
|
+
display: inline-flex;
|
|
471
|
+
flex: 0 0 auto;
|
|
472
|
+
font: inherit;
|
|
473
|
+
font-size: var(--slotted-control-font-size-sm, 12px);
|
|
474
|
+
gap: var(--slotted-space-2, 0.25rem);
|
|
475
|
+
justify-content: center;
|
|
476
|
+
min-block-size: var(--slotted-control-height-sm, 30px);
|
|
477
|
+
padding-block: 0;
|
|
478
|
+
padding-inline: var(--slotted-control-padding-inline-sm, 10px);
|
|
479
|
+
touch-action: manipulation;
|
|
480
|
+
transition:
|
|
481
|
+
background-color var(--slotted-control-transition-duration)
|
|
482
|
+
var(--slotted-control-transition-easing),
|
|
483
|
+
border-color var(--slotted-control-transition-duration)
|
|
484
|
+
var(--slotted-control-transition-easing);
|
|
485
|
+
white-space: nowrap;
|
|
486
|
+
-webkit-tap-highlight-color: transparent;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* The mark — the clock `Glyph` the binding draws before the label, at the
|
|
491
|
+
* `sm` icon step — takes the muted ink the label does not, so the pair reads
|
|
492
|
+
* as one control with a glyph rather than as two things of equal weight.
|
|
493
|
+
*/
|
|
494
|
+
[data-ui='datetime-picker'] [data-part='now'] > [data-ui='icon'] {
|
|
495
|
+
/* No system colour: a theme that never loaded should let the mark take the
|
|
496
|
+
label's ink rather than the operating system's own grey, which is the
|
|
497
|
+
rule `fallbacks.test.mjs` holds. */
|
|
498
|
+
color: var(--slotted-datetime-picker-now-icon-color, var(--slotted-text-muted));
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
[data-ui='datetime-picker'] [data-part='now']:hover:not(:disabled):not([data-disabled]) {
|
|
502
|
+
background-color: var(
|
|
503
|
+
--slotted-datetime-picker-now-hover-background,
|
|
504
|
+
var(--slotted-tone-secondary-subtle-hover)
|
|
505
|
+
);
|
|
506
|
+
border-color: var(
|
|
507
|
+
--slotted-datetime-picker-now-hover-border-color,
|
|
508
|
+
var(--slotted-tone-accent-border)
|
|
509
|
+
);
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
[data-ui='datetime-picker'] [data-part='now']:active:not(:disabled):not([data-disabled]) {
|
|
513
|
+
background-color: var(
|
|
514
|
+
--slotted-datetime-picker-now-active-background,
|
|
515
|
+
var(--slotted-tone-secondary-subtle-active)
|
|
516
|
+
);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
[data-ui='datetime-picker'] [data-part='now']:focus-visible {
|
|
520
|
+
outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
|
|
521
|
+
outline-offset: calc(var(--slotted-focus-ring-offset, 2px) * -1);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* The consumer's own shortcuts. This family ships no list of them: "tomorrow
|
|
526
|
+
* at nine" is a business clock, and a library that guessed at one would be
|
|
527
|
+
* guessing at an industry. What it ships is the row they stand in, at the
|
|
528
|
+
* reading end of the head beside `now`.
|
|
529
|
+
*/
|
|
530
|
+
[data-ui='datetime-picker'] [data-part='presets'] {
|
|
531
|
+
align-items: center;
|
|
532
|
+
display: flex;
|
|
533
|
+
flex-wrap: wrap;
|
|
534
|
+
gap: var(--slotted-space-2, 0.25rem);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
/* ── The two panels ───────────────────────────────────────────────────
|
|
538
|
+
*
|
|
539
|
+
* A wrapping flex row of exactly two items, in the value's own order. Where
|
|
540
|
+
* the positioner measured room for both, they stand side by side; where it
|
|
541
|
+
* did not, the time panel wraps under the date panel and nothing is hidden.
|
|
542
|
+
*
|
|
543
|
+
* The reflow is the row's own, at every width. `openTo` does not reorder it:
|
|
544
|
+
* moving a whole calendar because focus starts elsewhere would make one
|
|
545
|
+
* setting look like a different component, and what answers the narrow case
|
|
546
|
+
* is `scrollIntoView` on the surface focus lands in.
|
|
547
|
+
*/
|
|
548
|
+
[data-ui='datetime-picker'] [data-part='panels'] {
|
|
549
|
+
/**
|
|
550
|
+
* The two columns are told apart by the air between them and by what they
|
|
551
|
+
* hold, not by a rule. A rule would have to be on one inline edge, and the
|
|
552
|
+
* same declaration is a divider beside the month in one arrangement and a
|
|
553
|
+
* stray line under it in the other — the arrangement is the row's own and
|
|
554
|
+
* no selector can tell which one is on screen.
|
|
555
|
+
*/
|
|
556
|
+
column-gap: var(--slotted-space-6, 1rem);
|
|
557
|
+
display: flex;
|
|
558
|
+
flex-wrap: wrap;
|
|
559
|
+
grid-area: panels;
|
|
560
|
+
min-inline-size: 0;
|
|
561
|
+
row-gap: var(--slotted-space-4, 0.5rem);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* The month's column never shrinks below the month.
|
|
566
|
+
*
|
|
567
|
+
* A calendar has an intrinsic width — its cell is a share of its own
|
|
568
|
+
* container — and this column is that width. A flexible basis with
|
|
569
|
+
* `min-inline-size: 0` would let the grid be squeezed under it, and a squeezed
|
|
570
|
+
* month is the half of this panel a reader came for. When the room runs out it
|
|
571
|
+
* is the time panel that wraps instead, which is the arrangement this family
|
|
572
|
+
* already draws.
|
|
573
|
+
*/
|
|
574
|
+
[data-ui='datetime-picker'] [data-part='date-panel'] {
|
|
575
|
+
flex: 0 0 auto;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* The list's column.
|
|
580
|
+
*
|
|
581
|
+
* `flex-grow: 1` against a basis of seven rem does two things at once and
|
|
582
|
+
* needs no query to tell them apart. Beside the month, the surface is
|
|
583
|
+
* shrink-wrapped to the sum of the two bases, so there is no free space to
|
|
584
|
+
* grow into and the column stays the narrow one it should be — a column of
|
|
585
|
+
* times spread across half a panel is a column of numbers nobody chose that
|
|
586
|
+
* shape for. Wrapped onto a line of its own, the free space is the whole line
|
|
587
|
+
* and the column takes it, so the times read as a section rather than as a
|
|
588
|
+
* narrow strip under a wide month.
|
|
589
|
+
*/
|
|
590
|
+
[data-ui='datetime-picker'] [data-part='time-panel'] {
|
|
591
|
+
display: flex;
|
|
592
|
+
flex: 1 1 var(--slotted-datetime-picker-time-panel-inline-size, 7rem);
|
|
593
|
+
flex-direction: column;
|
|
594
|
+
gap: var(--slotted-space-2, 0.25rem);
|
|
595
|
+
min-inline-size: var(--slotted-datetime-picker-time-panel-inline-size, 7rem);
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
/* ── The list ─────────────────────────────────────────────────────────
|
|
599
|
+
*
|
|
600
|
+
* One column of times on the day the reader is on, capped in control heights
|
|
601
|
+
* so the cap holds at every density and every type step, and scrolled rather
|
|
602
|
+
* than truncated: a day of quarter-hours is ninety-six rows and every one of
|
|
603
|
+
* them is choosable.
|
|
604
|
+
*/
|
|
605
|
+
[data-ui='datetime-picker'] [data-part='list'] {
|
|
606
|
+
display: flex;
|
|
607
|
+
flex: 1 1 auto;
|
|
608
|
+
flex-direction: column;
|
|
609
|
+
/**
|
|
610
|
+
* One step of air between rows, so the chosen row's painted ground and the
|
|
611
|
+
* focused row's inset ring never share an edge. Touching, the two read as
|
|
612
|
+
* one band with a dark underline rather than as two states of two rows.
|
|
613
|
+
*/
|
|
614
|
+
gap: var(--slotted-space-1, 0.125rem);
|
|
615
|
+
/**
|
|
616
|
+
* Seven rows and a half, which is deliberately *shorter* than a six-week
|
|
617
|
+
* month: the month is what governs the height of a panel holding both, and
|
|
618
|
+
* a list one row taller left the calendar's column with dead space under it
|
|
619
|
+
* and cut the list's last row against the panel's own border. Under the cap
|
|
620
|
+
* the list stretches to whatever the month leaves, so the two surfaces end
|
|
621
|
+
* on the same line at every density and in every month.
|
|
622
|
+
*
|
|
623
|
+
* The half is the point wherever the cap is what applies — the wrapped
|
|
624
|
+
* arrangement and the sheet: a list cut on a row boundary looks like the
|
|
625
|
+
* whole list, and a reader who cannot see that ninety-six times are
|
|
626
|
+
* available never scrolls for them.
|
|
627
|
+
*/
|
|
628
|
+
max-block-size: var(--slotted-datetime-picker-list-block-size, calc(var(--_row-pitch) * 7.5));
|
|
629
|
+
/* Beside a month, the column is stretched to the month's height and the
|
|
630
|
+
list fills what the label leaves — so the list is as tall as the calendar
|
|
631
|
+
rather than a number of rows chosen against nothing. The cap above is
|
|
632
|
+
what holds when there is no month beside it, which is the wrapped
|
|
633
|
+
arrangement and the sheet. */
|
|
634
|
+
min-block-size: 0;
|
|
635
|
+
min-inline-size: 0;
|
|
636
|
+
overflow-y: auto;
|
|
637
|
+
/* A highlight moved by a key lands whole rather than half under the edge. */
|
|
638
|
+
scroll-padding-block: var(--slotted-space-2, 0.25rem);
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
/**
|
|
642
|
+
* One time on the day the reader is on.
|
|
643
|
+
*
|
|
644
|
+
* The row carries the time and nothing else. The day is the calendar's to
|
|
645
|
+
* say, and repeating it ninety-six times beside a month that already shows it
|
|
646
|
+
* would spend the whole column on one word.
|
|
647
|
+
*/
|
|
648
|
+
[data-ui='datetime-picker'] [data-part='option'] {
|
|
649
|
+
align-items: center;
|
|
650
|
+
background-color: transparent;
|
|
651
|
+
border-radius: var(--slotted-datetime-picker-option-radius, var(--slotted-radius-sm, 4px));
|
|
652
|
+
color: inherit;
|
|
653
|
+
cursor: pointer;
|
|
654
|
+
display: flex;
|
|
655
|
+
flex: 0 0 auto;
|
|
656
|
+
font-variant-numeric: tabular-nums;
|
|
657
|
+
gap: var(--slotted-space-2, 0.25rem);
|
|
658
|
+
/* The row *is* `--_row`: no block padding on top of it, so eight rows are
|
|
659
|
+
eight rows and the cap that counts them is arithmetic rather than an
|
|
660
|
+
estimate. A time never wraps, so there is nothing for the padding to
|
|
661
|
+
protect. */
|
|
662
|
+
min-block-size: var(--_row);
|
|
663
|
+
padding-inline: var(--slotted-space-3, 0.375rem);
|
|
664
|
+
transition:
|
|
665
|
+
background-color var(--slotted-control-transition-duration)
|
|
666
|
+
var(--slotted-control-transition-easing),
|
|
667
|
+
color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing);
|
|
668
|
+
user-select: none;
|
|
669
|
+
-webkit-tap-highlight-color: transparent;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
/* ── Option states ────────────────────────────────────────────────────
|
|
673
|
+
*
|
|
674
|
+
* Written strongest last, and each weaker one guarded against every stronger
|
|
675
|
+
* one it can meet, which is the order `STATE_PRECEDENCE` sets: the chosen
|
|
676
|
+
* time outranks the highlight, and the highlight outranks the pointer.
|
|
677
|
+
*
|
|
678
|
+
* Specificity is what makes this a rule rather than an ordering: a hover
|
|
679
|
+
* selector carrying `:hover` and one `:not()` outweighs a plain
|
|
680
|
+
* `[data-selected]`, so a chosen row turns grey under the pointer however far
|
|
681
|
+
* down the file its own rule is written. Found by the reviewer at
|
|
682
|
+
* `time-picker`'s visual gate and inherited whole.
|
|
683
|
+
*/
|
|
684
|
+
[data-ui='datetime-picker']
|
|
685
|
+
[data-part='option']:hover:not([data-disabled]):not([data-selected]):not([data-current]) {
|
|
686
|
+
background-color: var(
|
|
687
|
+
--slotted-datetime-picker-option-hover-background,
|
|
688
|
+
var(--slotted-tone-secondary-subtle-hover)
|
|
689
|
+
);
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
[data-ui='datetime-picker'] [data-part='option'][data-current]:not([data-selected]) {
|
|
693
|
+
background-color: var(
|
|
694
|
+
--slotted-datetime-picker-option-current-background,
|
|
695
|
+
var(--slotted-tone-secondary-subtle-active)
|
|
696
|
+
);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
[data-ui='datetime-picker'] [data-part='option']:focus-visible {
|
|
700
|
+
outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
|
|
701
|
+
outline-offset: calc(var(--slotted-focus-ring-offset, 2px) * -1);
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
[data-ui='datetime-picker'] [data-part='option'][data-selected] {
|
|
705
|
+
background-color: var(
|
|
706
|
+
--slotted-datetime-picker-option-selected-background,
|
|
707
|
+
var(--slotted-tone-accent-solid)
|
|
708
|
+
);
|
|
709
|
+
color: var(
|
|
710
|
+
--slotted-datetime-picker-option-selected-color,
|
|
711
|
+
var(--slotted-tone-accent-on-solid)
|
|
712
|
+
);
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
/* The chosen row still answers the pointer — one step along its own tone,
|
|
716
|
+
rather than the grey every other row takes. A row that swapped colour
|
|
717
|
+
family under the pointer read as a different row. */
|
|
718
|
+
[data-ui='datetime-picker'] [data-part='option'][data-selected]:hover:not([data-disabled]) {
|
|
719
|
+
background-color: var(
|
|
720
|
+
--slotted-datetime-picker-option-selected-hover-background,
|
|
721
|
+
var(--slotted-tone-accent-solid-hover)
|
|
722
|
+
);
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
/**
|
|
726
|
+
* A time a bound or a predicate refuses. It stays in the list by default,
|
|
727
|
+
* because a list that silently drops rows is a list whose step the reader
|
|
728
|
+
* cannot infer — and it is muted to the colour the theme measures rather than
|
|
729
|
+
* faded by opacity, so it stays readable.
|
|
730
|
+
*/
|
|
731
|
+
[data-ui='datetime-picker'] [data-part='option'][data-disabled] {
|
|
732
|
+
background-color: transparent;
|
|
733
|
+
color: var(--slotted-disabled-foreground);
|
|
734
|
+
cursor: not-allowed;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
/**
|
|
738
|
+
* The day the reader is on offers no time at all — a closed Saturday, a
|
|
739
|
+
* window `minTime` and `maxTime` leave empty, a predicate that refuses every
|
|
740
|
+
* step. It is a sentence rather than an empty box, and it is the state that
|
|
741
|
+
* makes the list worth recomputing as the reader moves through the month.
|
|
742
|
+
*/
|
|
743
|
+
[data-ui='datetime-picker'] [data-part='empty'] {
|
|
744
|
+
align-items: center;
|
|
745
|
+
color: var(--slotted-datetime-picker-label-color, var(--slotted-text-muted, GrayText));
|
|
746
|
+
display: flex;
|
|
747
|
+
flex: 1 1 auto;
|
|
748
|
+
justify-content: center;
|
|
749
|
+
min-block-size: calc(var(--_row) * 2);
|
|
750
|
+
padding: var(--slotted-space-4, 0.5rem);
|
|
751
|
+
text-align: center;
|
|
752
|
+
text-wrap: balance;
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
[data-ui='datetime-picker'] [data-part='footer'] {
|
|
756
|
+
/* The band's rule, for the same reason: a consumer's two buttons are not
|
|
757
|
+
what decides how wide a month is drawn — and `border-box` with it, or the
|
|
758
|
+
padding pushes the last button past the panel's edge. */
|
|
759
|
+
box-sizing: border-box;
|
|
760
|
+
inline-size: 0;
|
|
761
|
+
min-inline-size: 100%;
|
|
762
|
+
|
|
763
|
+
align-items: center;
|
|
764
|
+
border-block-start: var(--slotted-border-width-thin, 1px) solid
|
|
765
|
+
var(
|
|
766
|
+
--slotted-datetime-picker-content-border-color,
|
|
767
|
+
var(--slotted-border-subtle, ButtonBorder)
|
|
768
|
+
);
|
|
769
|
+
display: flex;
|
|
770
|
+
gap: var(--slotted-space-2, 0.25rem);
|
|
771
|
+
grid-area: footer;
|
|
772
|
+
justify-content: flex-end;
|
|
773
|
+
/* The same one gutter: the last button ends where the rows above it end. */
|
|
774
|
+
padding-block-start: var(--slotted-space-3, 0.375rem);
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
/* ── Narrow, on a finger ──────────────────────────────────────────────
|
|
778
|
+
*
|
|
779
|
+
* §2.7 of `docs/component-features.md` asks for it by name: a popover on the
|
|
780
|
+
* desktop and a sheet in a narrow viewport. The DOM does not change, so the
|
|
781
|
+
* decision is testable without a device — and the query is on the viewport
|
|
782
|
+
* rather than on a container because a layer in a portal has no container to
|
|
783
|
+
* ask, and the question really is how much screen there is.
|
|
784
|
+
*/
|
|
785
|
+
@media (max-width: 480px) and (pointer: coarse) {
|
|
786
|
+
[data-ui='datetime-picker'][data-part='positioner'][data-presentation='sheet'] {
|
|
787
|
+
/* The positioner's own measurement is overridden here on purpose: a sheet
|
|
788
|
+
is not placed against an anchor, it is placed against the screen. */
|
|
789
|
+
inset: auto 0 0;
|
|
790
|
+
position: fixed;
|
|
791
|
+
translate: 0 var(--slotted-space-9, 2rem);
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
[data-ui='datetime-picker'][data-part='positioner'][data-presentation='sheet'][data-open] {
|
|
795
|
+
translate: 0 0;
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
[data-ui='datetime-picker'][data-part='positioner'][data-presentation='sheet']
|
|
799
|
+
[data-part='content'] {
|
|
800
|
+
border-end-end-radius: 0;
|
|
801
|
+
border-end-start-radius: 0;
|
|
802
|
+
border-inline: 0;
|
|
803
|
+
border-block-end: 0;
|
|
804
|
+
inline-size: var(--slotted-datetime-picker-sheet-inline-size, 100%);
|
|
805
|
+
max-inline-size: none;
|
|
806
|
+
/* The two surfaces are stacked here and the sheet has the screen's height
|
|
807
|
+
to spend, so the whole panel scrolls rather than each surface scrolling
|
|
808
|
+
inside its own box. */
|
|
809
|
+
max-block-size: 85vh;
|
|
810
|
+
overflow-y: auto;
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
/* Stacked under a month, the list gets a shorter run: the reader scrolls
|
|
814
|
+
the sheet to reach it, and a full-height list would put the footer out of
|
|
815
|
+
reach behind ninety-six rows. */
|
|
816
|
+
[data-ui='datetime-picker'][data-part='positioner'][data-presentation='sheet']
|
|
817
|
+
[data-part='list'] {
|
|
818
|
+
max-block-size: calc(var(--_row-pitch) * 5.5);
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
@media (forced-colors: active) {
|
|
823
|
+
/* The chosen row and the highlighted row both lose their painted grounds,
|
|
824
|
+
so each says what it is with a system pair the operating system
|
|
825
|
+
guarantees legible together. */
|
|
826
|
+
[data-ui='datetime-picker'] [data-part='option'][data-selected] {
|
|
827
|
+
background-color: Highlight;
|
|
828
|
+
color: HighlightText;
|
|
829
|
+
forced-color-adjust: none;
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
[data-ui='datetime-picker'] [data-part='option'][data-current]:not([data-selected]) {
|
|
833
|
+
outline: var(--slotted-focus-ring-width, 2px) solid Highlight;
|
|
834
|
+
outline-offset: calc(var(--slotted-focus-ring-offset, 2px) * -1);
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
/* No rule between the two surfaces is added here. The gap between them is
|
|
838
|
+
only space, but each panel already carries a label with its own mark
|
|
839
|
+
above it, and a label is a boundary that reads in both arrangements — a
|
|
840
|
+
border on one inline edge would be a divider beside the month in one and
|
|
841
|
+
a stray rule under it in the other. */
|
|
842
|
+
}
|
|
843
|
+
}
|