@vmz/ui 0.3.5 → 0.3.6
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 +51 -51
- package/package.json +2 -2
- package/presets/web-surface.v0.json +19 -7
- package/src/components/Accordion.vmz +94 -94
- package/src/components/AppShell.vmz +77 -33
- package/src/components/Autocomplete.vmz +154 -154
- package/src/components/Badge.vmz +70 -70
- package/src/components/Breadcrumb.vmz +72 -72
- package/src/components/BulkActions.vmz +51 -51
- package/src/components/Button.vmz +211 -192
- package/src/components/Callout.vmz +77 -77
- package/src/components/Card.vmz +120 -106
- package/src/components/Checkbox.vmz +55 -55
- package/src/components/CodeBlock.vmz +77 -18
- package/src/components/ConsoleShell.vmz +251 -251
- package/src/components/DataTable.vmz +194 -194
- package/src/components/DatePicker.vmz +674 -674
- package/src/components/Dialog.vmz +10 -7
- package/src/components/Drawer.vmz +427 -427
- package/src/components/Dropdown.vmz +135 -16
- package/src/components/Empty.vmz +54 -54
- package/src/components/Field.vmz +115 -115
- package/src/components/FormItem.vmz +79 -79
- package/src/components/Link.vmz +34 -4
- package/src/components/List.vmz +102 -102
- package/src/components/Menu.vmz +243 -243
- package/src/components/Pagination.vmz +69 -69
- package/src/components/Popover.vmz +223 -223
- package/src/components/Prose.vmz +81 -81
- package/src/components/RadioGroup.vmz +124 -124
- package/src/components/Segmented.vmz +51 -51
- package/src/components/Select.vmz +533 -533
- package/src/components/Steps.vmz +103 -103
- package/src/components/Switch.vmz +98 -98
- package/src/components/Table.vmz +165 -133
- package/src/components/Tabs.vmz +110 -110
- package/src/components/Tag.vmz +43 -40
- package/src/components/TextArea.vmz +118 -118
- package/src/components/Timeline.vmz +76 -76
- package/src/components/Toc.vmz +74 -74
- package/src/components/Tooltip.vmz +58 -58
- package/src/components/Tree.vmz +191 -191
- package/src/components/Upload.vmz +1289 -1289
|
@@ -1,124 +1,124 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<fieldset data-vmz-ui="radio-group" :data-invalid="invalidAttr" :aria-describedby="describedBy" :disabled="disabled" class="vmz-ui-radio-group">
|
|
3
|
-
<legend class="vmz-ui-radio-group__legend">
|
|
4
|
-
{{ label }}
|
|
5
|
-
</legend>
|
|
6
|
-
<div role="radiogroup" :aria-label="label" @click="onListClick" class="vmz-ui-radio-group__list">
|
|
7
|
-
<label v-for="item in items" :key="item.value" :for="item.id" class="vmz-ui-radio-group__option">
|
|
8
|
-
<input :id="item.id" type="radio" :name="name" :value="item.value" :checked="value === item.value" :disabled="disabled" :data-vmz-radio="item.value" class="vmz-ui-radio-group__input" />
|
|
9
|
-
<span class="vmz-ui-radio-group__text">
|
|
10
|
-
{{ item.label }}
|
|
11
|
-
</span>
|
|
12
|
-
</label>
|
|
13
|
-
</div>
|
|
14
|
-
<p v-if="description" :id="descriptionId" class="vmz-ui-radio-group__description">
|
|
15
|
-
{{ description }}
|
|
16
|
-
</p>
|
|
17
|
-
<p v-if="error" :id="errorId" role="alert" class="vmz-ui-radio-group__error">
|
|
18
|
-
{{ error }}
|
|
19
|
-
</p>
|
|
20
|
-
</fieldset>
|
|
21
|
-
</template>
|
|
22
|
-
<style>
|
|
23
|
-
.vmz-ui-radio-group {
|
|
24
|
-
display: flex;
|
|
25
|
-
flex-direction: column;
|
|
26
|
-
gap: 0.
|
|
27
|
-
max-width: 28rem;
|
|
28
|
-
margin: 0;
|
|
29
|
-
padding: 0;
|
|
30
|
-
border: 0;
|
|
31
|
-
min-width: 0;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
.vmz-ui-radio-group__legend {
|
|
35
|
-
padding: 0;
|
|
36
|
-
font: inherit;
|
|
37
|
-
font-weight: 600;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
.vmz-ui-radio-group__list {
|
|
41
|
-
display: flex;
|
|
42
|
-
flex-direction: column;
|
|
43
|
-
gap: 0.
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
.vmz-ui-radio-group__option {
|
|
47
|
-
display: inline-flex;
|
|
48
|
-
align-items: center;
|
|
49
|
-
gap: 0.
|
|
50
|
-
font: inherit;
|
|
51
|
-
cursor: pointer;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
.vmz-ui-radio-group__input {
|
|
55
|
-
width: 1rem;
|
|
56
|
-
height: 1rem;
|
|
57
|
-
accent-color: var(--vmz-action-primary-background);
|
|
58
|
-
outline: none;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
.vmz-ui-radio-group__input:focus-visible {
|
|
62
|
-
box-shadow: 0 0 0
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
.vmz-ui-radio-group__input:disabled {
|
|
66
|
-
opacity: 0.55;
|
|
67
|
-
cursor: not-allowed;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
.vmz-ui-radio-group__text {
|
|
71
|
-
font-weight: 600;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
.vmz-ui-radio-group__description {
|
|
75
|
-
margin: 0;
|
|
76
|
-
opacity: 0.75;
|
|
77
|
-
font-size: 0.9em;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
.vmz-ui-radio-group__error {
|
|
81
|
-
margin: 0;
|
|
82
|
-
color: var(--vmz-status-danger-foreground);
|
|
83
|
-
font-size: 0.9em;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
.vmz-ui-radio-group[data-invalid="true"] .vmz-ui-radio-group__legend {
|
|
87
|
-
color: var(--vmz-status-danger-foreground);
|
|
88
|
-
}
|
|
89
|
-
</style>
|
|
90
|
-
<script client>
|
|
91
|
-
/**
|
|
92
|
-
* VMZ UI — RadioGroup.
|
|
93
|
-
* Parent owns selected value; click path updates via onChange (live prop remains authoritative).
|
|
94
|
-
*/
|
|
95
|
-
export default class RadioGroup {
|
|
96
|
-
public label: string = "";
|
|
97
|
-
public description: string = "";
|
|
98
|
-
public error: string = "";
|
|
99
|
-
public name: string = "vmz-radio";
|
|
100
|
-
public value: string = "";
|
|
101
|
-
public items: Array<{
|
|
102
|
-
id: string;
|
|
103
|
-
value: string;
|
|
104
|
-
label: string;
|
|
105
|
-
}> = [];
|
|
106
|
-
public disabled: boolean = false;
|
|
107
|
-
public invalidAttr: string = "false";
|
|
108
|
-
public descriptionId: string = "vmz-radio-desc";
|
|
109
|
-
public errorId: string = "vmz-radio-err";
|
|
110
|
-
public describedBy: string = "";
|
|
111
|
-
public onChange: ((value: string) => void) | null = null;
|
|
112
|
-
onListClick(ev) {
|
|
113
|
-
if (this.disabled) return;
|
|
114
|
-
const t = ev && ev.target;
|
|
115
|
-
if (!t || typeof t.closest !== "function") return;
|
|
116
|
-
const input = t.closest("input[data-vmz-radio]");
|
|
117
|
-
if (!input) return;
|
|
118
|
-
const next = input.getAttribute("data-vmz-radio") || input.value || "";
|
|
119
|
-
if (!next || next === this.value) return;
|
|
120
|
-
this.emit("change", next);
|
|
121
|
-
if (typeof this.onChange === "function") this.onChange(next);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
</script>
|
|
1
|
+
<template>
|
|
2
|
+
<fieldset data-vmz-ui="radio-group" :data-invalid="invalidAttr" :aria-describedby="describedBy" :disabled="disabled" class="vmz-ui-radio-group">
|
|
3
|
+
<legend class="vmz-ui-radio-group__legend">
|
|
4
|
+
{{ label }}
|
|
5
|
+
</legend>
|
|
6
|
+
<div role="radiogroup" :aria-label="label" @click="onListClick" class="vmz-ui-radio-group__list">
|
|
7
|
+
<label v-for="item in items" :key="item.value" :for="item.id" class="vmz-ui-radio-group__option">
|
|
8
|
+
<input :id="item.id" type="radio" :name="name" :value="item.value" :checked="value === item.value" :disabled="disabled" :data-vmz-radio="item.value" class="vmz-ui-radio-group__input" />
|
|
9
|
+
<span class="vmz-ui-radio-group__text">
|
|
10
|
+
{{ item.label }}
|
|
11
|
+
</span>
|
|
12
|
+
</label>
|
|
13
|
+
</div>
|
|
14
|
+
<p v-if="description" :id="descriptionId" class="vmz-ui-radio-group__description">
|
|
15
|
+
{{ description }}
|
|
16
|
+
</p>
|
|
17
|
+
<p v-if="error" :id="errorId" role="alert" class="vmz-ui-radio-group__error">
|
|
18
|
+
{{ error }}
|
|
19
|
+
</p>
|
|
20
|
+
</fieldset>
|
|
21
|
+
</template>
|
|
22
|
+
<style>
|
|
23
|
+
.vmz-ui-radio-group {
|
|
24
|
+
display: flex;
|
|
25
|
+
flex-direction: column;
|
|
26
|
+
gap: 0.5rem;
|
|
27
|
+
max-width: 28rem;
|
|
28
|
+
margin: 0;
|
|
29
|
+
padding: 0;
|
|
30
|
+
border: 0;
|
|
31
|
+
min-width: 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.vmz-ui-radio-group__legend {
|
|
35
|
+
padding: 0;
|
|
36
|
+
font: inherit;
|
|
37
|
+
font-weight: 600;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.vmz-ui-radio-group__list {
|
|
41
|
+
display: flex;
|
|
42
|
+
flex-direction: column;
|
|
43
|
+
gap: 0.375rem;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.vmz-ui-radio-group__option {
|
|
47
|
+
display: inline-flex;
|
|
48
|
+
align-items: center;
|
|
49
|
+
gap: 0.5rem;
|
|
50
|
+
font: inherit;
|
|
51
|
+
cursor: pointer;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.vmz-ui-radio-group__input {
|
|
55
|
+
width: 1rem;
|
|
56
|
+
height: 1rem;
|
|
57
|
+
accent-color: var(--vmz-action-primary-background);
|
|
58
|
+
outline: none;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.vmz-ui-radio-group__input:focus-visible {
|
|
62
|
+
box-shadow: 0 0 0 3px var(--vmz-focus-ring);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.vmz-ui-radio-group__input:disabled {
|
|
66
|
+
opacity: 0.55;
|
|
67
|
+
cursor: not-allowed;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.vmz-ui-radio-group__text {
|
|
71
|
+
font-weight: 600;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.vmz-ui-radio-group__description {
|
|
75
|
+
margin: 0;
|
|
76
|
+
opacity: 0.75;
|
|
77
|
+
font-size: 0.9em;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.vmz-ui-radio-group__error {
|
|
81
|
+
margin: 0;
|
|
82
|
+
color: var(--vmz-status-danger-foreground);
|
|
83
|
+
font-size: 0.9em;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.vmz-ui-radio-group[data-invalid="true"] .vmz-ui-radio-group__legend {
|
|
87
|
+
color: var(--vmz-status-danger-foreground);
|
|
88
|
+
}
|
|
89
|
+
</style>
|
|
90
|
+
<script client>
|
|
91
|
+
/**
|
|
92
|
+
* VMZ UI — RadioGroup.
|
|
93
|
+
* Parent owns selected value; click path updates via onChange (live prop remains authoritative).
|
|
94
|
+
*/
|
|
95
|
+
export default class RadioGroup {
|
|
96
|
+
public label: string = "";
|
|
97
|
+
public description: string = "";
|
|
98
|
+
public error: string = "";
|
|
99
|
+
public name: string = "vmz-radio";
|
|
100
|
+
public value: string = "";
|
|
101
|
+
public items: Array<{
|
|
102
|
+
id: string;
|
|
103
|
+
value: string;
|
|
104
|
+
label: string;
|
|
105
|
+
}> = [];
|
|
106
|
+
public disabled: boolean = false;
|
|
107
|
+
public invalidAttr: string = "false";
|
|
108
|
+
public descriptionId: string = "vmz-radio-desc";
|
|
109
|
+
public errorId: string = "vmz-radio-err";
|
|
110
|
+
public describedBy: string = "";
|
|
111
|
+
public onChange: ((value: string) => void) | null = null;
|
|
112
|
+
onListClick(ev) {
|
|
113
|
+
if (this.disabled) return;
|
|
114
|
+
const t = ev && ev.target;
|
|
115
|
+
if (!t || typeof t.closest !== "function") return;
|
|
116
|
+
const input = t.closest("input[data-vmz-radio]");
|
|
117
|
+
if (!input) return;
|
|
118
|
+
const next = input.getAttribute("data-vmz-radio") || input.value || "";
|
|
119
|
+
if (!next || next === this.value) return;
|
|
120
|
+
this.emit("change", next);
|
|
121
|
+
if (typeof this.onChange === "function") this.onChange(next);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
</script>
|
|
@@ -1,51 +1,51 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div data-vmz-ui="segmented" role="group" :aria-label="label" class="vmz-ui-segmented">
|
|
3
|
-
<button v-for="opt in options" :key="opt.value" type="button" :data-vmz-segment="opt.value" :aria-pressed="opt.value === value ? 'true' : 'false'" @click="(() => onPick(opt.value))">
|
|
4
|
-
{{ opt.label }}
|
|
5
|
-
</button>
|
|
6
|
-
</div>
|
|
7
|
-
</template>
|
|
8
|
-
<style>
|
|
9
|
-
.vmz-ui-segmented {
|
|
10
|
-
display: inline-flex;
|
|
11
|
-
max-width: 100%;
|
|
12
|
-
padding: 0.2rem;
|
|
13
|
-
border-radius: var(--vmz-radius-md, 6px);
|
|
14
|
-
background: var(--vmz-surface-mist);
|
|
15
|
-
overflow-x: auto;
|
|
16
|
-
}
|
|
17
|
-
.vmz-ui-segmented button {
|
|
18
|
-
min-height: 2rem;
|
|
19
|
-
padding: 0.
|
|
20
|
-
border: 0;
|
|
21
|
-
border-radius: calc(var(--vmz-radius-md, 6px) - 2px);
|
|
22
|
-
background: transparent;
|
|
23
|
-
color: var(--vmz-text-steel);
|
|
24
|
-
font: inherit;
|
|
25
|
-
font-size: 0.875rem;
|
|
26
|
-
font-weight: 550;
|
|
27
|
-
white-space: nowrap;
|
|
28
|
-
cursor: pointer;
|
|
29
|
-
}
|
|
30
|
-
.vmz-ui-segmented button[aria-pressed="true"] {
|
|
31
|
-
background: var(--vmz-surface-paper);
|
|
32
|
-
color: var(--vmz-text-ink);
|
|
33
|
-
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
34
|
-
}
|
|
35
|
-
.vmz-ui-segmented button:focus-visible {
|
|
36
|
-
outline: 2px solid var(--vmz-focus-ring);
|
|
37
|
-
outline-offset: -2px;
|
|
38
|
-
}
|
|
39
|
-
</style>
|
|
40
|
-
<script client>
|
|
41
|
-
export default class Segmented {
|
|
42
|
-
public label: string = "Segments";
|
|
43
|
-
public value: string = "";
|
|
44
|
-
public options: Array<{ value: string; label: string }> = [];
|
|
45
|
-
public onChange: ((value: string) => void) | null = null;
|
|
46
|
-
onPick(next: string) {
|
|
47
|
-
this.emit("change", next);
|
|
48
|
-
if (typeof this.onChange === "function") this.onChange(next);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
</script>
|
|
1
|
+
<template>
|
|
2
|
+
<div data-vmz-ui="segmented" role="group" :aria-label="label" class="vmz-ui-segmented">
|
|
3
|
+
<button v-for="opt in options" :key="opt.value" type="button" :data-vmz-segment="opt.value" :aria-pressed="opt.value === value ? 'true' : 'false'" @click="(() => onPick(opt.value))">
|
|
4
|
+
{{ opt.label }}
|
|
5
|
+
</button>
|
|
6
|
+
</div>
|
|
7
|
+
</template>
|
|
8
|
+
<style>
|
|
9
|
+
.vmz-ui-segmented {
|
|
10
|
+
display: inline-flex;
|
|
11
|
+
max-width: 100%;
|
|
12
|
+
padding: 0.2rem;
|
|
13
|
+
border-radius: var(--vmz-radius-md, 6px);
|
|
14
|
+
background: var(--vmz-surface-mist);
|
|
15
|
+
overflow-x: auto;
|
|
16
|
+
}
|
|
17
|
+
.vmz-ui-segmented button {
|
|
18
|
+
min-height: 2rem;
|
|
19
|
+
padding: 0.25rem 0.75rem;
|
|
20
|
+
border: 0;
|
|
21
|
+
border-radius: calc(var(--vmz-radius-md, 6px) - 2px);
|
|
22
|
+
background: transparent;
|
|
23
|
+
color: var(--vmz-text-steel);
|
|
24
|
+
font: inherit;
|
|
25
|
+
font-size: 0.875rem;
|
|
26
|
+
font-weight: 550;
|
|
27
|
+
white-space: nowrap;
|
|
28
|
+
cursor: pointer;
|
|
29
|
+
}
|
|
30
|
+
.vmz-ui-segmented button[aria-pressed="true"] {
|
|
31
|
+
background: var(--vmz-surface-paper);
|
|
32
|
+
color: var(--vmz-text-ink);
|
|
33
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
34
|
+
}
|
|
35
|
+
.vmz-ui-segmented button:focus-visible {
|
|
36
|
+
outline: 2px solid var(--vmz-focus-ring);
|
|
37
|
+
outline-offset: -2px;
|
|
38
|
+
}
|
|
39
|
+
</style>
|
|
40
|
+
<script client>
|
|
41
|
+
export default class Segmented {
|
|
42
|
+
public label: string = "Segments";
|
|
43
|
+
public value: string = "";
|
|
44
|
+
public options: Array<{ value: string; label: string }> = [];
|
|
45
|
+
public onChange: ((value: string) => void) | null = null;
|
|
46
|
+
onPick(next: string) {
|
|
47
|
+
this.emit("change", next);
|
|
48
|
+
if (typeof this.onChange === "function") this.onChange(next);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
</script>
|