@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,719 @@
|
|
|
1
|
+
@layer slotted.components {
|
|
2
|
+
/**
|
|
3
|
+
* ── The segmented time control ─────────────────────────────────────────
|
|
4
|
+
*
|
|
5
|
+
* The frame `date-field` draws, holding hour, minute, second and day period
|
|
6
|
+
* instead of year, month and day. The frame carries no role: `role="group"`
|
|
7
|
+
* is on the row, because the APG's spin-button example names the group as
|
|
8
|
+
* what tells a screen-reader user that the buttons are one time.
|
|
9
|
+
*
|
|
10
|
+
* There is no `input[type=time]` under any of it, for the reason
|
|
11
|
+
* `date-field` refuses `input[type=date]`: the browser's own control cannot
|
|
12
|
+
* be styled past its closed state, its panel is drawn by the operating
|
|
13
|
+
* system and answers no scheme, no density and no direction, and its field
|
|
14
|
+
* order is the browser's locale rather than the application's. The value
|
|
15
|
+
* reaches a form through a hidden input carrying `HH:mm:ss`.
|
|
16
|
+
*/
|
|
17
|
+
[data-ui='time-field'][data-part='root'] {
|
|
18
|
+
/**
|
|
19
|
+
* Type, height, inline padding, gap and glyph size come from the control
|
|
20
|
+
* scales — the only ones the theme restates per density — so a time in a
|
|
21
|
+
* dense table shrinks whole rather than in parts.
|
|
22
|
+
*/
|
|
23
|
+
--_font-size: var(--slotted-control-font-size-md, 13px);
|
|
24
|
+
--_height: var(--slotted-control-height-md, 34px);
|
|
25
|
+
--_padding-inline: var(--slotted-control-padding-inline-md, 13px);
|
|
26
|
+
--_gap: var(--slotted-control-gap-md, 8px);
|
|
27
|
+
--_icon-floor: var(--slotted-time-field-icon-size-min, 14px);
|
|
28
|
+
--_icon-size: max(var(--_icon-floor), var(--slotted-control-icon-size-md, 16px));
|
|
29
|
+
|
|
30
|
+
/* The same inner-control box every family in the library draws: the glyph,
|
|
31
|
+
and one step of air on each side, bounded by the frame's own height. */
|
|
32
|
+
--_action-size: var(
|
|
33
|
+
--slotted-time-field-action-size,
|
|
34
|
+
min(
|
|
35
|
+
calc(var(--_icon-size) + 2 * var(--slotted-space-2, 0.25rem)),
|
|
36
|
+
calc(
|
|
37
|
+
var(--_height) - var(--slotted-control-border-width, 1px) * 2 -
|
|
38
|
+
var(--slotted-space-2, 0.25rem)
|
|
39
|
+
)
|
|
40
|
+
)
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
align-items: center;
|
|
44
|
+
background-color: var(--slotted-time-field-background, var(--slotted-control-surface, Field));
|
|
45
|
+
border: var(--slotted-control-border-width, 1px) solid
|
|
46
|
+
var(--slotted-time-field-border-color, var(--slotted-control-border-color, ButtonBorder));
|
|
47
|
+
border-radius: var(--slotted-time-field-radius, var(--slotted-control-radius, 4px));
|
|
48
|
+
box-shadow: var(--slotted-time-field-shadow, var(--slotted-control-shadow, none));
|
|
49
|
+
box-sizing: border-box;
|
|
50
|
+
color: var(--slotted-time-field-color, var(--slotted-text, CanvasText));
|
|
51
|
+
display: flex;
|
|
52
|
+
font-family: var(--slotted-control-font-family, system-ui, sans-serif);
|
|
53
|
+
font-size: var(--_font-size);
|
|
54
|
+
gap: var(--_gap);
|
|
55
|
+
inline-size: 100%;
|
|
56
|
+
min-block-size: var(--_height);
|
|
57
|
+
min-inline-size: 0;
|
|
58
|
+
padding-inline: var(--_padding-inline);
|
|
59
|
+
transition:
|
|
60
|
+
background-color var(--slotted-control-transition-duration)
|
|
61
|
+
var(--slotted-control-transition-easing),
|
|
62
|
+
border-color var(--slotted-control-transition-duration)
|
|
63
|
+
var(--slotted-control-transition-easing),
|
|
64
|
+
box-shadow var(--slotted-control-transition-duration) var(--slotted-control-transition-easing);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* The button inside the frame is inset by its own gutter less than the value
|
|
69
|
+
* is, so the *glyph* ends the same distance from the border as the digits
|
|
70
|
+
* begin from it — the arithmetic `text-field` records, holding at every step
|
|
71
|
+
* and every density.
|
|
72
|
+
*/
|
|
73
|
+
[data-ui='time-field'][data-part='root']:has(> [data-part='clear']:last-child) {
|
|
74
|
+
padding-inline-end: max(
|
|
75
|
+
0px,
|
|
76
|
+
calc(var(--_padding-inline) - (var(--_action-size) - var(--_icon-size)) / 2)
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* The row of segments. It takes the whole of the space the adornments leave
|
|
82
|
+
* and puts the time at the reading edge, so an empty field and a full one
|
|
83
|
+
* start in the same place.
|
|
84
|
+
*/
|
|
85
|
+
[data-ui='time-field'] [data-part='segments'] {
|
|
86
|
+
align-items: center;
|
|
87
|
+
/* It says what it is before it is pressed. A time is typed, so the pointer
|
|
88
|
+
over it is a caret — and the row rather than only the segments, because
|
|
89
|
+
the gap between two fields is part of the control the reader aims at. */
|
|
90
|
+
cursor: text;
|
|
91
|
+
display: flex;
|
|
92
|
+
flex: 1 1 auto;
|
|
93
|
+
min-inline-size: 0;
|
|
94
|
+
/* One line, whatever the frame's width: the row is clipped at the frame's
|
|
95
|
+
edge, as a text input clips a long value, and a field the reader steps
|
|
96
|
+
into is scrolled into view. The rule `date-field` records. */
|
|
97
|
+
overflow: hidden;
|
|
98
|
+
/* Digits that do not shift under one another as a value is typed over, and
|
|
99
|
+
four fields that keep their columns while the reader steps. */
|
|
100
|
+
font-variant-numeric: tabular-nums;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* The sequence runs left to right in every document, because a clock time
|
|
104
|
+
* is a numeric run and that is how the bidirectional algorithm renders one:
|
|
105
|
+
* `Intl.DateTimeFormat` writes `٠٢:٣٠ م` for `ar-EG` with the hour leftmost,
|
|
106
|
+
* and it hands the parts back in that same order for every locale it knows.
|
|
107
|
+
*
|
|
108
|
+
* A flex row that took the paragraph's direction reversed them, and the
|
|
109
|
+
* right-to-left capture read `30:14` — a time nobody wrote, in a field that
|
|
110
|
+
* had done nothing wrong but inherit. The isolation keeps the decision
|
|
111
|
+
* inside the row, so the frame around it still reads with the document.
|
|
112
|
+
*/
|
|
113
|
+
direction: ltr;
|
|
114
|
+
unicode-bidi: isolate;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* The row is still placed with the document, though: a right-to-left form
|
|
119
|
+
* puts its values at the right edge, and a row whose own direction is now
|
|
120
|
+
* left-to-right would otherwise start at the left of a full-width box.
|
|
121
|
+
*
|
|
122
|
+
* `:dir()` rather than an ancestor `[dir]` selector, because the row's own
|
|
123
|
+
* `direction` above does not change what `:dir()` answers — that comes from
|
|
124
|
+
* the document — which is the reason every other family in this library
|
|
125
|
+
* reaches for it too.
|
|
126
|
+
*/
|
|
127
|
+
[data-ui='time-field'] [data-part='segments']:dir(rtl) {
|
|
128
|
+
justify-content: flex-end;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* One field of the time.
|
|
133
|
+
*
|
|
134
|
+
* Its width is stated rather than measured, so the row does not move when a
|
|
135
|
+
* single digit becomes two: `1ch` is the advance of a digit in a tabular
|
|
136
|
+
* face, and `--_digits` is how many the field can hold.
|
|
137
|
+
*/
|
|
138
|
+
[data-ui='time-field'] [data-part='segment'] {
|
|
139
|
+
--_digits: 2;
|
|
140
|
+
|
|
141
|
+
background-color: transparent;
|
|
142
|
+
border-radius: var(--slotted-time-field-segment-radius, var(--slotted-radius-xs, 2px));
|
|
143
|
+
box-sizing: content-box;
|
|
144
|
+
/* The caret belongs to no segment: the whole field is replaced by typing,
|
|
145
|
+
and a caret between two digits would offer an edit the family refuses. */
|
|
146
|
+
caret-color: transparent;
|
|
147
|
+
color: inherit;
|
|
148
|
+
cursor: text;
|
|
149
|
+
font: inherit;
|
|
150
|
+
/* A field never shrinks under its digits: a row narrower than its value
|
|
151
|
+
overflows and is clipped at the frame, the way an input clips text. A
|
|
152
|
+
flex item shrunk to its minimum drew `mm` as `mr`. */
|
|
153
|
+
flex: 0 0 auto;
|
|
154
|
+
min-inline-size: var(--slotted-time-field-segment-min-inline-size, calc(var(--_digits) * 1ch));
|
|
155
|
+
padding-inline: var(
|
|
156
|
+
--slotted-time-field-segment-padding-inline,
|
|
157
|
+
var(--slotted-space-1, 0.125rem)
|
|
158
|
+
);
|
|
159
|
+
text-align: center;
|
|
160
|
+
transition:
|
|
161
|
+
background-color var(--slotted-control-transition-duration)
|
|
162
|
+
var(--slotted-control-transition-easing),
|
|
163
|
+
color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing);
|
|
164
|
+
/* A spin button is operated by keys and by the pointer; nothing in it is
|
|
165
|
+
text a reader selects, and a drag across it would look like one. */
|
|
166
|
+
user-select: none;
|
|
167
|
+
-webkit-tap-highlight-color: transparent;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* The day period holds a word rather than digits, so it is sized by what it
|
|
172
|
+
* holds with a floor under it. `es-MX` writes `a.m.`, `en-US` writes `AM`
|
|
173
|
+
* and a locale may write more; a box cut to two characters would clip the
|
|
174
|
+
* first of those, and `max-content` with a floor clips none of them. The
|
|
175
|
+
* digit face is dropped here for the same reason: tabular figures inside a
|
|
176
|
+
* word letter-space it.
|
|
177
|
+
*/
|
|
178
|
+
[data-ui='time-field'] [data-part='segment'][data-field='dayPeriod'] {
|
|
179
|
+
font-variant-numeric: normal;
|
|
180
|
+
min-inline-size: var(--slotted-time-field-period-min-inline-size, 2ch);
|
|
181
|
+
/* An abbreviation, in whatever case the locale itself writes it. */
|
|
182
|
+
text-transform: none;
|
|
183
|
+
white-space: nowrap;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* A field with no value yet. It is muted rather than hidden, because the
|
|
188
|
+
* placeholder is the format — `hh:mm` in the reader's own words rather than
|
|
189
|
+
* in English — and a time being typed has to keep saying what is missing.
|
|
190
|
+
*/
|
|
191
|
+
[data-ui='time-field'] [data-part='segment'][data-placeholder] {
|
|
192
|
+
color: var(--slotted-time-field-placeholder-color, var(--slotted-text-muted, GrayText));
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* The separator the locale writes. It is decoration: the group's accessible
|
|
197
|
+
* name already carries the whole time in words, so a screen reader reading
|
|
198
|
+
* "colon" between two numbers would be reading punctuation aloud.
|
|
199
|
+
*/
|
|
200
|
+
[data-ui='time-field'] [data-part='literal'] {
|
|
201
|
+
color: var(--slotted-time-field-literal-color, var(--slotted-text-muted, GrayText));
|
|
202
|
+
flex: 0 0 auto;
|
|
203
|
+
/* Its own bidi run: a colon between two numbers takes the paragraph's
|
|
204
|
+
direction, and in a right-to-left document the time read back to front. */
|
|
205
|
+
unicode-bidi: plaintext;
|
|
206
|
+
user-select: none;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/* ── The relative expression ──────────────────────────────────────────
|
|
210
|
+
*
|
|
211
|
+
* The one entry no surveyed implementation has: a time written as a duration
|
|
212
|
+
* from now, resolved in view before it is accepted. It replaces the segments
|
|
213
|
+
* rather than sitting beside them, because both of them writing one value
|
|
214
|
+
* would be two controls disagreeing about which is the time.
|
|
215
|
+
*
|
|
216
|
+
* It is a real `input`, so a mobile keyboard opens and the platform supplies
|
|
217
|
+
* every text-editing key the reader already knows.
|
|
218
|
+
*/
|
|
219
|
+
[data-ui='time-field'] [data-part='duration'] {
|
|
220
|
+
appearance: none;
|
|
221
|
+
background-color: transparent;
|
|
222
|
+
border: 0;
|
|
223
|
+
color: inherit;
|
|
224
|
+
flex: 1 1 auto;
|
|
225
|
+
font: inherit;
|
|
226
|
+
/* An expression is arithmetic, so its digits line up like the value's. */
|
|
227
|
+
font-variant-numeric: tabular-nums;
|
|
228
|
+
min-inline-size: 0;
|
|
229
|
+
outline: none;
|
|
230
|
+
padding: 0;
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* `+40m` is a left-to-right construct wherever it is typed: the sign leads,
|
|
234
|
+
* the unit follows the number, and the grammar is symbols rather than
|
|
235
|
+
* words. Left to the document it read `40m+` in the right-to-left capture.
|
|
236
|
+
*/
|
|
237
|
+
direction: ltr;
|
|
238
|
+
unicode-bidi: isolate;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/* Left-to-right content in a right-to-left field still sits at the reading
|
|
242
|
+
edge, which is the treatment every form gives a phone number or an IBAN. */
|
|
243
|
+
[data-ui='time-field'] [data-part='duration']:dir(rtl) {
|
|
244
|
+
text-align: right;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
[data-ui='time-field'] [data-part='duration']::placeholder {
|
|
248
|
+
color: var(--slotted-time-field-placeholder-color, var(--slotted-text-muted, GrayText));
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* What the expression resolves to, before anything commits.
|
|
253
|
+
*
|
|
254
|
+
* It is the answer rather than the question, so it takes the accent ink and
|
|
255
|
+
* the expression keeps the value's. The chevron between them is the mark the
|
|
256
|
+
* library already has for "and then"; it is direction-sensitive, so it turns
|
|
257
|
+
* with the document rather than pointing out of it.
|
|
258
|
+
*/
|
|
259
|
+
[data-ui='time-field'] [data-part='preview'] {
|
|
260
|
+
/**
|
|
261
|
+
* One line box, not a flex row. The chevron sits *in* the line rather than
|
|
262
|
+
* beside it, which is the only way it can be aligned to the text at all —
|
|
263
|
+
* a flex box centres its children on the whole line box, and the letters
|
|
264
|
+
* do not live in the middle of that.
|
|
265
|
+
*/
|
|
266
|
+
--_mark: 1cap;
|
|
267
|
+
|
|
268
|
+
color: var(--slotted-time-field-preview-color, var(--slotted-tone-accent-text));
|
|
269
|
+
display: block;
|
|
270
|
+
flex: 0 0 auto;
|
|
271
|
+
font-variant-numeric: tabular-nums;
|
|
272
|
+
white-space: nowrap;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* The mark, on the text's own axis.
|
|
277
|
+
*
|
|
278
|
+
* Two things were wrong and only together: it was drawn at the control glyph
|
|
279
|
+
* size — sixteen pixels of chevron beside a nine-pixel capital, which is a
|
|
280
|
+
* control's mark standing in a sentence — and it was centred on the line box
|
|
281
|
+
* rather than on the band the letters occupy, so it read high. `1cap` is the
|
|
282
|
+
* size `status-indicator` already uses for a mark inside a line of text, and
|
|
283
|
+
* the `vertical-align` is the formula `docs/build-briefing.md` records under
|
|
284
|
+
* _Decisions already taken_: half the difference between the band and the
|
|
285
|
+
* mark, which lands the mark's centre on the middle of the band.
|
|
286
|
+
*
|
|
287
|
+
* The band is the midpoint of cap and x-height, which is the one `toast`
|
|
288
|
+
* chose after reading all three at four times the type size: `1cap` alone
|
|
289
|
+
* reads high, because every glyph in the scale overshoots a capital, and
|
|
290
|
+
* `1ex` alone reads low, because the mark then hangs below the descenders.
|
|
291
|
+
*
|
|
292
|
+
* The mark is the chevron the binding renders as the preview's first child,
|
|
293
|
+
* marked `directional`: it points along the reading direction, so the `icon`
|
|
294
|
+
* family turns it in a right-to-left context.
|
|
295
|
+
*/
|
|
296
|
+
[data-ui='time-field'] [data-part='preview'] > [data-ui='icon'] {
|
|
297
|
+
--slotted-icon-size: var(--_mark);
|
|
298
|
+
|
|
299
|
+
margin-inline-end: var(--slotted-space-1, 0.125rem);
|
|
300
|
+
vertical-align: calc((((1cap + 1ex) / 2) - var(--_mark)) / 2);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* A duration that ran past midnight. It resolves into a different day, and
|
|
305
|
+
* this library holds no day beside a time — so the preview changes tone and
|
|
306
|
+
* the family writes the day beside the time. Colour alone never says it:
|
|
307
|
+
* `docs/component-features.md` §2.5 refuses that, and a reader on a screen
|
|
308
|
+
* reader hears the same words the sighted reader sees.
|
|
309
|
+
*/
|
|
310
|
+
[data-ui='time-field'] [data-part='preview'][data-crosses-midnight] {
|
|
311
|
+
color: var(--slotted-time-field-preview-next-color, var(--slotted-tone-warning-text));
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* While an expression is open the frame says so, because the control now
|
|
316
|
+
* takes text where a moment ago it took digits one field at a time. The
|
|
317
|
+
* border is the accent the preview is written in, so the two marks are one
|
|
318
|
+
* statement rather than two.
|
|
319
|
+
*/
|
|
320
|
+
[data-ui='time-field'][data-part='root'][data-relative] {
|
|
321
|
+
border-color: var(
|
|
322
|
+
--slotted-time-field-relative-border-color,
|
|
323
|
+
var(--slotted-tone-accent-border)
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/* ── Size ─────────────────────────────────────────────────────────────
|
|
328
|
+
*
|
|
329
|
+
* Three steps, matching the field the control sits in. A `size="sm"` field
|
|
330
|
+
* holding an `md` control is a field and a control disagreeing about one row.
|
|
331
|
+
*/
|
|
332
|
+
|
|
333
|
+
[data-ui='time-field'][data-part='root'][data-size='sm'] {
|
|
334
|
+
--_font-size: var(--slotted-control-font-size-sm, 12px);
|
|
335
|
+
--_height: var(--slotted-control-height-sm, 30px);
|
|
336
|
+
--_padding-inline: var(--slotted-control-padding-inline-sm, 10px);
|
|
337
|
+
--_gap: var(--slotted-control-gap-sm, 6px);
|
|
338
|
+
--_icon-size: max(var(--_icon-floor), var(--slotted-control-icon-size-sm, 14px));
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
[data-ui='time-field'][data-part='root'][data-size='md'] {
|
|
342
|
+
--_font-size: var(--slotted-control-font-size-md, 13px);
|
|
343
|
+
--_height: var(--slotted-control-height-md, 34px);
|
|
344
|
+
--_padding-inline: var(--slotted-control-padding-inline-md, 13px);
|
|
345
|
+
--_gap: var(--slotted-control-gap-md, 8px);
|
|
346
|
+
--_icon-size: max(var(--_icon-floor), var(--slotted-control-icon-size-md, 16px));
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
[data-ui='time-field'][data-part='root'][data-size='lg'] {
|
|
350
|
+
--_font-size: var(--slotted-control-font-size-lg, 14px);
|
|
351
|
+
--_height: var(--slotted-control-height-lg, 38px);
|
|
352
|
+
--_padding-inline: var(--slotted-control-padding-inline-lg, 16px);
|
|
353
|
+
--_gap: var(--slotted-control-gap-lg, 8px);
|
|
354
|
+
--_icon-size: max(var(--_icon-floor), var(--slotted-control-icon-size-lg, 18px));
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/* ── Variant ──────────────────────────────────────────────────────────
|
|
358
|
+
*
|
|
359
|
+
* The three steps `text-field` set, so a form holding a name and a time
|
|
360
|
+
* shows one frame twice rather than two frames.
|
|
361
|
+
*/
|
|
362
|
+
|
|
363
|
+
[data-ui='time-field'][data-part='root'][data-variant='subtle'] {
|
|
364
|
+
background-color: var(
|
|
365
|
+
--slotted-time-field-subtle-background,
|
|
366
|
+
var(--slotted-surface-sunken, Canvas)
|
|
367
|
+
);
|
|
368
|
+
border-color: var(
|
|
369
|
+
--slotted-time-field-subtle-border-color,
|
|
370
|
+
var(--slotted-border-subtle, ButtonBorder)
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
[data-ui='time-field'][data-part='root'][data-variant='plain'] {
|
|
375
|
+
background-color: transparent;
|
|
376
|
+
border-color: transparent;
|
|
377
|
+
border-radius: var(--slotted-radius-none, 0px);
|
|
378
|
+
box-shadow: none;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/* ── Adornments ───────────────────────────────────────────────────────
|
|
382
|
+
*
|
|
383
|
+
* Named for the reading direction rather than for a side, and quieter than
|
|
384
|
+
* the value: an adornment annotates, and a reader looking for the time
|
|
385
|
+
* should not have to step over it.
|
|
386
|
+
*/
|
|
387
|
+
[data-ui='time-field'] > [data-part='start'],
|
|
388
|
+
[data-ui='time-field'] > [data-part='end'] {
|
|
389
|
+
--slotted-icon-size: var(--_icon-size);
|
|
390
|
+
|
|
391
|
+
align-items: center;
|
|
392
|
+
color: var(--slotted-time-field-adornment-color, var(--slotted-text-muted, GrayText));
|
|
393
|
+
display: inline-flex;
|
|
394
|
+
flex: 0 0 auto;
|
|
395
|
+
gap: var(--slotted-space-2, 0.25rem);
|
|
396
|
+
line-height: 1;
|
|
397
|
+
unicode-bidi: plaintext;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
[data-ui='time-field'] > [data-part='start'] > svg,
|
|
401
|
+
[data-ui='time-field'] > [data-part='end'] > svg {
|
|
402
|
+
block-size: var(--_icon-size);
|
|
403
|
+
inline-size: var(--_icon-size);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/* ── The clear button ─────────────────────────────────────────────────
|
|
407
|
+
*
|
|
408
|
+
* A real button, with the `Glyph` element the binding renders rather than a
|
|
409
|
+
* character, and held to the target minimum by the family rather than by the
|
|
410
|
+
* page.
|
|
411
|
+
*/
|
|
412
|
+
[data-ui='time-field'] > [data-part='clear'] {
|
|
413
|
+
align-items: center;
|
|
414
|
+
appearance: none;
|
|
415
|
+
background-color: transparent;
|
|
416
|
+
block-size: var(--_action-size);
|
|
417
|
+
border: 0;
|
|
418
|
+
border-radius: var(--slotted-time-field-radius, var(--slotted-control-radius, 4px));
|
|
419
|
+
color: var(--slotted-time-field-action-color, var(--slotted-text-muted, GrayText));
|
|
420
|
+
cursor: pointer;
|
|
421
|
+
display: inline-flex;
|
|
422
|
+
flex: 0 0 auto;
|
|
423
|
+
inline-size: var(--_action-size);
|
|
424
|
+
justify-content: center;
|
|
425
|
+
padding: 0;
|
|
426
|
+
position: relative;
|
|
427
|
+
touch-action: manipulation;
|
|
428
|
+
transition:
|
|
429
|
+
background-color var(--slotted-control-transition-duration)
|
|
430
|
+
var(--slotted-control-transition-easing),
|
|
431
|
+
color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing);
|
|
432
|
+
-webkit-tap-highlight-color: transparent;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* The hit area, recovered outside the paint. At `sm` with `dense` the whole
|
|
437
|
+
* control is 24 pixels tall — the WCAG 2.2 minimum — so nothing drawn inside
|
|
438
|
+
* it can also be 24. This grows the target back in both axes and leaves a
|
|
439
|
+
* larger one alone, which is the correction `docs/token-foundation.md`
|
|
440
|
+
* leaves to the family rather than to the theme.
|
|
441
|
+
*/
|
|
442
|
+
[data-ui='time-field'] > [data-part='clear']::after {
|
|
443
|
+
content: '';
|
|
444
|
+
inset: min(0px, calc((100% - var(--slotted-target-min, 24px)) / 2));
|
|
445
|
+
position: absolute;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/* On a finger the target is the comfortable size in both axes and the box
|
|
449
|
+
is the one a mouse sees: the ground and the focus ring stay square, and
|
|
450
|
+
the hit area above grows to 44 pixels around them. After an end
|
|
451
|
+
adornment — a picker's trigger — it does not reach back across it. */
|
|
452
|
+
@media (pointer: coarse) {
|
|
453
|
+
[data-ui='time-field'] > [data-part='clear']::after {
|
|
454
|
+
inset: min(0px, calc((100% - var(--slotted-target-comfortable, 44px)) / 2));
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
[data-ui='time-field'] > [data-part='end'] + [data-part='clear']::after {
|
|
458
|
+
inset-inline-start: 0;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/* The cross is drawn at the control's own icon step. */
|
|
463
|
+
[data-ui='time-field'] > [data-part='clear'] {
|
|
464
|
+
--slotted-icon-size: var(--_icon-size);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
[data-ui='time-field'] > [data-part='clear']:hover:not(:disabled):not([data-disabled]) {
|
|
468
|
+
background-color: var(
|
|
469
|
+
--slotted-time-field-action-hover-background,
|
|
470
|
+
var(--slotted-tone-secondary-subtle-hover)
|
|
471
|
+
);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
[data-ui='time-field'] > [data-part='clear']:active:not(:disabled):not([data-disabled]) {
|
|
475
|
+
background-color: var(
|
|
476
|
+
--slotted-time-field-action-active-background,
|
|
477
|
+
var(--slotted-tone-secondary-subtle-active)
|
|
478
|
+
);
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* The button carries its own ring rather than borrowing the frame's. Tabbing
|
|
483
|
+
* from the last segment to the clear button has to move something visible,
|
|
484
|
+
* and a ring around the whole frame would sit still while focus moved inside
|
|
485
|
+
* it.
|
|
486
|
+
*/
|
|
487
|
+
[data-ui='time-field'] > [data-part='clear']:focus-visible {
|
|
488
|
+
outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
|
|
489
|
+
outline-offset: calc(var(--slotted-focus-ring-offset, 2px) * -1);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
/* ── States ───────────────────────────────────────────────────────────
|
|
493
|
+
*
|
|
494
|
+
* Written strongest last, and each weaker one guarded against every stronger
|
|
495
|
+
* one it can meet, which is the order `STATE_PRECEDENCE` sets.
|
|
496
|
+
*/
|
|
497
|
+
|
|
498
|
+
[data-ui='time-field'][data-part='root']:hover:not([data-disabled]):not([data-readonly]):not(
|
|
499
|
+
[data-invalid]
|
|
500
|
+
) {
|
|
501
|
+
border-color: var(--slotted-time-field-hover-border-color, var(--slotted-tone-accent-border));
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
[data-ui='time-field'][data-part='root'][data-variant='subtle']:hover:not([data-disabled]):not(
|
|
505
|
+
[data-readonly]
|
|
506
|
+
):not([data-invalid]) {
|
|
507
|
+
background-color: var(
|
|
508
|
+
--slotted-time-field-subtle-hover-background,
|
|
509
|
+
var(--slotted-tone-secondary-subtle-hover)
|
|
510
|
+
);
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
[data-ui='time-field'][data-part='root'][data-variant='plain']:hover:not([data-disabled]):not(
|
|
514
|
+
[data-readonly]
|
|
515
|
+
):not([data-invalid]) {
|
|
516
|
+
background-color: var(
|
|
517
|
+
--slotted-time-field-plain-hover-background,
|
|
518
|
+
var(--slotted-tone-secondary-subtle-hover)
|
|
519
|
+
);
|
|
520
|
+
border-color: transparent;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* Focus is two marks and they answer two different questions.
|
|
525
|
+
*
|
|
526
|
+
* The frame's ring says the control has the reader's attention, exactly as
|
|
527
|
+
* every other control in the library says it. The band on one segment says
|
|
528
|
+
* which field a key will move, and no ring can say that: a second outline
|
|
529
|
+
* two pixels inside the first would be two rings nested, and at `dense`
|
|
530
|
+
* there is not room for two.
|
|
531
|
+
*
|
|
532
|
+
* Both are `:focus` and not `:focus-visible`, which is the rule `date-field`
|
|
533
|
+
* paid for: a browser matches `:focus-visible` on a text input for a pointer
|
|
534
|
+
* press as well as for a Tab, and refuses it for a `div` a pointer focused.
|
|
535
|
+
* Every segment here is a `div`, so a clicked field would look exactly as it
|
|
536
|
+
* had before the press. The expression is an `input` and takes the frame's
|
|
537
|
+
* ring on `:focus-within` for the same reason from the other side.
|
|
538
|
+
*/
|
|
539
|
+
[data-ui='time-field'][data-part='root']:has([data-part='segment']:focus),
|
|
540
|
+
[data-ui='time-field'][data-part='root']:has([data-part='duration']:focus) {
|
|
541
|
+
box-shadow: var(--slotted-control-shadow-focus-geometry, 0 1px 4px -1px)
|
|
542
|
+
var(--slotted-focus-ring-color, Highlight);
|
|
543
|
+
outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
|
|
544
|
+
outline-offset: var(--slotted-focus-ring-offset, 2px);
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
/**
|
|
548
|
+
* The ring of a control whose box is not its own is drawn inside that box,
|
|
549
|
+
* the way the inner controls draw theirs inside the frame: two pixels past
|
|
550
|
+
* the control is two pixels over the next row's rule. No lift either — a
|
|
551
|
+
* shadow that appears only under focus is a cell that changes size when it
|
|
552
|
+
* is used.
|
|
553
|
+
*/
|
|
554
|
+
[data-ui='time-field'][data-part='root'][data-variant='plain']:has([data-part='segment']:focus),
|
|
555
|
+
[data-ui='time-field'][data-part='root'][data-variant='plain']:has([data-part='duration']:focus) {
|
|
556
|
+
box-shadow: none;
|
|
557
|
+
outline-offset: calc(var(--slotted-focus-ring-offset, 2px) * -1);
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
[data-ui='time-field'] [data-part='segment']:focus {
|
|
561
|
+
background-color: var(
|
|
562
|
+
--slotted-time-field-segment-focus-background,
|
|
563
|
+
var(--slotted-tone-accent-solid)
|
|
564
|
+
);
|
|
565
|
+
color: var(--slotted-time-field-segment-focus-color, var(--slotted-tone-accent-on-solid));
|
|
566
|
+
/* The frame already draws the ring, so the segment does not draw a second. */
|
|
567
|
+
outline: none;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* Invalid outranks hover and is written after it: a control reporting an
|
|
572
|
+
* error should not stop looking wrong because the pointer is over it. The
|
|
573
|
+
* ring is retargeted rather than repainted, so the frame's outline, the
|
|
574
|
+
* shadow under it and the ring on the clear button all move at once.
|
|
575
|
+
*/
|
|
576
|
+
[data-ui='time-field'][data-part='root'][data-invalid] {
|
|
577
|
+
--slotted-focus-ring-color: var(
|
|
578
|
+
--slotted-time-field-invalid-focus-ring-color,
|
|
579
|
+
var(--slotted-focus-ring-color-invalid, Highlight)
|
|
580
|
+
);
|
|
581
|
+
--_invalid-edge-width: var(
|
|
582
|
+
--slotted-time-field-invalid-edge-width,
|
|
583
|
+
var(--slotted-control-invalid-edge-width, 1px)
|
|
584
|
+
);
|
|
585
|
+
--_invalid-edge-color: var(
|
|
586
|
+
--slotted-time-field-invalid-border-color,
|
|
587
|
+
var(--slotted-tone-danger-border)
|
|
588
|
+
);
|
|
589
|
+
--_invalid-edge: inset 0 0 0 var(--_invalid-edge-width) var(--_invalid-edge-color);
|
|
590
|
+
|
|
591
|
+
border-color: var(--slotted-time-field-invalid-border-color, var(--slotted-tone-danger-border));
|
|
592
|
+
/*
|
|
593
|
+
* Width as well as colour (WCAG 1.4.1), the edge `text-field` draws: in
|
|
594
|
+
* `high-contrast` the danger border is the resting edge's black. The line
|
|
595
|
+
* is a shadow inside the border, so neither box nor text moves, and it
|
|
596
|
+
* takes the resting lift's place.
|
|
597
|
+
*/
|
|
598
|
+
box-shadow: var(--_invalid-edge);
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
[data-ui='time-field'][data-part='root'][data-invalid]:has([data-part='segment']:focus),
|
|
602
|
+
[data-ui='time-field'][data-part='root'][data-invalid]:has([data-part='duration']:focus) {
|
|
603
|
+
box-shadow:
|
|
604
|
+
var(--_invalid-edge),
|
|
605
|
+
var(--slotted-control-shadow-focus-geometry, 0 1px 4px -1px)
|
|
606
|
+
var(--slotted-focus-ring-color, Highlight);
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
[data-ui='time-field'][data-part='root'][data-variant='plain'][data-invalid]:has(
|
|
610
|
+
[data-part='segment']:focus
|
|
611
|
+
),
|
|
612
|
+
[data-ui='time-field'][data-part='root'][data-variant='plain'][data-invalid]:has(
|
|
613
|
+
[data-part='duration']:focus
|
|
614
|
+
) {
|
|
615
|
+
/* The ring lies inside the box here, over the border and an edge as wide as
|
|
616
|
+
it; the edge reaches past the ring. */
|
|
617
|
+
box-shadow: inset 0 0 0
|
|
618
|
+
calc(
|
|
619
|
+
var(--slotted-focus-ring-offset, 2px) - var(--slotted-control-border-width, 1px) +
|
|
620
|
+
var(--_invalid-edge-width)
|
|
621
|
+
)
|
|
622
|
+
var(--_invalid-edge-color);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
/*
|
|
626
|
+
* Forced colours remove every box shadow, and the edge with them. The
|
|
627
|
+
* width comes back as an outline inside the border, and a focused invalid
|
|
628
|
+
* control draws its ring double, which a valid ring is not.
|
|
629
|
+
*/
|
|
630
|
+
@media (forced-colors: active) {
|
|
631
|
+
[data-ui='time-field'][data-part='root'][data-invalid] {
|
|
632
|
+
outline: var(--_invalid-edge-width) solid CanvasText;
|
|
633
|
+
outline-offset: calc(
|
|
634
|
+
-1 * (var(--slotted-control-border-width, 1px) + var(--_invalid-edge-width))
|
|
635
|
+
);
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
[data-ui='time-field'][data-part='root'][data-invalid]:has([data-part='segment']:focus),
|
|
639
|
+
[data-ui='time-field'][data-part='root'][data-invalid]:has([data-part='duration']:focus) {
|
|
640
|
+
outline: calc(var(--slotted-focus-ring-width, 2px) + var(--_invalid-edge-width)) double
|
|
641
|
+
var(--slotted-focus-ring-color, Highlight);
|
|
642
|
+
outline-offset: var(--slotted-focus-ring-offset, 2px);
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
[data-ui='time-field'][data-part='root'][data-variant='plain'][data-invalid]:has(
|
|
646
|
+
[data-part='segment']:focus
|
|
647
|
+
),
|
|
648
|
+
[data-ui='time-field'][data-part='root'][data-variant='plain'][data-invalid]:has(
|
|
649
|
+
[data-part='duration']:focus
|
|
650
|
+
) {
|
|
651
|
+
outline: calc(var(--slotted-focus-ring-width, 2px) + var(--_invalid-edge-width)) double
|
|
652
|
+
var(--slotted-focus-ring-color, Highlight);
|
|
653
|
+
outline-offset: calc(
|
|
654
|
+
-1 * (var(--slotted-focus-ring-width, 2px) + var(--_invalid-edge-width))
|
|
655
|
+
);
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
/**
|
|
660
|
+
* Read-only stays focusable, readable and copyable, and must not be
|
|
661
|
+
* mistakable for disabled: the value is still real and still submitted. The
|
|
662
|
+
* ground says "not yours to change" and the ink says nothing at all.
|
|
663
|
+
*/
|
|
664
|
+
[data-ui='time-field'][data-part='root'][data-readonly],
|
|
665
|
+
[data-ui='time-field'][data-part='root'][data-readonly] [data-part='segments'],
|
|
666
|
+
[data-ui='time-field'][data-part='root'][data-readonly] [data-part='segment'] {
|
|
667
|
+
cursor: default;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
[data-ui='time-field'][data-part='root'][data-readonly] {
|
|
671
|
+
background-color: var(
|
|
672
|
+
--slotted-time-field-readonly-background,
|
|
673
|
+
var(--slotted-tone-secondary-subtle-hover)
|
|
674
|
+
);
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
/**
|
|
678
|
+
* Muted to the colour the theme measures rather than faded by opacity: a
|
|
679
|
+
* time nobody can read is a field nobody can check, and a disabled form
|
|
680
|
+
* still has to say what it holds.
|
|
681
|
+
*/
|
|
682
|
+
[data-ui='time-field'][data-part='root'][data-disabled] {
|
|
683
|
+
background-color: var(
|
|
684
|
+
--slotted-time-field-disabled-background,
|
|
685
|
+
var(--slotted-disabled-background)
|
|
686
|
+
);
|
|
687
|
+
border-color: var(--slotted-time-field-disabled-border-color, var(--slotted-disabled-border));
|
|
688
|
+
/* Nothing a person cannot reach is lifted off the page. */
|
|
689
|
+
box-shadow: none;
|
|
690
|
+
color: var(--slotted-time-field-disabled-color, var(--slotted-disabled-foreground));
|
|
691
|
+
cursor: not-allowed;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
[data-ui='time-field'][data-part='root'][data-disabled] [data-part='segments'],
|
|
695
|
+
[data-ui='time-field'][data-part='root'][data-disabled] [data-part='segment'] {
|
|
696
|
+
cursor: not-allowed;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
[data-ui='time-field'][data-part='root'][data-disabled] > [data-part='start'],
|
|
700
|
+
[data-ui='time-field'][data-part='root'][data-disabled] > [data-part='end'],
|
|
701
|
+
[data-ui='time-field'][data-part='root'][data-disabled] [data-part='literal'],
|
|
702
|
+
[data-ui='time-field'][data-part='root'][data-disabled] [data-part='segment'][data-placeholder] {
|
|
703
|
+
color: var(--slotted-disabled-foreground);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
@media (forced-colors: active) {
|
|
707
|
+
/* A transparent border has no system colour to be remapped to, so the
|
|
708
|
+
`plain` control would lose its only edge where an edge matters most. */
|
|
709
|
+
[data-ui='time-field'][data-part='root'][data-variant='plain'] {
|
|
710
|
+
border-color: ButtonBorder;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
/* The preview's two tones both map to the same system ink, so the border
|
|
714
|
+
is what is left to say the control is in a different mode. */
|
|
715
|
+
[data-ui='time-field'][data-part='root'][data-relative] {
|
|
716
|
+
border-color: Highlight;
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
}
|