@expressivecss/expressive 0.3.0 → 0.4.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/README.md +1 -1
- package/dist/css/expressive.css +1011 -1339
- 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 +701 -853
- package/dist/js/expressive.cjs.map +4 -4
- package/dist/js/expressive.js +701 -853
- package/dist/js/expressive.js.map +4 -4
- package/dist/js/expressive.min.js +10 -20
- package/dist/js/expressive.min.js.map +4 -4
- package/dist/js/expressive.mjs +701 -854
- package/dist/js/expressive.mjs.map +4 -4
- package/dist/types/components/autocomplete.d.ts +2 -9
- package/dist/types/components/buttons.d.ts +2 -2
- package/dist/types/components/cards.d.ts +3 -6
- package/dist/types/components/carousel.d.ts +3 -3
- package/dist/types/components/characterCounter.d.ts +3 -5
- package/dist/types/components/chips.d.ts +2 -2
- package/dist/types/components/collapsible.d.ts +6 -23
- package/dist/types/components/datepicker.d.ts +2 -8
- package/dist/types/components/dropdown.d.ts +11 -2
- package/dist/types/components/index.d.ts +0 -1
- package/dist/types/components/lightbox.d.ts +2 -2
- package/dist/types/components/parallax.d.ts +2 -8
- package/dist/types/components/pushpin.d.ts +2 -2
- package/dist/types/components/range.d.ts +2 -2
- package/dist/types/components/registry.d.ts +0 -4
- package/dist/types/components/scrollspy.d.ts +26 -50
- package/dist/types/components/select.d.ts +20 -6
- package/dist/types/components/sidenav.d.ts +40 -55
- package/dist/types/components/slider.d.ts +2 -2
- package/dist/types/components/tabs.d.ts +2 -2
- package/dist/types/components/tapTarget.d.ts +2 -2
- package/dist/types/components/timepicker.d.ts +2 -4
- package/dist/types/components/tooltip.d.ts +2 -2
- package/dist/types/core/component.d.ts +4 -4
- package/dist/types/index.d.ts +1 -1
- package/package.json +2 -2
- package/src/sass/README.md +2 -6
- package/src/sass/abstracts/_breakpoints.scss +0 -16
- package/src/sass/abstracts/_variables.scss +0 -21
- package/src/sass/base/_grid.scss +0 -19
- package/src/sass/components/_badges.scss +1 -1
- package/src/sass/components/_buttons.scss +22 -54
- package/src/sass/components/_cards.scss +50 -123
- package/src/sass/components/_carousel.scss +4 -6
- package/src/sass/components/_collapsible.scss +13 -15
- package/src/sass/components/_collection.scss +9 -27
- package/src/sass/components/_datepicker.scss +1 -15
- package/src/sass/components/_dropdown.scss +110 -14
- package/src/sass/components/_index.scss +1 -0
- package/src/sass/components/_modal.scss +13 -31
- package/src/sass/components/_navbar.scss +9 -6
- package/src/sass/components/_page-footer.scss +134 -15
- package/src/sass/components/_parallax.scss +7 -28
- package/src/sass/components/_preloader.scss +145 -300
- package/src/sass/components/_scrollspy.scss +18 -0
- package/src/sass/components/_sidenav.scss +226 -120
- package/src/sass/components/_table_of_contents.scss +30 -14
- package/src/sass/components/_tabs.scss +54 -35
- package/src/sass/components/_tapTarget.scss +2 -6
- package/src/sass/components/_toast.scss +10 -11
- package/src/sass/components/_toolbar.scss +2 -2
- package/src/sass/components/_tooltip.scss +4 -9
- package/src/sass/components/_transitions.scss +0 -5
- package/src/sass/components/forms/_index.scss +0 -5
- package/src/sass/components/forms/_input-fields.scss +49 -52
- package/src/sass/components/forms/_select.scss +175 -60
- package/src/sass/components/forms/_switches.scss +21 -8
- package/src/sass/utilities/_helpers.scss +1 -3
- package/src/sass/utilities/_typescale.scss +0 -5
- package/src/sass/utilities/_visibility.scss +2 -2
- package/dist/types/components/modal.d.ts +0 -45
|
@@ -11,8 +11,6 @@
|
|
|
11
11
|
// --md-comp-tap-target-supporting-color
|
|
12
12
|
// --md-comp-tap-target-duration 300ms
|
|
13
13
|
// --md-comp-tap-target-easing soft ease-in-out
|
|
14
|
-
//
|
|
15
|
-
// .feature-discovery is an alias of .tap-target.
|
|
16
14
|
|
|
17
15
|
.tap-target-wrapper {
|
|
18
16
|
--md-comp-tap-target-size: 480px;
|
|
@@ -53,8 +51,7 @@
|
|
|
53
51
|
pointer-events: none;
|
|
54
52
|
transition-delay: 0s;
|
|
55
53
|
|
|
56
|
-
.tap-target
|
|
57
|
-
.feature-discovery {
|
|
54
|
+
.tap-target {
|
|
58
55
|
transform: scale(1);
|
|
59
56
|
opacity: 1;
|
|
60
57
|
}
|
|
@@ -69,8 +66,7 @@
|
|
|
69
66
|
}
|
|
70
67
|
}
|
|
71
68
|
|
|
72
|
-
.tap-target
|
|
73
|
-
.feature-discovery {
|
|
69
|
+
.tap-target {
|
|
74
70
|
position: absolute;
|
|
75
71
|
inset: 0;
|
|
76
72
|
display: grid;
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
// Snackbars (toasts).
|
|
4
4
|
//
|
|
5
|
-
// Anatomy is the HTML. A .snackbar
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
// <i> is an icon.
|
|
5
|
+
// Anatomy is the HTML. A .snackbar is the container. A <p> (or <span>,
|
|
6
|
+
// or loose text) is the supporting text. A trailing <button> is the
|
|
7
|
+
// action; a .circle button is the optional close. An optional leading
|
|
8
|
+
// <i> is an icon.
|
|
9
9
|
//
|
|
10
10
|
// Tokens follow https://m3.material.io/components/snackbar/specs
|
|
11
11
|
// container inverse-surface, 4dp corners, elevation 3, min 48dp
|
|
@@ -15,11 +15,10 @@
|
|
|
15
15
|
// close 24dp icon, inverse-on-surface
|
|
16
16
|
// inset 8dp compact, 24dp from start+bottom on larger screens
|
|
17
17
|
//
|
|
18
|
-
// The constructor
|
|
19
|
-
//
|
|
20
|
-
// There is no AutoInit and no toast() helper.
|
|
18
|
+
// The constructor adds .snackbar. A static .snackbar is in-flow (docs
|
|
19
|
+
// previews). .active pins it to the viewport. There is no AutoInit.
|
|
21
20
|
|
|
22
|
-
$_bar: "
|
|
21
|
+
$_bar: ".snackbar";
|
|
23
22
|
|
|
24
23
|
#toast-container {
|
|
25
24
|
--md-comp-snackbar-container-margin-leading: 8px;
|
|
@@ -128,7 +127,7 @@ $_bar: ":is(.toast, .snackbar)";
|
|
|
128
127
|
}
|
|
129
128
|
|
|
130
129
|
// Inline links in the supporting text use the action color.
|
|
131
|
-
a:not(.button
|
|
130
|
+
a:not(.button) {
|
|
132
131
|
color: var(--md-comp-snackbar-action-label-text-color);
|
|
133
132
|
}
|
|
134
133
|
|
|
@@ -147,8 +146,8 @@ $_bar: ":is(.toast, .snackbar)";
|
|
|
147
146
|
}
|
|
148
147
|
|
|
149
148
|
// Text action — inverse-primary, not the filled common-button default.
|
|
150
|
-
> :is(button, a.button
|
|
151
|
-
> nav > :is(button, a.button
|
|
149
|
+
> :is(button, a.button):not(.circle),
|
|
150
|
+
> nav > :is(button, a.button):not(.circle) {
|
|
152
151
|
flex: 0 0 auto;
|
|
153
152
|
height: 40px;
|
|
154
153
|
min-width: 48px;
|
|
@@ -49,7 +49,7 @@ nav.toolbar {
|
|
|
49
49
|
|
|
50
50
|
// Actions — transparent at rest so they sit on the container, not filled.
|
|
51
51
|
// .extra is the 56dp FAB; leave it alone so a docked bar can embed one.
|
|
52
|
-
> :is(a, button):not(.
|
|
52
|
+
> :is(a, button):not(.extra) {
|
|
53
53
|
box-sizing: border-box;
|
|
54
54
|
display: inline-flex;
|
|
55
55
|
flex: 0 0 auto;
|
|
@@ -103,7 +103,7 @@ nav.toolbar {
|
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
// Icon-only — .circle, or an <i> with no <span> sibling.
|
|
106
|
-
> :is(a, button):not(.
|
|
106
|
+
> :is(a, button):not(.extra):is(.circle, :has(> i):not(:has(> span))) {
|
|
107
107
|
width: var(--md-comp-toolbar-action-size);
|
|
108
108
|
padding: 0;
|
|
109
109
|
border-radius: 50%;
|
|
@@ -14,11 +14,9 @@
|
|
|
14
14
|
// gap 4dp from the activator
|
|
15
15
|
//
|
|
16
16
|
// The JS plugin still exists: .tooltipped + data-tooltip, AutoInit,
|
|
17
|
-
// class .tooltip
|
|
18
|
-
// is an alias. There is no data-html / unsafeHTML.
|
|
17
|
+
// class .tooltip appended to <body>. There is no data-html / unsafeHTML.
|
|
19
18
|
|
|
20
|
-
.tooltip
|
|
21
|
-
.material-tooltip {
|
|
19
|
+
.tooltip {
|
|
22
20
|
--md-comp-plain-tooltip-container-color: var(--md-sys-color-inverse-surface);
|
|
23
21
|
--md-comp-plain-tooltip-supporting-text-color: var(--md-sys-color-inverse-on-surface);
|
|
24
22
|
--md-comp-plain-tooltip-container-shape: 4px;
|
|
@@ -109,8 +107,7 @@
|
|
|
109
107
|
|
|
110
108
|
// JS plugin: appended to <body>, top/left set in script. Do not use the
|
|
111
109
|
// child-positioning rules; they would fight the inline transform.
|
|
112
|
-
body > .tooltip
|
|
113
|
-
.material-tooltip {
|
|
110
|
+
body > .tooltip {
|
|
114
111
|
position: absolute;
|
|
115
112
|
left: 0;
|
|
116
113
|
top: 0;
|
|
@@ -121,9 +118,7 @@ body > .tooltip,
|
|
|
121
118
|
|
|
122
119
|
// Rich tooltip — title, supporting text, optional action.
|
|
123
120
|
.tooltip.rich,
|
|
124
|
-
.tooltip.max
|
|
125
|
-
.material-tooltip.rich,
|
|
126
|
-
.material-tooltip.max {
|
|
121
|
+
.tooltip.max {
|
|
127
122
|
--md-comp-rich-tooltip-container-color: var(--md-sys-color-surface);
|
|
128
123
|
--md-comp-rich-tooltip-container-shape: 12px;
|
|
129
124
|
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
@use "../abstracts" as *;
|
|
2
2
|
|
|
3
|
-
// Starting states for JS-driven animations: Sidenav staggers its list items in,
|
|
4
|
-
// and .fade-in is applied before an element is animated into view.
|
|
5
|
-
ul.staggered-list li { opacity: 0; }
|
|
6
|
-
.fade-in { opacity: 0; transform-origin: 0 50%; }
|
|
7
|
-
|
|
8
3
|
.scale-transition {
|
|
9
4
|
transition: transform .3s cubic-bezier(0.53, 0.01, 0.36, 1.63) !important;
|
|
10
5
|
|
|
@@ -2,14 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
// Text fields.
|
|
4
4
|
//
|
|
5
|
-
// Anatomy is the HTML. .field
|
|
6
|
-
//
|
|
7
|
-
// leading icon.
|
|
8
|
-
//
|
|
5
|
+
// Anatomy is the HTML. .field is the container. The <label> after the
|
|
6
|
+
// control is the floating label. A leading <i> (or .prefix) is the
|
|
7
|
+
// leading icon; .suffix (or a second / trailing <i>) is the trailing
|
|
8
|
+
// icon. Icons come before the control in the documented markup, so
|
|
9
|
+
// trailing cannot be selected with :last-child — that left .suffix
|
|
10
|
+
// in flow above the well. <small> is supporting text. .outlined is
|
|
11
|
+
// the outlined variant; the default is filled.
|
|
9
12
|
//
|
|
10
13
|
// Tokens follow https://m3.material.io/components/text-fields/specs
|
|
11
|
-
// filled surface-variant well,
|
|
12
|
-
// outlined 1dp/2dp outline,
|
|
14
|
+
// filled surface-variant well, 1rem corners, 1dp/2dp bottom indicator
|
|
15
|
+
// outlined 1dp/2dp outline, 1rem corners
|
|
13
16
|
// height 56dp
|
|
14
17
|
// label body-large rest, body-small floated
|
|
15
18
|
// input body-large / on-surface
|
|
@@ -34,21 +37,23 @@ $_text-inputs: "input:not([type]):not(.browser-default), input[type=text]:not(.b
|
|
|
34
37
|
font-family: $font-stack;
|
|
35
38
|
}
|
|
36
39
|
|
|
37
|
-
.field
|
|
38
|
-
.input-field {
|
|
40
|
+
.field {
|
|
39
41
|
--md-comp-filled-text-field-container-color: var(--md-sys-color-surface-variant);
|
|
42
|
+
--md-comp-filled-text-field-container-shape: 1rem;
|
|
40
43
|
--md-comp-filled-text-field-caret-color: var(--md-sys-color-primary);
|
|
41
44
|
--input-color: var(--md-comp-filled-text-field-caret-color);
|
|
42
45
|
|
|
43
46
|
position: relative;
|
|
44
47
|
clear: both;
|
|
45
48
|
|
|
46
|
-
|
|
49
|
+
// Checkboxes / radios inside a field (multi-select menu) are not text
|
|
50
|
+
// fields — do not give them the 56dp well.
|
|
51
|
+
input:not([type="range"], [type="checkbox"], [type="radio"], [type="file"]),
|
|
47
52
|
textarea {
|
|
48
53
|
box-sizing: border-box;
|
|
49
54
|
padding: 20px 16px 8px;
|
|
50
55
|
border: none;
|
|
51
|
-
border-radius:
|
|
56
|
+
border-radius: var(--md-comp-filled-text-field-container-shape);
|
|
52
57
|
border-bottom: 1px solid var(--md-sys-color-on-surface-variant);
|
|
53
58
|
background-color: var(--md-comp-filled-text-field-container-color);
|
|
54
59
|
caret-color: var(--input-color);
|
|
@@ -67,16 +72,16 @@ $_text-inputs: "input:not([type]):not(.browser-default), input[type=text]:not(.b
|
|
|
67
72
|
}
|
|
68
73
|
|
|
69
74
|
&:focus:not([readonly]) + label,
|
|
70
|
-
&:focus:not([readonly]) + span:not(.supporting-text, .character-counter) {
|
|
75
|
+
&:focus:not([readonly]) + span:not(.supporting-text, .character-counter, .caret) {
|
|
71
76
|
color: var(--input-color);
|
|
72
77
|
}
|
|
73
78
|
|
|
74
79
|
&:focus:not([readonly]) + label,
|
|
75
80
|
&:not([placeholder=" "]) + label,
|
|
76
81
|
&:not(:placeholder-shown) + label,
|
|
77
|
-
&:focus:not([readonly]) + span:not(.supporting-text, .character-counter),
|
|
78
|
-
&:not([placeholder=" "]) + span:not(.supporting-text, .character-counter),
|
|
79
|
-
&:not(:placeholder-shown) + span:not(.supporting-text, .character-counter) {
|
|
82
|
+
&:focus:not([readonly]) + span:not(.supporting-text, .character-counter, .caret),
|
|
83
|
+
&:not([placeholder=" "]) + span:not(.supporting-text, .character-counter, .caret),
|
|
84
|
+
&:not(:placeholder-shown) + span:not(.supporting-text, .character-counter, .caret) {
|
|
80
85
|
transform: scale(calc(12 / 16));
|
|
81
86
|
top: 8px;
|
|
82
87
|
}
|
|
@@ -119,7 +124,7 @@ $_text-inputs: "input:not([type]):not(.browser-default), input[type=text]:not(.b
|
|
|
119
124
|
}
|
|
120
125
|
|
|
121
126
|
> label,
|
|
122
|
-
> span:not(.supporting-text, .character-counter, .file-path) {
|
|
127
|
+
> span:not(.supporting-text, .character-counter, .file-path, .caret) {
|
|
123
128
|
color: var(--md-sys-color-on-surface-variant);
|
|
124
129
|
user-select: none;
|
|
125
130
|
position: absolute;
|
|
@@ -152,10 +157,11 @@ $_text-inputs: "input:not([type]):not(.browser-default), input[type=text]:not(.b
|
|
|
152
157
|
font-family: $font-stack;
|
|
153
158
|
}
|
|
154
159
|
|
|
155
|
-
|
|
156
|
-
>
|
|
160
|
+
// Shared icon box. Position is set on the leading / trailing rules;
|
|
161
|
+
// a lone <i> matches several of the :is() items and must not pick
|
|
162
|
+
// a side here.
|
|
163
|
+
> i:is(.prefix, .suffix, :first-of-type, :last-of-type, :last-child) {
|
|
157
164
|
position: absolute;
|
|
158
|
-
left: 12px;
|
|
159
165
|
top: 16px;
|
|
160
166
|
display: flex;
|
|
161
167
|
align-items: center;
|
|
@@ -165,53 +171,44 @@ $_text-inputs: "input:not([type]):not(.browser-default), input[type=text]:not(.b
|
|
|
165
171
|
line-height: 24px;
|
|
166
172
|
color: var(--md-sys-color-on-surface-variant);
|
|
167
173
|
user-select: none;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
> i:first-of-type:not(.suffix):not(:last-child),
|
|
177
|
+
> i.prefix {
|
|
178
|
+
left: 12px;
|
|
168
179
|
pointer-events: none;
|
|
169
180
|
}
|
|
170
181
|
|
|
171
|
-
> .suffix,
|
|
172
|
-
> i
|
|
173
|
-
|
|
182
|
+
> i.suffix,
|
|
183
|
+
> i:last-of-type:not(:first-of-type),
|
|
184
|
+
> i:last-child:not(:first-child):not(.prefix) {
|
|
174
185
|
right: 12px;
|
|
175
|
-
top: 16px;
|
|
176
|
-
display: flex;
|
|
177
|
-
align-items: center;
|
|
178
|
-
font-size: 24px;
|
|
179
|
-
width: 24px;
|
|
180
|
-
height: 24px;
|
|
181
|
-
line-height: 24px;
|
|
182
|
-
color: var(--md-sys-color-on-surface-variant);
|
|
183
|
-
user-select: none;
|
|
184
186
|
}
|
|
185
187
|
|
|
186
|
-
> i:first-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
padding-left: 52px;
|
|
191
|
-
}
|
|
188
|
+
&:has(> i:first-of-type:not(.suffix):not(:last-child), > i.prefix) {
|
|
189
|
+
> :is(input, textarea) {
|
|
190
|
+
padding-left: 52px;
|
|
191
|
+
}
|
|
192
192
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
> i.suffix ~ textarea {
|
|
197
|
-
padding-right: 52px;
|
|
193
|
+
> :is(label, span:not(.supporting-text, .character-counter, .file-path, .caret)) {
|
|
194
|
+
left: 52px;
|
|
195
|
+
}
|
|
198
196
|
}
|
|
199
197
|
|
|
200
|
-
> i:first-child:not(.
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
198
|
+
&:has(> i.suffix, > i:last-of-type:not(:first-of-type), > i:last-child:not(:first-child):not(.prefix)) {
|
|
199
|
+
> :is(input, textarea) {
|
|
200
|
+
padding-right: 52px;
|
|
201
|
+
}
|
|
204
202
|
}
|
|
205
203
|
|
|
206
|
-
&.outlined
|
|
207
|
-
&.border {
|
|
204
|
+
&.outlined {
|
|
208
205
|
> input,
|
|
209
206
|
> textarea {
|
|
210
207
|
padding-top: 8px;
|
|
211
208
|
padding-bottom: 8px;
|
|
212
209
|
background-color: transparent;
|
|
213
210
|
border: 1px solid var(--md-sys-color-outline);
|
|
214
|
-
border-radius:
|
|
211
|
+
border-radius: var(--md-comp-filled-text-field-container-shape);
|
|
215
212
|
|
|
216
213
|
&:focus:not([readonly]) {
|
|
217
214
|
border-width: 2px;
|
|
@@ -223,9 +220,9 @@ $_text-inputs: "input:not([type]):not(.browser-default), input[type=text]:not(.b
|
|
|
223
220
|
&:focus:not([readonly]) + label,
|
|
224
221
|
&:not([placeholder=" "]) + label,
|
|
225
222
|
&:not(:placeholder-shown) + label,
|
|
226
|
-
&:focus:not([readonly]) + span:not(.supporting-text, .character-counter),
|
|
227
|
-
&:not([placeholder=" "]) + span:not(.supporting-text, .character-counter),
|
|
228
|
-
&:not(:placeholder-shown) + span:not(.supporting-text, .character-counter) {
|
|
223
|
+
&:focus:not([readonly]) + span:not(.supporting-text, .character-counter, .caret),
|
|
224
|
+
&:not([placeholder=" "]) + span:not(.supporting-text, .character-counter, .caret),
|
|
225
|
+
&:not(:placeholder-shown) + span:not(.supporting-text, .character-counter, .caret) {
|
|
229
226
|
top: -8px;
|
|
230
227
|
left: 16px;
|
|
231
228
|
margin-left: -4px;
|
|
@@ -253,7 +250,7 @@ $_text-inputs: "input:not([type]):not(.browser-default), input[type=text]:not(.b
|
|
|
253
250
|
}
|
|
254
251
|
|
|
255
252
|
.searchbar {
|
|
256
|
-
|
|
253
|
+
> i:first-child {
|
|
257
254
|
position: absolute;
|
|
258
255
|
padding-left: 1rem;
|
|
259
256
|
top: 0;
|
|
@@ -1,103 +1,218 @@
|
|
|
1
1
|
@use "../../abstracts" as *;
|
|
2
2
|
|
|
3
|
+
// Select (exposed dropdown).
|
|
4
|
+
//
|
|
5
|
+
// Anatomy is the HTML. A <select> is the control. FormSelect wraps it
|
|
6
|
+
// in .field (or reuses an existing one) and paints a text field + menu.
|
|
7
|
+
// .browser-default keeps the native control. .caret is the trailing
|
|
8
|
+
// expand icon (CSS, not an SVG node).
|
|
9
|
+
//
|
|
10
|
+
// Tokens follow https://m3.material.io/components/menus/overview
|
|
11
|
+
// (exposed dropdown = text field + menu) and the filled/outlined field
|
|
12
|
+
// tokens in _input-fields.scss.
|
|
13
|
+
// field 56dp, same chrome as .field
|
|
14
|
+
// trailing icon 24dp, 12dp from the end, rotates when open
|
|
15
|
+
// selected item 10% on-surface + trailing check
|
|
16
|
+
// optgroup on-surface-variant, outline-variant rule
|
|
17
|
+
//
|
|
18
|
+
$_select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='black' d='M7 10l5 5 5-5z'/%3E%3C/svg%3E");
|
|
19
|
+
$_select-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='black' d='M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/%3E%3C/svg%3E");
|
|
20
|
+
|
|
21
|
+
// Native / no-js / .browser-default: a 56dp field, not a 3rem box.
|
|
22
|
+
select {
|
|
23
|
+
--md-comp-filled-select-container-color: var(--md-sys-color-surface-variant);
|
|
24
|
+
--md-comp-filled-select-container-shape: 1rem;
|
|
25
|
+
--md-comp-filled-select-input-text-color: var(--md-sys-color-on-surface);
|
|
26
|
+
|
|
27
|
+
box-sizing: border-box;
|
|
28
|
+
width: 100%;
|
|
29
|
+
height: 56px;
|
|
30
|
+
margin: 0;
|
|
31
|
+
padding: 16px 12px;
|
|
32
|
+
border: 1px solid var(--md-sys-color-outline);
|
|
33
|
+
border-radius: var(--md-comp-filled-select-container-shape);
|
|
34
|
+
background-color: var(--md-comp-filled-select-container-color);
|
|
35
|
+
color: var(--md-comp-filled-select-input-text-color);
|
|
36
|
+
@include typescale("body-large");
|
|
37
|
+
font-family: $font-stack;
|
|
38
|
+
|
|
39
|
+
&:focus {
|
|
40
|
+
outline: 2px solid var(--md-sys-color-primary);
|
|
41
|
+
outline-offset: 2px;
|
|
42
|
+
border-color: var(--md-sys-color-primary);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
&:disabled {
|
|
46
|
+
color: color-mix(in oklab, var(--md-sys-color-on-surface) 38%, transparent);
|
|
47
|
+
border-color: color-mix(in oklab, var(--md-sys-color-on-surface) 12%, transparent);
|
|
48
|
+
background-color: color-mix(in oklab, var(--md-sys-color-on-surface) 4%, transparent);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
3
52
|
select.browser-default {
|
|
4
53
|
opacity: 1;
|
|
5
|
-
color: var(--md-sys-color-on-background);
|
|
6
54
|
}
|
|
7
55
|
|
|
8
|
-
|
|
9
|
-
|
|
56
|
+
@supports (appearance: base-select) {
|
|
57
|
+
select.browser-default,
|
|
58
|
+
select.browser-default::picker(select) {
|
|
59
|
+
appearance: base-select;
|
|
60
|
+
}
|
|
10
61
|
|
|
11
|
-
select {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
62
|
+
select.browser-default::picker(select) {
|
|
63
|
+
border: none;
|
|
64
|
+
border-radius: var(--md-comp-menu-container-shape, 1rem);
|
|
65
|
+
background-color: var(--md-sys-color-surface);
|
|
66
|
+
color: var(--md-sys-color-on-surface);
|
|
67
|
+
@include z-depth("2");
|
|
68
|
+
}
|
|
18
69
|
}
|
|
19
70
|
|
|
20
|
-
.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
71
|
+
.field:has(> .hide-select) {
|
|
72
|
+
// BeerCSS menu: 1rem surface, stadium items. Same radius on the
|
|
73
|
+
// field so the closed control and the open list read as one shape.
|
|
74
|
+
--md-comp-filled-select-container-shape: 1rem;
|
|
75
|
+
--md-comp-menu-container-shape: 1rem;
|
|
76
|
+
--md-comp-filled-select-trailing-icon-size: 24px;
|
|
77
|
+
--md-comp-filled-select-trailing-icon-color: var(--md-sys-color-on-surface-variant);
|
|
78
|
+
--md-comp-menu-item-leading-image-size: 40px;
|
|
24
79
|
|
|
25
|
-
.select-wrapper {
|
|
26
80
|
position: relative;
|
|
81
|
+
border-radius: var(--md-comp-filled-select-container-shape);
|
|
27
82
|
|
|
83
|
+
> input.dropdown-trigger {
|
|
84
|
+
border-radius: inherit;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
> input.dropdown-trigger {
|
|
88
|
+
padding-inline-end: 52px;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Trailing expand icon. Empty .caret is the hook; the glyph is a mask.
|
|
92
|
+
// `left: auto` beats `.field > span { left: 16px }` if that rule ever
|
|
93
|
+
// matches again — left + width would otherwise ignore inset-inline-end
|
|
94
|
+
// and pin the chevron over the value.
|
|
28
95
|
.caret {
|
|
29
96
|
position: absolute;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
z-index:
|
|
35
|
-
|
|
97
|
+
inset-block-start: 16px;
|
|
98
|
+
inset-inline-start: auto;
|
|
99
|
+
left: auto;
|
|
100
|
+
inset-inline-end: 12px;
|
|
101
|
+
z-index: 1;
|
|
102
|
+
width: var(--md-comp-filled-select-trailing-icon-size);
|
|
103
|
+
height: var(--md-comp-filled-select-trailing-icon-size);
|
|
104
|
+
margin: 0;
|
|
36
105
|
pointer-events: none;
|
|
106
|
+
background-color: var(--md-comp-filled-select-trailing-icon-color);
|
|
107
|
+
mask: $_select-chevron center / 24px no-repeat;
|
|
108
|
+
transition: transform 0.2s ease;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
&:has(> input[aria-expanded="true"]) .caret,
|
|
112
|
+
&:has(> menu:popover-open) .caret {
|
|
113
|
+
transform: rotate(180deg);
|
|
37
114
|
}
|
|
38
115
|
|
|
39
|
-
//
|
|
40
|
-
//
|
|
116
|
+
// Keep the native select in the field's box so constraint-validation
|
|
117
|
+
// bubbles land on the control, not at (0, 0).
|
|
41
118
|
.hide-select {
|
|
42
|
-
width: 0;
|
|
43
|
-
height: 0;
|
|
44
|
-
overflow: hidden;
|
|
45
119
|
position: absolute;
|
|
46
|
-
|
|
120
|
+
inset: 0;
|
|
121
|
+
overflow: hidden;
|
|
122
|
+
opacity: 0;
|
|
123
|
+
pointer-events: none;
|
|
47
124
|
z-index: -1;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
125
|
|
|
51
|
-
select
|
|
52
|
-
|
|
126
|
+
select {
|
|
127
|
+
width: 100%;
|
|
128
|
+
height: 100%;
|
|
129
|
+
margin: 0;
|
|
130
|
+
padding: 0;
|
|
131
|
+
border: 0;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
53
134
|
}
|
|
54
135
|
|
|
55
|
-
.select
|
|
56
|
-
+ label {
|
|
57
|
-
color: var(--md-sys-color-on-surface);
|
|
58
|
-
}
|
|
136
|
+
.field:has(> .hide-select).disabled {
|
|
59
137
|
.caret {
|
|
60
|
-
|
|
138
|
+
background-color: color-mix(in oklab, var(--md-sys-color-on-surface) 38%, transparent);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
+ label,
|
|
142
|
+
> label {
|
|
143
|
+
color: color-mix(in oklab, var(--md-sys-color-on-surface) 38%, transparent);
|
|
61
144
|
}
|
|
62
145
|
}
|
|
63
146
|
|
|
64
|
-
.select
|
|
65
|
-
color: var(--md-sys-color-on-surface);
|
|
147
|
+
.field:has(> .hide-select) > input.dropdown-trigger:disabled {
|
|
66
148
|
cursor: default;
|
|
67
149
|
user-select: none;
|
|
68
150
|
}
|
|
69
151
|
|
|
70
|
-
|
|
71
|
-
|
|
152
|
+
menu[role="listbox"] > li.disabled,
|
|
153
|
+
menu[role="listbox"] > li.disabled > span,
|
|
154
|
+
menu[role="listbox"] > li.optgroup {
|
|
155
|
+
color: color-mix(in oklab, var(--md-sys-color-on-surface) 38%, transparent);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
menu[role="listbox"] > li:not(.optgroup, .divider) {
|
|
159
|
+
display: flex;
|
|
160
|
+
align-items: center;
|
|
72
161
|
}
|
|
73
162
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
.select-dropdown li.optgroup {
|
|
77
|
-
color: var(--md-sys-color-on-surface);
|
|
78
|
-
//background-color: transparent;
|
|
163
|
+
menu[role="listbox"] > li.selected:not(.disabled, .optgroup) {
|
|
164
|
+
background-color: color-mix(in oklab, var(--md-sys-color-on-surface) 10%, transparent);
|
|
79
165
|
}
|
|
80
166
|
|
|
81
|
-
//
|
|
82
|
-
.select-dropdown li {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
167
|
+
// Single-select: trailing check. Multi-select already has a leading checkbox.
|
|
168
|
+
menu[role="listbox"]:not(.multiple-select-dropdown) > li.selected:not(.disabled, .optgroup)::after {
|
|
169
|
+
content: "";
|
|
170
|
+
flex: 0 0 24px;
|
|
171
|
+
width: 24px;
|
|
172
|
+
height: 24px;
|
|
173
|
+
margin-inline-start: auto;
|
|
174
|
+
margin-inline-end: 12px;
|
|
175
|
+
background-color: var(--md-sys-color-on-surface);
|
|
176
|
+
mask: $_select-check center / 24px no-repeat;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
menu[role="listbox"] li img {
|
|
180
|
+
box-sizing: border-box;
|
|
181
|
+
flex: 0 0 var(--md-comp-menu-item-leading-image-size);
|
|
182
|
+
width: var(--md-comp-menu-item-leading-image-size);
|
|
183
|
+
height: var(--md-comp-menu-item-leading-image-size);
|
|
184
|
+
margin: 4px 12px;
|
|
185
|
+
object-fit: cover;
|
|
186
|
+
border-radius: 4px;
|
|
187
|
+
order: 1;
|
|
188
|
+
margin-inline-start: auto;
|
|
189
|
+
|
|
190
|
+
&.left {
|
|
191
|
+
order: 0;
|
|
192
|
+
margin-inline-start: 12px;
|
|
193
|
+
margin-inline-end: 0;
|
|
88
194
|
}
|
|
89
195
|
}
|
|
90
196
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
197
|
+
menu[role="listbox"] li.optgroup {
|
|
198
|
+
cursor: default;
|
|
199
|
+
pointer-events: none;
|
|
200
|
+
|
|
201
|
+
&:not(:first-child) {
|
|
202
|
+
border-top: 1px solid var(--md-sys-color-outline-variant);
|
|
96
203
|
}
|
|
97
|
-
|
|
204
|
+
|
|
205
|
+
> span {
|
|
98
206
|
color: var(--md-sys-color-on-surface-variant);
|
|
99
207
|
}
|
|
100
|
-
|
|
101
|
-
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
menu[role="listbox"] li.optgroup-option {
|
|
211
|
+
padding-inline-start: 1rem;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
@media (prefers-reduced-motion: reduce) {
|
|
215
|
+
.field:has(> .hide-select) .caret {
|
|
216
|
+
transition: none;
|
|
102
217
|
}
|
|
103
218
|
}
|
|
@@ -68,13 +68,21 @@
|
|
|
68
68
|
border: 2px solid var(--md-sys-color-outline);
|
|
69
69
|
border-radius: 16px;
|
|
70
70
|
background-color: var(--md-sys-color-surface-variant);
|
|
71
|
+
// Size the image to the handle. A 100% gradient keeps the circle in
|
|
72
|
+
// the middle of the track, so background-position cannot put off on
|
|
73
|
+
// the start and on on the end.
|
|
71
74
|
background-image: radial-gradient(
|
|
72
|
-
circle,
|
|
73
|
-
var(--md-sys-color-outline)
|
|
74
|
-
transparent
|
|
75
|
+
circle closest-side,
|
|
76
|
+
var(--md-sys-color-outline) 100%,
|
|
77
|
+
transparent 101%
|
|
75
78
|
);
|
|
76
79
|
background-repeat: no-repeat;
|
|
77
|
-
background-
|
|
80
|
+
background-origin: padding-box;
|
|
81
|
+
background-size: var(--md-comp-switch-handle-unselected) var(--md-comp-switch-handle-unselected);
|
|
82
|
+
// Lengths only. A % in background-position is “align this point of the
|
|
83
|
+
// image with that point of the box”, so calc(100% - handle) leaves the
|
|
84
|
+
// thumb on the start and it only grows.
|
|
85
|
+
background-position: 6px 50%;
|
|
78
86
|
cursor: pointer;
|
|
79
87
|
transition: background-color .2s ease, background-position .2s ease,
|
|
80
88
|
background-size .2s ease, border-color .2s ease, box-shadow .2s ease;
|
|
@@ -83,11 +91,16 @@
|
|
|
83
91
|
border-color: var(--md-sys-color-primary);
|
|
84
92
|
background-color: var(--md-sys-color-primary);
|
|
85
93
|
background-image: radial-gradient(
|
|
86
|
-
circle,
|
|
87
|
-
var(--md-sys-color-on-primary)
|
|
88
|
-
transparent
|
|
94
|
+
circle closest-side,
|
|
95
|
+
var(--md-sys-color-on-primary) 100%,
|
|
96
|
+
transparent 101%
|
|
89
97
|
);
|
|
90
|
-
background-
|
|
98
|
+
background-size: var(--md-comp-switch-handle-selected) var(--md-comp-switch-handle-selected);
|
|
99
|
+
// padding-box is track minus the 2px border on each side; 2px inset.
|
|
100
|
+
background-position: calc(
|
|
101
|
+
var(--md-comp-switch-track-width) - 4px - 2px - var(--md-comp-switch-handle-selected)
|
|
102
|
+
)
|
|
103
|
+
50%;
|
|
91
104
|
}
|
|
92
105
|
|
|
93
106
|
&:hover {
|