maverick-wave 5.38.0 → 6.0.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 +63 -47
- package/maverick-wave.min.css +94 -68
- package/maverick-wave.min.js +1 -1
- package/package.json +7 -7
- package/src/js/main.js +382 -57
- package/src/scss/abstracts/_mixins.scss +35 -24
- package/src/scss/abstracts/_variables.scss +15 -0
- package/src/scss/base/_base.scss +107 -64
- package/src/scss/base/_index.scss +1 -0
- package/src/scss/base/_page-transitions.scss +29 -0
- package/src/scss/base/_reset.scss +0 -8
- package/src/scss/components/_accordions.scss +23 -18
- package/src/scss/components/_action-bar.scss +143 -0
- package/src/scss/components/_alerts.scss +13 -1
- package/src/scss/components/_avatars.scss +17 -0
- package/src/scss/components/_badge.scss +12 -0
- package/src/scss/components/_breadcrumbs.scss +10 -2
- package/src/scss/components/_chat.scss +250 -0
- package/src/scss/components/_code.scss +3 -1
- package/src/scss/components/_compare.scss +135 -0
- package/src/scss/components/_deck.scss +8 -14
- package/src/scss/components/_devices.scss +323 -0
- package/src/scss/components/_dropdown.scss +43 -2
- package/src/scss/components/_empty-state.scss +43 -0
- package/src/scss/components/_flag.scss +16 -0
- package/src/scss/components/_index.scss +6 -0
- package/src/scss/components/_lightbox.scss +1 -1
- package/src/scss/components/_marquee.scss +132 -0
- package/src/scss/components/_modals.scss +112 -83
- package/src/scss/components/_occasions.scss +62 -11
- package/src/scss/components/_pagination.scss +91 -0
- package/src/scss/components/_portrait-gallery.scss +1 -1
- package/src/scss/components/_progress.scss +122 -2
- package/src/scss/components/_segmented.scss +65 -2
- package/src/scss/components/_skeleton.scss +8 -0
- package/src/scss/components/_spinners.scss +38 -0
- package/src/scss/components/_stat.scss +232 -0
- package/src/scss/components/_stepper.scss +42 -2
- package/src/scss/components/_stories.scss +36 -22
- package/src/scss/components/_tables.scss +160 -17
- package/src/scss/components/_tabs.scss +42 -4
- package/src/scss/components/_tags.scss +39 -4
- package/src/scss/components/_tiles.scss +1 -1
- package/src/scss/components/_timelines.scss +138 -1
- package/src/scss/components/_toasts.scss +5 -1
- package/src/scss/components/_tooltip.scss +13 -0
- package/src/scss/form-elements/_checkbox.scss +40 -7
- package/src/scss/form-elements/_form.scss +2 -4
- package/src/scss/form-elements/_input.scss +9 -6
- package/src/scss/form-elements/_radio.scss +32 -3
- package/src/scss/form-elements/_select.scss +44 -1
- package/src/scss/form-elements/_slider.scss +18 -0
- package/src/scss/form-elements/_textarea.scss +9 -6
- package/src/scss/form-elements/_toggle.scss +37 -4
- package/src/scss/layout/_app-shell.scss +661 -0
- package/src/scss/layout/_bento.scss +43 -0
- package/src/scss/layout/_footer.scss +114 -2
- package/src/scss/layout/_grid.scss +7 -2
- package/src/scss/layout/_header-reveal.scss +30 -17
- package/src/scss/layout/_header.scss +21 -4
- package/src/scss/layout/_index.scss +2 -0
- package/src/scss/layout/_parallax.scss +13 -11
- package/src/scss/utilities/_accessibility.scss +4 -19
- package/src/scss/utilities/_index.scss +1 -0
- package/src/scss/utilities/_print.scss +7 -3
- package/src/scss/utilities/_reveal.scss +25 -17
- package/src/scss/utilities/_shape.scss +24 -0
- package/src/scss/utilities/_touch-targets.scss +23 -0
- package/src/scss/utilities/_variants.scss +25 -6
|
@@ -29,18 +29,6 @@
|
|
|
29
29
|
background: var(--mw-gray-background);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
// The tinted surface at rest, not the hovered one. A row starts out
|
|
33
|
-
// transparent, so it takes the whole step in one go - and at the hover tone
|
|
34
|
-
// it lands close enough to the solid header above it to read as selected
|
|
35
|
-
// rather than as pointed at. A badge or a tag is already sitting on the
|
|
36
|
-
// resting tint, which is why the louder one is right there and not here.
|
|
37
|
-
tr:hover {
|
|
38
|
-
td {
|
|
39
|
-
background: var(--mw-primary-background);
|
|
40
|
-
color: var(--mw-text-color);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
32
|
@include media-up('sm') {
|
|
45
33
|
th,
|
|
46
34
|
td {
|
|
@@ -145,11 +133,10 @@
|
|
|
145
133
|
}
|
|
146
134
|
}
|
|
147
135
|
|
|
148
|
-
//
|
|
149
|
-
.mw-table-hover {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
136
|
+
// The resting tint: the hover tone next to the solid header reads as selected
|
|
137
|
+
.mw-table-hover tbody tr:hover > td {
|
|
138
|
+
background: var(--mw-primary-background);
|
|
139
|
+
color: var(--mw-text-color);
|
|
153
140
|
}
|
|
154
141
|
|
|
155
142
|
// Quiet header for data-heavy views
|
|
@@ -192,4 +179,160 @@
|
|
|
192
179
|
--mw-table-scroll-height: 400px;
|
|
193
180
|
}
|
|
194
181
|
}
|
|
182
|
+
|
|
183
|
+
// The button sorts, aria-sort says which way - the arrow only repeats it
|
|
184
|
+
.mw-table th[aria-sort] > button {
|
|
185
|
+
appearance: none;
|
|
186
|
+
padding: 0;
|
|
187
|
+
border: 0;
|
|
188
|
+
background: none;
|
|
189
|
+
color: inherit;
|
|
190
|
+
font: inherit;
|
|
191
|
+
cursor: pointer;
|
|
192
|
+
// The header's fill is the ring's usual tone
|
|
193
|
+
@include focus-ring($color: currentColor);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.mw-table th[aria-sort]::after {
|
|
197
|
+
content: '';
|
|
198
|
+
display: inline-block;
|
|
199
|
+
width: 0.55em;
|
|
200
|
+
height: 0.55em;
|
|
201
|
+
margin-left: spacing('2');
|
|
202
|
+
vertical-align: middle;
|
|
203
|
+
background: currentColor;
|
|
204
|
+
clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
|
|
205
|
+
opacity: 0.45;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.mw-table th[aria-sort='ascending']::after {
|
|
209
|
+
clip-path: polygon(50% 10%, 100% 90%, 0 90%);
|
|
210
|
+
opacity: 1;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.mw-table th[aria-sort='descending']::after {
|
|
214
|
+
clip-path: polygon(0 10%, 100% 10%, 50% 90%);
|
|
215
|
+
opacity: 1;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Set by the app or by a checked first cell; an edge too, not colour alone
|
|
219
|
+
$_selected-row: ':is([aria-selected="true"], .mw-selected, :has(> :first-child input[type="checkbox"]:checked))';
|
|
220
|
+
|
|
221
|
+
.mw-table tr#{$_selected-row} > td {
|
|
222
|
+
background: var(--mw-primary-background-hover);
|
|
223
|
+
color: var(--mw-text-color);
|
|
224
|
+
|
|
225
|
+
&:first-child {
|
|
226
|
+
box-shadow: inset 3px 0 0 var(--mw-primary-text-color);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// After the table in the markup, so the counter has seen every row first
|
|
231
|
+
.mw-table-bulk {
|
|
232
|
+
counter-reset: mw-table-selected;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.mw-table-bulk tbody tr > :first-child input[type='checkbox']:checked {
|
|
236
|
+
counter-increment: mw-table-selected;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.mw-table-bulk-bar {
|
|
240
|
+
position: sticky;
|
|
241
|
+
bottom: calc(#{spacing('4')} + var(--mw-action-bar-reserve, 0px));
|
|
242
|
+
z-index: z-index('menu');
|
|
243
|
+
display: none;
|
|
244
|
+
align-items: center;
|
|
245
|
+
gap: spacing('3');
|
|
246
|
+
width: fit-content;
|
|
247
|
+
max-width: 100%;
|
|
248
|
+
margin: spacing('4') auto 0;
|
|
249
|
+
padding: spacing('2') spacing('2') spacing('2') spacing('5');
|
|
250
|
+
border-radius: radius-sharp() radius('lg') radius-sharp() radius('lg');
|
|
251
|
+
background: var(--mw-header-background);
|
|
252
|
+
color: var(--mw-header-text-color);
|
|
253
|
+
box-shadow: var(--mw-elevation-4);
|
|
254
|
+
// Dark in both themes like the header bar, so what sits in it reads dark too
|
|
255
|
+
color-scheme: dark;
|
|
256
|
+
--mw-focus-ring-color: var(--mw-header-navbar-list-active-color);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.mw-table-bulk:has(tbody tr > :first-child input[type='checkbox']:checked)
|
|
260
|
+
.mw-table-bulk-bar {
|
|
261
|
+
display: flex;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.mw-table-bulk-count {
|
|
265
|
+
font-weight: font-weight('medium');
|
|
266
|
+
font-variant-numeric: tabular-nums;
|
|
267
|
+
white-space: nowrap;
|
|
268
|
+
|
|
269
|
+
// Empty, the bar counts for itself; an app that knows the number writes it
|
|
270
|
+
&:empty::before {
|
|
271
|
+
content: counter(mw-table-selected);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Sticky cells need an opaque tone of their own, or the row slides through
|
|
276
|
+
.mw-table-sticky-col :is(th, td):first-child {
|
|
277
|
+
position: sticky;
|
|
278
|
+
left: 0;
|
|
279
|
+
z-index: z-index('lift');
|
|
280
|
+
// A collapsed border stays behind when the cell sticks, so it draws its own
|
|
281
|
+
box-shadow: inset -1px 0 0 var(--mw-border);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
.mw-table-sticky-col th:first-child {
|
|
285
|
+
z-index: z-index('lift') + 1;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
.mw-table-sticky-col td:first-child {
|
|
289
|
+
background: var(--mw-card-background);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.mw-table-sticky-col tr:nth-child(even) > td:first-child {
|
|
293
|
+
background: color-mix(
|
|
294
|
+
in srgb,
|
|
295
|
+
var(--mw-gray-color) 20%,
|
|
296
|
+
var(--mw-card-background)
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
.mw-table-sticky-col.mw-table-hover tr:hover > td:first-child {
|
|
301
|
+
background: color-mix(
|
|
302
|
+
in srgb,
|
|
303
|
+
var(--mw-primary-color) 30%,
|
|
304
|
+
var(--mw-card-background)
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
.mw-table-sticky-col tr#{$_selected-row} > td:first-child {
|
|
309
|
+
background: color-mix(
|
|
310
|
+
in srgb,
|
|
311
|
+
var(--mw-primary-color) 50%,
|
|
312
|
+
var(--mw-card-background)
|
|
313
|
+
);
|
|
314
|
+
box-shadow:
|
|
315
|
+
inset 3px 0 0 var(--mw-primary-text-color),
|
|
316
|
+
inset -1px 0 0 var(--mw-border);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// Forced colours drop fills: selection in Highlight, the arrow in text colour
|
|
320
|
+
@media (forced-colors: active) {
|
|
321
|
+
.mw-table tr#{$_selected-row} > td,
|
|
322
|
+
.mw-table-sticky-col tr#{$_selected-row} > td:first-child {
|
|
323
|
+
forced-color-adjust: none;
|
|
324
|
+
background: Highlight;
|
|
325
|
+
color: HighlightText;
|
|
326
|
+
box-shadow: none;
|
|
327
|
+
|
|
328
|
+
* {
|
|
329
|
+
color: inherit;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
.mw-table th[aria-sort]::after {
|
|
334
|
+
forced-color-adjust: none;
|
|
335
|
+
background: CanvasText;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
195
338
|
}
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
@use '../abstracts' as *;
|
|
2
2
|
|
|
3
3
|
@layer mw.components {
|
|
4
|
+
// aria-selected carries the same state, for a tablist an application renders
|
|
5
|
+
@mixin _selected {
|
|
6
|
+
@include active {
|
|
7
|
+
@content;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
&[aria-selected='true'] {
|
|
11
|
+
@content;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
4
15
|
// Registered, so a half-written value from the script cannot invalidate the
|
|
5
16
|
// whole `transform` and leave the marker somewhere other than at rest.
|
|
6
17
|
// `inherits: true` because the bar is the nav's ::after, and a pseudo element
|
|
@@ -85,10 +96,16 @@
|
|
|
85
96
|
transition-duration: var(--mw-duration-instant);
|
|
86
97
|
}
|
|
87
98
|
|
|
88
|
-
@include
|
|
99
|
+
@include _selected {
|
|
89
100
|
color: var(--mw-primary-text-color);
|
|
90
101
|
border-bottom-color: var(--mw-primary-text-color);
|
|
91
102
|
}
|
|
103
|
+
|
|
104
|
+
&:is(:disabled, [aria-disabled='true']) {
|
|
105
|
+
opacity: 0.5;
|
|
106
|
+
cursor: not-allowed;
|
|
107
|
+
pointer-events: none;
|
|
108
|
+
}
|
|
92
109
|
}
|
|
93
110
|
|
|
94
111
|
// The active tab is marked by a bar that travels to it rather than appearing
|
|
@@ -177,7 +194,7 @@
|
|
|
177
194
|
border-bottom: none;
|
|
178
195
|
border-right: 2px solid transparent;
|
|
179
196
|
|
|
180
|
-
@include
|
|
197
|
+
@include _selected {
|
|
181
198
|
border-right-color: var(--mw-primary-text-color);
|
|
182
199
|
}
|
|
183
200
|
|
|
@@ -186,7 +203,7 @@
|
|
|
186
203
|
border-bottom: 2px solid transparent;
|
|
187
204
|
flex-shrink: 0;
|
|
188
205
|
|
|
189
|
-
@include
|
|
206
|
+
@include _selected {
|
|
190
207
|
border-right-color: transparent;
|
|
191
208
|
border-bottom-color: var(--mw-primary-text-color);
|
|
192
209
|
}
|
|
@@ -273,7 +290,7 @@
|
|
|
273
290
|
border: 1px solid var(--mw-border-accent);
|
|
274
291
|
background: var(--mw-card-background);
|
|
275
292
|
|
|
276
|
-
@include
|
|
293
|
+
@include _selected {
|
|
277
294
|
background: var(--mw-primary-color);
|
|
278
295
|
color: var(--mw-primary-accent-text-color);
|
|
279
296
|
}
|
|
@@ -289,4 +306,25 @@
|
|
|
289
306
|
opacity: 1;
|
|
290
307
|
}
|
|
291
308
|
}
|
|
309
|
+
|
|
310
|
+
// Forced colours drop the travelling bar and the pill's fill
|
|
311
|
+
@media (forced-colors: active) {
|
|
312
|
+
.mw-tabs-nav[data-mw-tabs-marker]::after {
|
|
313
|
+
forced-color-adjust: none;
|
|
314
|
+
background: Highlight;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
.mw-tabs-nav-item:is(.mw-active, .active, [aria-selected='true']) {
|
|
318
|
+
text-decoration: underline 2px;
|
|
319
|
+
text-underline-offset: 0.35em;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.mw-tabs-pills
|
|
323
|
+
.mw-tabs-nav-item:is(.mw-active, .active, [aria-selected='true']) {
|
|
324
|
+
forced-color-adjust: none;
|
|
325
|
+
background: Highlight;
|
|
326
|
+
color: HighlightText;
|
|
327
|
+
text-decoration: none;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
292
330
|
}
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
transition: var(--mw-transition-fast);
|
|
33
33
|
user-select: none;
|
|
34
34
|
|
|
35
|
-
&:hover {
|
|
35
|
+
&:is(a, button):hover {
|
|
36
36
|
background: var(--mw-primary-background-hover);
|
|
37
37
|
}
|
|
38
38
|
}
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
background-color: var(--mw-#{$name}-#{$infix}background);
|
|
78
78
|
border-color: var(--mw-#{$name}-color);
|
|
79
79
|
|
|
80
|
-
&:hover {
|
|
80
|
+
&:is(a, button):hover {
|
|
81
81
|
background: var(--mw-#{$name}-#{$infix}background-hover);
|
|
82
82
|
}
|
|
83
83
|
}
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
border-color: var(--mw-border);
|
|
91
91
|
color: var(--mw-text-muted-color);
|
|
92
92
|
|
|
93
|
-
&:hover {
|
|
93
|
+
&:is(a, button):hover {
|
|
94
94
|
background-color: var(--mw-gray-background);
|
|
95
95
|
border-color: var(--mw-text-muted-color);
|
|
96
96
|
color: var(--mw-text-color);
|
|
@@ -107,7 +107,7 @@
|
|
|
107
107
|
border-color: var(--mw-border);
|
|
108
108
|
color: var(--mw-text-color);
|
|
109
109
|
|
|
110
|
-
&:hover {
|
|
110
|
+
&:is(a, button):hover {
|
|
111
111
|
background-color: var(--mw-surface-muted);
|
|
112
112
|
border-color: var(--mw-border-accent);
|
|
113
113
|
}
|
|
@@ -135,4 +135,39 @@
|
|
|
135
135
|
}
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
|
+
|
|
139
|
+
// A tag that does something - a filter, a link - is a control: ring and floor
|
|
140
|
+
:is(a, button).mw-tag {
|
|
141
|
+
font-family: inherit;
|
|
142
|
+
cursor: pointer;
|
|
143
|
+
text-decoration: none;
|
|
144
|
+
@include tappable;
|
|
145
|
+
@include focus-ring;
|
|
146
|
+
@include touch-floor(2.25rem);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Pressed fills and ticks, so the state never rests on colour alone
|
|
150
|
+
:is(a, button).mw-tag:is([aria-pressed='true'], .mw-active) {
|
|
151
|
+
background: var(--mw-primary-color);
|
|
152
|
+
border-color: var(--mw-primary-color);
|
|
153
|
+
color: var(--mw-primary-accent-text-color);
|
|
154
|
+
|
|
155
|
+
&::before {
|
|
156
|
+
content: '';
|
|
157
|
+
width: 0.3em;
|
|
158
|
+
height: 0.6em;
|
|
159
|
+
margin: 0 0.55em 0.15em 0.1em;
|
|
160
|
+
border: solid currentColor;
|
|
161
|
+
border-width: 0 0.15em 0.15em 0;
|
|
162
|
+
rotate: 45deg;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
@each $name, $infix in $_mw-tag-colors {
|
|
167
|
+
:is(a, button).mw-tag-#{$name}:is([aria-pressed='true'], .mw-active) {
|
|
168
|
+
background: var(--mw-#{$name}-color);
|
|
169
|
+
border-color: var(--mw-#{$name}-color);
|
|
170
|
+
color: var(--mw-#{$name}-accent-text-color);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
138
173
|
}
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
// A tile is tapped, so it needs a press of its own - the lift above never
|
|
61
61
|
// runs on a finger. Guarded like every other travel in the framework; what
|
|
62
62
|
// is left without it is the latched hover, which is feedback enough.
|
|
63
|
-
@
|
|
63
|
+
@include motion-safe {
|
|
64
64
|
&:active {
|
|
65
65
|
transform: scale(0.985);
|
|
66
66
|
transition-duration: var(--mw-duration-instant);
|
|
@@ -16,10 +16,13 @@
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
// Never further than the page gutter, or the slide scrolls the page sideways
|
|
19
20
|
@keyframes mw-slide-in-right {
|
|
20
21
|
from {
|
|
21
22
|
opacity: 0;
|
|
22
|
-
transform: translateX(
|
|
23
|
+
transform: translateX(
|
|
24
|
+
min(60px, calc(var(--mw-container-gutter) - #{spacing('3')}))
|
|
25
|
+
);
|
|
23
26
|
}
|
|
24
27
|
to {
|
|
25
28
|
opacity: 1;
|
|
@@ -27,6 +30,18 @@
|
|
|
27
30
|
}
|
|
28
31
|
}
|
|
29
32
|
|
|
33
|
+
// From the side, a full-width column runs past the screen edge while it plays
|
|
34
|
+
@keyframes mw-timeline-rise {
|
|
35
|
+
from {
|
|
36
|
+
opacity: 0;
|
|
37
|
+
transform: translateY(24px);
|
|
38
|
+
}
|
|
39
|
+
to {
|
|
40
|
+
opacity: 1;
|
|
41
|
+
transform: translateY(0);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
30
45
|
@keyframes mw-pulse-ring-big {
|
|
31
46
|
0% {
|
|
32
47
|
box-shadow: 0 0 0 0 var(--mw-primary-text-color);
|
|
@@ -223,6 +238,7 @@
|
|
|
223
238
|
// Override odd/even: content always full-width below the date
|
|
224
239
|
&-step:nth-child(odd) &-content,
|
|
225
240
|
&-step:nth-child(even) &-content {
|
|
241
|
+
animation-name: mw-timeline-rise;
|
|
226
242
|
align-self: stretch;
|
|
227
243
|
width: 100%;
|
|
228
244
|
padding-left: 0;
|
|
@@ -305,6 +321,14 @@
|
|
|
305
321
|
opacity: 0;
|
|
306
322
|
}
|
|
307
323
|
|
|
324
|
+
// Every step: the stagger covers ten, an eleventh stayed at opacity 0
|
|
325
|
+
&-step &-content {
|
|
326
|
+
animation-name: mw-slide-in-right;
|
|
327
|
+
animation-duration: var(--mw-duration-slow);
|
|
328
|
+
animation-timing-function: var(--mw-ease-out);
|
|
329
|
+
animation-fill-mode: forwards;
|
|
330
|
+
}
|
|
331
|
+
|
|
308
332
|
// Staggered animation
|
|
309
333
|
@for $i from 1 through 10 {
|
|
310
334
|
&-step:nth-child(#{$i}) &-content {
|
|
@@ -316,6 +340,10 @@
|
|
|
316
340
|
}
|
|
317
341
|
}
|
|
318
342
|
|
|
343
|
+
&-step:nth-child(n + 11) &-content {
|
|
344
|
+
animation-delay: 2.2s;
|
|
345
|
+
}
|
|
346
|
+
|
|
319
347
|
// Active step
|
|
320
348
|
&-step.mw-active &-date,
|
|
321
349
|
&-step.active &-date {
|
|
@@ -351,6 +379,115 @@
|
|
|
351
379
|
align-self: stretch;
|
|
352
380
|
padding-left: spacing('3');
|
|
353
381
|
}
|
|
382
|
+
|
|
383
|
+
&-step:nth-child(n) &-content {
|
|
384
|
+
animation-name: mw-timeline-rise;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// An activity feed or audit log: many lines, no entrance to wait for
|
|
390
|
+
.mw-timeline-compact {
|
|
391
|
+
position: relative;
|
|
392
|
+
margin: 0;
|
|
393
|
+
padding: 0;
|
|
394
|
+
list-style: none;
|
|
395
|
+
|
|
396
|
+
&::before {
|
|
397
|
+
content: '';
|
|
398
|
+
position: absolute;
|
|
399
|
+
top: spacing('2');
|
|
400
|
+
bottom: spacing('2');
|
|
401
|
+
left: calc(#{spacing('2')} - 1px);
|
|
402
|
+
width: 2px;
|
|
403
|
+
background: var(--mw-border);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
.mw-timeline-compact-item {
|
|
408
|
+
--mw-timeline-dot: var(--mw-primary-text-color);
|
|
409
|
+
|
|
410
|
+
position: relative;
|
|
411
|
+
display: grid;
|
|
412
|
+
grid-template-columns: minmax(0, 1fr);
|
|
413
|
+
gap: 0 spacing('3');
|
|
414
|
+
padding: 0 0 spacing('4') spacing('6');
|
|
415
|
+
font-size: font-size('sm');
|
|
416
|
+
|
|
417
|
+
&:last-child {
|
|
418
|
+
padding-bottom: 0;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// The dot sits on the line, ringed in the page colour so the line breaks
|
|
422
|
+
&::before {
|
|
423
|
+
content: '';
|
|
424
|
+
position: absolute;
|
|
425
|
+
top: 0.4em;
|
|
426
|
+
left: 0;
|
|
427
|
+
width: spacing('4');
|
|
428
|
+
height: spacing('4');
|
|
429
|
+
border-radius: radius('full');
|
|
430
|
+
background: var(--mw-timeline-dot);
|
|
431
|
+
box-shadow: 0 0 0 3px var(--mw-page-background);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
@include media-up('sm') {
|
|
435
|
+
grid-template-columns: 6.5rem minmax(0, 1fr);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
.mw-timeline-compact-time {
|
|
440
|
+
color: var(--mw-text-muted-color);
|
|
441
|
+
font-size: font-size('xs');
|
|
442
|
+
font-variant-numeric: tabular-nums;
|
|
443
|
+
white-space: nowrap;
|
|
444
|
+
|
|
445
|
+
@include media-up('sm') {
|
|
446
|
+
padding-top: 0.15em;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
.mw-timeline-compact-body {
|
|
451
|
+
min-width: 0;
|
|
452
|
+
color: var(--mw-text-color);
|
|
453
|
+
overflow-wrap: anywhere;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
@each $name, $col in $semantic-colors {
|
|
457
|
+
.mw-timeline-compact-#{$name} {
|
|
458
|
+
--mw-timeline-dot: var(--mw-#{$name}-text-color);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// On a surface the ring has to match the surface, not the page
|
|
463
|
+
:is(.mw-card, .mw-panel, .mw-modal, .mw-app-aside)
|
|
464
|
+
.mw-timeline-compact-item::before {
|
|
465
|
+
box-shadow: 0 0 0 3px var(--mw-card-background);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// Forced colours drop the lines and dots (fills) and the active date's colour
|
|
469
|
+
@media (forced-colors: active) {
|
|
470
|
+
.mw-timeline-big::before,
|
|
471
|
+
.mw-timeline-simple::before,
|
|
472
|
+
.mw-timeline-compact::before,
|
|
473
|
+
.mw-timeline-compact-item::before {
|
|
474
|
+
forced-color-adjust: none;
|
|
475
|
+
background: CanvasText;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
.mw-timeline-big-step:is(.mw-active, .active)
|
|
479
|
+
.mw-timeline-big-date-container,
|
|
480
|
+
.mw-timeline-simple-step:is(.mw-active, .active) .mw-timeline-simple-date {
|
|
481
|
+
forced-color-adjust: none;
|
|
482
|
+
background: Highlight;
|
|
483
|
+
color: HighlightText;
|
|
484
|
+
|
|
485
|
+
// The date classes named too: they outweigh a bare `*`
|
|
486
|
+
*,
|
|
487
|
+
.mw-timeline-big-date-main,
|
|
488
|
+
.mw-timeline-big-date-sub {
|
|
489
|
+
color: inherit;
|
|
490
|
+
}
|
|
354
491
|
}
|
|
355
492
|
}
|
|
356
493
|
}
|
|
@@ -37,11 +37,15 @@
|
|
|
37
37
|
transform: translateX(-50%);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
// The reserve only exists while an action bar holds the foot of the screen
|
|
40
41
|
&-bottom-right {
|
|
41
|
-
bottom: spacing('5');
|
|
42
|
+
bottom: calc(#{spacing('5')} + var(--mw-action-bar-reserve, 0px));
|
|
42
43
|
right: spacing('5');
|
|
43
44
|
top: auto;
|
|
44
45
|
left: auto;
|
|
46
|
+
max-height: calc(
|
|
47
|
+
100dvh - #{2 * spacing('5')} - var(--mw-action-bar-reserve, 0px)
|
|
48
|
+
);
|
|
45
49
|
flex-direction: column-reverse;
|
|
46
50
|
|
|
47
51
|
> * {
|
|
@@ -188,6 +188,19 @@
|
|
|
188
188
|
position-area: block-start;
|
|
189
189
|
transform: rotate(45deg);
|
|
190
190
|
}
|
|
191
|
+
|
|
192
|
+
// Beside the trigger, for an icon rail - anchored only, or a scroller cuts it
|
|
193
|
+
&.mw-tooltip-inline-end {
|
|
194
|
+
&::before {
|
|
195
|
+
position-area: inline-end;
|
|
196
|
+
margin: 0 0 0 ($_mw-tooltip-gap + $_mw-tooltip-arrow);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
&::after {
|
|
200
|
+
position-area: inline-end;
|
|
201
|
+
margin: 0 0 0 $_mw-tooltip-arrow-inset;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
191
204
|
}
|
|
192
205
|
}
|
|
193
206
|
}
|
|
@@ -37,13 +37,18 @@
|
|
|
37
37
|
cursor: pointer;
|
|
38
38
|
user-select: none;
|
|
39
39
|
position: relative;
|
|
40
|
+
isolation: isolate;
|
|
40
41
|
|
|
42
|
+
// Row-sized for touch exploration, behind the content so a label link works
|
|
41
43
|
input[type='checkbox'] {
|
|
42
44
|
position: absolute;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
inset: 0;
|
|
46
|
+
z-index: -1;
|
|
47
|
+
width: 100%;
|
|
48
|
+
height: 100%;
|
|
46
49
|
margin: spacing('0');
|
|
50
|
+
opacity: 0;
|
|
51
|
+
cursor: inherit;
|
|
47
52
|
}
|
|
48
53
|
|
|
49
54
|
.mw-checkbox-box {
|
|
@@ -76,13 +81,30 @@
|
|
|
76
81
|
border-color: var(--mw-primary-color);
|
|
77
82
|
}
|
|
78
83
|
|
|
79
|
-
|
|
84
|
+
&:hover
|
|
85
|
+
input[type='checkbox']:not(:checked, :indeterminate, :disabled)
|
|
86
|
+
+ .mw-checkbox-box {
|
|
87
|
+
border-color: var(--mw-gray-color);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
input[type='checkbox']:is(:checked, :indeterminate) + .mw-checkbox-box {
|
|
80
91
|
border-color: var(--mw-primary-color);
|
|
81
92
|
}
|
|
82
93
|
input[type='checkbox']:checked + .mw-checkbox-box::after {
|
|
83
94
|
transform: translate(-50%, -60%) rotate(-45deg) scale(1);
|
|
84
95
|
}
|
|
85
96
|
|
|
97
|
+
// A bar instead of the tick - the "some of them" state of a select-all box
|
|
98
|
+
input[type='checkbox']:indeterminate + .mw-checkbox-box::after {
|
|
99
|
+
height: 0;
|
|
100
|
+
border-left-width: 0;
|
|
101
|
+
transform: translate(-50%, -50%) scale(1);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
input[type='checkbox']:is(#{$invalid-states}) + .mw-checkbox-box {
|
|
105
|
+
border-color: var(--mw-danger-color);
|
|
106
|
+
}
|
|
107
|
+
|
|
86
108
|
.mw-checkbox-label {
|
|
87
109
|
font-size: font-size('base');
|
|
88
110
|
color: var(--mw-text-color);
|
|
@@ -119,16 +141,19 @@
|
|
|
119
141
|
|
|
120
142
|
@each $name, $col in $semantic-colors {
|
|
121
143
|
&-#{$name} {
|
|
122
|
-
input[type='checkbox']:checked + .mw-checkbox-box {
|
|
144
|
+
input[type='checkbox']:is(:checked, :indeterminate) + .mw-checkbox-box {
|
|
123
145
|
border-color: #{$col};
|
|
124
146
|
}
|
|
125
|
-
input[type='checkbox']:checked
|
|
147
|
+
input[type='checkbox']:is(:checked, :indeterminate)
|
|
148
|
+
+ .mw-checkbox-box::after {
|
|
126
149
|
border-color: #{$col};
|
|
127
150
|
}
|
|
128
151
|
}
|
|
129
152
|
}
|
|
130
153
|
|
|
131
|
-
|
|
154
|
+
// The attribute too: a reactive form disables the input, not the label
|
|
155
|
+
&-disabled,
|
|
156
|
+
&:has(input[type='checkbox']:disabled) {
|
|
132
157
|
cursor: not-allowed;
|
|
133
158
|
|
|
134
159
|
input[type='checkbox'] {
|
|
@@ -142,4 +167,12 @@
|
|
|
142
167
|
}
|
|
143
168
|
}
|
|
144
169
|
}
|
|
170
|
+
|
|
171
|
+
// Forced colours drop the halo, which is the whole focus indicator here
|
|
172
|
+
@media (forced-colors: active) {
|
|
173
|
+
.mw-checkbox input[type='checkbox']:focus-visible + .mw-checkbox-box {
|
|
174
|
+
outline: 2px solid;
|
|
175
|
+
outline-offset: 2px;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
145
178
|
}
|
|
@@ -169,14 +169,12 @@
|
|
|
169
169
|
// mw-field-has-error. `:user-invalid` and never `:invalid`, which is true from
|
|
170
170
|
// page load and would mark an empty required field before anyone typed.
|
|
171
171
|
// The class stays authoritative for a validator that lives in the application.
|
|
172
|
-
.mw-input:
|
|
173
|
-
.mw-select:user-invalid,
|
|
174
|
-
.mw-textarea:user-invalid {
|
|
172
|
+
:is(.mw-input, .mw-select, .mw-textarea):is(#{$invalid-states}) {
|
|
175
173
|
border-color: var(--mw-danger-color);
|
|
176
174
|
@include focus-halo('danger-text-color');
|
|
177
175
|
}
|
|
178
176
|
|
|
179
|
-
.mw-field:has(> :
|
|
177
|
+
.mw-field:has(> :is(#{$invalid-states})) > .mw-field-hint {
|
|
180
178
|
color: var(--mw-danger-text-color);
|
|
181
179
|
}
|
|
182
180
|
}
|