@vmz/ui 0.3.6 → 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 +53 -51
- 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 +127 -94
- package/src/components/Alert.vmz +125 -28
- package/src/components/AppShell.vmz +125 -57
- package/src/components/Autocomplete.vmz +261 -154
- package/src/components/Avatar.vmz +20 -12
- package/src/components/Badge.vmz +62 -70
- package/src/components/Breadcrumb.vmz +86 -72
- package/src/components/BulkActions.vmz +56 -51
- package/src/components/Button.vmz +237 -211
- package/src/components/Callout.vmz +178 -77
- package/src/components/Card.vmz +141 -120
- package/src/components/Checkbox.vmz +131 -55
- package/src/components/CodeBlock.vmz +77 -30
- package/src/components/Collapse.vmz +64 -11
- package/src/components/ConsoleShell.vmz +405 -251
- package/src/components/Content.vmz +15 -1
- package/src/components/DataTable.vmz +294 -194
- package/src/components/DatePicker.vmz +766 -674
- package/src/components/Descriptions.vmz +90 -0
- package/src/components/Dialog.vmz +137 -38
- package/src/components/Divider.vmz +8 -1
- package/src/components/Drawer.vmz +518 -427
- package/src/components/Dropdown.vmz +195 -51
- package/src/components/Empty.vmz +96 -54
- package/src/components/Field.vmz +170 -115
- 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 +78 -79
- 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 +25 -10
- package/src/components/List.vmz +124 -102
- package/src/components/Menu.vmz +416 -243
- package/src/components/Message.vmz +167 -0
- package/src/components/Notification.vmz +132 -37
- package/src/components/Pagination.vmz +237 -69
- package/src/components/Popconfirm.vmz +287 -0
- package/src/components/Popover.vmz +341 -223
- package/src/components/Progress.vmz +16 -5
- package/src/components/Prose.vmz +180 -81
- package/src/components/QueryForm.vmz +31 -9
- package/src/components/RadioGroup.vmz +204 -124
- package/src/components/Result.vmz +60 -27
- package/src/components/Segmented.vmz +86 -51
- package/src/components/Select.vmz +620 -533
- 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 +118 -103
- package/src/components/Switch.vmz +131 -98
- package/src/components/Table.vmz +270 -165
- package/src/components/Tabs.vmz +125 -110
- package/src/components/Tag.vmz +60 -43
- package/src/components/TextArea.vmz +125 -118
- package/src/components/Timeline.vmz +111 -76
- package/src/components/Toc.vmz +90 -74
- package/src/components/Tooltip.vmz +107 -58
- package/src/components/Tree.vmz +214 -191
- package/src/components/Typography.vmz +23 -8
- package/src/components/Upload.vmz +1394 -1289
package/README.md
CHANGED
|
@@ -1,51 +1,53 @@
|
|
|
1
|
-
# @vmz/ui — VMZ UI
|
|
2
|
-
|
|
3
|
-
Official **VMZ UI** framework package.
|
|
4
|
-
|
|
5
|
-
```text
|
|
6
|
-
VMZ Design ≠ VMZ UI
|
|
7
|
-
/designs ≠ this package
|
|
8
|
-
@vmz/ui ≠ theme truth source
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
- Declares **semantic token requirements** (see `contracts/`).
|
|
12
|
-
- Ships ordinary `.vmz` under **`src/components/`** (same hard convention as apps) — **not** `@vmz/plugin-*`, no
|
|
13
|
-
`componentsRoot` config.
|
|
14
|
-
- **Never** hardcodes brand hex (`#176BFF`, etc.). Applications provide values via `/designs`.
|
|
15
|
-
|
|
16
|
-
## Preview `0.0.4`
|
|
17
|
-
|
|
18
|
-
This is a **preview** release. It is **not** `production-ready` and **not** a mature / production UI.
|
|
19
|
-
|
|
20
|
-
Headline surface for this cut:
|
|
21
|
-
|
|
22
|
-
- Commercial / Console / Document-Product composition on official homepage
|
|
23
|
-
- Form depth, Structure, Overlay stacking, DataTable (ordinary HTML table — not `@vmz/ui-data-grid`)
|
|
24
|
-
- DatePicker owned calendar overlay (not native `input[type=date]` popup)
|
|
25
|
-
- Upload multipart binary (parent-owned FormData → `#server` File/Blob; progress/cancel)
|
|
26
|
-
- Density / RTL / preset materialize
|
|
27
|
-
- Motion continuity + interrupt/cancel
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
pnpm verify -- ui-
|
|
38
|
-
pnpm verify --
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
1
|
+
# @vmz/ui — VMZ UI
|
|
2
|
+
|
|
3
|
+
Official **VMZ UI** framework package.
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
VMZ Design ≠ VMZ UI
|
|
7
|
+
/designs ≠ this package
|
|
8
|
+
@vmz/ui ≠ theme truth source
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
- Declares **semantic token requirements** (see `contracts/`).
|
|
12
|
+
- Ships ordinary `.vmz` under **`src/components/`** (same hard convention as apps) — **not** `@vmz/plugin-*`, no
|
|
13
|
+
`componentsRoot` config.
|
|
14
|
+
- **Never** hardcodes brand hex (`#176BFF`, etc.). Applications provide values via `/designs`.
|
|
15
|
+
|
|
16
|
+
## Preview `0.0.4`
|
|
17
|
+
|
|
18
|
+
This is a **preview** release. It is **not** `production-ready` and **not** a mature / production UI.
|
|
19
|
+
|
|
20
|
+
Headline surface for this cut:
|
|
21
|
+
|
|
22
|
+
- Commercial / Console / Document-Product composition on official homepage
|
|
23
|
+
- Form depth, Structure, Overlay stacking, DataTable (ordinary HTML table — not `@vmz/ui-data-grid`)
|
|
24
|
+
- DatePicker owned calendar overlay (not native `input[type=date]` popup)
|
|
25
|
+
- Upload multipart binary (parent-owned FormData → `#server` File/Blob; progress/cancel)
|
|
26
|
+
- Density / RTL / preset materialize
|
|
27
|
+
- Motion continuity + interrupt/cancel
|
|
28
|
+
- Form rule validation (`Form#rules` + `values` → `invalid`), destructive `Popconfirm`,
|
|
29
|
+
transient `Message`, read-only `Descriptions`
|
|
30
|
+
- Motion compiler IR thin gate (`pnpm verify -- motion-ir`)
|
|
31
|
+
- UI7 conformance pack (`@vmz/ui/conformance` + `pnpm verify -- ui7`)
|
|
32
|
+
- `@vmz/ui-data-grid` thin gate (virtualization + pinned column — not tree/group/pivot/edit)
|
|
33
|
+
|
|
34
|
+
Verify:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pnpm verify -- ui-automation
|
|
38
|
+
pnpm verify -- ui7
|
|
39
|
+
pnpm verify -- ui-data-grid
|
|
40
|
+
pnpm verify -- official-homepage
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Still open relative to Browser Production Profile v1: `browser-production` aggregate core gaps,
|
|
44
|
+
`@vmz/ui-data-grid` deep capabilities, Upload cross-page session / multi-file parallel chunks,
|
|
45
|
+
`@vmz/test` Browser Host U0–U1, sibling `vmz-panel` product app.
|
|
46
|
+
|
|
47
|
+
## Commercial default surface
|
|
48
|
+
|
|
49
|
+
Default web surface targets modern commercial console density: flat 32px-class controls,
|
|
50
|
+
quiet borders, restrained radii, layered page/paper surfaces without Bootstrap-era inset
|
|
51
|
+
fields, accent bars, or card lift. Applications replace every semantic value through `/designs`.
|
|
52
|
+
Additional general-purpose components include layout primitives, typography, segmented controls,
|
|
53
|
+
tags, avatars, dropdowns, collapse panels and progress indicators.
|
|
@@ -192,7 +192,7 @@
|
|
|
192
192
|
"density.control.padding-x"
|
|
193
193
|
],
|
|
194
194
|
"surfaces": ["WebSurface"],
|
|
195
|
-
"contracts": ["submit-reset", "error-summary", "no-parallel-form-store", "novalidate"]
|
|
195
|
+
"contracts": ["submit-reset", "error-summary", "no-parallel-form-store", "novalidate", "rule-validation"]
|
|
196
196
|
},
|
|
197
197
|
"FormItem": {
|
|
198
198
|
"source": "src/components/FormItem.vmz",
|
|
@@ -326,6 +326,63 @@
|
|
|
326
326
|
"overlay-stacking"
|
|
327
327
|
]
|
|
328
328
|
},
|
|
329
|
+
"Popconfirm": {
|
|
330
|
+
"source": "src/components/Popconfirm.vmz",
|
|
331
|
+
"stableHint": "ui.Popconfirm",
|
|
332
|
+
"tokens": [
|
|
333
|
+
"line.subtle",
|
|
334
|
+
"surface.paper",
|
|
335
|
+
"text.ink",
|
|
336
|
+
"text.steel",
|
|
337
|
+
"radius.lg",
|
|
338
|
+
"shadow.popup",
|
|
339
|
+
"status.danger.accent",
|
|
340
|
+
"status.warning.accent",
|
|
341
|
+
"status.info.accent",
|
|
342
|
+
"focus.ring",
|
|
343
|
+
"motion.overlay.duration",
|
|
344
|
+
"motion.overlay.easing"
|
|
345
|
+
],
|
|
346
|
+
"surfaces": ["WebSurface"],
|
|
347
|
+
"contracts": [
|
|
348
|
+
"destructive-confirm",
|
|
349
|
+
"overlay-ownership",
|
|
350
|
+
"outside-dismiss",
|
|
351
|
+
"focus-enter",
|
|
352
|
+
"focus-restore",
|
|
353
|
+
"escape-dismiss",
|
|
354
|
+
"overlay-stacking"
|
|
355
|
+
]
|
|
356
|
+
},
|
|
357
|
+
"Message": {
|
|
358
|
+
"source": "src/components/Message.vmz",
|
|
359
|
+
"stableHint": "ui.Message",
|
|
360
|
+
"tokens": [
|
|
361
|
+
"surface.paper",
|
|
362
|
+
"text.ink",
|
|
363
|
+
"text.steel",
|
|
364
|
+
"text.tertiary",
|
|
365
|
+
"line.subtle",
|
|
366
|
+
"radius.lg",
|
|
367
|
+
"shadow.popup",
|
|
368
|
+
"status.info.accent",
|
|
369
|
+
"status.success.accent",
|
|
370
|
+
"status.warning.accent",
|
|
371
|
+
"status.danger.accent",
|
|
372
|
+
"focus.ring",
|
|
373
|
+
"motion.overlay.duration",
|
|
374
|
+
"motion.overlay.easing"
|
|
375
|
+
],
|
|
376
|
+
"surfaces": ["WebSurface"],
|
|
377
|
+
"contracts": ["transient-feedback", "auto-dismiss", "tone-matrix", "status-tokens"]
|
|
378
|
+
},
|
|
379
|
+
"Descriptions": {
|
|
380
|
+
"source": "src/components/Descriptions.vmz",
|
|
381
|
+
"stableHint": "ui.Descriptions",
|
|
382
|
+
"tokens": ["text.ink", "text.steel", "line.default", "line.subtle", "radius.md"],
|
|
383
|
+
"surfaces": ["WebSurface"],
|
|
384
|
+
"contracts": ["read-only-detail", "column-layout", "no-column-inference"]
|
|
385
|
+
},
|
|
329
386
|
"AppShell": {
|
|
330
387
|
"source": "src/components/AppShell.vmz",
|
|
331
388
|
"stableHint": "ui.AppShell",
|
package/package.json
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"./Content": "./src/components/Content.vmz",
|
|
20
20
|
"./DataTable": "./src/components/DataTable.vmz",
|
|
21
21
|
"./DatePicker": "./src/components/DatePicker.vmz",
|
|
22
|
+
"./Descriptions": "./src/components/Descriptions.vmz",
|
|
22
23
|
"./Dialog": "./src/components/Dialog.vmz",
|
|
23
24
|
"./Divider": "./src/components/Divider.vmz",
|
|
24
25
|
"./Drawer": "./src/components/Drawer.vmz",
|
|
@@ -37,8 +38,10 @@
|
|
|
37
38
|
"./Link": "./src/components/Link.vmz",
|
|
38
39
|
"./List": "./src/components/List.vmz",
|
|
39
40
|
"./Menu": "./src/components/Menu.vmz",
|
|
41
|
+
"./Message": "./src/components/Message.vmz",
|
|
40
42
|
"./Notification": "./src/components/Notification.vmz",
|
|
41
43
|
"./Pagination": "./src/components/Pagination.vmz",
|
|
44
|
+
"./Popconfirm": "./src/components/Popconfirm.vmz",
|
|
42
45
|
"./Popover": "./src/components/Popover.vmz",
|
|
43
46
|
"./Progress": "./src/components/Progress.vmz",
|
|
44
47
|
"./Prose": "./src/components/Prose.vmz",
|
|
@@ -82,7 +85,7 @@
|
|
|
82
85
|
"license": "MIT",
|
|
83
86
|
"name": "@vmz/ui",
|
|
84
87
|
"peerDependencies": {
|
|
85
|
-
"@vmz/ui-icons": "0.3.
|
|
88
|
+
"@vmz/ui-icons": "0.3.8"
|
|
86
89
|
},
|
|
87
90
|
"peerDependenciesMeta": {
|
|
88
91
|
"@vmz/ui-icons": {
|
|
@@ -98,5 +101,5 @@
|
|
|
98
101
|
"url": "git+https://github.com/doki-land/vmz-framework.git"
|
|
99
102
|
},
|
|
100
103
|
"type": "module",
|
|
101
|
-
"version": "0.3.
|
|
104
|
+
"version": "0.3.8"
|
|
102
105
|
}
|
|
@@ -9,29 +9,31 @@
|
|
|
9
9
|
"sm": "4px",
|
|
10
10
|
"md": "6px",
|
|
11
11
|
"lg": "8px",
|
|
12
|
+
"xl": "12px",
|
|
12
13
|
"pill": "999px"
|
|
13
14
|
},
|
|
14
|
-
"controlHeight": { "sm": "1.5rem", "middle": "2rem", "lg": "2.5rem" },
|
|
15
|
+
"controlHeight": { "sm": "1.5rem", "middle": "2rem", "lg": "2.5rem", "mobile": "2.75rem" },
|
|
15
16
|
"layoutMaxWidth": "75rem",
|
|
16
|
-
"surfacePage": "#
|
|
17
|
-
"surfaceFill": "#
|
|
18
|
-
"textTertiary": "#
|
|
19
|
-
"
|
|
20
|
-
"
|
|
17
|
+
"surfacePage": "#F5F6F8",
|
|
18
|
+
"surfaceFill": "#FAFBFC",
|
|
19
|
+
"textTertiary": "#646A73",
|
|
20
|
+
"textMuted": "#8A9099",
|
|
21
|
+
"lineDefault": "#E5E6EB",
|
|
22
|
+
"lineSubtle": "#F0F1F3",
|
|
21
23
|
"shadowCard": "none",
|
|
22
|
-
"shadowCardHover": "
|
|
23
|
-
"shadowPopup": "0
|
|
24
|
+
"shadowCardHover": "none",
|
|
25
|
+
"shadowPopup": "0 12px 32px 0 rgba(15,23,42,.12), 0 2px 8px 0 rgba(15,23,42,.06)",
|
|
24
26
|
"elevation": {
|
|
25
27
|
"note": "Floating layers only. Cards stay flat per visualIntent; interactive surfaces lift on hover, never at rest.",
|
|
26
|
-
"float-sm": "0 1px 2px 0 rgba(
|
|
27
|
-
"float-md": "0
|
|
28
|
-
"float-lg": "0
|
|
28
|
+
"float-sm": "0 1px 2px 0 rgba(15,23,42,.04), 0 1px 4px -1px rgba(15,23,42,.03)",
|
|
29
|
+
"float-md": "0 4px 12px 0 rgba(15,23,42,.08), 0 1px 3px 0 rgba(15,23,42,.04)",
|
|
30
|
+
"float-lg": "0 12px 32px 0 rgba(15,23,42,.12), 0 2px 8px 0 rgba(15,23,42,.06)"
|
|
29
31
|
}
|
|
30
32
|
},
|
|
31
33
|
"density": {
|
|
32
34
|
"control": {
|
|
33
35
|
"padding-y": "0.25rem",
|
|
34
|
-
"padding-x": "0.
|
|
36
|
+
"padding-x": "0.75rem",
|
|
35
37
|
"gap": "0.5rem"
|
|
36
38
|
},
|
|
37
39
|
"compact": {
|
|
@@ -1,94 +1,127 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div data-vmz-ui="accordion" :aria-label="label" class="vmz-ui-accordion">
|
|
3
|
-
<div v-for="item in items" :key="item.id" :data-vmz-accordion="item.id" class="vmz-ui-accordion__item">
|
|
4
|
-
<h3 class="vmz-ui-accordion__heading">
|
|
5
|
-
<button type="button" :id="item.triggerId" :data-vmz-accordion-trigger="item.id" :aria-expanded="openId === item.id ? 'true' : 'false'" :aria-controls="item.panelId" @click="
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
</
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
</
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
1
|
+
<template>
|
|
2
|
+
<div data-vmz-ui="accordion" :aria-label="label" class="vmz-ui-accordion">
|
|
3
|
+
<div v-for="item in items" :key="item.id" :data-vmz-accordion="item.id" class="vmz-ui-accordion__item">
|
|
4
|
+
<h3 class="vmz-ui-accordion__heading">
|
|
5
|
+
<button type="button" :id="item.triggerId" :data-vmz-accordion-trigger="item.id" :aria-expanded="openId === item.id ? 'true' : 'false'" :aria-controls="item.panelId" @click="toggle(item.id)" class="vmz-ui-accordion__trigger">
|
|
6
|
+
<span class="vmz-ui-accordion__title">
|
|
7
|
+
{{ item.title }}
|
|
8
|
+
</span>
|
|
9
|
+
<Icon name="action.chevron-down" size="sm" decorative />
|
|
10
|
+
</button>
|
|
11
|
+
</h3>
|
|
12
|
+
<div v-if="openId === item.id" :id="item.panelId" role="region" :data-vmz-accordion-panel="item.id" :aria-labelledby="item.triggerId" class="vmz-ui-accordion__panel">
|
|
13
|
+
{{ item.body }}
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
</template>
|
|
18
|
+
<style>
|
|
19
|
+
.vmz-ui-accordion {
|
|
20
|
+
display: flex;
|
|
21
|
+
flex-direction: column;
|
|
22
|
+
box-sizing: border-box;
|
|
23
|
+
border: 1px solid var(--vmz-line-default);
|
|
24
|
+
border-radius: var(--vmz-radius-lg);
|
|
25
|
+
background: var(--vmz-surface-paper);
|
|
26
|
+
color: var(--vmz-text-ink);
|
|
27
|
+
overflow: hidden;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.vmz-ui-accordion__item {
|
|
31
|
+
border-bottom: 1px solid var(--vmz-line-subtle);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.vmz-ui-accordion__item:last-child {
|
|
35
|
+
border-bottom: none;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.vmz-ui-accordion__heading {
|
|
39
|
+
margin: 0;
|
|
40
|
+
font: inherit;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.vmz-ui-accordion__trigger {
|
|
44
|
+
display: flex;
|
|
45
|
+
align-items: center;
|
|
46
|
+
gap: 12px;
|
|
47
|
+
width: 100%;
|
|
48
|
+
min-height: 40px;
|
|
49
|
+
box-sizing: border-box;
|
|
50
|
+
text-align: start;
|
|
51
|
+
font: inherit;
|
|
52
|
+
font-size: 14px;
|
|
53
|
+
font-weight: 600;
|
|
54
|
+
line-height: 22px;
|
|
55
|
+
padding: var(--vmz-density-control-padding-y) var(--vmz-density-control-padding-x);
|
|
56
|
+
border: 0;
|
|
57
|
+
background: transparent;
|
|
58
|
+
color: var(--vmz-text-ink);
|
|
59
|
+
cursor: pointer;
|
|
60
|
+
outline: none;
|
|
61
|
+
transition: background-color var(--vmz-motion-control-duration)
|
|
62
|
+
var(--vmz-motion-control-easing);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.vmz-ui-accordion__title {
|
|
66
|
+
flex: 1 1 auto;
|
|
67
|
+
min-width: 0;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.vmz-ui-accordion__trigger .vmz-ui-icon {
|
|
71
|
+
flex: 0 0 auto;
|
|
72
|
+
color: var(--vmz-text-tertiary);
|
|
73
|
+
transition:
|
|
74
|
+
color var(--vmz-motion-control-duration) var(--vmz-motion-control-easing),
|
|
75
|
+
transform var(--vmz-motion-control-duration) var(--vmz-motion-control-easing);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.vmz-ui-accordion__trigger[aria-expanded="true"] .vmz-ui-icon {
|
|
79
|
+
color: var(--vmz-action-primary-active);
|
|
80
|
+
transform: rotate(180deg);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.vmz-ui-accordion__trigger:hover {
|
|
84
|
+
background: var(--vmz-surface-mist);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.vmz-ui-accordion__trigger:focus-visible {
|
|
88
|
+
box-shadow: inset 0 0 0 2px var(--vmz-focus-ring);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.vmz-ui-accordion__panel {
|
|
92
|
+
padding: 0 16px 16px;
|
|
93
|
+
font-size: 14px;
|
|
94
|
+
line-height: 26px;
|
|
95
|
+
color: var(--vmz-text-steel);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
@media (prefers-reduced-motion: reduce) {
|
|
99
|
+
.vmz-ui-accordion__trigger,
|
|
100
|
+
.vmz-ui-accordion__trigger .vmz-ui-icon {
|
|
101
|
+
transition: none;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
</style>
|
|
105
|
+
<script client>
|
|
106
|
+
/**
|
|
107
|
+
* VMZ UI — Accordion.
|
|
108
|
+
* Exclusive open: parent owns `openId`. Toggle same id closes.
|
|
109
|
+
* Panel body lives on items (no per-panel slot runtime).
|
|
110
|
+
*/
|
|
111
|
+
export default class Accordion {
|
|
112
|
+
public label: string = "";
|
|
113
|
+
public openId: string = "";
|
|
114
|
+
/** @type {{ id: string, title: string, body: string, triggerId: string, panelId: string }[]} */
|
|
115
|
+
public items: {
|
|
116
|
+
id: string;
|
|
117
|
+
title: string;
|
|
118
|
+
body: string;
|
|
119
|
+
triggerId: string;
|
|
120
|
+
panelId: string;
|
|
121
|
+
}[] = [];
|
|
122
|
+
public onToggle: ((id: string) => void) | null = null;
|
|
123
|
+
toggle(id) {
|
|
124
|
+
if (typeof this.onToggle === "function") this.onToggle(id);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
</script>
|