maverick-wave 5.16.0 → 5.17.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 +10 -7
- package/.claude/skills/mw-maverick-wave/examples/angular-list-page.md +40 -35
- package/.claude/skills/mw-maverick-wave/examples/angular-services.md +95 -33
- package/.claude/skills/mw-maverick-wave/examples/static-landing-page.md +38 -53
- package/.claude/skills/mw-maverick-wave/references/components.md +45 -46
- package/.claude/skills/mw-maverick-wave/references/javascript.md +16 -17
- package/CHANGELOG.md +7 -0
- package/README.md +2 -2
- package/index.html +0 -4
- package/maverick-wave.min.css +2 -2
- package/package.json +2 -2
- package/release.sh +5 -0
- package/scripts/verify.js +23 -10
- package/src/partials/get-started-container.html +5 -3
- package/src/partials/modals-container.html +137 -186
- package/src/scss/abstracts/_mixins.scss +30 -6
- package/src/scss/components/_modals.scss +13 -2
- package/src/scss/layout/_main.scss +18 -0
- package/src/scss/utilities/_touch-targets.scss +5 -4
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "maverick-wave",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.17.0",
|
|
4
4
|
"config": {
|
|
5
|
-
"version_short": "5.
|
|
5
|
+
"version_short": "5.17"
|
|
6
6
|
},
|
|
7
7
|
"description": "A lightweight, modern CSS framework for building responsive websites with elegance and speed.",
|
|
8
8
|
"main": "src/js/main.js",
|
package/release.sh
CHANGED
|
@@ -4,6 +4,11 @@ echo "## extract version from package.json"
|
|
|
4
4
|
VERSION=$(npm pkg get version --workspaces=false | tr -d \")
|
|
5
5
|
echo "## checkout release branch and grab changes from main"
|
|
6
6
|
git checkout release && git merge main --no-commit
|
|
7
|
+
echo "## point the README CDN snippets at this version"
|
|
8
|
+
# The skills pin a major range and need no bump; the README is the place the
|
|
9
|
+
# exact-version advice belongs, and it is the one that kept going stale - 5.0.0
|
|
10
|
+
# shipped with six snippets still on 4.28.0.
|
|
11
|
+
sed -i '' -E "s|maverick-wave@[0-9]+\.[0-9]+\.[0-9]+|maverick-wave@${VERSION}|g" README.md
|
|
7
12
|
echo "## make a new release"
|
|
8
13
|
npm run build && npm run prepack
|
|
9
14
|
echo "## add all changes and push it"
|
package/scripts/verify.js
CHANGED
|
@@ -155,22 +155,35 @@ for (const f of ['maverick-wave.min.css', 'maverick-wave.min.js']) {
|
|
|
155
155
|
}
|
|
156
156
|
|
|
157
157
|
// --- 5: pinned CDN version -------------------------------------------------
|
|
158
|
-
//
|
|
159
|
-
//
|
|
158
|
+
// Two rules, because the two places are read at different times. The README is
|
|
159
|
+
// where someone decides how to pull the framework in, so it names the exact
|
|
160
|
+
// version - release.sh rewrites it, and this catches a bump that went around the
|
|
161
|
+
// script. The skills are installed outside this repo and never get that rewrite,
|
|
162
|
+
// so they carry a major range; an exact pin there is stale the day the next
|
|
163
|
+
// version ships and nobody notices, which is how 5.0.0 went out with six
|
|
164
|
+
// snippets still on 4.28.0.
|
|
160
165
|
|
|
161
166
|
const { version } = require(path.join(ROOT, 'package.json'));
|
|
167
|
+
const EXACT_PIN = /maverick-wave@([0-9]+\.[0-9]+\.[0-9]+)/g;
|
|
162
168
|
|
|
163
|
-
|
|
169
|
+
const readme = read(path.join(ROOT, 'README.md'));
|
|
170
|
+
if (readme) {
|
|
171
|
+
for (const v of new Set(
|
|
172
|
+
all(readme, EXACT_PIN).filter((v) => v !== version)
|
|
173
|
+
)) {
|
|
174
|
+
errors.push(
|
|
175
|
+
`stale CDN pin in README.md: maverick-wave@${v} - package.json is ${version}`
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const major = version.split('.')[0];
|
|
181
|
+
for (const p of DOCS) {
|
|
164
182
|
const md = read(p);
|
|
165
183
|
if (!md) continue;
|
|
166
|
-
const
|
|
167
|
-
all(md, /maverick-wave@([0-9]+\.[0-9]+\.[0-9]+)/g).filter(
|
|
168
|
-
(v) => v !== version
|
|
169
|
-
)
|
|
170
|
-
);
|
|
171
|
-
for (const v of stale) {
|
|
184
|
+
for (const v of new Set(all(md, EXACT_PIN))) {
|
|
172
185
|
errors.push(
|
|
173
|
-
`
|
|
186
|
+
`exact CDN pin in ${path.relative(ROOT, p)}: maverick-wave@${v} - a skill carries @${major}, so it never goes stale`
|
|
174
187
|
);
|
|
175
188
|
}
|
|
176
189
|
}
|
|
@@ -276,9 +276,11 @@ body {
|
|
|
276
276
|
<code>DOMContentLoaded</code> and writes straight into the DOM - in a
|
|
277
277
|
SPA everything rendered afterwards stays uninitialized, and the class
|
|
278
278
|
toggles happen behind change detection. Rebuild the behaviors in
|
|
279
|
-
components; the state classes (<code>active</code>,
|
|
280
|
-
<code>
|
|
281
|
-
|
|
279
|
+
components; the state classes (<code>mw-active</code>,
|
|
280
|
+
<code>open</code>, <code>mw-selected</code>) are the whole contract. A
|
|
281
|
+
modal is the exception - write it as a
|
|
282
|
+
<code><dialog class="mw-modal"></code> and the element brings
|
|
283
|
+
Escape, the focus trap and the scroll lock with it.
|
|
282
284
|
</p>
|
|
283
285
|
<p>
|
|
284
286
|
Alternatively, use the CDN link directly in
|
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
<h3 class="mw-section-subtitle">Simple Modals</h3>
|
|
2
2
|
<p class="mw-text-muted mw-mb-6">
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
A <code><dialog></code> carrying the same <code>mw-modal</code> classes.
|
|
4
|
+
Escape, the focus trap, the inert page behind it and the body scroll lock come
|
|
5
|
+
from the element - only opening it needs a line of script. The older
|
|
6
|
+
<code>mw-modal-overlay</code> div is still styled for markup that predates
|
|
7
|
+
this.
|
|
5
8
|
</p>
|
|
6
9
|
|
|
7
10
|
<!-- Size Triggers -->
|
|
8
11
|
<h4 class="mw-mb-3">Modal Sizes</h4>
|
|
9
12
|
<div class="mw-grid-4 mw-mb-8">
|
|
10
|
-
<button
|
|
13
|
+
<button data-mw-modal="modal-sm" class="mw-btn mw-btn-outline">
|
|
11
14
|
Small Modal
|
|
12
15
|
</button>
|
|
13
|
-
<button
|
|
16
|
+
<button data-mw-modal="modal-default" class="mw-btn mw-btn-outline">
|
|
14
17
|
Default Modal
|
|
15
18
|
</button>
|
|
16
|
-
<button
|
|
19
|
+
<button data-mw-modal="modal-lg" class="mw-btn mw-btn-outline">
|
|
17
20
|
Large Modal
|
|
18
21
|
</button>
|
|
19
|
-
<button
|
|
22
|
+
<button data-mw-modal="modal-xl" class="mw-btn mw-btn-outline">
|
|
20
23
|
XL Modal
|
|
21
24
|
</button>
|
|
22
25
|
</div>
|
|
@@ -24,212 +27,160 @@
|
|
|
24
27
|
<!-- Example Triggers -->
|
|
25
28
|
<h4 class="mw-mb-3">Examples</h4>
|
|
26
29
|
<div class="mw-grid-2 mw-mb-8">
|
|
27
|
-
<button
|
|
30
|
+
<button data-mw-modal="modal-form" class="mw-btn mw-btn-primary">
|
|
28
31
|
Open Form Modal
|
|
29
32
|
</button>
|
|
30
33
|
<button data-mw-modal="modal-confirm" class="mw-btn mw-btn-secondary">
|
|
31
|
-
Open Confirmation
|
|
34
|
+
Open Delete Confirmation
|
|
32
35
|
</button>
|
|
33
36
|
</div>
|
|
34
37
|
|
|
38
|
+
<!-- The close buttons carry no handler - the framework script closes the dialog
|
|
39
|
+
they sit in - and closedby="any" dismisses it on a backdrop click, so there
|
|
40
|
+
is no mw-modal-backdrop element either. `data-mw-modal` on a trigger opens
|
|
41
|
+
the dialog with that id. -->
|
|
35
42
|
<!-- Small Modal -->
|
|
36
|
-
<
|
|
37
|
-
<div class="mw-modal
|
|
38
|
-
<
|
|
39
|
-
|
|
40
|
-
<button onclick="closeModal('modal-sm')" class="mw-modal-close">
|
|
41
|
-
𝗫
|
|
42
|
-
</button>
|
|
43
|
-
</div>
|
|
44
|
-
<div class="mw-modal-body">
|
|
45
|
-
<p class="mw-text-muted">
|
|
46
|
-
Max-width <strong>370px</strong>. Good for short confirmations or
|
|
47
|
-
alerts.
|
|
48
|
-
</p>
|
|
49
|
-
</div>
|
|
50
|
-
<div class="mw-modal-footer">
|
|
51
|
-
<button onclick="closeModal('modal-sm')" class="mw-btn mw-btn-outline">
|
|
52
|
-
Close
|
|
53
|
-
</button>
|
|
54
|
-
</div>
|
|
43
|
+
<dialog id="modal-sm" class="mw-modal mw-modal-sm" closedby="any">
|
|
44
|
+
<div class="mw-modal-header">
|
|
45
|
+
<h4 class="mw-modal-title">Small Modal</h4>
|
|
46
|
+
<button class="mw-modal-close">𝗫</button>
|
|
55
47
|
</div>
|
|
56
|
-
<div class="mw-modal-
|
|
57
|
-
|
|
48
|
+
<div class="mw-modal-body">
|
|
49
|
+
<p class="mw-text-muted">
|
|
50
|
+
Max-width <strong>370px</strong>. Good for short confirmations or alerts.
|
|
51
|
+
</p>
|
|
52
|
+
</div>
|
|
53
|
+
<div class="mw-modal-footer">
|
|
54
|
+
<button class="mw-modal-close mw-btn mw-btn-outline">Close</button>
|
|
55
|
+
</div>
|
|
56
|
+
</dialog>
|
|
58
57
|
|
|
59
58
|
<!-- Default Modal -->
|
|
60
|
-
<
|
|
61
|
-
<div class="mw-modal">
|
|
62
|
-
<
|
|
63
|
-
|
|
64
|
-
<button onclick="closeModal('modal-default')" class="mw-modal-close">
|
|
65
|
-
𝗫
|
|
66
|
-
</button>
|
|
67
|
-
</div>
|
|
68
|
-
<div class="mw-modal-body">
|
|
69
|
-
<p class="mw-text-muted">
|
|
70
|
-
Max-width <strong>520px</strong>. The default size - fits most use
|
|
71
|
-
cases.
|
|
72
|
-
</p>
|
|
73
|
-
</div>
|
|
74
|
-
<div class="mw-modal-footer">
|
|
75
|
-
<button
|
|
76
|
-
onclick="closeModal('modal-default')"
|
|
77
|
-
class="mw-btn mw-btn-outline"
|
|
78
|
-
>
|
|
79
|
-
Cancel
|
|
80
|
-
</button>
|
|
81
|
-
<button
|
|
82
|
-
onclick="closeModal('modal-default')"
|
|
83
|
-
class="mw-btn mw-btn-primary"
|
|
84
|
-
>
|
|
85
|
-
Confirm
|
|
86
|
-
</button>
|
|
87
|
-
</div>
|
|
59
|
+
<dialog id="modal-default" class="mw-modal" closedby="any">
|
|
60
|
+
<div class="mw-modal-header">
|
|
61
|
+
<h4 class="mw-modal-title">Default Modal</h4>
|
|
62
|
+
<button class="mw-modal-close">𝗫</button>
|
|
88
63
|
</div>
|
|
89
|
-
<div class="mw-modal-
|
|
90
|
-
|
|
64
|
+
<div class="mw-modal-body">
|
|
65
|
+
<p class="mw-text-muted">
|
|
66
|
+
Max-width <strong>520px</strong>. The default size - fits most use cases.
|
|
67
|
+
</p>
|
|
68
|
+
</div>
|
|
69
|
+
<div class="mw-modal-footer">
|
|
70
|
+
<button class="mw-modal-close mw-btn mw-btn-outline">Cancel</button>
|
|
71
|
+
<button class="mw-modal-close mw-btn mw-btn-primary">Confirm</button>
|
|
72
|
+
</div>
|
|
73
|
+
</dialog>
|
|
91
74
|
|
|
92
75
|
<!-- Large Modal -->
|
|
93
|
-
<
|
|
94
|
-
<div class="mw-modal
|
|
95
|
-
<
|
|
96
|
-
|
|
97
|
-
<button onclick="closeModal('modal-lg')" class="mw-modal-close">
|
|
98
|
-
𝗫
|
|
99
|
-
</button>
|
|
100
|
-
</div>
|
|
101
|
-
<div class="mw-modal-body">
|
|
102
|
-
<p class="mw-text-muted">
|
|
103
|
-
Max-width <strong>720px</strong>. More room for richer content or forms.
|
|
104
|
-
</p>
|
|
105
|
-
</div>
|
|
106
|
-
<div class="mw-modal-footer">
|
|
107
|
-
<button onclick="closeModal('modal-lg')" class="mw-btn mw-btn-outline">
|
|
108
|
-
Cancel
|
|
109
|
-
</button>
|
|
110
|
-
<button onclick="closeModal('modal-lg')" class="mw-btn mw-btn-primary">
|
|
111
|
-
Confirm
|
|
112
|
-
</button>
|
|
113
|
-
</div>
|
|
76
|
+
<dialog id="modal-lg" class="mw-modal mw-modal-lg" closedby="any">
|
|
77
|
+
<div class="mw-modal-header">
|
|
78
|
+
<h4 class="mw-modal-title">Large Modal</h4>
|
|
79
|
+
<button class="mw-modal-close">𝗫</button>
|
|
114
80
|
</div>
|
|
115
|
-
<div class="mw-modal-
|
|
116
|
-
|
|
81
|
+
<div class="mw-modal-body">
|
|
82
|
+
<p class="mw-text-muted">
|
|
83
|
+
Max-width <strong>720px</strong>. More room for richer content or forms.
|
|
84
|
+
</p>
|
|
85
|
+
</div>
|
|
86
|
+
<div class="mw-modal-footer">
|
|
87
|
+
<button class="mw-modal-close mw-btn mw-btn-outline">Cancel</button>
|
|
88
|
+
<button class="mw-modal-close mw-btn mw-btn-primary">Confirm</button>
|
|
89
|
+
</div>
|
|
90
|
+
</dialog>
|
|
117
91
|
|
|
118
92
|
<!-- XL Modal -->
|
|
119
|
-
<
|
|
120
|
-
<div class="mw-modal
|
|
121
|
-
<
|
|
122
|
-
|
|
123
|
-
<button onclick="closeModal('modal-xl')" class="mw-modal-close">
|
|
124
|
-
𝗫
|
|
125
|
-
</button>
|
|
126
|
-
</div>
|
|
127
|
-
<div class="mw-modal-body">
|
|
128
|
-
<p class="mw-text-muted">
|
|
129
|
-
Max-width <strong>960px</strong>. Use for detail views, data tables, or
|
|
130
|
-
complex layouts.
|
|
131
|
-
</p>
|
|
132
|
-
</div>
|
|
133
|
-
<div class="mw-modal-footer">
|
|
134
|
-
<button onclick="closeModal('modal-xl')" class="mw-btn mw-btn-outline">
|
|
135
|
-
Cancel
|
|
136
|
-
</button>
|
|
137
|
-
<button onclick="closeModal('modal-xl')" class="mw-btn mw-btn-primary">
|
|
138
|
-
Confirm
|
|
139
|
-
</button>
|
|
140
|
-
</div>
|
|
93
|
+
<dialog id="modal-xl" class="mw-modal mw-modal-xl" closedby="any">
|
|
94
|
+
<div class="mw-modal-header">
|
|
95
|
+
<h4 class="mw-modal-title">XL Modal</h4>
|
|
96
|
+
<button class="mw-modal-close">𝗫</button>
|
|
141
97
|
</div>
|
|
142
|
-
<div class="mw-modal-
|
|
143
|
-
|
|
98
|
+
<div class="mw-modal-body">
|
|
99
|
+
<p class="mw-text-muted">
|
|
100
|
+
Max-width <strong>960px</strong>. Use for detail views, data tables, or
|
|
101
|
+
complex layouts.
|
|
102
|
+
</p>
|
|
103
|
+
</div>
|
|
104
|
+
<div class="mw-modal-footer">
|
|
105
|
+
<button class="mw-modal-close mw-btn mw-btn-outline">Cancel</button>
|
|
106
|
+
<button class="mw-modal-close mw-btn mw-btn-primary">Confirm</button>
|
|
107
|
+
</div>
|
|
108
|
+
</dialog>
|
|
144
109
|
|
|
145
110
|
<!-- Form Modal -->
|
|
146
|
-
<
|
|
147
|
-
<div class="mw-modal
|
|
148
|
-
<
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
111
|
+
<dialog id="modal-form" class="mw-modal mw-modal-lg" closedby="any">
|
|
112
|
+
<div class="mw-modal-header">
|
|
113
|
+
<h4 class="mw-modal-title">New Contact</h4>
|
|
114
|
+
<button class="mw-modal-close">𝗫</button>
|
|
115
|
+
</div>
|
|
116
|
+
<div class="mw-modal-body">
|
|
117
|
+
<div class="mw-grid-2 mw-mb-3">
|
|
118
|
+
<label for="modal-firstname">
|
|
119
|
+
<span>First Name</span>
|
|
120
|
+
<input
|
|
121
|
+
id="modal-firstname"
|
|
122
|
+
type="text"
|
|
123
|
+
class="mw-input"
|
|
124
|
+
placeholder="Jane"
|
|
125
|
+
/>
|
|
126
|
+
</label>
|
|
127
|
+
<label for="modal-lastname">
|
|
128
|
+
<span>Last Name</span>
|
|
129
|
+
<input
|
|
130
|
+
id="modal-lastname"
|
|
131
|
+
type="text"
|
|
132
|
+
class="mw-input"
|
|
133
|
+
placeholder="Doe"
|
|
134
|
+
/>
|
|
135
|
+
</label>
|
|
153
136
|
</div>
|
|
154
|
-
<div class="mw-
|
|
155
|
-
<
|
|
156
|
-
<
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
/>
|
|
164
|
-
</label>
|
|
165
|
-
<label for="modal-lastname">
|
|
166
|
-
<span>Last Name</span>
|
|
167
|
-
<input
|
|
168
|
-
id="modal-lastname"
|
|
169
|
-
type="text"
|
|
170
|
-
class="mw-input"
|
|
171
|
-
placeholder="Doe"
|
|
172
|
-
/>
|
|
173
|
-
</label>
|
|
174
|
-
</div>
|
|
175
|
-
<div class="mw-mb-3">
|
|
176
|
-
<label for="modal-email">
|
|
177
|
-
<span>Email</span>
|
|
178
|
-
<input
|
|
179
|
-
id="modal-email"
|
|
180
|
-
type="email"
|
|
181
|
-
class="mw-input"
|
|
182
|
-
placeholder="jane@example.com"
|
|
183
|
-
/>
|
|
184
|
-
</label>
|
|
185
|
-
</div>
|
|
186
|
-
<div class="mw-mb-3">
|
|
187
|
-
<label for="modal-role">
|
|
188
|
-
<span>Role</span>
|
|
189
|
-
<select id="modal-role" class="mw-select">
|
|
190
|
-
<option value="" disabled selected>Select a role</option>
|
|
191
|
-
<option>Developer</option>
|
|
192
|
-
<option>Designer</option>
|
|
193
|
-
<option>Product Manager</option>
|
|
194
|
-
<option>Other</option>
|
|
195
|
-
</select>
|
|
196
|
-
</label>
|
|
197
|
-
</div>
|
|
198
|
-
<div class="mw-mb-3">
|
|
199
|
-
<label for="modal-notes">
|
|
200
|
-
<span>Notes</span>
|
|
201
|
-
<textarea
|
|
202
|
-
id="modal-notes"
|
|
203
|
-
rows="3"
|
|
204
|
-
class="mw-textarea"
|
|
205
|
-
placeholder="Optional notes..."
|
|
206
|
-
></textarea>
|
|
207
|
-
</label>
|
|
208
|
-
</div>
|
|
209
|
-
<label class="mw-toggle">
|
|
210
|
-
<input type="checkbox" />
|
|
211
|
-
<div class="mw-toggle-track"></div>
|
|
212
|
-
<span class="mw-toggle-label">Send welcome email</span>
|
|
137
|
+
<div class="mw-mb-3">
|
|
138
|
+
<label for="modal-email">
|
|
139
|
+
<span>Email</span>
|
|
140
|
+
<input
|
|
141
|
+
id="modal-email"
|
|
142
|
+
type="email"
|
|
143
|
+
class="mw-input"
|
|
144
|
+
placeholder="jane@example.com"
|
|
145
|
+
/>
|
|
213
146
|
</label>
|
|
214
147
|
</div>
|
|
215
|
-
<div class="mw-
|
|
216
|
-
<
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
148
|
+
<div class="mw-mb-3">
|
|
149
|
+
<label for="modal-role">
|
|
150
|
+
<span>Role</span>
|
|
151
|
+
<select id="modal-role" class="mw-select">
|
|
152
|
+
<option value="" disabled selected>Select a role</option>
|
|
153
|
+
<option>Developer</option>
|
|
154
|
+
<option>Designer</option>
|
|
155
|
+
<option>Product Manager</option>
|
|
156
|
+
<option>Other</option>
|
|
157
|
+
</select>
|
|
158
|
+
</label>
|
|
222
159
|
</div>
|
|
160
|
+
<div class="mw-mb-3">
|
|
161
|
+
<label for="modal-notes">
|
|
162
|
+
<span>Notes</span>
|
|
163
|
+
<textarea
|
|
164
|
+
id="modal-notes"
|
|
165
|
+
rows="3"
|
|
166
|
+
class="mw-textarea"
|
|
167
|
+
placeholder="Optional notes..."
|
|
168
|
+
></textarea>
|
|
169
|
+
</label>
|
|
170
|
+
</div>
|
|
171
|
+
<label class="mw-toggle">
|
|
172
|
+
<input type="checkbox" />
|
|
173
|
+
<div class="mw-toggle-track"></div>
|
|
174
|
+
<span class="mw-toggle-label">Send welcome email</span>
|
|
175
|
+
</label>
|
|
223
176
|
</div>
|
|
224
|
-
<div class="mw-modal-
|
|
225
|
-
</
|
|
177
|
+
<div class="mw-modal-footer">
|
|
178
|
+
<button class="mw-modal-close mw-btn mw-btn-outline">Cancel</button>
|
|
179
|
+
<button class="mw-modal-close mw-btn mw-btn-primary">Save Contact</button>
|
|
180
|
+
</div>
|
|
181
|
+
</dialog>
|
|
226
182
|
|
|
227
183
|
<!-- Confirmation Modal -->
|
|
228
|
-
<!-- Same classes, a <dialog> instead of a div: Escape, the focus trap, the
|
|
229
|
-
inert page behind it and the scroll lock all come from the element. The
|
|
230
|
-
close buttons need no onclick - the framework script closes the dialog
|
|
231
|
-
they sit in - and closedby="any" is what dismisses it on a backdrop
|
|
232
|
-
click, so there is no mw-modal-backdrop either. -->
|
|
233
184
|
<dialog id="modal-confirm" class="mw-modal mw-modal-sm" closedby="any">
|
|
234
185
|
<div class="mw-modal-header">
|
|
235
186
|
<h4 class="mw-modal-title">Delete Item</h4>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
@use 'sass:map';
|
|
2
|
+
@use 'sass:math';
|
|
2
3
|
@use 'variables' as v;
|
|
3
4
|
@use 'functions' as *;
|
|
4
5
|
|
|
@@ -171,15 +172,27 @@
|
|
|
171
172
|
// Grows the hit area without touching the silhouette - for a control whose size
|
|
172
173
|
// is the design: a 9px gallery dot, an 18px mini button. Neighbours need a gap
|
|
173
174
|
// of at least twice $grow, or two hit areas overlap and a tap lands on the one
|
|
174
|
-
// next door.
|
|
175
|
-
|
|
175
|
+
// next door.
|
|
176
|
+
//
|
|
177
|
+
// A `data-tooltip` owns both pseudo-elements, so the overlay has nowhere to go
|
|
178
|
+
// and used to land on the arrow, leaving its paint on the trigger as a grey
|
|
179
|
+
// diamond. The selector carries that exclusion rather than a note to callers,
|
|
180
|
+
// who apply this to a class and cannot see which instance has the attribute.
|
|
181
|
+
// Those grow the box instead - it costs the silhouette, but of the two only the
|
|
182
|
+
// target is load-bearing under a thumb.
|
|
183
|
+
@mixin hit-area($grow: 6px, $box: 1.5rem) {
|
|
176
184
|
position: relative;
|
|
177
185
|
|
|
178
|
-
|
|
186
|
+
&:not([data-tooltip])::after {
|
|
179
187
|
content: '';
|
|
180
188
|
position: absolute;
|
|
181
189
|
inset: -#{$grow};
|
|
182
190
|
}
|
|
191
|
+
|
|
192
|
+
&[data-tooltip] {
|
|
193
|
+
min-width: $box;
|
|
194
|
+
min-height: $box;
|
|
195
|
+
}
|
|
183
196
|
}
|
|
184
197
|
|
|
185
198
|
// One shape for every scroll container and the page itself
|
|
@@ -287,6 +300,15 @@
|
|
|
287
300
|
$_corner-stretch: 1.5;
|
|
288
301
|
$_corner-opaque: 55%;
|
|
289
302
|
|
|
303
|
+
// `surface(0)` is the natural way to say "no border to subtract", but a unitless
|
|
304
|
+
// zero makes every `calc(<length> - 0)` below invalid - and an invalid calc takes
|
|
305
|
+
// its whole declaration with it. Losing the radius and the mask leaves the accent
|
|
306
|
+
// as a plain 2px border all the way round the box, which is how a modal ended up
|
|
307
|
+
// framed instead of cornered.
|
|
308
|
+
@function _accent-width($value) {
|
|
309
|
+
@return if(math.is-unitless($value), $value * 1px, $value);
|
|
310
|
+
}
|
|
311
|
+
|
|
290
312
|
// What is left of the signature once the silhouette is switched off: the same
|
|
291
313
|
// arc, on one corner, thinner and over a shorter run. The two-corner shape is
|
|
292
314
|
// the loud half and mw-corners-even exists to turn it off - but a surface with
|
|
@@ -297,7 +319,8 @@ $_corner-opaque: 55%;
|
|
|
297
319
|
// it follows --mw-radius-scale down to a square, where the arc becomes a
|
|
298
320
|
// bracket in the corner rather than disappearing.
|
|
299
321
|
@mixin corner-mark($border-width: 1px) {
|
|
300
|
-
$
|
|
322
|
+
$width: _accent-width($border-width);
|
|
323
|
+
$r: max(0px, calc(#{radius('md')} - #{$width}));
|
|
301
324
|
|
|
302
325
|
content: '';
|
|
303
326
|
position: absolute;
|
|
@@ -319,8 +342,9 @@ $_corner-opaque: 55%;
|
|
|
319
342
|
// max(), not a bare subtraction: --mw-radius-scale can take the radius to 0,
|
|
320
343
|
// and while a negative border-radius is clamped for us, a negative circle in
|
|
321
344
|
// the mask below would throw the whole gradient away and lose the arc.
|
|
322
|
-
$
|
|
323
|
-
$
|
|
345
|
+
$width: _accent-width($border-width);
|
|
346
|
+
$sharp: max(0px, calc(#{radius-sharp()} - #{$width}));
|
|
347
|
+
$round: max(0px, calc(#{radius('xl')} - #{$width}));
|
|
324
348
|
// Opaque to where the curve ends, fading from there, so the arc runs into the
|
|
325
349
|
// straight edge instead of stopping at the tangent. 1.8 is bounded by the
|
|
326
350
|
// shortest surface: past about 2 the two arcs meet on a 50px box and read as
|
|
@@ -146,6 +146,12 @@
|
|
|
146
146
|
padding: spacing('0');
|
|
147
147
|
border: none;
|
|
148
148
|
color: inherit;
|
|
149
|
+
// `.mw-modal` carries `position: relative` from surface(), which is what its
|
|
150
|
+
// corner accent is drawn against - and being an author rule it beats the UA's
|
|
151
|
+
// `dialog:modal { position: fixed }`. The dialog then centres itself in the
|
|
152
|
+
// document rather than the viewport, so on a long page it opens somewhere far
|
|
153
|
+
// above the fold with only its backdrop to show for it.
|
|
154
|
+
position: fixed;
|
|
149
155
|
// In the top layer there is nothing left to sit above
|
|
150
156
|
z-index: auto;
|
|
151
157
|
// The UA centres a dialog with auto margins; these keep that while giving
|
|
@@ -267,8 +273,13 @@
|
|
|
267
273
|
justify-content: flex-end;
|
|
268
274
|
}
|
|
269
275
|
|
|
270
|
-
// Close button
|
|
271
|
-
.
|
|
276
|
+
// Close button. `:not(.mw-btn)` because the class is two things at once: the
|
|
277
|
+
// hook main.js closes a dialog by, and the look of the X in the header. A
|
|
278
|
+
// footer button that dismisses carries both it and `mw-btn mw-btn-primary` -
|
|
279
|
+
// and this rule sits after the button styles in the same layer at the same
|
|
280
|
+
// specificity, so without the guard it wins and paints the primary action in
|
|
281
|
+
// `background: none`.
|
|
282
|
+
.mw-modal-close:not(.mw-btn) {
|
|
272
283
|
background: none;
|
|
273
284
|
font-size: font-size('md');
|
|
274
285
|
cursor: pointer;
|
|
@@ -338,11 +338,29 @@
|
|
|
338
338
|
// bottom edge, the bubble does not fit, and it gets pushed back over the
|
|
339
339
|
// trigger it belongs to. What this gives up is the clipping immunity the
|
|
340
340
|
// anchored path buys - a modifier inside a scroll container is cut off.
|
|
341
|
+
//
|
|
342
|
+
// Opting out has to restore the placement, not just the positioning scheme:
|
|
343
|
+
// the anchored path below is the later rule and clears `bottom`, `top`,
|
|
344
|
+
// `left` and the centring transform so `position-area` can resolve them
|
|
345
|
+
// itself. Leave that cleared and the box falls to its static position, which
|
|
346
|
+
// for a pseudo element is inside the trigger it is supposed to sit above.
|
|
347
|
+
// The three rules under this one then move the one edge each of them owns.
|
|
341
348
|
&:is(.mw-tooltip-below, .mw-tooltip-end, .mw-tooltip-start) {
|
|
342
349
|
&::before,
|
|
343
350
|
&::after {
|
|
344
351
|
position: absolute;
|
|
345
352
|
position-area: none;
|
|
353
|
+
bottom: 100%;
|
|
354
|
+
top: auto;
|
|
355
|
+
left: 50%;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
&::before {
|
|
359
|
+
transform: translateX(-50%);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
&::after {
|
|
363
|
+
transform: translateX(-50%) rotate(45deg);
|
|
346
364
|
}
|
|
347
365
|
}
|
|
348
366
|
|
|
@@ -100,7 +100,8 @@
|
|
|
100
100
|
// The 18px silhouette stays: mini buttons sit in tag rows and table cells,
|
|
101
101
|
// where growing the circle would shift the layout around them. Only the hit
|
|
102
102
|
// area grows, to 28px - clear of the 24px floor. The extra margin keeps two
|
|
103
|
-
// neighbouring hit areas from overlapping.
|
|
103
|
+
// neighbouring hit areas from overlapping. One with a `data-tooltip` is the
|
|
104
|
+
// exception the mixin makes and goes to a 24px circle instead.
|
|
104
105
|
.mw-btn-mini {
|
|
105
106
|
margin-left: spacing('4');
|
|
106
107
|
@include hit-area(5px);
|
|
@@ -117,9 +118,9 @@
|
|
|
117
118
|
@include hit-area(6px);
|
|
118
119
|
}
|
|
119
120
|
|
|
120
|
-
//
|
|
121
|
-
// `data-tooltip`,
|
|
122
|
-
//
|
|
121
|
+
// One size for the whole row rather than hit-area(): half of these carry a
|
|
122
|
+
// `data-tooltip`, and the mixin treats those differently by design - a row
|
|
123
|
+
// of logos where some grew and some did not reads as a rendering fault.
|
|
123
124
|
.mw-techstack-item-sm {
|
|
124
125
|
min-width: 2.5rem;
|
|
125
126
|
min-height: 2.5rem;
|