@vmz/ui 0.2.3 → 0.2.5
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/package.json +1 -1
- package/src/components/Accordion.vmz +46 -63
- package/src/components/Alert.vmz +35 -38
- package/src/components/AppShell.vmz +92 -75
- package/src/components/Autocomplete.vmz +91 -119
- package/src/components/Avatar.vmz +37 -8
- package/src/components/Badge.vmz +29 -23
- package/src/components/Breadcrumb.vmz +36 -34
- package/src/components/BulkActions.vmz +22 -28
- package/src/components/Button.vmz +139 -121
- package/src/components/Callout.vmz +33 -36
- package/src/components/Card.vmz +68 -51
- package/src/components/Checkbox.vmz +28 -47
- package/src/components/CodeBlock.vmz +31 -25
- package/src/components/Collapse.vmz +34 -16
- package/src/components/ConsoleShell.vmz +107 -110
- package/src/components/Content.vmz +8 -4
- package/src/components/DataTable.vmz +124 -150
- package/src/components/DatePicker.vmz +526 -521
- package/src/components/Dialog.vmz +408 -327
- package/src/components/Divider.vmz +38 -11
- package/src/components/Drawer.vmz +325 -318
- package/src/components/Dropdown.vmz +53 -19
- package/src/components/Empty.vmz +23 -21
- package/src/components/Field.vmz +77 -83
- package/src/components/FilterBar.vmz +8 -10
- package/src/components/Flex.vmz +21 -6
- package/src/components/Footer.vmz +9 -4
- package/src/components/Form.vmz +35 -46
- package/src/components/FormItem.vmz +44 -43
- package/src/components/Grid.vmz +22 -6
- package/src/components/Header.vmz +11 -4
- package/src/components/Icon.vmz +43 -44
- package/src/components/Layout.vmz +9 -4
- package/src/components/Link.vmz +17 -25
- package/src/components/List.vmz +62 -75
- package/src/components/Menu.vmz +182 -197
- package/src/components/Notification.vmz +35 -38
- package/src/components/Pagination.vmz +37 -47
- package/src/components/Popover.vmz +157 -171
- package/src/components/Progress.vmz +36 -10
- package/src/components/Prose.vmz +29 -31
- package/src/components/QueryForm.vmz +14 -22
- package/src/components/RadioGroup.vmz +70 -84
- package/src/components/Result.vmz +36 -38
- package/src/components/Segmented.vmz +43 -22
- package/src/components/Select.vmz +404 -411
- package/src/components/Sider.vmz +21 -4
- package/src/components/Skeleton.vmz +34 -42
- package/src/components/Space.vmz +24 -9
- package/src/components/Spinner.vmz +17 -23
- package/src/components/Steps.vmz +48 -51
- package/src/components/Switch.vmz +50 -60
- package/src/components/Table.vmz +81 -84
- package/src/components/Tabs.vmz +66 -88
- package/src/components/Tag.vmz +36 -11
- package/src/components/TextArea.vmz +73 -77
- package/src/components/Timeline.vmz +36 -32
- package/src/components/Toc.vmz +31 -37
- package/src/components/Tooltip.vmz +25 -35
- package/src/components/Tree.vmz +127 -144
- package/src/components/Typography.vmz +33 -7
- package/src/components/Upload.vmz +1135 -1057
|
@@ -1,75 +1,49 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
aria-label="Dismiss dialog"
|
|
19
|
-
@click="dismiss"
|
|
20
|
-
></button>
|
|
21
|
-
<div
|
|
22
|
-
class="vmz-ui-dialog__panel"
|
|
23
|
-
role="dialog"
|
|
24
|
-
aria-modal="true"
|
|
25
|
-
:aria-labelledby="titleId"
|
|
26
|
-
tabindex="-1"
|
|
27
|
-
data-vmz-overlay-layer="panel"
|
|
28
|
-
data-vmz-focus="enter"
|
|
29
|
-
data-vmz-motion="overlay-enter"
|
|
30
|
-
data-vmz-motion-token="motion.overlay"
|
|
31
|
-
:onKeyDown="onPanelKeyDown"
|
|
32
|
-
>
|
|
33
|
-
<h2 :id="titleId" class="vmz-ui-dialog__title">{{ title }}</h2>
|
|
34
|
-
<div class="vmz-ui-dialog__body">
|
|
35
|
-
<slot />
|
|
36
|
-
</div>
|
|
37
|
-
<div class="vmz-ui-dialog__actions">
|
|
38
|
-
<button type="button" class="vmz-ui-dialog__close" data-vmz-focus="close" @click="dismiss">
|
|
39
|
-
Close
|
|
40
|
-
</button>
|
|
41
|
-
</div>
|
|
2
|
+
<div data-vmz-ui="dialog" :data-vmz-overlay-open="open" class="vmz-ui-dialog-root">
|
|
3
|
+
<div v-if="open" data-vmz-overlay="dialog" data-vmz-overlay-owner="dialog" :data-vmz-overlay-stack="stackLevel" class="vmz-ui-dialog">
|
|
4
|
+
<button type="button" data-vmz-overlay-layer="backdrop" aria-label="Dismiss dialog" @click="dismiss" class="vmz-ui-dialog__backdrop" />
|
|
5
|
+
<div role="dialog" aria-modal="true" :aria-labelledby="titleId" tabindex="-1" data-vmz-overlay-layer="panel" data-vmz-focus="enter" data-vmz-motion="overlay-enter" data-vmz-motion-token="motion.overlay" :onKeyDown="onPanelKeyDown" class="vmz-ui-dialog__panel">
|
|
6
|
+
<h2 :id="titleId" class="vmz-ui-dialog__title">
|
|
7
|
+
{{ title }}
|
|
8
|
+
</h2>
|
|
9
|
+
<div class="vmz-ui-dialog__body">
|
|
10
|
+
<slot />
|
|
11
|
+
</div>
|
|
12
|
+
<div class="vmz-ui-dialog__actions">
|
|
13
|
+
<button type="button" data-vmz-focus="close" @click="dismiss" class="vmz-ui-dialog__close">
|
|
14
|
+
Close
|
|
15
|
+
</button>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
42
18
|
</div>
|
|
43
|
-
</div>
|
|
44
19
|
</div>
|
|
45
20
|
</template>
|
|
46
|
-
|
|
47
21
|
<style>
|
|
48
|
-
|
|
22
|
+
.vmz-ui-dialog-root {
|
|
49
23
|
display: block;
|
|
50
|
-
|
|
24
|
+
}
|
|
51
25
|
|
|
52
|
-
|
|
26
|
+
.vmz-ui-dialog {
|
|
53
27
|
position: fixed;
|
|
54
28
|
inset: 0;
|
|
55
29
|
z-index: 40;
|
|
56
30
|
display: grid;
|
|
57
31
|
place-items: center;
|
|
58
|
-
|
|
32
|
+
}
|
|
59
33
|
|
|
60
|
-
|
|
34
|
+
.vmz-ui-dialog[data-vmz-overlay-stack="1"] {
|
|
61
35
|
z-index: 50;
|
|
62
|
-
|
|
36
|
+
}
|
|
63
37
|
|
|
64
|
-
|
|
38
|
+
.vmz-ui-dialog[data-vmz-overlay-stack="2"] {
|
|
65
39
|
z-index: 60;
|
|
66
|
-
|
|
40
|
+
}
|
|
67
41
|
|
|
68
|
-
|
|
42
|
+
.vmz-ui-dialog[data-vmz-overlay-stack="3"] {
|
|
69
43
|
z-index: 70;
|
|
70
|
-
|
|
44
|
+
}
|
|
71
45
|
|
|
72
|
-
|
|
46
|
+
.vmz-ui-dialog__backdrop {
|
|
73
47
|
position: absolute;
|
|
74
48
|
inset: 0;
|
|
75
49
|
border: 0;
|
|
@@ -77,10 +51,11 @@
|
|
|
77
51
|
margin: 0;
|
|
78
52
|
cursor: pointer;
|
|
79
53
|
background: rgba(0, 0, 0, 0.45);
|
|
80
|
-
animation: vmz-ui-overlay-fade-in var(--vmz-motion-overlay-duration)
|
|
81
|
-
|
|
54
|
+
animation: vmz-ui-overlay-fade-in var(--vmz-motion-overlay-duration)
|
|
55
|
+
var(--vmz-motion-overlay-easing);
|
|
56
|
+
}
|
|
82
57
|
|
|
83
|
-
|
|
58
|
+
.vmz-ui-dialog__panel {
|
|
84
59
|
position: relative;
|
|
85
60
|
z-index: 1;
|
|
86
61
|
width: min(32rem, calc(100vw - 2rem));
|
|
@@ -91,40 +66,43 @@
|
|
|
91
66
|
color: var(--vmz-text-ink);
|
|
92
67
|
box-shadow: var(--vmz-shadow-popup);
|
|
93
68
|
outline: none;
|
|
94
|
-
animation: vmz-ui-overlay-panel-in var(--vmz-motion-overlay-duration)
|
|
95
|
-
|
|
69
|
+
animation: vmz-ui-overlay-panel-in var(--vmz-motion-overlay-duration)
|
|
70
|
+
var(--vmz-motion-overlay-easing);
|
|
71
|
+
}
|
|
96
72
|
|
|
97
|
-
|
|
98
|
-
|
|
73
|
+
.vmz-ui-dialog[data-vmz-motion-adopt="true"] .vmz-ui-dialog__backdrop,
|
|
74
|
+
.vmz-ui-dialog[data-vmz-motion-adopt="true"] .vmz-ui-dialog__panel {
|
|
99
75
|
animation: none;
|
|
100
|
-
|
|
76
|
+
}
|
|
101
77
|
|
|
102
|
-
|
|
103
|
-
animation: vmz-ui-overlay-fade-out var(--vmz-motion-overlay-duration)
|
|
104
|
-
|
|
78
|
+
.vmz-ui-dialog[data-vmz-motion-phase="exit"] .vmz-ui-dialog__backdrop {
|
|
79
|
+
animation: vmz-ui-overlay-fade-out var(--vmz-motion-overlay-duration)
|
|
80
|
+
var(--vmz-motion-overlay-easing);
|
|
81
|
+
}
|
|
105
82
|
|
|
106
|
-
|
|
107
|
-
animation: vmz-ui-overlay-panel-out var(--vmz-motion-overlay-duration)
|
|
108
|
-
|
|
83
|
+
.vmz-ui-dialog[data-vmz-motion-phase="exit"] .vmz-ui-dialog__panel {
|
|
84
|
+
animation: vmz-ui-overlay-panel-out var(--vmz-motion-overlay-duration)
|
|
85
|
+
var(--vmz-motion-overlay-easing);
|
|
86
|
+
}
|
|
109
87
|
|
|
110
|
-
|
|
88
|
+
.vmz-ui-dialog__panel:focus-visible {
|
|
111
89
|
box-shadow: 0 0 0 2px var(--vmz-focus-ring);
|
|
112
|
-
|
|
90
|
+
}
|
|
113
91
|
|
|
114
|
-
|
|
92
|
+
.vmz-ui-dialog__title {
|
|
115
93
|
margin: 0 0 0.75rem;
|
|
116
94
|
font-size: 1rem;
|
|
117
95
|
font-weight: 600;
|
|
118
96
|
line-height: 1.4;
|
|
119
97
|
color: var(--vmz-text-ink);
|
|
120
|
-
|
|
98
|
+
}
|
|
121
99
|
|
|
122
|
-
|
|
100
|
+
.vmz-ui-dialog__body {
|
|
123
101
|
margin-bottom: 1rem;
|
|
124
102
|
color: var(--vmz-text-ink);
|
|
125
|
-
|
|
103
|
+
}
|
|
126
104
|
|
|
127
|
-
|
|
105
|
+
.vmz-ui-dialog__close {
|
|
128
106
|
font: inherit;
|
|
129
107
|
font-size: 0.875rem;
|
|
130
108
|
font-weight: 400;
|
|
@@ -135,291 +113,394 @@
|
|
|
135
113
|
cursor: pointer;
|
|
136
114
|
background: var(--vmz-surface-paper, #fff);
|
|
137
115
|
color: var(--vmz-text-ink);
|
|
138
|
-
|
|
116
|
+
}
|
|
139
117
|
|
|
140
|
-
|
|
118
|
+
.vmz-ui-dialog__close:hover {
|
|
141
119
|
color: var(--vmz-action-primary-background);
|
|
142
120
|
border-color: var(--vmz-action-primary-background);
|
|
143
|
-
|
|
121
|
+
}
|
|
144
122
|
|
|
145
|
-
|
|
123
|
+
.vmz-ui-dialog__close:focus-visible {
|
|
146
124
|
box-shadow: 0 0 0 2px var(--vmz-focus-ring);
|
|
147
|
-
|
|
125
|
+
}
|
|
148
126
|
|
|
149
|
-
|
|
127
|
+
@keyframes vmz-ui-overlay-fade-in {
|
|
150
128
|
from {
|
|
151
|
-
|
|
129
|
+
opacity: 0;
|
|
152
130
|
}
|
|
153
131
|
to {
|
|
154
|
-
|
|
132
|
+
opacity: 1;
|
|
155
133
|
}
|
|
156
|
-
|
|
134
|
+
}
|
|
157
135
|
|
|
158
|
-
|
|
136
|
+
@keyframes vmz-ui-overlay-panel-in {
|
|
159
137
|
from {
|
|
160
|
-
|
|
161
|
-
|
|
138
|
+
opacity: 0;
|
|
139
|
+
transform: translateY(0.35rem);
|
|
162
140
|
}
|
|
163
141
|
to {
|
|
164
|
-
|
|
165
|
-
|
|
142
|
+
opacity: 1;
|
|
143
|
+
transform: none;
|
|
166
144
|
}
|
|
167
|
-
|
|
145
|
+
}
|
|
168
146
|
|
|
169
|
-
|
|
147
|
+
@keyframes vmz-ui-overlay-fade-out {
|
|
170
148
|
from {
|
|
171
|
-
|
|
149
|
+
opacity: 1;
|
|
172
150
|
}
|
|
173
151
|
to {
|
|
174
|
-
|
|
152
|
+
opacity: 0;
|
|
175
153
|
}
|
|
176
|
-
|
|
154
|
+
}
|
|
177
155
|
|
|
178
|
-
|
|
156
|
+
@keyframes vmz-ui-overlay-panel-out {
|
|
179
157
|
from {
|
|
180
|
-
|
|
181
|
-
|
|
158
|
+
opacity: 1;
|
|
159
|
+
transform: none;
|
|
182
160
|
}
|
|
183
161
|
to {
|
|
184
|
-
|
|
185
|
-
|
|
162
|
+
opacity: 0;
|
|
163
|
+
transform: translateY(0.35rem);
|
|
186
164
|
}
|
|
187
|
-
|
|
165
|
+
}
|
|
188
166
|
|
|
189
|
-
|
|
167
|
+
@media (prefers-reduced-motion: reduce) {
|
|
190
168
|
.vmz-ui-dialog__backdrop,
|
|
191
169
|
.vmz-ui-dialog__panel,
|
|
192
|
-
.vmz-ui-dialog[data-vmz-motion-phase=
|
|
193
|
-
.vmz-ui-dialog[data-vmz-motion-phase=
|
|
194
|
-
|
|
170
|
+
.vmz-ui-dialog[data-vmz-motion-phase="exit"] .vmz-ui-dialog__backdrop,
|
|
171
|
+
.vmz-ui-dialog[data-vmz-motion-phase="exit"] .vmz-ui-dialog__panel {
|
|
172
|
+
animation: none;
|
|
195
173
|
}
|
|
196
|
-
|
|
174
|
+
}
|
|
197
175
|
</style>
|
|
198
|
-
|
|
199
176
|
<script client>
|
|
200
177
|
/**
|
|
201
|
-
* VMZ UI — Dialog (UI1).
|
|
202
|
-
* Live `open` + overlay ownership + focus + Escape/outside dismiss + stackLevel.
|
|
203
|
-
* SSR/resume adopt skips enter replay; dismiss plays overlay-exit then calls onClose.
|
|
204
|
-
*/
|
|
178
|
+
* VMZ UI — Dialog (UI1).
|
|
179
|
+
* Live `open` + overlay ownership + focus + Escape/outside dismiss + stackLevel.
|
|
180
|
+
* SSR/resume adopt skips enter replay; dismiss plays overlay-exit then calls onClose.
|
|
181
|
+
*/
|
|
205
182
|
export default class Dialog {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
183
|
+
public open: boolean = false;
|
|
184
|
+
public title: string = "Dialog";
|
|
185
|
+
public titleId: string = "vmz-dialog-title";
|
|
186
|
+
public stackLevel: string = "0";
|
|
187
|
+
public onClose: (() => void) | null = null;
|
|
188
|
+
_restoreFocus = null;
|
|
189
|
+
_panel = null;
|
|
190
|
+
_docKeyHandler = null;
|
|
191
|
+
_pointerCapture = null;
|
|
192
|
+
_observer = null;
|
|
193
|
+
_adoptNextEnter = false;
|
|
194
|
+
_exiting = false;
|
|
195
|
+
_exitTimer = null;
|
|
196
|
+
/** Motion generation — exit timer and cancel edges key off this owner counter. */
|
|
197
|
+
_motionGen = 0;
|
|
198
|
+
async onMount() {
|
|
199
|
+
if (typeof document === "undefined" || typeof MutationObserver === "undefined") return;
|
|
200
|
+
const root = this.__vmzDomRoot;
|
|
201
|
+
if (!root || typeof root.querySelector !== "function") return;
|
|
202
|
+
if (root.querySelector('[data-vmz-overlay="dialog"]')) this._adoptNextEnter = true;
|
|
203
|
+
this._observer = new MutationObserver(() => this._syncFromDom());
|
|
204
|
+
this._observer.observe(root, {
|
|
205
|
+
childList: true,
|
|
206
|
+
subtree: true,
|
|
207
|
+
});
|
|
208
|
+
this._ensurePointerCapture();
|
|
209
|
+
this._syncFromDom();
|
|
210
|
+
}
|
|
211
|
+
onDestroy() {
|
|
212
|
+
if (this._exitTimer) {
|
|
213
|
+
clearTimeout(this._exitTimer);
|
|
214
|
+
this._exitTimer = null;
|
|
215
|
+
}
|
|
216
|
+
this._exiting = false;
|
|
217
|
+
if (this._observer) {
|
|
218
|
+
this._observer.disconnect();
|
|
219
|
+
this._observer = null;
|
|
220
|
+
}
|
|
221
|
+
this._exitFocus();
|
|
222
|
+
}
|
|
223
|
+
dismiss() {
|
|
224
|
+
if (!this._isTopmostStack()) return;
|
|
225
|
+
// Reverse / interrupt: second dismiss during exit cancels close (stay open).
|
|
226
|
+
if (this._exiting) {
|
|
227
|
+
this._cancelExit("reverse");
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
const panel = this._panel;
|
|
231
|
+
const overlay =
|
|
232
|
+
panel && typeof panel.closest === "function"
|
|
233
|
+
? panel.closest('[data-vmz-overlay="dialog"]')
|
|
234
|
+
: null;
|
|
235
|
+
const reduce =
|
|
236
|
+
typeof window !== "undefined" &&
|
|
237
|
+
typeof window.matchMedia === "function" &&
|
|
238
|
+
window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
239
|
+
if (panel && overlay && !reduce) {
|
|
240
|
+
this._exiting = true;
|
|
241
|
+
const exitGen = this._motionGen;
|
|
242
|
+
overlay.setAttribute("data-vmz-motion-phase", "exit");
|
|
243
|
+
overlay.removeAttribute("data-vmz-motion-cancelled");
|
|
244
|
+
panel.setAttribute("data-vmz-motion", "overlay-exit");
|
|
245
|
+
const ms = this._overlayDurationMs(panel);
|
|
246
|
+
this._exitTimer = setTimeout(() => {
|
|
247
|
+
this._exitTimer = null;
|
|
248
|
+
// Stale exit after interrupt/re-enter must not call onClose.
|
|
249
|
+
if (!this._exiting || exitGen !== this._motionGen) return;
|
|
250
|
+
this._exiting = false;
|
|
251
|
+
this._finishDismiss();
|
|
252
|
+
}, ms);
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
this._finishDismiss();
|
|
256
|
+
}
|
|
257
|
+
_finishDismiss() {
|
|
258
|
+
const restore = this._restoreFocus;
|
|
259
|
+
this._restoreFocus = null;
|
|
260
|
+
const opener =
|
|
261
|
+
restore && typeof restore.focus === "function" && document.contains(restore)
|
|
262
|
+
? restore
|
|
263
|
+
: this._openerElement();
|
|
264
|
+
this._exiting = false;
|
|
265
|
+
if (this._exitTimer) {
|
|
266
|
+
clearTimeout(this._exitTimer);
|
|
267
|
+
this._exitTimer = null;
|
|
268
|
+
}
|
|
269
|
+
this._teardownDocKey();
|
|
270
|
+
this._panel = null;
|
|
271
|
+
this.emit("close");
|
|
272
|
+
if (typeof this.onClose === "function") this.onClose();
|
|
273
|
+
this._refocus(opener, true);
|
|
274
|
+
}
|
|
275
|
+
_refocus(el, sync = false) {
|
|
276
|
+
if (!(el instanceof HTMLElement) || typeof el.focus !== "function") return;
|
|
277
|
+
const focus = () => {
|
|
278
|
+
if (document.contains(el)) el.focus();
|
|
279
|
+
};
|
|
280
|
+
if (sync) {
|
|
281
|
+
focus();
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
if (typeof requestAnimationFrame === "function") {
|
|
285
|
+
requestAnimationFrame(() => requestAnimationFrame(focus));
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
focus();
|
|
289
|
+
}
|
|
290
|
+
_cancelExit(reason) {
|
|
291
|
+
if (this._exitTimer) {
|
|
292
|
+
clearTimeout(this._exitTimer);
|
|
293
|
+
this._exitTimer = null;
|
|
294
|
+
}
|
|
295
|
+
this._exiting = false;
|
|
296
|
+
this._motionGen += 1;
|
|
297
|
+
const panel = this._panel;
|
|
298
|
+
const overlay =
|
|
299
|
+
panel && typeof panel.closest === "function"
|
|
300
|
+
? panel.closest('[data-vmz-overlay="dialog"]')
|
|
301
|
+
: null;
|
|
302
|
+
if (overlay) {
|
|
303
|
+
overlay.removeAttribute("data-vmz-motion-phase");
|
|
304
|
+
overlay.setAttribute("data-vmz-motion-cancelled", reason || "true");
|
|
305
|
+
overlay.setAttribute("data-vmz-motion-gen", String(this._motionGen));
|
|
306
|
+
}
|
|
307
|
+
if (panel) {
|
|
308
|
+
panel.setAttribute("data-vmz-motion", "overlay-enter");
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
_overlayDurationMs(panel) {
|
|
312
|
+
try {
|
|
313
|
+
const raw =
|
|
314
|
+
(
|
|
315
|
+
getComputedStyle(panel).getPropertyValue("--vmz-motion-overlay-duration") || ""
|
|
316
|
+
).trim() || "180ms";
|
|
317
|
+
if (raw.endsWith("ms")) return Math.max(0, Number.parseFloat(raw) || 180);
|
|
318
|
+
if (raw.endsWith("s")) return Math.max(0, (Number.parseFloat(raw) || 0.18) * 1e3);
|
|
319
|
+
return 180;
|
|
320
|
+
} catch {
|
|
321
|
+
return 180;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
_isTopmostStack() {
|
|
325
|
+
if (typeof document === "undefined") return true;
|
|
326
|
+
const root = this.__vmzDomRoot;
|
|
327
|
+
const mine =
|
|
328
|
+
root && typeof root.querySelector === "function"
|
|
329
|
+
? root.querySelector("[data-vmz-overlay][data-vmz-overlay-stack]")
|
|
330
|
+
: null;
|
|
331
|
+
if (!mine) return true;
|
|
332
|
+
const myStack = Number(
|
|
333
|
+
mine.getAttribute("data-vmz-overlay-stack") || this.stackLevel || "0",
|
|
334
|
+
);
|
|
335
|
+
const open = [...document.querySelectorAll("[data-vmz-overlay][data-vmz-overlay-stack]")];
|
|
336
|
+
let max = -Infinity;
|
|
337
|
+
for (const el of open) {
|
|
338
|
+
const n = Number(el.getAttribute("data-vmz-overlay-stack") || "0");
|
|
339
|
+
if (Number.isFinite(n) && n > max) max = n;
|
|
340
|
+
}
|
|
341
|
+
if (!Number.isFinite(max)) return true;
|
|
342
|
+
if ((Number.isFinite(myStack) ? myStack : 0) < max) return false;
|
|
343
|
+
if ((Number.isFinite(myStack) ? myStack : 0) > max) return true;
|
|
344
|
+
const same = open.filter(
|
|
345
|
+
(el) => Number(el.getAttribute("data-vmz-overlay-stack") || "0") === max,
|
|
346
|
+
);
|
|
347
|
+
return same[same.length - 1] === mine;
|
|
348
|
+
}
|
|
349
|
+
onPanelKeyDown(ev) {
|
|
350
|
+
if (!ev || ev.key !== "Tab") return;
|
|
351
|
+
const panel = this._panel;
|
|
352
|
+
if (!panel) return;
|
|
353
|
+
const nodes = panel.querySelectorAll(
|
|
354
|
+
'a[href],button:not([disabled]),textarea:not([disabled]),input:not([disabled]),select:not([disabled]),[tabindex]:not([tabindex="-1"])',
|
|
355
|
+
);
|
|
356
|
+
const list = [];
|
|
357
|
+
for (const n of nodes) {
|
|
358
|
+
if (n instanceof HTMLElement && n.offsetParent !== null) list.push(n);
|
|
359
|
+
}
|
|
360
|
+
if (panel.tabIndex >= 0) list.unshift(panel);
|
|
361
|
+
if (!list.length) {
|
|
362
|
+
ev.preventDefault();
|
|
363
|
+
panel.focus();
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
const first = list[0];
|
|
367
|
+
const last = list[list.length - 1];
|
|
368
|
+
const active = document.activeElement;
|
|
369
|
+
if (ev.shiftKey) {
|
|
370
|
+
if (active === first || active === panel) {
|
|
371
|
+
ev.preventDefault();
|
|
372
|
+
last.focus();
|
|
373
|
+
}
|
|
374
|
+
} else if (active === last) {
|
|
375
|
+
ev.preventDefault();
|
|
376
|
+
first.focus();
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
_syncFromDom() {
|
|
380
|
+
const root = this.__vmzDomRoot;
|
|
381
|
+
const panel =
|
|
382
|
+
root && typeof root.querySelector === "function"
|
|
383
|
+
? root.querySelector('[data-vmz-focus="enter"]')
|
|
384
|
+
: null;
|
|
385
|
+
if (panel && !this._panel) {
|
|
386
|
+
this._enterFocus(panel);
|
|
387
|
+
} else if (!panel && this._panel) {
|
|
388
|
+
this._exitFocus();
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
_enterFocus(panel) {
|
|
392
|
+
if (typeof document === "undefined") return;
|
|
393
|
+
const active = document.activeElement;
|
|
394
|
+
if (!this._restoreFocus) {
|
|
395
|
+
if (
|
|
396
|
+
active instanceof HTMLElement &&
|
|
397
|
+
active !== document.body &&
|
|
398
|
+
active !== panel &&
|
|
399
|
+
!(panel instanceof HTMLElement && panel.contains(active))
|
|
400
|
+
) {
|
|
401
|
+
this._restoreFocus = active;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
this._panel = panel instanceof HTMLElement ? panel : null;
|
|
405
|
+
const overlay =
|
|
406
|
+
this._panel && typeof this._panel.closest === "function"
|
|
407
|
+
? this._panel.closest('[data-vmz-overlay="dialog"]')
|
|
408
|
+
: null;
|
|
409
|
+
// Owner remount / re-enter cancels any in-flight exit from a prior generation.
|
|
410
|
+
if (this._exiting) {
|
|
411
|
+
this._cancelExit("reenter");
|
|
412
|
+
} else {
|
|
413
|
+
this._motionGen += 1;
|
|
414
|
+
}
|
|
415
|
+
if (overlay) {
|
|
416
|
+
overlay.setAttribute("data-vmz-motion-gen", String(this._motionGen));
|
|
417
|
+
}
|
|
418
|
+
if (this._adoptNextEnter && overlay) {
|
|
419
|
+
overlay.setAttribute("data-vmz-motion-adopt", "true");
|
|
420
|
+
this._panel.setAttribute("data-vmz-motion", "overlay-stable");
|
|
421
|
+
this._adoptNextEnter = false;
|
|
422
|
+
} else if (overlay) {
|
|
423
|
+
overlay.removeAttribute("data-vmz-motion-adopt");
|
|
424
|
+
overlay.removeAttribute("data-vmz-motion-phase");
|
|
425
|
+
overlay.removeAttribute("data-vmz-motion-cancelled");
|
|
426
|
+
this._panel.setAttribute("data-vmz-motion", "overlay-enter");
|
|
427
|
+
}
|
|
428
|
+
if (this._panel && typeof this._panel.focus === "function") {
|
|
429
|
+
this._panel.focus();
|
|
430
|
+
}
|
|
431
|
+
if (!this._docKeyHandler) {
|
|
432
|
+
this._docKeyHandler = (ev) => {
|
|
433
|
+
if (ev.key !== "Escape") return;
|
|
434
|
+
if (ev.defaultPrevented) return;
|
|
435
|
+
if (!this._isTopmostStack()) return;
|
|
436
|
+
ev.preventDefault();
|
|
437
|
+
ev.stopPropagation();
|
|
438
|
+
this.dismiss();
|
|
439
|
+
};
|
|
440
|
+
document.addEventListener("keydown", this._docKeyHandler);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
_exitFocus() {
|
|
444
|
+
if (this._exitTimer) {
|
|
445
|
+
clearTimeout(this._exitTimer);
|
|
446
|
+
this._exitTimer = null;
|
|
447
|
+
}
|
|
448
|
+
this._exiting = false;
|
|
449
|
+
this._teardownDocKey();
|
|
450
|
+
this._panel = null;
|
|
451
|
+
const restore = this._restoreFocus;
|
|
452
|
+
this._restoreFocus = null;
|
|
453
|
+
const focusTarget =
|
|
454
|
+
restore && typeof restore.focus === "function" && document.contains(restore)
|
|
455
|
+
? restore
|
|
456
|
+
: this._openerElement();
|
|
457
|
+
if (focusTarget && typeof focusTarget.focus === "function") {
|
|
458
|
+
focusTarget.focus();
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
_openerElement() {
|
|
462
|
+
if (typeof document === "undefined") return null;
|
|
463
|
+
const byTitle = document.querySelector(`[aria-controls="${this.titleId}"]`);
|
|
464
|
+
if (byTitle instanceof HTMLElement) return byTitle;
|
|
465
|
+
const byTrigger = document.querySelector(
|
|
466
|
+
`[data-vmz-dialog-trigger-for="${this.titleId}"] button, [data-vmz-dialog-trigger-for="${this.titleId}"]`,
|
|
467
|
+
);
|
|
468
|
+
if (byTrigger instanceof HTMLElement) return byTrigger;
|
|
469
|
+
const root = this.__vmzDomRoot;
|
|
470
|
+
if (!(root instanceof HTMLElement)) return null;
|
|
471
|
+
let host = root.parentElement;
|
|
472
|
+
while (host) {
|
|
473
|
+
const buttons = [...host.querySelectorAll("button.vmz-ui-btn")].filter(
|
|
474
|
+
(btn) => btn instanceof HTMLElement,
|
|
475
|
+
);
|
|
476
|
+
if (buttons.length === 1) return buttons[0];
|
|
477
|
+
for (const btn of buttons) {
|
|
478
|
+
if (root.compareDocumentPosition(btn) & Node.DOCUMENT_POSITION_PRECEDING) {
|
|
479
|
+
return btn;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
host = host.parentElement;
|
|
483
|
+
}
|
|
484
|
+
return null;
|
|
485
|
+
}
|
|
486
|
+
_ensurePointerCapture() {
|
|
487
|
+
if (typeof document === "undefined" || this._pointerCapture) return;
|
|
488
|
+
this._pointerCapture = (ev) => {
|
|
489
|
+
const t =
|
|
490
|
+
ev.target instanceof HTMLElement
|
|
491
|
+
? ev.target.closest("button, a[href], input, select, textarea, [tabindex]")
|
|
492
|
+
: null;
|
|
493
|
+
if (!(t instanceof HTMLElement)) return;
|
|
494
|
+
if (t.closest('[data-vmz-overlay="dialog"]')) return;
|
|
495
|
+
this._restoreFocus = t;
|
|
496
|
+
};
|
|
497
|
+
document.addEventListener("mousedown", this._pointerCapture, true);
|
|
498
|
+
}
|
|
499
|
+
_teardownDocKey() {
|
|
500
|
+
if (typeof document !== "undefined" && this._docKeyHandler) {
|
|
501
|
+
document.removeEventListener("keydown", this._docKeyHandler);
|
|
502
|
+
}
|
|
503
|
+
this._docKeyHandler = null;
|
|
504
|
+
}
|
|
424
505
|
}
|
|
425
506
|
</script>
|