@vmz/ui 0.3.6 → 0.3.7
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/src/components/Accordion.vmz +94 -94
- package/src/components/AppShell.vmz +5 -2
- 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 +213 -211
- package/src/components/Callout.vmz +77 -77
- package/src/components/Card.vmz +120 -120
- package/src/components/Checkbox.vmz +55 -55
- package/src/components/CodeBlock.vmz +21 -6
- 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 +17 -1
- package/src/components/Drawer.vmz +427 -427
- package/src/components/Dropdown.vmz +51 -5
- 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 +5 -1
- package/src/components/List.vmz +102 -102
- package/src/components/Menu.vmz +243 -243
- package/src/components/Pagination.vmz +71 -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 -165
- package/src/components/Tabs.vmz +110 -110
- package/src/components/Tag.vmz +43 -43
- 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 +1299 -1289
package/src/components/Card.vmz
CHANGED
|
@@ -1,120 +1,120 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<section data-vmz-ui="card" :data-size="size" :data-bordered="bordered ? 'true' : 'false'" :data-hoverable="hoverable ? 'true' : 'false'" class="vmz-ui-card">
|
|
3
|
-
<header v-if="title" class="vmz-ui-card__header">
|
|
4
|
-
<h2 class="vmz-ui-card__title">
|
|
5
|
-
{{ title }}
|
|
6
|
-
</h2>
|
|
7
|
-
<p v-if="description" class="vmz-ui-card__description">
|
|
8
|
-
{{ description }}
|
|
9
|
-
</p>
|
|
10
|
-
</header>
|
|
11
|
-
<div class="vmz-ui-card__body">
|
|
12
|
-
<slot />
|
|
13
|
-
</div>
|
|
14
|
-
</section>
|
|
15
|
-
</template>
|
|
16
|
-
<style>
|
|
17
|
-
.vmz-ui-card {
|
|
18
|
-
display: flex;
|
|
19
|
-
flex-direction: column;
|
|
20
|
-
gap: 0.75rem;
|
|
21
|
-
padding: 1.25rem 1.5rem;
|
|
22
|
-
border: 1px solid var(--vmz-line-subtle, var(--vmz-line-default));
|
|
23
|
-
border-radius: var(--vmz-radius-lg, 8px);
|
|
24
|
-
background: var(--vmz-surface-paper);
|
|
25
|
-
color: var(--vmz-text-ink);
|
|
26
|
-
box-shadow: var(--vmz-shadow-card, none);
|
|
27
|
-
}
|
|
28
|
-
.vmz-ui-card[data-bordered="false"] {
|
|
29
|
-
border-color: transparent;
|
|
30
|
-
}
|
|
31
|
-
.vmz-ui-card[data-hoverable="true"] {
|
|
32
|
-
transition:
|
|
33
|
-
border-color var(--vmz-motion-emphasis-duration, 240ms) var(--vmz-motion-emphasis-easing, cubic-bezier(0.16, 1, 0.3, 1)),
|
|
34
|
-
box-shadow var(--vmz-motion-emphasis-duration, 240ms) var(--vmz-motion-emphasis-easing, cubic-bezier(0.16, 1, 0.3, 1)),
|
|
35
|
-
transform var(--vmz-motion-emphasis-duration, 240ms) var(--vmz-motion-emphasis-easing, cubic-bezier(0.16, 1, 0.3, 1));
|
|
36
|
-
}
|
|
37
|
-
.vmz-ui-card[data-hoverable="true"]:hover {
|
|
38
|
-
border-color: var(--vmz-line-default);
|
|
39
|
-
box-shadow: var(
|
|
40
|
-
--vmz-shadow-card-hover,
|
|
41
|
-
0 1px 2px -2px rgba(0, 0, 0, 0.08),
|
|
42
|
-
0 3px 6px 0 rgba(0, 0, 0, 0.06)
|
|
43
|
-
);
|
|
44
|
-
transform: translateY(-1px);
|
|
45
|
-
}
|
|
46
|
-
.vmz-ui-card[data-hoverable="true"]:focus-within {
|
|
47
|
-
border-color: var(--vmz-action-primary-background);
|
|
48
|
-
}
|
|
49
|
-
@media (prefers-reduced-motion: reduce) {
|
|
50
|
-
.vmz-ui-card[data-hoverable="true"] {
|
|
51
|
-
transition: none;
|
|
52
|
-
}
|
|
53
|
-
.vmz-ui-card[data-hoverable="true"]:hover {
|
|
54
|
-
transform: none;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
.vmz-ui-card[data-size="small"] {
|
|
58
|
-
gap: 0.5rem;
|
|
59
|
-
padding: 0.875rem 1rem;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
:where([data-density="compact"]) .vmz-ui-card {
|
|
63
|
-
gap: var(--vmz-density-compact-gap);
|
|
64
|
-
padding: var(--vmz-density-compact-padding-y) var(--vmz-density-compact-padding-x);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
:where([data-density="dense"]) .vmz-ui-card {
|
|
68
|
-
gap: var(--vmz-density-dense-gap);
|
|
69
|
-
padding: var(--vmz-density-dense-padding-y) var(--vmz-density-dense-padding-x);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
.vmz-ui-card__header {
|
|
73
|
-
display: flex;
|
|
74
|
-
flex-direction: column;
|
|
75
|
-
gap: 0.375rem;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
.vmz-ui-card__title {
|
|
79
|
-
margin: 0;
|
|
80
|
-
font-family: var(--vmz-font-sans, inherit);
|
|
81
|
-
font-size: 1rem;
|
|
82
|
-
font-weight: 600;
|
|
83
|
-
color: var(--vmz-text-ink);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
.vmz-ui-card__description {
|
|
87
|
-
margin: 0;
|
|
88
|
-
color: var(--vmz-text-steel);
|
|
89
|
-
line-height: 1.45;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
.vmz-ui-card__body {
|
|
93
|
-
display: flex;
|
|
94
|
-
flex-direction: column;
|
|
95
|
-
gap: var(--vmz-density-control-gap);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/* Direct host default is display:contents (runtime); Badge-only CSS special-case removed. */
|
|
99
|
-
|
|
100
|
-
:where([data-density="compact"]) .vmz-ui-card__body {
|
|
101
|
-
gap: var(--vmz-density-compact-gap);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
:where([data-density="dense"]) .vmz-ui-card__body {
|
|
105
|
-
gap: var(--vmz-density-dense-gap);
|
|
106
|
-
}
|
|
107
|
-
</style>
|
|
108
|
-
<script client>
|
|
109
|
-
/**
|
|
110
|
-
* VMZ UI — Card (Commercial Surface).
|
|
111
|
-
* Surface container; spacing from density.*; chrome from surface/line/text.
|
|
112
|
-
*/
|
|
113
|
-
export default class Card {
|
|
114
|
-
public title: string = "";
|
|
115
|
-
public description: string = "";
|
|
116
|
-
public size: string = "middle";
|
|
117
|
-
public bordered: boolean = true;
|
|
118
|
-
public hoverable: boolean = false;
|
|
119
|
-
}
|
|
120
|
-
</script>
|
|
1
|
+
<template>
|
|
2
|
+
<section data-vmz-ui="card" :data-size="size" :data-bordered="bordered ? 'true' : 'false'" :data-hoverable="hoverable ? 'true' : 'false'" class="vmz-ui-card">
|
|
3
|
+
<header v-if="title" class="vmz-ui-card__header">
|
|
4
|
+
<h2 class="vmz-ui-card__title">
|
|
5
|
+
{{ title }}
|
|
6
|
+
</h2>
|
|
7
|
+
<p v-if="description" class="vmz-ui-card__description">
|
|
8
|
+
{{ description }}
|
|
9
|
+
</p>
|
|
10
|
+
</header>
|
|
11
|
+
<div class="vmz-ui-card__body">
|
|
12
|
+
<slot />
|
|
13
|
+
</div>
|
|
14
|
+
</section>
|
|
15
|
+
</template>
|
|
16
|
+
<style>
|
|
17
|
+
.vmz-ui-card {
|
|
18
|
+
display: flex;
|
|
19
|
+
flex-direction: column;
|
|
20
|
+
gap: 0.75rem;
|
|
21
|
+
padding: 1.25rem 1.5rem;
|
|
22
|
+
border: 1px solid var(--vmz-line-subtle, var(--vmz-line-default));
|
|
23
|
+
border-radius: var(--vmz-radius-lg, 8px);
|
|
24
|
+
background: var(--vmz-surface-paper);
|
|
25
|
+
color: var(--vmz-text-ink);
|
|
26
|
+
box-shadow: var(--vmz-shadow-card, none);
|
|
27
|
+
}
|
|
28
|
+
.vmz-ui-card[data-bordered="false"] {
|
|
29
|
+
border-color: transparent;
|
|
30
|
+
}
|
|
31
|
+
.vmz-ui-card[data-hoverable="true"] {
|
|
32
|
+
transition:
|
|
33
|
+
border-color var(--vmz-motion-emphasis-duration, 240ms) var(--vmz-motion-emphasis-easing, cubic-bezier(0.16, 1, 0.3, 1)),
|
|
34
|
+
box-shadow var(--vmz-motion-emphasis-duration, 240ms) var(--vmz-motion-emphasis-easing, cubic-bezier(0.16, 1, 0.3, 1)),
|
|
35
|
+
transform var(--vmz-motion-emphasis-duration, 240ms) var(--vmz-motion-emphasis-easing, cubic-bezier(0.16, 1, 0.3, 1));
|
|
36
|
+
}
|
|
37
|
+
.vmz-ui-card[data-hoverable="true"]:hover {
|
|
38
|
+
border-color: var(--vmz-line-default);
|
|
39
|
+
box-shadow: var(
|
|
40
|
+
--vmz-shadow-card-hover,
|
|
41
|
+
0 1px 2px -2px rgba(0, 0, 0, 0.08),
|
|
42
|
+
0 3px 6px 0 rgba(0, 0, 0, 0.06)
|
|
43
|
+
);
|
|
44
|
+
transform: translateY(-1px);
|
|
45
|
+
}
|
|
46
|
+
.vmz-ui-card[data-hoverable="true"]:focus-within {
|
|
47
|
+
border-color: var(--vmz-action-primary-background);
|
|
48
|
+
}
|
|
49
|
+
@media (prefers-reduced-motion: reduce) {
|
|
50
|
+
.vmz-ui-card[data-hoverable="true"] {
|
|
51
|
+
transition: none;
|
|
52
|
+
}
|
|
53
|
+
.vmz-ui-card[data-hoverable="true"]:hover {
|
|
54
|
+
transform: none;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
.vmz-ui-card[data-size="small"] {
|
|
58
|
+
gap: 0.5rem;
|
|
59
|
+
padding: 0.875rem 1rem;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
:where([data-density="compact"]) .vmz-ui-card {
|
|
63
|
+
gap: var(--vmz-density-compact-gap);
|
|
64
|
+
padding: var(--vmz-density-compact-padding-y) var(--vmz-density-compact-padding-x);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
:where([data-density="dense"]) .vmz-ui-card {
|
|
68
|
+
gap: var(--vmz-density-dense-gap);
|
|
69
|
+
padding: var(--vmz-density-dense-padding-y) var(--vmz-density-dense-padding-x);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.vmz-ui-card__header {
|
|
73
|
+
display: flex;
|
|
74
|
+
flex-direction: column;
|
|
75
|
+
gap: 0.375rem;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.vmz-ui-card__title {
|
|
79
|
+
margin: 0;
|
|
80
|
+
font-family: var(--vmz-font-sans, inherit);
|
|
81
|
+
font-size: 1rem;
|
|
82
|
+
font-weight: 600;
|
|
83
|
+
color: var(--vmz-text-ink);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.vmz-ui-card__description {
|
|
87
|
+
margin: 0;
|
|
88
|
+
color: var(--vmz-text-steel);
|
|
89
|
+
line-height: 1.45;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.vmz-ui-card__body {
|
|
93
|
+
display: flex;
|
|
94
|
+
flex-direction: column;
|
|
95
|
+
gap: var(--vmz-density-control-gap);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* Direct host default is display:contents (runtime); Badge-only CSS special-case removed. */
|
|
99
|
+
|
|
100
|
+
:where([data-density="compact"]) .vmz-ui-card__body {
|
|
101
|
+
gap: var(--vmz-density-compact-gap);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
:where([data-density="dense"]) .vmz-ui-card__body {
|
|
105
|
+
gap: var(--vmz-density-dense-gap);
|
|
106
|
+
}
|
|
107
|
+
</style>
|
|
108
|
+
<script client>
|
|
109
|
+
/**
|
|
110
|
+
* VMZ UI — Card (Commercial Surface).
|
|
111
|
+
* Surface container; spacing from density.*; chrome from surface/line/text.
|
|
112
|
+
*/
|
|
113
|
+
export default class Card {
|
|
114
|
+
public title: string = "";
|
|
115
|
+
public description: string = "";
|
|
116
|
+
public size: string = "middle";
|
|
117
|
+
public bordered: boolean = true;
|
|
118
|
+
public hoverable: boolean = false;
|
|
119
|
+
}
|
|
120
|
+
</script>
|
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<label data-vmz-ui="checkbox" :for="controlId" class="vmz-ui-checkbox">
|
|
3
|
-
<input :id="controlId" type="checkbox" :checked="checked" :disabled="disabled" :aria-describedby="describedBy" @change="onToggle" class="vmz-ui-checkbox__input" />
|
|
4
|
-
<span class="vmz-ui-checkbox__label">
|
|
5
|
-
{{ label }}
|
|
6
|
-
</span>
|
|
7
|
-
</label>
|
|
8
|
-
</template>
|
|
9
|
-
<style>
|
|
10
|
-
.vmz-ui-checkbox {
|
|
11
|
-
display: inline-flex;
|
|
12
|
-
align-items: center;
|
|
13
|
-
gap: 0.5rem;
|
|
14
|
-
font: inherit;
|
|
15
|
-
cursor: pointer;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
.vmz-ui-checkbox__input {
|
|
19
|
-
width: 1rem;
|
|
20
|
-
height: 1rem;
|
|
21
|
-
accent-color: var(--vmz-action-primary-background);
|
|
22
|
-
outline: none;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
.vmz-ui-checkbox__input:focus-visible {
|
|
26
|
-
box-shadow: 0 0 0 3px var(--vmz-focus-ring);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.vmz-ui-checkbox__input:disabled {
|
|
30
|
-
opacity: 0.55;
|
|
31
|
-
cursor: not-allowed;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
.vmz-ui-checkbox__label {
|
|
35
|
-
font-weight: 600;
|
|
36
|
-
}
|
|
37
|
-
</style>
|
|
38
|
-
<script client>
|
|
39
|
-
/**
|
|
40
|
-
* VMZ UI — Checkbox (UI2).
|
|
41
|
-
* Label association via wrapping label + for/id; parent owns checked (no parallel form store).
|
|
42
|
-
* Native change reports the committed checked state to the parent.
|
|
43
|
-
*/
|
|
44
|
-
export default class Checkbox {
|
|
45
|
-
public label: string = "";
|
|
46
|
-
public checked: boolean = false;
|
|
47
|
-
public disabled: boolean = false;
|
|
48
|
-
public controlId: string = "vmz-checkbox";
|
|
49
|
-
public describedBy: string = "";
|
|
50
|
-
onToggle(ev) {
|
|
51
|
-
if (this.disabled) return;
|
|
52
|
-
this.emit("change", !!ev?.target?.checked);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
</script>
|
|
1
|
+
<template>
|
|
2
|
+
<label data-vmz-ui="checkbox" :for="controlId" class="vmz-ui-checkbox">
|
|
3
|
+
<input :id="controlId" type="checkbox" :checked="checked" :disabled="disabled" :aria-describedby="describedBy" @change="onToggle" class="vmz-ui-checkbox__input" />
|
|
4
|
+
<span class="vmz-ui-checkbox__label">
|
|
5
|
+
{{ label }}
|
|
6
|
+
</span>
|
|
7
|
+
</label>
|
|
8
|
+
</template>
|
|
9
|
+
<style>
|
|
10
|
+
.vmz-ui-checkbox {
|
|
11
|
+
display: inline-flex;
|
|
12
|
+
align-items: center;
|
|
13
|
+
gap: 0.5rem;
|
|
14
|
+
font: inherit;
|
|
15
|
+
cursor: pointer;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.vmz-ui-checkbox__input {
|
|
19
|
+
width: 1rem;
|
|
20
|
+
height: 1rem;
|
|
21
|
+
accent-color: var(--vmz-action-primary-background);
|
|
22
|
+
outline: none;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.vmz-ui-checkbox__input:focus-visible {
|
|
26
|
+
box-shadow: 0 0 0 3px var(--vmz-focus-ring);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.vmz-ui-checkbox__input:disabled {
|
|
30
|
+
opacity: 0.55;
|
|
31
|
+
cursor: not-allowed;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.vmz-ui-checkbox__label {
|
|
35
|
+
font-weight: 600;
|
|
36
|
+
}
|
|
37
|
+
</style>
|
|
38
|
+
<script client>
|
|
39
|
+
/**
|
|
40
|
+
* VMZ UI — Checkbox (UI2).
|
|
41
|
+
* Label association via wrapping label + for/id; parent owns checked (no parallel form store).
|
|
42
|
+
* Native change reports the committed checked state to the parent.
|
|
43
|
+
*/
|
|
44
|
+
export default class Checkbox {
|
|
45
|
+
public label: string = "";
|
|
46
|
+
public checked: boolean = false;
|
|
47
|
+
public disabled: boolean = false;
|
|
48
|
+
public controlId: string = "vmz-checkbox";
|
|
49
|
+
public describedBy: string = "";
|
|
50
|
+
onToggle(ev) {
|
|
51
|
+
if (this.disabled) return;
|
|
52
|
+
this.emit("change", !!ev?.target?.checked);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
</script>
|
|
@@ -2,11 +2,17 @@
|
|
|
2
2
|
<figure data-vmz-ui="code-block" class="vmz-ui-code-block">
|
|
3
3
|
<div v-if="barVisible()" class="vmz-ui-code-block__bar">
|
|
4
4
|
<div class="vmz-ui-code-block__heading">
|
|
5
|
-
<span v-if="language" class="vmz-ui-code-block__lang">
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
<span v-if="language" class="vmz-ui-code-block__lang">
|
|
6
|
+
{{ language }}
|
|
7
|
+
</span>
|
|
8
|
+
<span v-if="title" class="vmz-ui-code-block__caption">
|
|
9
|
+
{{ title }}
|
|
10
|
+
</span>
|
|
11
|
+
<span v-else-if="caption" class="vmz-ui-code-block__caption">
|
|
12
|
+
{{ caption }}
|
|
13
|
+
</span>
|
|
8
14
|
</div>
|
|
9
|
-
<Button type="button" variant="text" size="sm" class="vmz-ui-code-block__copy"
|
|
15
|
+
<Button v-if="canCopy()" type="button" variant="text" size="sm" @click="onCopy" class="vmz-ui-code-block__copy">
|
|
10
16
|
{{ copyLabel }}
|
|
11
17
|
</Button>
|
|
12
18
|
</div>
|
|
@@ -112,21 +118,30 @@
|
|
|
112
118
|
<script client>
|
|
113
119
|
/**
|
|
114
120
|
* VMZ UI — CodeBlock (Document/Product composition).
|
|
115
|
-
*
|
|
121
|
+
* Readable `<pre><code>` shell: no syntax highlighting (use `<Shiki>` / `<Code>`).
|
|
122
|
+
* `title` wins over legacy `caption`; `language` is a display-only chip.
|
|
123
|
+
* Source and bar are server-rendered; copy is progressive enhancement via onCopy.
|
|
116
124
|
*/
|
|
117
125
|
export default class CodeBlock {
|
|
118
126
|
public code: string = "";
|
|
127
|
+
/** Legacy heading text; kept for existing callers and used when `title` is empty. */
|
|
119
128
|
public caption: string = "";
|
|
120
129
|
/** Preferred heading text; falls back to `caption` when absent. */
|
|
121
130
|
public title: string = "";
|
|
122
131
|
/** Optional syntax label rendered as a chip in the bar (e.g. `ts`, `bash`). */
|
|
123
132
|
public language: string = "";
|
|
133
|
+
/** Visible label of the copy control. */
|
|
124
134
|
public copyLabel: string = "Copy";
|
|
125
135
|
public onCopy: ((e: Event) => void) | null = null;
|
|
126
136
|
|
|
127
137
|
/** The bar renders when there is anything to show in it. */
|
|
128
138
|
public barVisible(): boolean {
|
|
129
|
-
return !!(this.title || this.caption || this.language || this.
|
|
139
|
+
return !!(this.title || this.caption || this.language || this.canCopy());
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** Copy is a real control only when a handler exists; no dead button. */
|
|
143
|
+
public canCopy(): boolean {
|
|
144
|
+
return typeof this.onCopy === "function";
|
|
130
145
|
}
|
|
131
146
|
}
|
|
132
147
|
</script>
|