@vmz/ui 0.3.7 → 0.3.8
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 +2 -0
- package/contracts/token-requirements.v0.json +58 -1
- package/package.json +5 -2
- package/presets/web-surface.v0.json +14 -12
- package/src/components/Accordion.vmz +49 -16
- package/src/components/Alert.vmz +125 -28
- package/src/components/AppShell.vmz +121 -56
- package/src/components/Autocomplete.vmz +136 -29
- package/src/components/Avatar.vmz +20 -12
- package/src/components/Badge.vmz +18 -26
- package/src/components/Breadcrumb.vmz +28 -14
- package/src/components/BulkActions.vmz +13 -8
- package/src/components/Button.vmz +68 -44
- package/src/components/Callout.vmz +128 -27
- package/src/components/Card.vmz +67 -46
- package/src/components/Checkbox.vmz +81 -5
- package/src/components/CodeBlock.vmz +59 -27
- package/src/components/Collapse.vmz +64 -11
- package/src/components/ConsoleShell.vmz +217 -63
- package/src/components/Content.vmz +15 -1
- package/src/components/DataTable.vmz +123 -23
- package/src/components/DatePicker.vmz +171 -79
- package/src/components/Descriptions.vmz +90 -0
- package/src/components/Dialog.vmz +133 -50
- package/src/components/Divider.vmz +8 -1
- package/src/components/Drawer.vmz +131 -40
- package/src/components/Dropdown.vmz +147 -49
- package/src/components/Empty.vmz +56 -14
- package/src/components/Field.vmz +78 -23
- package/src/components/FilterBar.vmz +34 -4
- package/src/components/Flex.vmz +3 -1
- package/src/components/Footer.vmz +6 -3
- package/src/components/Form.vmz +41 -0
- package/src/components/FormItem.vmz +2 -3
- package/src/components/Grid.vmz +6 -3
- package/src/components/Header.vmz +193 -6
- package/src/components/Layout.vmz +3 -1
- package/src/components/Link.vmz +20 -9
- package/src/components/List.vmz +35 -13
- package/src/components/Menu.vmz +198 -25
- package/src/components/Message.vmz +167 -0
- package/src/components/Notification.vmz +132 -37
- package/src/components/Pagination.vmz +186 -20
- package/src/components/Popconfirm.vmz +287 -0
- package/src/components/Popover.vmz +152 -34
- package/src/components/Progress.vmz +16 -5
- package/src/components/Prose.vmz +131 -32
- package/src/components/QueryForm.vmz +31 -9
- package/src/components/RadioGroup.vmz +91 -11
- package/src/components/Result.vmz +60 -27
- package/src/components/Segmented.vmz +46 -11
- package/src/components/Select.vmz +174 -87
- package/src/components/Sider.vmz +120 -7
- package/src/components/Skeleton.vmz +9 -7
- package/src/components/Space.vmz +9 -3
- package/src/components/Spinner.vmz +5 -4
- package/src/components/Steps.vmz +40 -25
- package/src/components/Switch.vmz +48 -15
- package/src/components/Table.vmz +130 -25
- package/src/components/Tabs.vmz +28 -13
- package/src/components/Tag.vmz +29 -12
- package/src/components/TextArea.vmz +32 -25
- package/src/components/Timeline.vmz +65 -30
- package/src/components/Toc.vmz +45 -29
- package/src/components/Tooltip.vmz +70 -21
- package/src/components/Tree.vmz +48 -25
- package/src/components/Typography.vmz +23 -8
- package/src/components/Upload.vmz +191 -96
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
<template>
|
|
2
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="
|
|
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
|
-
<
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
<div v-if="open" data-vmz-overlay="dialog" data-vmz-overlay-owner="dialog" :data-vmz-overlay-stack="stackLevel" :data-size="size" :data-action-size="actionSize" :data-tone="danger ? 'danger' : 'default'" class="vmz-ui-dialog">
|
|
4
|
+
<button type="button" data-vmz-overlay-layer="backdrop" :aria-label="dismissLabel || closeLabel || label || title" @click="dismiss" class="vmz-ui-dialog__backdrop" />
|
|
5
|
+
<div role="dialog" aria-modal="true" :aria-labelledby="title ? titleId : null" 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
|
+
<header class="vmz-ui-dialog__header">
|
|
7
|
+
<div class="vmz-ui-dialog__heading">
|
|
8
|
+
<h2 v-if="title" :id="titleId" class="vmz-ui-dialog__title">
|
|
9
|
+
{{ title }}
|
|
10
|
+
</h2>
|
|
11
|
+
<p v-if="description" class="vmz-ui-dialog__description">
|
|
12
|
+
{{ description }}
|
|
13
|
+
</p>
|
|
14
|
+
</div>
|
|
15
|
+
<button type="button" data-vmz-focus="close" :aria-label="closeLabel || label || title" @click="dismiss" class="vmz-ui-dialog__close">
|
|
16
|
+
<Icon name="action.close" size="md" decorative />
|
|
17
|
+
</button>
|
|
18
|
+
</header>
|
|
9
19
|
<div class="vmz-ui-dialog__body">
|
|
10
20
|
<slot />
|
|
11
21
|
</div>
|
|
12
22
|
<div class="vmz-ui-dialog__actions">
|
|
13
|
-
<
|
|
14
|
-
Close
|
|
15
|
-
</button>
|
|
23
|
+
<slot name="actions" />
|
|
16
24
|
</div>
|
|
17
25
|
</div>
|
|
18
26
|
</div>
|
|
@@ -29,6 +37,8 @@
|
|
|
29
37
|
z-index: 40;
|
|
30
38
|
display: grid;
|
|
31
39
|
place-items: center;
|
|
40
|
+
box-sizing: border-box;
|
|
41
|
+
padding: 24px;
|
|
32
42
|
}
|
|
33
43
|
|
|
34
44
|
.vmz-ui-dialog[data-vmz-overlay-stack="1"] {
|
|
@@ -50,7 +60,7 @@
|
|
|
50
60
|
padding: 0;
|
|
51
61
|
margin: 0;
|
|
52
62
|
cursor: pointer;
|
|
53
|
-
background:
|
|
63
|
+
background: color-mix(in srgb, var(--vmz-surface-ink) 45%, transparent);
|
|
54
64
|
animation: vmz-ui-overlay-fade-in var(--vmz-motion-overlay-duration)
|
|
55
65
|
var(--vmz-motion-overlay-easing);
|
|
56
66
|
}
|
|
@@ -58,11 +68,14 @@
|
|
|
58
68
|
.vmz-ui-dialog__panel {
|
|
59
69
|
position: relative;
|
|
60
70
|
z-index: 1;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
71
|
+
display: flex;
|
|
72
|
+
flex-direction: column;
|
|
73
|
+
box-sizing: border-box;
|
|
74
|
+
width: min(520px, 100%);
|
|
75
|
+
max-height: calc(100vh - 48px);
|
|
76
|
+
border: 1px solid var(--vmz-line-subtle);
|
|
77
|
+
border-radius: var(--vmz-radius-lg);
|
|
78
|
+
background: var(--vmz-surface-paper);
|
|
66
79
|
color: var(--vmz-text-ink);
|
|
67
80
|
box-shadow: var(--vmz-shadow-popup);
|
|
68
81
|
outline: none;
|
|
@@ -70,6 +83,14 @@
|
|
|
70
83
|
var(--vmz-motion-overlay-easing);
|
|
71
84
|
}
|
|
72
85
|
|
|
86
|
+
.vmz-ui-dialog[data-size="sm"] .vmz-ui-dialog__panel {
|
|
87
|
+
width: min(400px, 100%);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.vmz-ui-dialog[data-size="lg"] .vmz-ui-dialog__panel {
|
|
91
|
+
width: min(720px, 100%);
|
|
92
|
+
}
|
|
93
|
+
|
|
73
94
|
.vmz-ui-dialog[data-vmz-motion-adopt="true"] .vmz-ui-dialog__backdrop,
|
|
74
95
|
.vmz-ui-dialog[data-vmz-motion-adopt="true"] .vmz-ui-dialog__panel {
|
|
75
96
|
animation: none;
|
|
@@ -86,61 +107,107 @@
|
|
|
86
107
|
}
|
|
87
108
|
|
|
88
109
|
.vmz-ui-dialog__panel:focus-visible {
|
|
89
|
-
box-shadow: 0 0 0 3px var(--vmz-focus-ring);
|
|
110
|
+
box-shadow: 0 0 0 3px var(--vmz-focus-ring), var(--vmz-shadow-popup);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.vmz-ui-dialog__header {
|
|
114
|
+
display: flex;
|
|
115
|
+
align-items: flex-start;
|
|
116
|
+
gap: 16px;
|
|
117
|
+
padding: 20px 24px 16px;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.vmz-ui-dialog__heading {
|
|
121
|
+
flex: 1 1 auto;
|
|
122
|
+
min-width: 0;
|
|
90
123
|
}
|
|
91
124
|
|
|
92
125
|
.vmz-ui-dialog__title {
|
|
93
|
-
margin: 0
|
|
94
|
-
font-size:
|
|
126
|
+
margin: 0;
|
|
127
|
+
font-size: 18px;
|
|
95
128
|
font-weight: 600;
|
|
96
|
-
line-height:
|
|
129
|
+
line-height: 24px;
|
|
97
130
|
color: var(--vmz-text-ink);
|
|
98
131
|
}
|
|
99
132
|
|
|
100
|
-
.vmz-ui-
|
|
101
|
-
|
|
102
|
-
|
|
133
|
+
.vmz-ui-dialog[data-tone="danger"] .vmz-ui-dialog__title {
|
|
134
|
+
color: var(--vmz-status-danger-foreground);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.vmz-ui-dialog__description {
|
|
138
|
+
margin: 6px 0 0;
|
|
139
|
+
font-size: 14px;
|
|
140
|
+
line-height: 22px;
|
|
141
|
+
color: var(--vmz-text-tertiary);
|
|
103
142
|
}
|
|
104
143
|
|
|
105
144
|
.vmz-ui-dialog__close {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
145
|
+
flex: 0 0 auto;
|
|
146
|
+
display: inline-flex;
|
|
147
|
+
align-items: center;
|
|
148
|
+
justify-content: center;
|
|
149
|
+
width: 32px;
|
|
150
|
+
height: 32px;
|
|
151
|
+
margin: -4px -8px 0 0;
|
|
152
|
+
padding: 0;
|
|
153
|
+
border: 0;
|
|
154
|
+
border-radius: var(--vmz-radius-md);
|
|
155
|
+
background: transparent;
|
|
156
|
+
color: var(--vmz-text-steel);
|
|
113
157
|
cursor: pointer;
|
|
114
|
-
|
|
115
|
-
color: var(--vmz-text-ink);
|
|
158
|
+
outline: none;
|
|
116
159
|
transition:
|
|
117
|
-
color var(--vmz-motion-control-duration
|
|
118
|
-
|
|
119
|
-
background-color var(--vmz-motion-control-duration, 150ms) var(--vmz-motion-control-easing, cubic-bezier(0.4, 0, 0.2, 1));
|
|
160
|
+
color var(--vmz-motion-control-duration) var(--vmz-motion-control-easing),
|
|
161
|
+
background-color var(--vmz-motion-control-duration) var(--vmz-motion-control-easing);
|
|
120
162
|
}
|
|
121
163
|
|
|
122
|
-
.vmz-ui-dialog__close
|
|
123
|
-
background: var(--vmz-
|
|
124
|
-
color: var(--vmz-
|
|
125
|
-
border-color: transparent;
|
|
164
|
+
.vmz-ui-dialog__close:hover {
|
|
165
|
+
background: var(--vmz-surface-mist);
|
|
166
|
+
color: var(--vmz-text-ink);
|
|
126
167
|
}
|
|
127
168
|
|
|
128
|
-
.vmz-ui-dialog__close
|
|
129
|
-
|
|
130
|
-
border-color: transparent;
|
|
169
|
+
.vmz-ui-dialog__close:focus-visible {
|
|
170
|
+
box-shadow: 0 0 0 3px var(--vmz-focus-ring);
|
|
131
171
|
}
|
|
132
172
|
|
|
133
|
-
.vmz-ui-
|
|
134
|
-
|
|
173
|
+
.vmz-ui-dialog__body {
|
|
174
|
+
flex: 1 1 auto;
|
|
175
|
+
min-height: 0;
|
|
176
|
+
padding: 0 24px 20px;
|
|
177
|
+
overflow: auto;
|
|
178
|
+
font-size: 14px;
|
|
179
|
+
line-height: 22px;
|
|
180
|
+
color: var(--vmz-text-ink);
|
|
135
181
|
}
|
|
136
182
|
|
|
137
|
-
.vmz-ui-
|
|
183
|
+
.vmz-ui-dialog__body :where(a) {
|
|
184
|
+
color: var(--vmz-action-primary-background);
|
|
185
|
+
text-underline-offset: 2px;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.vmz-ui-dialog__body :where(a):hover {
|
|
138
189
|
color: var(--vmz-action-primary-hover);
|
|
139
|
-
border-color: var(--vmz-action-primary-hover);
|
|
140
190
|
}
|
|
141
191
|
|
|
142
|
-
.vmz-ui-
|
|
143
|
-
|
|
192
|
+
.vmz-ui-dialog__actions {
|
|
193
|
+
display: flex;
|
|
194
|
+
flex-wrap: wrap;
|
|
195
|
+
align-items: center;
|
|
196
|
+
justify-content: flex-end;
|
|
197
|
+
gap: 8px;
|
|
198
|
+
padding: 0 24px 20px;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.vmz-ui-dialog__actions:empty {
|
|
202
|
+
display: none;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.vmz-ui-dialog__actions :where(button, a) {
|
|
206
|
+
min-height: var(--vmz-control-height, 32px);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.vmz-ui-dialog[data-action-size="lg"] .vmz-ui-dialog__actions :where(button, a) {
|
|
210
|
+
min-height: 40px;
|
|
144
211
|
}
|
|
145
212
|
|
|
146
213
|
@keyframes vmz-ui-overlay-fade-in {
|
|
@@ -155,7 +222,7 @@
|
|
|
155
222
|
@keyframes vmz-ui-overlay-panel-in {
|
|
156
223
|
from {
|
|
157
224
|
opacity: 0;
|
|
158
|
-
transform: translateY(0.
|
|
225
|
+
transform: translateY(8px) scale(0.98);
|
|
159
226
|
}
|
|
160
227
|
to {
|
|
161
228
|
opacity: 1;
|
|
@@ -179,16 +246,18 @@
|
|
|
179
246
|
}
|
|
180
247
|
to {
|
|
181
248
|
opacity: 0;
|
|
182
|
-
transform: translateY(0.
|
|
249
|
+
transform: translateY(8px) scale(0.98);
|
|
183
250
|
}
|
|
184
251
|
}
|
|
185
252
|
|
|
186
253
|
@media (prefers-reduced-motion: reduce) {
|
|
187
254
|
.vmz-ui-dialog__backdrop,
|
|
188
255
|
.vmz-ui-dialog__panel,
|
|
256
|
+
.vmz-ui-dialog__close,
|
|
189
257
|
.vmz-ui-dialog[data-vmz-motion-phase="exit"] .vmz-ui-dialog__backdrop,
|
|
190
258
|
.vmz-ui-dialog[data-vmz-motion-phase="exit"] .vmz-ui-dialog__panel {
|
|
191
259
|
animation: none;
|
|
260
|
+
transition: none;
|
|
192
261
|
}
|
|
193
262
|
}
|
|
194
263
|
</style>
|
|
@@ -197,10 +266,24 @@
|
|
|
197
266
|
* VMZ UI — Dialog (UI1).
|
|
198
267
|
* Live `open` + overlay ownership + focus + Escape/outside dismiss + stackLevel.
|
|
199
268
|
* SSR/resume adopt skips enter replay; dismiss plays overlay-exit then calls onClose.
|
|
269
|
+
*
|
|
270
|
+
* Appearance props: `size` (sm 400 / md 520 / lg 720), `danger` tone,
|
|
271
|
+
* `description`, `actionSize` (md 32 / lg 40 action buttons).
|
|
272
|
+
* Visible copy is author-supplied; `closeLabel` / `dismissLabel` only name the
|
|
273
|
+
* icon button and backdrop for assistive tech.
|
|
200
274
|
*/
|
|
201
275
|
export default class Dialog {
|
|
202
276
|
public open: boolean = false;
|
|
203
|
-
public title: string = "
|
|
277
|
+
public title: string = "";
|
|
278
|
+
public label: string = "";
|
|
279
|
+
public description: string = "";
|
|
280
|
+
/** sm | md | lg */
|
|
281
|
+
public size: string = "md";
|
|
282
|
+
/** md | lg */
|
|
283
|
+
public actionSize: string = "md";
|
|
284
|
+
public danger: boolean = false;
|
|
285
|
+
public closeLabel: string = "";
|
|
286
|
+
public dismissLabel: string = "";
|
|
204
287
|
public titleId: string = "vmz-dialog-title";
|
|
205
288
|
public stackLevel: string = "0";
|
|
206
289
|
public onClose: (() => void) | null = null;
|
|
@@ -9,11 +9,13 @@
|
|
|
9
9
|
.vmz-ui-divider {
|
|
10
10
|
display: flex;
|
|
11
11
|
align-items: center;
|
|
12
|
-
gap:
|
|
12
|
+
gap: var(--vmz-space-3);
|
|
13
13
|
width: 100%;
|
|
14
14
|
color: var(--vmz-text-steel);
|
|
15
15
|
font-size: 0.875rem;
|
|
16
|
+
line-height: 1.5715;
|
|
16
17
|
}
|
|
18
|
+
|
|
17
19
|
.vmz-ui-divider:before,
|
|
18
20
|
.vmz-ui-divider:after {
|
|
19
21
|
content: "";
|
|
@@ -21,18 +23,23 @@
|
|
|
21
23
|
flex: 1;
|
|
22
24
|
background: var(--vmz-line-default);
|
|
23
25
|
}
|
|
26
|
+
|
|
24
27
|
.vmz-ui-divider:not(:has(span)):before {
|
|
25
28
|
flex: 1;
|
|
26
29
|
}
|
|
30
|
+
|
|
27
31
|
.vmz-ui-divider:not(:has(span)):after {
|
|
28
32
|
display: none;
|
|
29
33
|
}
|
|
34
|
+
|
|
30
35
|
.vmz-ui-divider[data-direction="vertical"] {
|
|
31
36
|
display: inline-block;
|
|
32
37
|
width: 1px;
|
|
33
38
|
height: 1em;
|
|
39
|
+
margin: 0 var(--vmz-space-2);
|
|
34
40
|
background: var(--vmz-line-default);
|
|
35
41
|
}
|
|
42
|
+
|
|
36
43
|
.vmz-ui-divider[data-direction="vertical"]:before,
|
|
37
44
|
.vmz-ui-divider[data-direction="vertical"]:after {
|
|
38
45
|
display: none;
|
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div data-vmz-ui="drawer" :data-vmz-overlay-open="open" class="vmz-ui-drawer-root">
|
|
3
|
-
<div v-if="open" data-vmz-overlay="drawer" data-vmz-overlay-owner="drawer" :data-vmz-overlay-stack="stackLevel" class="vmz-ui-drawer">
|
|
4
|
-
<button type="button" data-vmz-overlay-layer="backdrop" aria-label="
|
|
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-drawer__panel">
|
|
6
|
-
<
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
<div v-if="open" data-vmz-overlay="drawer" data-vmz-overlay-owner="drawer" :data-vmz-overlay-stack="stackLevel" :data-size="size" class="vmz-ui-drawer">
|
|
4
|
+
<button type="button" data-vmz-overlay-layer="backdrop" :aria-label="dismissLabel || closeLabel || title" @click="dismiss" class="vmz-ui-drawer__backdrop" />
|
|
5
|
+
<div role="dialog" aria-modal="true" :aria-labelledby="title ? titleId : null" 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-drawer__panel">
|
|
6
|
+
<header class="vmz-ui-drawer__header">
|
|
7
|
+
<div class="vmz-ui-drawer__heading">
|
|
8
|
+
<h2 v-if="title" :id="titleId" class="vmz-ui-drawer__title">
|
|
9
|
+
{{ title }}
|
|
10
|
+
</h2>
|
|
11
|
+
<p v-if="description" class="vmz-ui-drawer__description">
|
|
12
|
+
{{ description }}
|
|
13
|
+
</p>
|
|
14
|
+
</div>
|
|
15
|
+
<button type="button" data-vmz-focus="close" :aria-label="closeLabel || title" @click="dismiss" class="vmz-ui-drawer__close">
|
|
16
|
+
<Icon name="action.close" size="md" decorative />
|
|
17
|
+
</button>
|
|
18
|
+
</header>
|
|
9
19
|
<div class="vmz-ui-drawer__body">
|
|
10
20
|
<slot />
|
|
11
21
|
</div>
|
|
12
|
-
<
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
</button>
|
|
16
|
-
</div>
|
|
22
|
+
<footer class="vmz-ui-drawer__footer">
|
|
23
|
+
<slot name="footer" />
|
|
24
|
+
</footer>
|
|
17
25
|
</div>
|
|
18
26
|
</div>
|
|
19
27
|
</div>
|
|
@@ -48,7 +56,7 @@
|
|
|
48
56
|
padding: 0;
|
|
49
57
|
margin: 0;
|
|
50
58
|
cursor: pointer;
|
|
51
|
-
background:
|
|
59
|
+
background: color-mix(in srgb, var(--vmz-surface-ink) 45%, transparent);
|
|
52
60
|
animation: vmz-ui-drawer-fade-in var(--vmz-motion-overlay-duration)
|
|
53
61
|
var(--vmz-motion-overlay-easing);
|
|
54
62
|
}
|
|
@@ -59,20 +67,27 @@
|
|
|
59
67
|
right: 0;
|
|
60
68
|
z-index: 1;
|
|
61
69
|
box-sizing: border-box;
|
|
62
|
-
|
|
70
|
+
display: flex;
|
|
71
|
+
flex-direction: column;
|
|
72
|
+
width: min(420px, 100vw);
|
|
63
73
|
height: 100%;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
background: var(--vmz-surface-paper, #fff);
|
|
74
|
+
border-left: 1px solid var(--vmz-line-subtle);
|
|
75
|
+
background: var(--vmz-surface-paper);
|
|
67
76
|
color: var(--vmz-text-ink);
|
|
68
77
|
box-shadow: var(--vmz-shadow-popup);
|
|
69
78
|
outline: none;
|
|
70
|
-
display: flex;
|
|
71
|
-
flex-direction: column;
|
|
72
79
|
animation: vmz-ui-drawer-panel-in var(--vmz-motion-overlay-duration)
|
|
73
80
|
var(--vmz-motion-overlay-easing);
|
|
74
81
|
}
|
|
75
82
|
|
|
83
|
+
.vmz-ui-drawer[data-size="sm"] .vmz-ui-drawer__panel {
|
|
84
|
+
width: min(320px, 100vw);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.vmz-ui-drawer[data-size="lg"] .vmz-ui-drawer__panel {
|
|
88
|
+
width: min(560px, 100vw);
|
|
89
|
+
}
|
|
90
|
+
|
|
76
91
|
.vmz-ui-drawer[data-vmz-motion-adopt="true"] .vmz-ui-drawer__backdrop,
|
|
77
92
|
.vmz-ui-drawer[data-vmz-motion-adopt="true"] .vmz-ui-drawer__panel {
|
|
78
93
|
animation: none;
|
|
@@ -89,45 +104,103 @@
|
|
|
89
104
|
}
|
|
90
105
|
|
|
91
106
|
.vmz-ui-drawer__panel:focus-visible {
|
|
92
|
-
box-shadow: 0 0 0 3px var(--vmz-focus-ring);
|
|
107
|
+
box-shadow: 0 0 0 3px var(--vmz-focus-ring), var(--vmz-shadow-popup);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.vmz-ui-drawer__header {
|
|
111
|
+
display: flex;
|
|
112
|
+
align-items: flex-start;
|
|
113
|
+
gap: 12px;
|
|
114
|
+
padding: 16px 20px;
|
|
115
|
+
border-bottom: 1px solid var(--vmz-line-subtle);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.vmz-ui-drawer__heading {
|
|
119
|
+
flex: 1 1 auto;
|
|
120
|
+
min-width: 0;
|
|
93
121
|
}
|
|
94
122
|
|
|
95
123
|
.vmz-ui-drawer__title {
|
|
96
|
-
margin: 0
|
|
97
|
-
font-size:
|
|
124
|
+
margin: 0;
|
|
125
|
+
font-size: 16px;
|
|
98
126
|
font-weight: 600;
|
|
127
|
+
line-height: 24px;
|
|
99
128
|
color: var(--vmz-text-ink);
|
|
100
129
|
}
|
|
101
130
|
|
|
102
|
-
.vmz-ui-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
color: var(--vmz-text-
|
|
131
|
+
.vmz-ui-drawer__description {
|
|
132
|
+
margin: 4px 0 0;
|
|
133
|
+
font-size: 14px;
|
|
134
|
+
line-height: 22px;
|
|
135
|
+
color: var(--vmz-text-tertiary);
|
|
107
136
|
}
|
|
108
137
|
|
|
109
138
|
.vmz-ui-drawer__close {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
139
|
+
flex: 0 0 auto;
|
|
140
|
+
display: inline-flex;
|
|
141
|
+
align-items: center;
|
|
142
|
+
justify-content: center;
|
|
143
|
+
width: 32px;
|
|
144
|
+
height: 32px;
|
|
145
|
+
margin: -4px -8px -4px 0;
|
|
146
|
+
padding: 0;
|
|
147
|
+
border: 0;
|
|
148
|
+
border-radius: var(--vmz-radius-md);
|
|
149
|
+
background: transparent;
|
|
150
|
+
color: var(--vmz-text-steel);
|
|
117
151
|
cursor: pointer;
|
|
118
|
-
|
|
119
|
-
|
|
152
|
+
outline: none;
|
|
153
|
+
transition:
|
|
154
|
+
color var(--vmz-motion-control-duration) var(--vmz-motion-control-easing),
|
|
155
|
+
background-color var(--vmz-motion-control-duration) var(--vmz-motion-control-easing);
|
|
120
156
|
}
|
|
121
157
|
|
|
122
158
|
.vmz-ui-drawer__close:hover {
|
|
123
|
-
|
|
124
|
-
|
|
159
|
+
background: var(--vmz-surface-mist);
|
|
160
|
+
color: var(--vmz-text-ink);
|
|
125
161
|
}
|
|
126
162
|
|
|
127
163
|
.vmz-ui-drawer__close:focus-visible {
|
|
128
164
|
box-shadow: 0 0 0 3px var(--vmz-focus-ring);
|
|
129
165
|
}
|
|
130
166
|
|
|
167
|
+
.vmz-ui-drawer__body {
|
|
168
|
+
flex: 1 1 auto;
|
|
169
|
+
min-height: 0;
|
|
170
|
+
padding: 16px 20px;
|
|
171
|
+
overflow: auto;
|
|
172
|
+
font-size: 14px;
|
|
173
|
+
line-height: 22px;
|
|
174
|
+
color: var(--vmz-text-ink);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.vmz-ui-drawer__body :where(a) {
|
|
178
|
+
color: var(--vmz-action-primary-background);
|
|
179
|
+
text-underline-offset: 2px;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.vmz-ui-drawer__body :where(a):hover {
|
|
183
|
+
color: var(--vmz-action-primary-hover);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.vmz-ui-drawer__footer {
|
|
187
|
+
display: flex;
|
|
188
|
+
flex-wrap: wrap;
|
|
189
|
+
align-items: center;
|
|
190
|
+
justify-content: flex-end;
|
|
191
|
+
gap: 8px;
|
|
192
|
+
padding: 12px 20px;
|
|
193
|
+
border-top: 1px solid var(--vmz-line-subtle);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.vmz-ui-drawer__footer:empty {
|
|
197
|
+
display: none;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.vmz-ui-drawer__footer :where(button, a) {
|
|
201
|
+
min-height: var(--vmz-control-height, 32px);
|
|
202
|
+
}
|
|
203
|
+
|
|
131
204
|
@keyframes vmz-ui-drawer-fade-in {
|
|
132
205
|
from {
|
|
133
206
|
opacity: 0;
|
|
@@ -140,7 +213,7 @@
|
|
|
140
213
|
@keyframes vmz-ui-drawer-panel-in {
|
|
141
214
|
from {
|
|
142
215
|
opacity: 0;
|
|
143
|
-
transform: translateX(
|
|
216
|
+
transform: translateX(16px);
|
|
144
217
|
}
|
|
145
218
|
to {
|
|
146
219
|
opacity: 1;
|
|
@@ -164,16 +237,25 @@
|
|
|
164
237
|
}
|
|
165
238
|
to {
|
|
166
239
|
opacity: 0;
|
|
167
|
-
transform: translateX(
|
|
240
|
+
transform: translateX(16px);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
@media (max-width: 720px) {
|
|
245
|
+
.vmz-ui-drawer__panel {
|
|
246
|
+
width: 100vw;
|
|
247
|
+
border-left: 0;
|
|
168
248
|
}
|
|
169
249
|
}
|
|
170
250
|
|
|
171
251
|
@media (prefers-reduced-motion: reduce) {
|
|
172
252
|
.vmz-ui-drawer__backdrop,
|
|
173
253
|
.vmz-ui-drawer__panel,
|
|
254
|
+
.vmz-ui-drawer__close,
|
|
174
255
|
.vmz-ui-drawer[data-vmz-motion-phase="exit"] .vmz-ui-drawer__backdrop,
|
|
175
256
|
.vmz-ui-drawer[data-vmz-motion-phase="exit"] .vmz-ui-drawer__panel {
|
|
176
257
|
animation: none;
|
|
258
|
+
transition: none;
|
|
177
259
|
}
|
|
178
260
|
}
|
|
179
261
|
</style>
|
|
@@ -182,10 +264,19 @@
|
|
|
182
264
|
* VMZ UI — Drawer (UI2).
|
|
183
265
|
* Same overlay ownership / focus / Escape / stack as Dialog.
|
|
184
266
|
* SSR/resume adopt skips enter replay; dismiss plays overlay-exit then calls onClose.
|
|
267
|
+
*
|
|
268
|
+
* Appearance props: `size` (sm 320 / md 420 / lg 560), `description`.
|
|
269
|
+
* Visible copy is author-supplied; `closeLabel` / `dismissLabel` only name the
|
|
270
|
+
* icon button and backdrop for assistive tech.
|
|
185
271
|
*/
|
|
186
272
|
export default class Drawer {
|
|
187
273
|
public open: boolean = false;
|
|
188
|
-
public title: string = "
|
|
274
|
+
public title: string = "";
|
|
275
|
+
public description: string = "";
|
|
276
|
+
/** sm | md | lg */
|
|
277
|
+
public size: string = "md";
|
|
278
|
+
public closeLabel: string = "";
|
|
279
|
+
public dismissLabel: string = "";
|
|
189
280
|
public titleId: string = "vmz-drawer-title";
|
|
190
281
|
public stackLevel: string = "0";
|
|
191
282
|
public onClose: (() => void) | null = null;
|