maverick-wave 5.6.0 → 5.7.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/.claude/skills/mw-maverick-wave/SKILL.md +5 -5
- package/.claude/skills/mw-maverick-wave/examples/static-landing-page.md +2 -2
- package/.claude/skills/mw-maverick-wave/references/components.md +5 -2
- package/.claude/skills/mw-maverick-wave/references/forms.md +5 -5
- package/.claude/skills/mw-maverick-wave/references/theming.md +12 -11
- package/CHANGELOG.md +11 -0
- package/README.md +8 -7
- package/index.html +168 -4
- package/maverick-wave.min.css +4 -4
- package/package.json +2 -2
- package/src/partials/history-container.html +1 -1
- package/src/partials/palette-container.html +37 -10
- package/src/partials/typography-container.html +8 -9
- package/src/partials/utilities-container.html +10 -3
- package/src/scss/abstracts/_mixins.scss +6 -1
- package/src/scss/abstracts/_variables.scss +4 -4
- package/src/scss/components/_avatars.scss +29 -0
- package/src/scss/components/_button-bar.scss +1 -1
- package/src/scss/components/_buttons.scss +1 -1
- package/src/scss/form-elements/_input.scss +1 -1
- package/src/scss/form-elements/_select.scss +1 -1
- package/src/scss/layout/_main.scss +31 -2
- package/src/scss/utilities/_reveal.scss +9 -2
- package/src/scss/utilities/_touch-targets.scss +1 -1
- package/src/scss/utilities/_variants.scss +48 -18
|
@@ -44,14 +44,14 @@ Load the one you need - do not read them all up front.
|
|
|
44
44
|
```html
|
|
45
45
|
<link
|
|
46
46
|
rel="stylesheet"
|
|
47
|
-
href="https://cdn.jsdelivr.net/npm/maverick-wave@5.
|
|
47
|
+
href="https://cdn.jsdelivr.net/npm/maverick-wave@5.7.0/maverick-wave.min.css"
|
|
48
48
|
/>
|
|
49
49
|
<link
|
|
50
50
|
rel="stylesheet"
|
|
51
51
|
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css"
|
|
52
52
|
/>
|
|
53
53
|
...
|
|
54
|
-
<script src="https://cdn.jsdelivr.net/npm/maverick-wave@5.
|
|
54
|
+
<script src="https://cdn.jsdelivr.net/npm/maverick-wave@5.7.0/maverick-wave.min.js"></script>
|
|
55
55
|
```
|
|
56
56
|
|
|
57
57
|
Pin the version. The JS file is optional and only for server-rendered/static pages -
|
|
@@ -195,8 +195,8 @@ back), `--mw-ease-spring` (a pop). Two ready-made transitions:
|
|
|
195
195
|
for anything that should feel instant under the pointer. Both list their
|
|
196
196
|
properties explicitly rather than saying `all`.
|
|
197
197
|
|
|
198
|
-
**Control sizes** `--mw-control-height-sm|base|lg` =
|
|
199
|
-
|
|
198
|
+
**Control sizes** `--mw-control-height-sm|base|lg` = 1.875 / 2.125 / 2.375rem (an
|
|
199
|
+
even 30 / 34 / 38px step) and
|
|
200
200
|
`--mw-control-font-sm|base|lg` = 0.8 / 0.9 / 1rem, shared by `mw-input`,
|
|
201
201
|
`mw-select`, `mw-textarea` and `mw-btn`. A field and the button beside it are
|
|
202
202
|
the same height by construction. Buttons run one font step above the fields.
|
|
@@ -402,7 +402,7 @@ feature frame) ·
|
|
|
402
402
|
28. **A link in running text is `mw-link`, not `mw-btn mw-btn-link`.** Since
|
|
403
403
|
4.13.0 there is a class for exactly that. `mw-btn` is `inline-flex` with
|
|
404
404
|
`min-height: var(--mw-control-height)`, so a link written that way pulls its
|
|
405
|
-
own line up to 2.
|
|
405
|
+
own line up to 2.125rem while every line around it keeps the paragraph's
|
|
406
406
|
height - in a footer disclaimer at `font-size: sm` that is nearly double,
|
|
407
407
|
and it reads as a layout bug. `mw-p-0` is not the fix it looks like: the
|
|
408
408
|
height does it, not the padding. `mw-link` is the same look without the
|
|
@@ -20,7 +20,7 @@ accordion FAQ.
|
|
|
20
20
|
|
|
21
21
|
<link
|
|
22
22
|
rel="stylesheet"
|
|
23
|
-
href="https://cdn.jsdelivr.net/npm/maverick-wave@5.
|
|
23
|
+
href="https://cdn.jsdelivr.net/npm/maverick-wave@5.7.0/maverick-wave.min.css"
|
|
24
24
|
/>
|
|
25
25
|
<link
|
|
26
26
|
rel="stylesheet"
|
|
@@ -487,7 +487,7 @@ accordion FAQ.
|
|
|
487
487
|
<div class="mw-modal-backdrop" onclick="closeModal('demo')"></div>
|
|
488
488
|
</div>
|
|
489
489
|
|
|
490
|
-
<script src="https://cdn.jsdelivr.net/npm/maverick-wave@5.
|
|
490
|
+
<script src="https://cdn.jsdelivr.net/npm/maverick-wave@5.7.0/maverick-wave.min.js"></script>
|
|
491
491
|
<script>
|
|
492
492
|
// The only thing the shipped script does not cover: opening a modal.
|
|
493
493
|
// Closing works through .mw-modal-close, the backdrop is wired above.
|
|
@@ -28,7 +28,7 @@ exhaustive: what is not named does not exist.
|
|
|
28
28
|
is, so do not override it away
|
|
29
29
|
- **A link inside a sentence is `mw-link`, not `mw-btn mw-btn-link`.** The base
|
|
30
30
|
class carries a control height, so in running text it lifts that one line to
|
|
31
|
-
2.
|
|
31
|
+
2.125rem while the lines around it stay where they are. `mw-p-0` does not help
|
|
32
32
|
- the height does it, not the padding. Keep `mw-btn` only where the link
|
|
33
33
|
really is a button in a row of buttons and has to line up with them
|
|
34
34
|
- On a coarse pointer or below 768px `mw-btn` grows to a 2.75rem minimum height
|
|
@@ -1445,7 +1445,7 @@ deprecated). Any card fits into the content wrapper.
|
|
|
1445
1445
|
<div class="mw-avatar mw-avatar-initials mw-avatar-xs">MW</div>
|
|
1446
1446
|
```
|
|
1447
1447
|
|
|
1448
|
-
- Sizes: `mw-avatar-xs` 32, `-sm` 64, default 96, `-lg` 144, `-xl`
|
|
1448
|
+
- Sizes: `mw-avatar-xs` 32, `-sm` 64, default 96, `-lg` 144, `-xl` 210 px.
|
|
1449
1449
|
- Shape: `mw-avatar-square`.
|
|
1450
1450
|
- Colours `mw-avatar-primary`, `-secondary`, `-success`, `-warning`, `-danger`,
|
|
1451
1451
|
`-info` tint the **border**. On `mw-avatar-initials` the same class also tints
|
|
@@ -1454,6 +1454,9 @@ deprecated). Any card fits into the content wrapper.
|
|
|
1454
1454
|
the standard display for a signed-in user without a picture.
|
|
1455
1455
|
- `mw-avatar-group` overlaps its avatars; `mw-avatar-group-sm` / `-lg` change
|
|
1456
1456
|
the overlap.
|
|
1457
|
+
- Hover on an avatar **with an image** zooms the picture and sweeps a light
|
|
1458
|
+
across it. Nothing to switch on. It is skipped on `mw-avatar-initials`, on
|
|
1459
|
+
touch, under `prefers-reduced-motion` and under `mw-hover-static`.
|
|
1457
1460
|
|
|
1458
1461
|
## Item lists
|
|
1459
1462
|
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
`mw-input`, `mw-select`, `mw-textarea` and `mw-btn` share one scale:
|
|
6
6
|
|
|
7
|
-
| step | height
|
|
8
|
-
| ----- |
|
|
9
|
-
| `-sm` |
|
|
10
|
-
| base | 2.
|
|
11
|
-
| `-lg` | 2.
|
|
7
|
+
| step | height | font |
|
|
8
|
+
| ----- | -------- | ------ |
|
|
9
|
+
| `-sm` | 1.875rem | 0.8rem |
|
|
10
|
+
| base | 2.125rem | 0.9rem |
|
|
11
|
+
| `-lg` | 2.375rem | 1rem |
|
|
12
12
|
|
|
13
13
|
A field and the button beside it are therefore the same height by construction -
|
|
14
14
|
before 4.11.0 each control worked its own height out and an input, a select and
|
|
@@ -194,19 +194,20 @@ root.classList.remove('mw-theme-switching');
|
|
|
194
194
|
|
|
195
195
|
## Site-wide variants
|
|
196
196
|
|
|
197
|
-
|
|
197
|
+
Nine classes on `<html>` and four custom properties retune the whole look
|
|
198
198
|
without a rebuild. They stack, and none of them need a class per element.
|
|
199
199
|
|
|
200
|
-
| Class | Effect
|
|
201
|
-
| ------------------- |
|
|
202
|
-
| `mw-corners-even` | Drops the surface signature - every card, panel and modal becomes an evenly rounded `radius('md')` box
|
|
203
|
-
| `mw-accent-single` | `--mw-secondary-color` follows the primary; `mw-btn-secondary` turns outline so the two stay apart
|
|
204
|
-
| `mw-shadows-flat` | Elevation 1-3 to `none`. The dropdown (4) and the modal (5) keep their shadow
|
|
205
|
-
| `mw-hover-static` | No hover travels - lifts, image zooms and slides go. Colour and border still respond
|
|
206
|
-
| `mw-
|
|
207
|
-
| `mw-
|
|
208
|
-
| `mw-
|
|
209
|
-
| `mw-
|
|
200
|
+
| Class | Effect |
|
|
201
|
+
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
202
|
+
| `mw-corners-even` | Drops the surface signature - every card, panel and modal becomes an evenly rounded `radius('md')` box |
|
|
203
|
+
| `mw-accent-single` | `--mw-secondary-color` follows the primary; `mw-btn-secondary` turns outline so the two stay apart |
|
|
204
|
+
| `mw-shadows-flat` | Elevation 1-3 to `none`. The dropdown (4) and the modal (5) keep their shadow |
|
|
205
|
+
| `mw-hover-static` | No hover travels - lifts, image zooms and slides go. Colour and border still respond |
|
|
206
|
+
| `mw-scroll-static` | No scroll entrance - `mw-reveal` and `mw-reveal-stagger` blocks sit where they land |
|
|
207
|
+
| `mw-sections-plain` | The diagonal hatch behind `mw-section-alternate` collapses into the page colour |
|
|
208
|
+
| `mw-headings-caps` | `h1`-`h3` in capitals with 0.045em tracking |
|
|
209
|
+
| `mw-btn-pill` | `mw-btn` fully rounded. Form fields keep their own radius |
|
|
210
|
+
| `mw-btn-glass` | Filled buttons become tinted glass: translucent wash, vertical ramp, specular top edge. No `backdrop-filter` - it would trap a fixed-position tooltip inside the button |
|
|
210
211
|
|
|
211
212
|
| Property | Effect |
|
|
212
213
|
| ---------------------------- | -------------------------------------------------------------- |
|
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,17 @@ Patch releases are only for test purposes - here I only document major and minor
|
|
|
6
6
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
7
7
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
8
8
|
|
|
9
|
+
## [5.7.0] - 2026-09-12
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- avatar hover animation
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- slimmer control heights
|
|
18
|
+
- showcase variants
|
|
19
|
+
|
|
9
20
|
## [5.6.0] - 2026-09-12
|
|
10
21
|
|
|
11
22
|
### Added
|
package/README.md
CHANGED
|
@@ -42,12 +42,12 @@ The result is a framework that balances utility with simplicity, offering develo
|
|
|
42
42
|
<title>My MaverickWave Project</title>
|
|
43
43
|
<link
|
|
44
44
|
rel="stylesheet"
|
|
45
|
-
href="https://cdn.jsdelivr.net/npm/maverick-wave@5.
|
|
45
|
+
href="https://cdn.jsdelivr.net/npm/maverick-wave@5.7.0/maverick-wave.min.css"
|
|
46
46
|
/>
|
|
47
47
|
</head>
|
|
48
48
|
<body>
|
|
49
49
|
<!-- Your content here -->
|
|
50
|
-
<script src="https://cdn.jsdelivr.net/npm/maverick-wave@5.
|
|
50
|
+
<script src="https://cdn.jsdelivr.net/npm/maverick-wave@5.7.0/maverick-wave.min.js"></script>
|
|
51
51
|
</body>
|
|
52
52
|
</html>
|
|
53
53
|
```
|
|
@@ -153,9 +153,9 @@ assembled rather than designed.
|
|
|
153
153
|
|
|
154
154
|
/* Control sizes - one height per step, shared by input, select, textarea
|
|
155
155
|
and button, so a field and the button beside it line up */
|
|
156
|
-
--mw-control-height-sm:
|
|
157
|
-
--mw-control-height: 2.
|
|
158
|
-
--mw-control-height-lg: 2.
|
|
156
|
+
--mw-control-height-sm: 1.875rem;
|
|
157
|
+
--mw-control-height: 2.125rem;
|
|
158
|
+
--mw-control-height-lg: 2.375rem;
|
|
159
159
|
--mw-control-font-sm: 0.8rem;
|
|
160
160
|
--mw-control-font: 0.9rem;
|
|
161
161
|
--mw-control-font-lg: 1rem;
|
|
@@ -347,7 +347,7 @@ layer of its own:
|
|
|
347
347
|
|
|
348
348
|
### Site-wide variants
|
|
349
349
|
|
|
350
|
-
|
|
350
|
+
Nine classes on `<html>` retune the whole look without touching markup or
|
|
351
351
|
rebuilding. They stack.
|
|
352
352
|
|
|
353
353
|
| Class | Effect |
|
|
@@ -356,10 +356,11 @@ rebuilding. They stack.
|
|
|
356
356
|
| `mw-accent-single` | One brand colour instead of two; `mw-btn-secondary` turns outline |
|
|
357
357
|
| `mw-shadows-flat` | Elevation 1-3 to `none`; dropdown and modal keep theirs |
|
|
358
358
|
| `mw-hover-static` | No hover travels - lifts and image zooms go, colour still responds |
|
|
359
|
+
| `mw-scroll-static` | No scroll entrance - `mw-reveal` blocks sit where they land |
|
|
359
360
|
| `mw-sections-plain` | The hatch behind `mw-section-alternate` collapses into the page colour |
|
|
360
361
|
| `mw-headings-caps` | `h1`-`h3` in capitals |
|
|
361
362
|
| `mw-btn-pill` | Fully rounded buttons; form fields keep their radius |
|
|
362
|
-
| `mw-
|
|
363
|
+
| `mw-btn-glass` | Filled buttons become a translucent wash with a lit top edge |
|
|
363
364
|
|
|
364
365
|
Four properties do the rest: `--mw-radius-scale` multiplies every radius (`0`
|
|
365
366
|
squares the framework off), `--mw-font-family-heading`, `--mw-container-width`
|
package/index.html
CHANGED
|
@@ -21,7 +21,10 @@
|
|
|
21
21
|
@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css')
|
|
22
22
|
layer(vendor);
|
|
23
23
|
</style>
|
|
24
|
-
|
|
24
|
+
<!-- ?v= so a release actually reaches a browser that has the last one
|
|
25
|
+
cached: the filename never changes, and without it a stale stylesheet
|
|
26
|
+
survives a normal reload -->
|
|
27
|
+
<link rel="stylesheet" href="maverick-wave.min.css?v={{VERSION}}" />
|
|
25
28
|
<!-- Favicons -->
|
|
26
29
|
<link rel="icon" type="image/svg+xml" href="favicon/favicon.svg" />
|
|
27
30
|
<link
|
|
@@ -336,8 +339,18 @@
|
|
|
336
339
|
background: var(--mw-primary-accent-text-color);
|
|
337
340
|
}
|
|
338
341
|
|
|
339
|
-
.variant-setup {
|
|
342
|
+
.variant-setup-label {
|
|
343
|
+
display: block;
|
|
340
344
|
margin-top: 14px;
|
|
345
|
+
margin-bottom: 5px;
|
|
346
|
+
font-size: 0.7rem;
|
|
347
|
+
color: var(--mw-text-muted-color);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
.variant-setup {
|
|
351
|
+
display: block;
|
|
352
|
+
width: 100%;
|
|
353
|
+
resize: vertical;
|
|
341
354
|
padding: 10px;
|
|
342
355
|
border-radius: 8px;
|
|
343
356
|
border: 1px solid var(--mw-border);
|
|
@@ -367,7 +380,7 @@
|
|
|
367
380
|
}
|
|
368
381
|
</style>
|
|
369
382
|
|
|
370
|
-
<script src="maverick-wave.min.js"></script>
|
|
383
|
+
<script src="maverick-wave.min.js?v={{VERSION}}"></script>
|
|
371
384
|
</head>
|
|
372
385
|
|
|
373
386
|
<body>
|
|
@@ -904,6 +917,13 @@
|
|
|
904
917
|
|
|
905
918
|
const root = document.documentElement;
|
|
906
919
|
|
|
920
|
+
// The values the markup ships with, so the setup box below can tell a
|
|
921
|
+
// chosen colour from the built-in one and print only the difference
|
|
922
|
+
const BUILT_IN = {
|
|
923
|
+
primary: primaryInput.value,
|
|
924
|
+
secondary: secondaryInput.value,
|
|
925
|
+
};
|
|
926
|
+
|
|
907
927
|
const DARK_INK = '#131925';
|
|
908
928
|
const LIGHT_INK = '#f2f6fc';
|
|
909
929
|
|
|
@@ -939,6 +959,7 @@
|
|
|
939
959
|
void root.offsetHeight;
|
|
940
960
|
root.classList.remove('mw-theme-switching');
|
|
941
961
|
window.mwRefreshColorSwatches?.();
|
|
962
|
+
window.mwRefreshSetup?.();
|
|
942
963
|
};
|
|
943
964
|
|
|
944
965
|
const paint = (name, color) => {
|
|
@@ -993,6 +1014,79 @@
|
|
|
993
1014
|
document.addEventListener('keydown', (event) => {
|
|
994
1015
|
if (event.key === 'Escape') toggle(false);
|
|
995
1016
|
});
|
|
1017
|
+
|
|
1018
|
+
// The seam to the variants panel below, which prints and reads the whole
|
|
1019
|
+
// setup - the palette is half of it. Only inline values count as chosen:
|
|
1020
|
+
// anything still coming from the stylesheet is the built-in one.
|
|
1021
|
+
const PAGE_GROUNDS = {
|
|
1022
|
+
dark: '--mw-dark-page-background',
|
|
1023
|
+
light: '--mw-light-page-background',
|
|
1024
|
+
};
|
|
1025
|
+
|
|
1026
|
+
window.mwPalette = {
|
|
1027
|
+
read: () => ({
|
|
1028
|
+
primary: root.style.getPropertyValue('--mw-primary-color') || null,
|
|
1029
|
+
secondary:
|
|
1030
|
+
root.style.getPropertyValue('--mw-secondary-color') || null,
|
|
1031
|
+
// The label colour ink() measured for each fill. It has to travel
|
|
1032
|
+
// with the setup: a project that only copies the two brand colours
|
|
1033
|
+
// keeps the stock accent text, and on a light brand tone that is an
|
|
1034
|
+
// unreadable button. write() recomputes it, so pasting it back is
|
|
1035
|
+
// harmless.
|
|
1036
|
+
primaryInk:
|
|
1037
|
+
root.style.getPropertyValue('--mw-primary-accent-text-color') ||
|
|
1038
|
+
null,
|
|
1039
|
+
secondaryInk:
|
|
1040
|
+
root.style.getPropertyValue('--mw-secondary-accent-text-color') ||
|
|
1041
|
+
null,
|
|
1042
|
+
dark: root.style.getPropertyValue(PAGE_GROUNDS.dark) || null,
|
|
1043
|
+
light: root.style.getPropertyValue(PAGE_GROUNDS.light) || null,
|
|
1044
|
+
}),
|
|
1045
|
+
|
|
1046
|
+
write: ({ primary, secondary, dark, light }) => {
|
|
1047
|
+
const current = window.mwPalette.read();
|
|
1048
|
+
const same =
|
|
1049
|
+
current.primary === primary &&
|
|
1050
|
+
current.secondary === secondary &&
|
|
1051
|
+
current.dark === dark &&
|
|
1052
|
+
current.light === light;
|
|
1053
|
+
// Typing into the setup box fires per keystroke, and settle() forces
|
|
1054
|
+
// a reflow - so a run that changes nothing has to cost nothing
|
|
1055
|
+
if (same) return;
|
|
1056
|
+
|
|
1057
|
+
[
|
|
1058
|
+
['primary', primary, primaryInput],
|
|
1059
|
+
['secondary', secondary, secondaryInput],
|
|
1060
|
+
].forEach(([name, value, input]) => {
|
|
1061
|
+
if (value) {
|
|
1062
|
+
paint(name, value);
|
|
1063
|
+
input.value = value;
|
|
1064
|
+
} else {
|
|
1065
|
+
root.style.removeProperty(`--mw-${name}-color`);
|
|
1066
|
+
root.style.removeProperty(`--mw-${name}-accent-text-color`);
|
|
1067
|
+
input.value = BUILT_IN[name];
|
|
1068
|
+
}
|
|
1069
|
+
});
|
|
1070
|
+
|
|
1071
|
+
Object.entries(PAGE_GROUNDS).forEach(([key, prop]) => {
|
|
1072
|
+
const value = key === 'dark' ? dark : light;
|
|
1073
|
+
if (value) root.style.setProperty(prop, value);
|
|
1074
|
+
else root.style.removeProperty(prop);
|
|
1075
|
+
});
|
|
1076
|
+
|
|
1077
|
+
const shownPrimary = primary || BUILT_IN.primary;
|
|
1078
|
+
const shownSecondary = secondary || BUILT_IN.secondary;
|
|
1079
|
+
items.forEach((item) =>
|
|
1080
|
+
item.classList.toggle(
|
|
1081
|
+
'mw-active',
|
|
1082
|
+
item.dataset.primary === shownPrimary &&
|
|
1083
|
+
item.dataset.secondary === shownSecondary
|
|
1084
|
+
)
|
|
1085
|
+
);
|
|
1086
|
+
|
|
1087
|
+
settle();
|
|
1088
|
+
},
|
|
1089
|
+
};
|
|
996
1090
|
});
|
|
997
1091
|
|
|
998
1092
|
// just for the showcase: the variant switches. Each one is a class on <html>
|
|
@@ -1014,10 +1108,28 @@
|
|
|
1014
1108
|
: input.checked;
|
|
1015
1109
|
|
|
1016
1110
|
const render = () => {
|
|
1111
|
+
// Never while it is being typed in - the box is an input as well as a
|
|
1112
|
+
// readout, and rewriting it under the cursor would eat the paste
|
|
1113
|
+
if (document.activeElement === setup) return;
|
|
1114
|
+
|
|
1017
1115
|
const classes = [];
|
|
1018
1116
|
const notes = [];
|
|
1019
1117
|
const props = [];
|
|
1020
1118
|
|
|
1119
|
+
// The palette is part of the setup, and it is printed first because a
|
|
1120
|
+
// project sets its brand colours before it retunes anything else
|
|
1121
|
+
const palette = window.mwPalette?.read() ?? {};
|
|
1122
|
+
[
|
|
1123
|
+
['--mw-primary-color', palette.primary],
|
|
1124
|
+
['--mw-primary-accent-text-color', palette.primaryInk],
|
|
1125
|
+
['--mw-secondary-color', palette.secondary],
|
|
1126
|
+
['--mw-secondary-accent-text-color', palette.secondaryInk],
|
|
1127
|
+
['--mw-dark-page-background', palette.dark],
|
|
1128
|
+
['--mw-light-page-background', palette.light],
|
|
1129
|
+
].forEach(([prop, value]) => {
|
|
1130
|
+
if (value) props.push(` ${prop}: ${value};`);
|
|
1131
|
+
});
|
|
1132
|
+
|
|
1021
1133
|
controls.forEach((control) => {
|
|
1022
1134
|
if (control.type !== 'checkbox') {
|
|
1023
1135
|
if (control.value) {
|
|
@@ -1047,7 +1159,7 @@
|
|
|
1047
1159
|
lines.push(...notes);
|
|
1048
1160
|
if (props.length) lines.push(':root {', ...props, '}');
|
|
1049
1161
|
|
|
1050
|
-
setup.
|
|
1162
|
+
setup.value = lines.length
|
|
1051
1163
|
? lines.join('\n')
|
|
1052
1164
|
: 'Default setup - nothing to change.';
|
|
1053
1165
|
};
|
|
@@ -1064,6 +1176,58 @@
|
|
|
1064
1176
|
}
|
|
1065
1177
|
};
|
|
1066
1178
|
|
|
1179
|
+
// The box read backwards: someone else's setup pasted in drives the
|
|
1180
|
+
// switches, which drive the page. Anything the text does not mention
|
|
1181
|
+
// falls back to the default, so an empty box is a reset.
|
|
1182
|
+
const load = (text) => {
|
|
1183
|
+
const named = new Set(
|
|
1184
|
+
(text.match(/class\s*=\s*"([^"]*)"/)?.[1] || '')
|
|
1185
|
+
.trim()
|
|
1186
|
+
.split(/\s+/)
|
|
1187
|
+
.filter(Boolean)
|
|
1188
|
+
);
|
|
1189
|
+
// `.mw-header: no mw-header-reveal` - a class the markup ships and the
|
|
1190
|
+
// setup takes away, which is the deviation worth reading
|
|
1191
|
+
const dropped = new Set(
|
|
1192
|
+
[...text.matchAll(/:\s*no\s+([\w-]+)/g)].map((m) => m[1])
|
|
1193
|
+
);
|
|
1194
|
+
const props = new Map(
|
|
1195
|
+
[...text.matchAll(/(--[\w-]+)\s*:\s*([^;\n}]+)/g)].map((m) => [
|
|
1196
|
+
m[1],
|
|
1197
|
+
m[2].trim(),
|
|
1198
|
+
])
|
|
1199
|
+
);
|
|
1200
|
+
|
|
1201
|
+
window.mwPalette?.write({
|
|
1202
|
+
primary: props.get('--mw-primary-color') ?? null,
|
|
1203
|
+
secondary: props.get('--mw-secondary-color') ?? null,
|
|
1204
|
+
dark: props.get('--mw-dark-page-background') ?? null,
|
|
1205
|
+
light: props.get('--mw-light-page-background') ?? null,
|
|
1206
|
+
});
|
|
1207
|
+
|
|
1208
|
+
controls.forEach((control) => {
|
|
1209
|
+
if (control.type === 'checkbox') {
|
|
1210
|
+
const name = control.dataset.variantClass;
|
|
1211
|
+
const on = control.dataset.variantTarget
|
|
1212
|
+
? !dropped.has(name)
|
|
1213
|
+
: named.has(name);
|
|
1214
|
+
control.checked = control.hasAttribute('data-variant-invert')
|
|
1215
|
+
? !on
|
|
1216
|
+
: on;
|
|
1217
|
+
} else {
|
|
1218
|
+
control.value = props.get(control.dataset.variantProp) ?? '';
|
|
1219
|
+
}
|
|
1220
|
+
apply(control);
|
|
1221
|
+
});
|
|
1222
|
+
};
|
|
1223
|
+
|
|
1224
|
+
// Picking a palette repaints the page, and the box has to say so
|
|
1225
|
+
window.mwRefreshSetup = render;
|
|
1226
|
+
|
|
1227
|
+
setup.addEventListener('input', () => load(setup.value));
|
|
1228
|
+
// Normalises what was pasted back into the shape render() writes
|
|
1229
|
+
setup.addEventListener('blur', render);
|
|
1230
|
+
|
|
1067
1231
|
controls.forEach((control) =>
|
|
1068
1232
|
control.addEventListener('change', () => {
|
|
1069
1233
|
apply(control);
|