@expressivecss/expressive 0.7.0-rc.0 → 0.8.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/CHANGELOG.md +1311 -1
- package/README.md +14 -11
- package/dist/css/expressive.css +4215 -1668
- package/dist/css/expressive.css.map +1 -1
- package/dist/css/expressive.min.css +1 -1
- package/dist/css/expressive.min.css.map +1 -1
- package/dist/js/expressive.cjs +1231 -1253
- package/dist/js/expressive.cjs.map +4 -4
- package/dist/js/expressive.js +1231 -1253
- package/dist/js/expressive.js.map +4 -4
- package/dist/js/expressive.min.js +12 -12
- package/dist/js/expressive.min.js.map +4 -4
- package/dist/js/expressive.mjs +1231 -1253
- package/dist/js/expressive.mjs.map +4 -4
- package/dist/types/behaviors/bottomSheets.d.ts +19 -11
- package/dist/types/behaviors/sheetDrag.d.ts +40 -0
- package/dist/types/behaviors/sideSheets.d.ts +2 -9
- package/dist/types/components/autocomplete.d.ts +15 -3
- package/dist/types/components/buttons.d.ts +5 -1
- package/dist/types/components/carousel.d.ts +87 -53
- package/dist/types/components/chips.d.ts +21 -1
- package/dist/types/components/expandingCard.d.ts +31 -0
- package/dist/types/components/index.d.ts +21 -20
- package/dist/types/components/lightbox.d.ts +1 -0
- package/dist/types/components/menu.d.ts +7 -1
- package/dist/types/components/{sidenav.d.ts → navigationDrawer.d.ts} +16 -16
- package/dist/types/components/registry.d.ts +8 -8
- package/dist/types/components/slider.d.ts +26 -85
- package/dist/types/components/snackbar.d.ts +20 -5
- package/dist/types/components/tabs.d.ts +12 -0
- package/dist/types/components/timepicker.d.ts +12 -9
- package/dist/types/core/utils.d.ts +64 -53
- package/dist/types/index.d.ts +8 -9
- package/package.json +15 -1
- package/src/sass/README.md +61 -11
- package/src/sass/abstracts/_breakpoints.scss +17 -19
- package/src/sass/abstracts/_mixins.scss +103 -21
- package/src/sass/abstracts/_variables.scss +50 -5
- package/src/sass/base/_global.scss +6 -24
- package/src/sass/base/_grid.scss +15 -12
- package/src/sass/base/_normalize.scss +34 -38
- package/src/sass/base/_typography.scss +4 -18
- package/src/sass/components/_badges.scss +2 -3
- package/src/sass/components/_banners.scss +298 -0
- package/src/sass/components/_bottom-app-bar.scss +180 -0
- package/src/sass/components/_bottom-sheet.scss +12 -4
- package/src/sass/components/_button-groups.scss +186 -0
- package/src/sass/components/_buttons.scss +245 -92
- package/src/sass/components/_cards.scss +494 -73
- package/src/sass/components/_carousel.scss +562 -68
- package/src/sass/components/_chips.scss +64 -5
- package/src/sass/components/_datepicker.scss +24 -24
- package/src/sass/components/_dialog.scss +17 -11
- package/src/sass/components/_drag-handle.scss +130 -0
- package/src/sass/components/_expanding-card.scss +260 -0
- package/src/sass/components/_fab-menu.scss +232 -0
- package/src/sass/components/_floating-sheet.scss +86 -0
- package/src/sass/components/_icon-buttons.scss +194 -0
- package/src/sass/components/_icons-material-design.scss +16 -4
- package/src/sass/components/_index.scss +22 -6
- package/src/sass/components/_list.scss +16 -13
- package/src/sass/components/_loading-indicator.scss +106 -0
- package/src/sass/components/_menu.scss +335 -61
- package/src/sass/components/_navbar.scss +71 -24
- package/src/sass/components/_navigation-bar.scss +13 -10
- package/src/sass/components/{_sidenav.scss → _navigation-drawer.scss} +123 -33
- package/src/sass/components/_navigation-rail.scss +22 -22
- package/src/sass/components/_page-footer.scss +19 -16
- package/src/sass/components/_pagination.scss +24 -6
- package/src/sass/components/_panes.scss +52 -11
- package/src/sass/components/{_preloader.scss → _progress.scss} +11 -3
- package/src/sass/components/_scrim.scss +37 -0
- package/src/sass/components/_search.scss +259 -0
- package/src/sass/components/_segmented-buttons.scss +188 -0
- package/src/sass/components/_side-sheet.scss +2 -2
- package/src/sass/components/_snackbar.scss +20 -15
- package/src/sass/components/_split-button.scss +196 -0
- package/src/sass/components/_tabs.scss +7 -8
- package/src/sass/components/_timepicker.scss +67 -58
- package/src/sass/components/_toolbar.scss +206 -80
- package/src/sass/components/forms/_checkboxes.scss +49 -12
- package/src/sass/components/forms/_fieldset.scss +4 -4
- package/src/sass/components/forms/_file-input.scss +8 -1
- package/src/sass/components/forms/_index.scss +1 -1
- package/src/sass/components/forms/_input-fields.scss +50 -44
- package/src/sass/components/forms/_radio-buttons.scss +42 -10
- package/src/sass/components/forms/_select.scss +0 -1
- package/src/sass/components/forms/{_range.scss → _slider.scss} +8 -9
- package/src/sass/components/forms/_switches.scss +6 -7
- package/src/sass/tokens/_index.scss +4 -1
- package/src/sass/tokens/_reference.scss +70 -61
- package/src/sass/tokens/_state.scss +24 -0
- package/src/sass/tokens/_theme.scss +6 -3
- package/src/sass/tokens/_vibrant.scss +76 -0
- package/src/sass/utilities/_colors.scss +14 -1
- package/src/sass/utilities/_helpers.scss +5 -5
- package/src/sass/utilities/_visibility.scss +48 -26
- package/dist/types/behaviors/waves.d.ts +0 -15
- package/dist/types/components/parallax.d.ts +0 -16
- package/dist/types/components/range.d.ts +0 -43
- package/dist/types/core/bounding.d.ts +0 -6
- package/dist/types/core/edges.d.ts +0 -6
- package/src/sass/components/_parallax.scss +0 -104
- package/src/sass/components/_pulse.scss +0 -37
- package/src/sass/components/_slider.scss +0 -129
|
@@ -2,63 +2,102 @@
|
|
|
2
2
|
|
|
3
3
|
// Toolbars (M3 Expressive).
|
|
4
4
|
//
|
|
5
|
-
// Anatomy is the HTML. A <
|
|
5
|
+
// Anatomy is the HTML. A <div class="toolbar"> is the bar. Direct
|
|
6
6
|
// <button> / <a> children are the actions. An <i> is the icon; wrap a
|
|
7
7
|
// label in <span>. .active marks the selected action. A .filled action
|
|
8
8
|
// is the emphasized control (the in-bar FAB). Helpers are only for
|
|
9
|
-
// variants markup cannot express: .docked, .vibrant
|
|
10
|
-
//
|
|
9
|
+
// variants markup cannot express: .docked, .vibrant, .vertical, .fixed,
|
|
10
|
+
// .top, .bottom.
|
|
11
11
|
//
|
|
12
|
-
//
|
|
13
|
-
// floating default. Hugs its actions, 64dp, 32dp stadium,
|
|
14
|
-
// surface-container, elevation 2. Horizontal or .vertical.
|
|
15
|
-
// docked .docked (or .max). Full width, 64dp, square, no
|
|
16
|
-
// elevation. Replaces the bottom app bar.
|
|
12
|
+
// Four variants, from two independent axes - shape and color:
|
|
17
13
|
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
//
|
|
14
|
+
// standard vibrant
|
|
15
|
+
// floating surface-container, 32dp, primary-container, 32dp,
|
|
16
|
+
// elevation 3, hugs its elevation 3
|
|
17
|
+
// actions
|
|
18
|
+
// docked surface-container, square, primary-container, square,
|
|
19
|
+
// full width, no lift full width, no lift
|
|
21
20
|
//
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
//
|
|
21
|
+
// Neither default needs a class. Each default arm is the *absence* of the
|
|
22
|
+
// other side, so a bar that names nothing still lands on it - and each also
|
|
23
|
+
// names its own class, so `.floating` and `.standard` are spellings a grep of
|
|
24
|
+
// the compiled sheet finds rather than prose the docs assert about nothing.
|
|
25
|
+
// All four variants can therefore be written out in full, and the two
|
|
26
|
+
// non-default arms are declared after their defaults so that markup naming
|
|
27
|
+
// both sides of an axis resolves to the more specific one on source order
|
|
28
|
+
// rather than on a specificity accident.
|
|
26
29
|
//
|
|
27
|
-
//
|
|
30
|
+
// Tokens follow the 34.0.21 sets md.comp.toolbar.{standard, vibrant, docked,
|
|
31
|
+
// floating, floating.fab}; https://m3.material.io/components/toolbars/specs
|
|
32
|
+
// is the prose behind them. M3 splits them into a shape/size pair (docked,
|
|
33
|
+
// floating) and a color pair (standard, vibrant), which is the same two axes
|
|
34
|
+
// as above; floating.fab is the companion FAB, not the in-bar .filled action.
|
|
35
|
+
//
|
|
36
|
+
// Color: `.vibrant` is M3's own toolbar-vibrant set - primary-container - and
|
|
37
|
+
// it is deliberately *not* also spelled `[vibrant]`. That attribute is the
|
|
38
|
+
// emphasis foundation, whose one ramp is tertiary; a bar carrying it is
|
|
39
|
+
// repainted by the foundation alone, with no toolbar-specific code, because
|
|
40
|
+
// every colour below is a --md-comp-toolbar-* token pointed at a
|
|
41
|
+
// --md-sys-color-* role. Matching the attribute here as well would give one
|
|
42
|
+
// variant two renderings - the class's primary chip against the foundation's
|
|
43
|
+
// tertiary one - and would contradict tokens/_vibrant.scss, which states that
|
|
44
|
+
// a component carrying its own .vibrant class keeps the colours its own M3
|
|
45
|
+
// token set gives it. Nothing collides either way: selection is
|
|
46
|
+
// secondary-container, which the foundation does not remap.
|
|
47
|
+
//
|
|
48
|
+
// Do not show a toolbar at the same time as nav.navigation-bar.
|
|
49
|
+
//
|
|
50
|
+
// #{$_toolbar} only - do not style every <nav>. div.fixed-action-btn.toolbar
|
|
28
51
|
// is the FAB-to-toolbar transition, not this component.
|
|
29
52
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
53
|
+
// The host. A toolbar holds commands, not destinations, so it is not a <nav>
|
|
54
|
+
// (rule 4) - and not role="toolbar" either, because that is a composite role
|
|
55
|
+
// promising arrow-key navigation nothing here implements (rule 2). The <nav>
|
|
56
|
+
// form is the older markup and still works.
|
|
57
|
+
//
|
|
58
|
+
// Wrapped in :is() so it stays one compound selector: interpolating a bare
|
|
59
|
+
// comma-separated list breaks out of its context. That mistake shipped once
|
|
60
|
+
// already, in $_bar.
|
|
61
|
+
$_toolbar: ":is(nav.toolbar, .toolbar:not(.fixed-action-btn):not(.fab))";
|
|
62
|
+
|
|
63
|
+
// The two axes. `.max` is BeerCSS's name for docked; `.filled` is the older
|
|
64
|
+
// name for vibrant. Both stay in the :is() lists.
|
|
65
|
+
$_floating: "#{$_toolbar}:is(.floating, :not(.docked, .max))";
|
|
66
|
+
$_docked: "#{$_toolbar}:is(.docked, .max)";
|
|
67
|
+
$_standard: "#{$_toolbar}:is(.standard, :not(.vibrant, .filled))";
|
|
68
|
+
$_vibrant: "#{$_toolbar}:is(.vibrant, .filled)";
|
|
69
|
+
|
|
70
|
+
#{$_toolbar} {
|
|
71
|
+
// Shared across all four variants. --md-comp-toolbar-color stands for
|
|
72
|
+
// md.comp.toolbar.*.icon.color and .label-text.color, which M3 gives the
|
|
73
|
+
// same value in both color sets.
|
|
33
74
|
--md-comp-toolbar-container-height: 64px;
|
|
34
|
-
--md-comp-toolbar-
|
|
75
|
+
--md-comp-toolbar-between-space: 4px;
|
|
35
76
|
--md-comp-toolbar-action-size: 48px;
|
|
36
77
|
--md-comp-toolbar-icon-size: 24px;
|
|
37
|
-
--md-comp-toolbar-selected-container-color: var(--md-sys-color-secondary-container);
|
|
38
|
-
--md-comp-toolbar-selected-color: var(--md-sys-color-on-secondary-container);
|
|
39
78
|
|
|
40
79
|
box-sizing: border-box;
|
|
41
80
|
display: inline-flex;
|
|
42
81
|
align-items: center;
|
|
43
82
|
justify-content: center;
|
|
44
|
-
gap:
|
|
83
|
+
gap: var(--md-comp-toolbar-between-space);
|
|
45
84
|
min-height: var(--md-comp-toolbar-container-height);
|
|
46
85
|
min-width: var(--md-comp-toolbar-container-height);
|
|
47
86
|
margin: 0;
|
|
48
|
-
padding: 8px
|
|
87
|
+
padding-block: 8px;
|
|
88
|
+
padding-inline: var(--md-comp-toolbar-leading-space) var(--md-comp-toolbar-trailing-space);
|
|
49
89
|
border: none;
|
|
50
90
|
border-radius: var(--md-comp-toolbar-container-shape);
|
|
51
91
|
background-color: var(--md-comp-toolbar-container-color);
|
|
52
|
-
color: var(--md-
|
|
53
|
-
@include z-depth("2");
|
|
92
|
+
color: var(--md-comp-toolbar-color);
|
|
54
93
|
|
|
55
94
|
& + & {
|
|
56
95
|
margin-block-start: 16px;
|
|
57
96
|
}
|
|
58
97
|
|
|
59
|
-
// Actions
|
|
98
|
+
// Actions - transparent at rest so they sit on the container, not filled.
|
|
60
99
|
// .extra is the 56dp companion FAB; leave it alone.
|
|
61
|
-
> :is(a, button):not(.extra) {
|
|
100
|
+
> :is(a, button):not(.extra, .icon-button) {
|
|
62
101
|
box-sizing: border-box;
|
|
63
102
|
display: inline-flex;
|
|
64
103
|
flex: 0 0 auto;
|
|
@@ -79,10 +118,9 @@ nav.toolbar {
|
|
|
79
118
|
cursor: pointer;
|
|
80
119
|
appearance: none;
|
|
81
120
|
@include typescale("label-large");
|
|
82
|
-
font-family: $font-stack;
|
|
83
121
|
@include focus-visible;
|
|
84
122
|
|
|
85
|
-
>
|
|
123
|
+
> #{$icon} {
|
|
86
124
|
flex: 0 0 auto;
|
|
87
125
|
font-size: var(--md-comp-toolbar-icon-size);
|
|
88
126
|
width: var(--md-comp-toolbar-icon-size);
|
|
@@ -90,12 +128,14 @@ nav.toolbar {
|
|
|
90
128
|
line-height: var(--md-comp-toolbar-icon-size);
|
|
91
129
|
}
|
|
92
130
|
|
|
131
|
+
// The state layer is the content color in both color sets, which is
|
|
132
|
+
// what currentColor already is on an action that has not been filled.
|
|
93
133
|
&:hover:not(.active, .filled) {
|
|
94
|
-
background-color: color-mix(in oklab, currentColor
|
|
134
|
+
background-color: color-mix(in oklab, currentColor state-opacity("hover"), transparent);
|
|
95
135
|
}
|
|
96
136
|
|
|
97
137
|
&:active:not(.active, .filled) {
|
|
98
|
-
background-color: color-mix(in oklab, currentColor
|
|
138
|
+
background-color: color-mix(in oklab, currentColor state-opacity("pressed"), transparent);
|
|
99
139
|
}
|
|
100
140
|
|
|
101
141
|
&.active {
|
|
@@ -104,6 +144,8 @@ nav.toolbar {
|
|
|
104
144
|
}
|
|
105
145
|
|
|
106
146
|
&:disabled {
|
|
147
|
+
// 0.38, md.comp.toolbar.*.disabled.{icon,label-text}.opacity. Left as a
|
|
148
|
+
// literal because it is the global disabled figure, not a toolbar knob.
|
|
107
149
|
color: color-mix(in oklab, var(--md-sys-color-on-surface) 38%, transparent);
|
|
108
150
|
background-color: transparent;
|
|
109
151
|
box-shadow: none;
|
|
@@ -111,15 +153,15 @@ nav.toolbar {
|
|
|
111
153
|
}
|
|
112
154
|
}
|
|
113
155
|
|
|
114
|
-
// Icon-only
|
|
115
|
-
> :is(a, button):not(.extra):is(.circle, :has(>
|
|
156
|
+
// Icon-only - .circle, or an icon with no label beside it.
|
|
157
|
+
> :is(a, button):not(.extra, .icon-button):is(.circle, :has(> #{$icon}):not(:has(> #{$icon-label}))) {
|
|
116
158
|
width: var(--md-comp-toolbar-action-size);
|
|
117
159
|
padding: 0;
|
|
118
160
|
border-radius: 50%;
|
|
119
161
|
}
|
|
120
162
|
|
|
121
163
|
// Emphasized action (the in-bar FAB). 48dp, 16dp corners, primary.
|
|
122
|
-
> :is(a, button).filled:not(.extra) {
|
|
164
|
+
> :is(a, button).filled:not(.extra, .icon-button) {
|
|
123
165
|
background-color: var(--md-sys-color-primary);
|
|
124
166
|
color: var(--md-sys-color-on-primary);
|
|
125
167
|
border-radius: 16px;
|
|
@@ -128,7 +170,7 @@ nav.toolbar {
|
|
|
128
170
|
&:hover {
|
|
129
171
|
background-color: color-mix(
|
|
130
172
|
in oklab,
|
|
131
|
-
var(--md-sys-color-on-primary)
|
|
173
|
+
var(--md-sys-color-on-primary) state-opacity("hover"),
|
|
132
174
|
var(--md-sys-color-primary)
|
|
133
175
|
);
|
|
134
176
|
}
|
|
@@ -136,13 +178,13 @@ nav.toolbar {
|
|
|
136
178
|
&:active {
|
|
137
179
|
background-color: color-mix(
|
|
138
180
|
in oklab,
|
|
139
|
-
var(--md-sys-color-on-primary)
|
|
181
|
+
var(--md-sys-color-on-primary) state-opacity("pressed"),
|
|
140
182
|
var(--md-sys-color-primary)
|
|
141
183
|
);
|
|
142
184
|
}
|
|
143
185
|
}
|
|
144
186
|
|
|
145
|
-
> :is(a, button).filled:not(.extra):has(>
|
|
187
|
+
> :is(a, button).filled:not(.extra):has(> #{$icon-label}) {
|
|
146
188
|
height: 40px;
|
|
147
189
|
min-height: 40px;
|
|
148
190
|
padding: 0 24px;
|
|
@@ -158,7 +200,8 @@ nav.toolbar {
|
|
|
158
200
|
margin: 0;
|
|
159
201
|
}
|
|
160
202
|
|
|
161
|
-
// Spacer between leading and trailing actions.
|
|
203
|
+
// Spacer between leading and trailing actions. `.max` on a *child* is the
|
|
204
|
+
// spacer; on the bar itself it is the docked alias.
|
|
162
205
|
> .max {
|
|
163
206
|
flex: 1 1 auto;
|
|
164
207
|
align-self: stretch;
|
|
@@ -167,21 +210,69 @@ nav.toolbar {
|
|
|
167
210
|
}
|
|
168
211
|
}
|
|
169
212
|
|
|
170
|
-
//
|
|
171
|
-
|
|
172
|
-
|
|
213
|
+
// Floating shape. Hugs its actions, stadium, lifted. 32px rather than a
|
|
214
|
+
// corner-full keyword because it has to be half the *short* side: on a
|
|
215
|
+
// vertical bar the container is 64dp wide and arbitrarily tall, where 9999px
|
|
216
|
+
// would round the long edge into an oval.
|
|
217
|
+
#{$_floating} {
|
|
218
|
+
--md-comp-toolbar-container-shape: 32px;
|
|
219
|
+
--md-comp-toolbar-leading-space: 8px;
|
|
220
|
+
--md-comp-toolbar-trailing-space: 8px;
|
|
221
|
+
--md-comp-toolbar-external-space: 16px;
|
|
222
|
+
|
|
223
|
+
@include z-depth("3");
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Docked shape. Full width, square, no lift. M3's replacement for the bottom
|
|
227
|
+
// app bar, and shorter than it (64dp, not 80).
|
|
228
|
+
//
|
|
229
|
+
// min-spacing and max-spacing bound how far apart the actions sit as the bar
|
|
230
|
+
// widens, which is a clamped gap on a centered row - space-around would add
|
|
231
|
+
// its own distribution on top of both bounds and honour neither. A child
|
|
232
|
+
// .max spacer still takes the slack.
|
|
233
|
+
#{$_docked} {
|
|
234
|
+
--md-comp-toolbar-container-shape: 0;
|
|
235
|
+
--md-comp-toolbar-leading-space: 16px;
|
|
236
|
+
--md-comp-toolbar-trailing-space: 16px;
|
|
237
|
+
--md-comp-toolbar-min-spacing: 4px;
|
|
238
|
+
--md-comp-toolbar-max-spacing: 32px;
|
|
239
|
+
|
|
240
|
+
display: flex;
|
|
241
|
+
width: 100%;
|
|
242
|
+
// 4vw is the growth rate between the two bounds, and has no token behind it
|
|
243
|
+
// because M3 states the bounds and not the ramp. The viewport unit is honest
|
|
244
|
+
// here and only here: a docked bar is full width by definition.
|
|
245
|
+
gap: clamp(var(--md-comp-toolbar-min-spacing), 4vw, var(--md-comp-toolbar-max-spacing));
|
|
246
|
+
@include z-depth("0");
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Standard color style, the same in both shapes.
|
|
250
|
+
#{$_standard} {
|
|
251
|
+
--md-comp-toolbar-container-color: var(--md-sys-color-surface-container);
|
|
252
|
+
--md-comp-toolbar-color: var(--md-sys-color-on-surface-variant);
|
|
253
|
+
--md-comp-toolbar-selected-container-color: var(--md-sys-color-secondary-container);
|
|
254
|
+
--md-comp-toolbar-selected-color: var(--md-sys-color-on-secondary-container);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Vibrant color style, the same in both shapes. Selection moves to a neutral
|
|
258
|
+
// chip so it still reads against the accent container.
|
|
259
|
+
#{$_vibrant} {
|
|
173
260
|
--md-comp-toolbar-container-color: var(--md-sys-color-primary-container);
|
|
174
|
-
--md-comp-toolbar-
|
|
261
|
+
--md-comp-toolbar-color: var(--md-sys-color-on-primary-container);
|
|
262
|
+
--md-comp-toolbar-selected-container-color: var(--md-sys-color-surface-container);
|
|
175
263
|
--md-comp-toolbar-selected-color: var(--md-sys-color-on-surface);
|
|
176
|
-
color: var(--md-sys-color-on-primary-container);
|
|
177
264
|
}
|
|
178
265
|
|
|
179
|
-
// Vertical floating bar.
|
|
180
|
-
|
|
266
|
+
// Vertical floating bar. Only floating goes vertical - a docked bar is a
|
|
267
|
+
// full-width strip by definition.
|
|
268
|
+
#{$_floating}.vertical {
|
|
269
|
+
--md-comp-toolbar-external-space: 24px;
|
|
270
|
+
|
|
181
271
|
flex-direction: column;
|
|
182
272
|
min-width: var(--md-comp-toolbar-container-height);
|
|
183
273
|
min-height: var(--md-comp-toolbar-container-height);
|
|
184
|
-
padding: var(--md-comp-toolbar-leading-space)
|
|
274
|
+
padding-block: var(--md-comp-toolbar-leading-space) var(--md-comp-toolbar-trailing-space);
|
|
275
|
+
padding-inline: 8px;
|
|
185
276
|
|
|
186
277
|
> .max {
|
|
187
278
|
min-width: 0;
|
|
@@ -190,68 +281,103 @@ nav.toolbar.vertical {
|
|
|
190
281
|
}
|
|
191
282
|
}
|
|
192
283
|
|
|
193
|
-
//
|
|
194
|
-
//
|
|
195
|
-
//
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
display: flex;
|
|
199
|
-
width: 100%;
|
|
200
|
-
--md-comp-toolbar-container-shape: 0;
|
|
201
|
-
justify-content: space-around;
|
|
202
|
-
@include z-depth("0");
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// Pair a floating toolbar with a companion FAB. The FAB is a sibling,
|
|
206
|
-
// not a child — typically .extra.circle.
|
|
284
|
+
// The companion FAB. It is a sibling of the bar, not a child, and it stays a
|
|
285
|
+
// FAB: md.comp.toolbar.floating.fab restates md.comp.fab's 56dp container,
|
|
286
|
+
// 24dp icon and 16dp corner, which .extra.circle already draws. Only three
|
|
287
|
+
// values are its own - the 8dp gap, the level-1 lift (the bar beside it is
|
|
288
|
+
// level 3), and a color pair that follows the bar's color style.
|
|
207
289
|
.toolbar-group {
|
|
290
|
+
--md-comp-toolbar-floating-fab-between-space: 8px;
|
|
291
|
+
--md-comp-toolbar-floating-fab-container-color: var(--md-sys-color-secondary-container);
|
|
292
|
+
--md-comp-toolbar-floating-fab-icon-color: var(--md-sys-color-on-secondary-container);
|
|
293
|
+
|
|
208
294
|
display: inline-flex;
|
|
209
295
|
align-items: center;
|
|
210
|
-
gap:
|
|
296
|
+
gap: var(--md-comp-toolbar-floating-fab-between-space);
|
|
211
297
|
|
|
212
298
|
&.vertical {
|
|
213
299
|
flex-direction: column;
|
|
214
300
|
}
|
|
215
301
|
|
|
216
|
-
>
|
|
302
|
+
> #{$_toolbar} {
|
|
217
303
|
margin: 0;
|
|
218
304
|
}
|
|
305
|
+
|
|
306
|
+
> .extra {
|
|
307
|
+
background-color: var(--md-comp-toolbar-floating-fab-container-color);
|
|
308
|
+
color: var(--md-comp-toolbar-floating-fab-icon-color);
|
|
309
|
+
@include z-depth("1");
|
|
310
|
+
|
|
311
|
+
// One opacity per state. All three arms are needed, bare `:focus`
|
|
312
|
+
// included: .extra.circle draws its own `:active, :focus` tint over
|
|
313
|
+
// primary-container, and leaving either uncovered would flash the FAB's
|
|
314
|
+
// default colour through a click on this one.
|
|
315
|
+
&:hover {
|
|
316
|
+
background-color: color-mix(
|
|
317
|
+
in oklab,
|
|
318
|
+
var(--md-comp-toolbar-floating-fab-icon-color) state-opacity("hover"),
|
|
319
|
+
var(--md-comp-toolbar-floating-fab-container-color)
|
|
320
|
+
);
|
|
321
|
+
@include z-depth("2");
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
&:focus {
|
|
325
|
+
background-color: color-mix(
|
|
326
|
+
in oklab,
|
|
327
|
+
var(--md-comp-toolbar-floating-fab-icon-color) state-opacity("focus"),
|
|
328
|
+
var(--md-comp-toolbar-floating-fab-container-color)
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
&:active {
|
|
333
|
+
background-color: color-mix(
|
|
334
|
+
in oklab,
|
|
335
|
+
var(--md-comp-toolbar-floating-fab-icon-color) state-opacity("pressed"),
|
|
336
|
+
var(--md-comp-toolbar-floating-fab-container-color)
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
219
340
|
}
|
|
220
341
|
|
|
221
|
-
//
|
|
222
|
-
//
|
|
223
|
-
|
|
342
|
+
// A vibrant bar takes a vibrant FAB. The author marks the bar, not the group,
|
|
343
|
+
// so the group reads it - the same one class drives both.
|
|
344
|
+
.toolbar-group:has(> #{$_vibrant}) > .extra {
|
|
345
|
+
--md-comp-toolbar-floating-fab-container-color: var(--md-sys-color-tertiary-container);
|
|
346
|
+
--md-comp-toolbar-floating-fab-icon-color: var(--md-sys-color-on-tertiary-container);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Pin to the viewport. The inset is the variant's own external space:
|
|
350
|
+
// 16dp for a horizontal floating bar, 24dp for a vertical one, 0 for a
|
|
351
|
+
// docked bar, which states its own and so declares no external space at all.
|
|
352
|
+
// Bottom is the default, so `.bottom`
|
|
353
|
+
// has no rule - a bar naming it falls through to the one above.
|
|
354
|
+
#{$_toolbar}.fixed {
|
|
224
355
|
position: fixed;
|
|
225
356
|
z-index: 996;
|
|
226
|
-
inset: auto auto
|
|
357
|
+
inset: auto auto var(--md-comp-toolbar-external-space) 50%;
|
|
227
358
|
transform: translateX(-50%);
|
|
228
359
|
}
|
|
229
360
|
|
|
230
|
-
|
|
231
|
-
inset:
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
nav.toolbar.fixed.bottom {
|
|
235
|
-
inset: auto auto 16px 50%;
|
|
361
|
+
#{$_toolbar}.fixed.top {
|
|
362
|
+
inset: var(--md-comp-toolbar-external-space) auto auto 50%;
|
|
236
363
|
}
|
|
237
364
|
|
|
238
|
-
|
|
239
|
-
inset: 50% auto auto
|
|
365
|
+
#{$_floating}.vertical.fixed {
|
|
366
|
+
inset: 50% auto auto var(--md-comp-toolbar-external-space);
|
|
240
367
|
transform: translateY(-50%);
|
|
241
368
|
}
|
|
242
369
|
|
|
243
|
-
|
|
244
|
-
inset: 50%
|
|
370
|
+
#{$_floating}.vertical.fixed.right {
|
|
371
|
+
inset: 50% var(--md-comp-toolbar-external-space) auto auto;
|
|
245
372
|
}
|
|
246
373
|
|
|
247
|
-
|
|
248
|
-
nav.toolbar:is(.max, .docked).fixed.bottom {
|
|
374
|
+
#{$_docked}.fixed {
|
|
249
375
|
inset: auto 0 0 0;
|
|
250
376
|
transform: none;
|
|
251
377
|
padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px));
|
|
252
378
|
}
|
|
253
379
|
|
|
254
|
-
|
|
380
|
+
#{$_docked}.fixed.top {
|
|
255
381
|
inset: 0 0 auto 0;
|
|
256
382
|
transform: none;
|
|
257
383
|
padding-bottom: 8px;
|
|
@@ -39,19 +39,21 @@ label:has(> [type="checkbox"]):not(.switch),
|
|
|
39
39
|
-webkit-tap-highlight-color: transparent;
|
|
40
40
|
color: var(--md-sys-color-on-surface);
|
|
41
41
|
@include typescale("body-large");
|
|
42
|
-
font-family: $font-stack;
|
|
43
42
|
}
|
|
44
43
|
|
|
45
|
-
|
|
46
|
-
nav
|
|
44
|
+
// A row of checkboxes is a group of controls, not navigation - see rule 4 in
|
|
45
|
+
// SEMANTICS.md. `.inline` is the documented hook; the bare <nav> is the older
|
|
46
|
+
// markup and still works. _radio-buttons.scss carries the same pair.
|
|
47
|
+
:is(nav, .inline):has(> label > [type="checkbox"]:not(.switch *)),
|
|
48
|
+
:is(nav, .inline):has(> .checkbox) {
|
|
47
49
|
display: flex;
|
|
48
50
|
flex-wrap: wrap;
|
|
49
51
|
align-items: center;
|
|
50
52
|
gap: 8px 24px;
|
|
51
53
|
}
|
|
52
54
|
|
|
53
|
-
nav > label:has(> [type="checkbox"]):not(.switch),
|
|
54
|
-
nav > .checkbox {
|
|
55
|
+
:is(nav, .inline) > label:has(> [type="checkbox"]):not(.switch),
|
|
56
|
+
:is(nav, .inline) > .checkbox {
|
|
55
57
|
display: inline-flex;
|
|
56
58
|
}
|
|
57
59
|
|
|
@@ -80,17 +82,32 @@ label:has(> [type="checkbox"]):not(.switch) > [type="checkbox"],
|
|
|
80
82
|
}
|
|
81
83
|
|
|
82
84
|
&:hover {
|
|
83
|
-
|
|
85
|
+
@include state-layer-ring(
|
|
86
|
+
var(--md-comp-checkbox-state-layer-size),
|
|
87
|
+
var(--md-comp-checkbox-container-size),
|
|
88
|
+
var(--md-sys-color-on-surface),
|
|
89
|
+
"hover"
|
|
90
|
+
);
|
|
84
91
|
}
|
|
85
92
|
|
|
86
93
|
&:checked:hover,
|
|
87
94
|
&:indeterminate:hover {
|
|
88
|
-
|
|
95
|
+
@include state-layer-ring(
|
|
96
|
+
var(--md-comp-checkbox-state-layer-size),
|
|
97
|
+
var(--md-comp-checkbox-container-size),
|
|
98
|
+
var(--md-sys-color-primary),
|
|
99
|
+
"hover"
|
|
100
|
+
);
|
|
89
101
|
}
|
|
90
102
|
|
|
91
103
|
&:focus-visible,
|
|
92
104
|
&.tabbed:focus {
|
|
93
|
-
|
|
105
|
+
@include state-layer-ring(
|
|
106
|
+
var(--md-comp-checkbox-state-layer-size),
|
|
107
|
+
var(--md-comp-checkbox-container-size),
|
|
108
|
+
var(--md-sys-color-primary),
|
|
109
|
+
"focus"
|
|
110
|
+
);
|
|
94
111
|
outline: none;
|
|
95
112
|
}
|
|
96
113
|
|
|
@@ -109,7 +126,12 @@ label:has(> [type="checkbox"]):not(.switch) > [type="checkbox"],
|
|
|
109
126
|
|
|
110
127
|
&.invalid:hover,
|
|
111
128
|
&[aria-invalid="true"]:hover {
|
|
112
|
-
|
|
129
|
+
@include state-layer-ring(
|
|
130
|
+
var(--md-comp-checkbox-state-layer-size),
|
|
131
|
+
var(--md-comp-checkbox-container-size),
|
|
132
|
+
var(--md-sys-color-error),
|
|
133
|
+
"hover"
|
|
134
|
+
);
|
|
113
135
|
}
|
|
114
136
|
|
|
115
137
|
&:disabled {
|
|
@@ -239,16 +261,31 @@ $_cb-span: "*:not(.switch) > [type='checkbox'] + span:not(.lever, .supporting-te
|
|
|
239
261
|
}
|
|
240
262
|
|
|
241
263
|
*:not(.switch) > [type="checkbox"]:hover + span:not(.lever, .supporting-text, .character-counter, .file-path)::before {
|
|
242
|
-
|
|
264
|
+
@include state-layer-ring(
|
|
265
|
+
var(--md-comp-checkbox-state-layer-size),
|
|
266
|
+
var(--md-comp-checkbox-container-size),
|
|
267
|
+
var(--md-sys-color-on-surface),
|
|
268
|
+
"hover"
|
|
269
|
+
);
|
|
243
270
|
}
|
|
244
271
|
|
|
245
272
|
*:not(.switch) > [type="checkbox"]:is(:checked, :indeterminate):hover + span:not(.lever, .supporting-text, .character-counter, .file-path)::before {
|
|
246
|
-
|
|
273
|
+
@include state-layer-ring(
|
|
274
|
+
var(--md-comp-checkbox-state-layer-size),
|
|
275
|
+
var(--md-comp-checkbox-container-size),
|
|
276
|
+
var(--md-sys-color-primary),
|
|
277
|
+
"hover"
|
|
278
|
+
);
|
|
247
279
|
}
|
|
248
280
|
|
|
249
281
|
*:not(.switch) > [type="checkbox"]:focus-visible + span:not(.lever, .supporting-text, .character-counter, .file-path)::before,
|
|
250
282
|
*:not(.switch) > [type="checkbox"].tabbed:focus + span:not(.lever, .supporting-text, .character-counter, .file-path)::before {
|
|
251
|
-
|
|
283
|
+
@include state-layer-ring(
|
|
284
|
+
var(--md-comp-checkbox-state-layer-size),
|
|
285
|
+
var(--md-comp-checkbox-container-size),
|
|
286
|
+
var(--md-sys-color-primary),
|
|
287
|
+
"focus"
|
|
288
|
+
);
|
|
252
289
|
}
|
|
253
290
|
|
|
254
291
|
*:not(.switch) > [type="checkbox"].invalid + span:not(.lever, .supporting-text, .character-counter, .file-path)::before,
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
//
|
|
5
5
|
// Anatomy is the HTML. A <fieldset> is the group. A <legend> is the
|
|
6
6
|
// headline. Direct children are the fields — .field, radios, switches,
|
|
7
|
-
// a
|
|
7
|
+
// a .inline row of radios, a trailing <small> as supporting text. No wrapper
|
|
8
8
|
// class. .filled / .border / .rounded are helpers markup cannot express.
|
|
9
9
|
//
|
|
10
10
|
// M3 has no fieldset component. Tokens follow the outlined grouping
|
|
@@ -49,7 +49,7 @@ fieldset {
|
|
|
49
49
|
background-color: transparent;
|
|
50
50
|
@include typescale("title-small");
|
|
51
51
|
|
|
52
|
-
>
|
|
52
|
+
> #{$icon} {
|
|
53
53
|
font-size: 18px;
|
|
54
54
|
width: 18px;
|
|
55
55
|
height: 18px;
|
|
@@ -64,7 +64,7 @@ fieldset {
|
|
|
64
64
|
margin-block-start: 16px;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
// Switches are inline-flex. Make a bare group stack;
|
|
67
|
+
// Switches are inline-flex. Make a bare group stack; .inline keeps
|
|
68
68
|
// radios on one line. Consecutive 48dp rows don't need the 16dp gap.
|
|
69
69
|
> label,
|
|
70
70
|
> .switch {
|
|
@@ -112,7 +112,7 @@ fieldset[disabled] {
|
|
|
112
112
|
transparent
|
|
113
113
|
);
|
|
114
114
|
|
|
115
|
-
> legend >
|
|
115
|
+
> legend > #{$icon} {
|
|
116
116
|
color: var(--md-comp-fieldset-legend-color);
|
|
117
117
|
}
|
|
118
118
|
}
|
|
@@ -12,6 +12,10 @@
|
|
|
12
12
|
|
|
13
13
|
input.file-path { width: 100%; }
|
|
14
14
|
|
|
15
|
+
// The trigger. `label.button` is the documented form - it wraps the file
|
|
16
|
+
// input, which is how clicking it opens the picker with no script. <button>
|
|
17
|
+
// and .btn are the older markup and still work.
|
|
18
|
+
> label.button,
|
|
15
19
|
> button,
|
|
16
20
|
> .btn {
|
|
17
21
|
position: relative;
|
|
@@ -24,7 +28,10 @@
|
|
|
24
28
|
cursor: pointer;
|
|
25
29
|
}
|
|
26
30
|
|
|
27
|
-
|
|
31
|
+
// Scoped to the trigger, not to .file-field. `inset: 0` against the field
|
|
32
|
+
// stretched the invisible input across the whole row, so clicking the path
|
|
33
|
+
// display - or any empty space - opened the file picker.
|
|
34
|
+
:is(label.button, button, .btn) input[type=file] {
|
|
28
35
|
position: absolute;
|
|
29
36
|
inset: 0;
|
|
30
37
|
cursor: pointer;
|