@vmz/ui 0.2.2 → 0.2.4
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 +183 -94
- 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,27 +1,61 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
</
|
|
12
|
-
</details>
|
|
2
|
+
<details data-vmz-ui="dropdown" class="vmz-ui-dropdown">
|
|
3
|
+
<summary data-vmz-dropdown-trigger="1">
|
|
4
|
+
{{ label }}
|
|
5
|
+
</summary>
|
|
6
|
+
<div data-vmz-dropdown-menu="1" class="vmz-ui-dropdown__menu">
|
|
7
|
+
<a v-for="item in items" :key="item.id" :href="item.href" :data-vmz-dropdown-item="item.id">
|
|
8
|
+
{{ item.title }}
|
|
9
|
+
</a>
|
|
10
|
+
</div>
|
|
11
|
+
</details>
|
|
13
12
|
</template>
|
|
14
13
|
<style>
|
|
15
|
-
.vmz-ui-dropdown{
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
.vmz-ui-
|
|
20
|
-
|
|
14
|
+
.vmz-ui-dropdown {
|
|
15
|
+
position: relative;
|
|
16
|
+
display: inline-block;
|
|
17
|
+
}
|
|
18
|
+
.vmz-ui-dropdown summary {
|
|
19
|
+
list-style: none;
|
|
20
|
+
min-height: 2.5rem;
|
|
21
|
+
display: inline-flex;
|
|
22
|
+
align-items: center;
|
|
23
|
+
padding: 0 0.85rem;
|
|
24
|
+
border: 1px solid var(--vmz-line-default);
|
|
25
|
+
border-radius: var(--vmz-radius-md, 6px);
|
|
26
|
+
background: var(--vmz-surface-paper);
|
|
27
|
+
cursor: pointer;
|
|
28
|
+
font-weight: 550;
|
|
29
|
+
}
|
|
30
|
+
.vmz-ui-dropdown summary::-webkit-details-marker {
|
|
31
|
+
display: none;
|
|
32
|
+
}
|
|
33
|
+
.vmz-ui-dropdown__menu {
|
|
34
|
+
position: absolute;
|
|
35
|
+
top: calc(100% + 0.35rem);
|
|
36
|
+
right: 0;
|
|
37
|
+
z-index: 50;
|
|
38
|
+
min-width: 11rem;
|
|
39
|
+
padding: 0.3rem;
|
|
40
|
+
border: 1px solid var(--vmz-line-default);
|
|
41
|
+
border-radius: var(--vmz-radius-lg, 8px);
|
|
42
|
+
background: var(--vmz-surface-paper);
|
|
43
|
+
box-shadow: var(--vmz-shadow-popup);
|
|
44
|
+
}
|
|
45
|
+
.vmz-ui-dropdown__menu a {
|
|
46
|
+
display: block;
|
|
47
|
+
padding: 0.55rem 0.7rem;
|
|
48
|
+
border-radius: var(--vmz-radius-sm, 2px);
|
|
49
|
+
color: var(--vmz-text-ink);
|
|
50
|
+
text-decoration: none;
|
|
51
|
+
}
|
|
52
|
+
.vmz-ui-dropdown__menu a:hover {
|
|
53
|
+
background: var(--vmz-surface-mist);
|
|
54
|
+
}
|
|
21
55
|
</style>
|
|
22
56
|
<script client>
|
|
23
57
|
export default class Dropdown {
|
|
24
|
-
|
|
25
|
-
|
|
58
|
+
public label: string = "Menu";
|
|
59
|
+
public items: Array<{ id: string; title: string; href: string }> = [];
|
|
26
60
|
}
|
|
27
61
|
</script>
|
package/src/components/Empty.vmz
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
<
|
|
7
|
-
|
|
2
|
+
<div data-vmz-ui="empty" class="vmz-ui-empty">
|
|
3
|
+
<h2 class="vmz-ui-empty__title">
|
|
4
|
+
{{ title }}
|
|
5
|
+
</h2>
|
|
6
|
+
<p v-if="description" class="vmz-ui-empty__description">
|
|
7
|
+
{{ description }}
|
|
8
|
+
</p>
|
|
9
|
+
<div class="vmz-ui-empty__actions">
|
|
10
|
+
<slot />
|
|
11
|
+
</div>
|
|
8
12
|
</div>
|
|
9
13
|
</template>
|
|
10
|
-
|
|
11
14
|
<style>
|
|
12
|
-
|
|
15
|
+
.vmz-ui-empty {
|
|
13
16
|
display: flex;
|
|
14
17
|
flex-direction: column;
|
|
15
18
|
align-items: flex-start;
|
|
@@ -19,34 +22,33 @@
|
|
|
19
22
|
border-radius: var(--vmz-radius-md, 6px);
|
|
20
23
|
background: color-mix(in srgb, var(--vmz-surface-mist) 70%, var(--vmz-surface-paper));
|
|
21
24
|
color: var(--vmz-text-ink);
|
|
22
|
-
|
|
25
|
+
}
|
|
23
26
|
|
|
24
|
-
|
|
27
|
+
.vmz-ui-empty__title {
|
|
25
28
|
margin: 0;
|
|
26
29
|
font-family: var(--vmz-font-display);
|
|
27
30
|
font-size: 1.1rem;
|
|
28
31
|
font-weight: 700;
|
|
29
|
-
|
|
32
|
+
}
|
|
30
33
|
|
|
31
|
-
|
|
34
|
+
.vmz-ui-empty__description {
|
|
32
35
|
margin: 0;
|
|
33
36
|
color: var(--vmz-text-steel);
|
|
34
37
|
max-width: 36rem;
|
|
35
38
|
line-height: 1.45;
|
|
36
|
-
|
|
39
|
+
}
|
|
37
40
|
|
|
38
|
-
|
|
41
|
+
.vmz-ui-empty__actions:empty {
|
|
39
42
|
display: none;
|
|
40
|
-
|
|
43
|
+
}
|
|
41
44
|
</style>
|
|
42
|
-
|
|
43
45
|
<script client>
|
|
44
46
|
/**
|
|
45
|
-
* VMZ UI — Empty (Commercial composition).
|
|
46
|
-
* Empty / zero-state surface with optional action slot.
|
|
47
|
-
*/
|
|
47
|
+
* VMZ UI — Empty (Commercial composition).
|
|
48
|
+
* Empty / zero-state surface with optional action slot.
|
|
49
|
+
*/
|
|
48
50
|
export default class Empty {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
+
public title: string = "Nothing here yet";
|
|
52
|
+
public description: string = "";
|
|
51
53
|
}
|
|
52
54
|
</script>
|
package/src/components/Field.vmz
CHANGED
|
@@ -1,121 +1,115 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class="vmz-ui-field__control"
|
|
7
|
-
:
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
:
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
:aria-invalid="error ? 'true' : 'false'"
|
|
14
|
-
:aria-describedby="describedBy"
|
|
15
|
-
@input="onDomInput"
|
|
16
|
-
/>
|
|
17
|
-
<p v-if="description" :id="descriptionId" class="vmz-ui-field__description">{{ description }}</p>
|
|
18
|
-
<p v-if="error" :id="errorId" class="vmz-ui-field__error" role="alert">{{ error }}</p>
|
|
2
|
+
<div data-vmz-ui="field" :data-invalid="invalidAttr" class="vmz-ui-field">
|
|
3
|
+
<label v-if="label" :for="controlId" class="vmz-ui-field__label">
|
|
4
|
+
{{ label }}
|
|
5
|
+
</label>
|
|
6
|
+
<input :id="controlId" :type="type" :value="value" :min="min" :max="max" :step="step" :disabled="disabled" :aria-invalid='error ? "true" : "false"' :aria-describedby="describedBy" @input="onDomInput" class="vmz-ui-field__control" />
|
|
7
|
+
<p v-if="description" :id="descriptionId" class="vmz-ui-field__description">
|
|
8
|
+
{{ description }}
|
|
9
|
+
</p>
|
|
10
|
+
<p v-if="error" :id="errorId" role="alert" class="vmz-ui-field__error">
|
|
11
|
+
{{ error }}
|
|
12
|
+
</p>
|
|
19
13
|
</div>
|
|
20
14
|
</template>
|
|
21
|
-
|
|
22
15
|
<style>
|
|
23
16
|
.vmz-ui-field {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
gap: 0.35rem;
|
|
20
|
+
max-width: 28rem;
|
|
28
21
|
}
|
|
29
22
|
|
|
30
23
|
.vmz-ui-field__label {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
24
|
+
font: inherit;
|
|
25
|
+
font-weight: 500;
|
|
26
|
+
font-size: 0.875rem;
|
|
27
|
+
color: var(--vmz-text-ink, inherit);
|
|
35
28
|
}
|
|
36
29
|
|
|
37
30
|
.vmz-ui-field__control {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
31
|
+
box-sizing: border-box;
|
|
32
|
+
width: 100%;
|
|
33
|
+
min-height: var(--vmz-control-height, 2rem);
|
|
34
|
+
font-family: var(--vmz-font-sans, inherit);
|
|
35
|
+
font-size: 0.875rem;
|
|
36
|
+
line-height: 1.5715;
|
|
37
|
+
padding: var(--vmz-density-control-padding-y, 0.25rem)
|
|
38
|
+
var(--vmz-density-control-padding-x, 0.75rem);
|
|
39
|
+
border: 1px solid var(--vmz-line-default, #d9d9d9);
|
|
40
|
+
border-radius: var(--vmz-radius-md, 6px);
|
|
41
|
+
background: var(--vmz-surface-paper, #fff);
|
|
42
|
+
color: var(--vmz-text-ink, inherit);
|
|
43
|
+
outline: none;
|
|
44
|
+
transition:
|
|
45
|
+
border-color var(--vmz-motion-control-duration, 120ms)
|
|
46
|
+
var(--vmz-motion-control-easing, linear),
|
|
47
|
+
box-shadow var(--vmz-motion-control-duration, 120ms)
|
|
48
|
+
var(--vmz-motion-control-easing, linear);
|
|
54
49
|
}
|
|
55
50
|
|
|
56
51
|
.vmz-ui-field__control::placeholder {
|
|
57
|
-
|
|
58
|
-
|
|
52
|
+
color: var(--vmz-text-steel, #8c8c8c);
|
|
53
|
+
opacity: 1;
|
|
59
54
|
}
|
|
60
55
|
|
|
61
|
-
.vmz-ui-field[data-invalid=
|
|
62
|
-
|
|
56
|
+
.vmz-ui-field[data-invalid="true"] .vmz-ui-field__control {
|
|
57
|
+
border-color: var(--vmz-status-danger-accent);
|
|
63
58
|
}
|
|
64
59
|
|
|
65
60
|
.vmz-ui-field__control:hover:not(:disabled):not(:focus-visible) {
|
|
66
|
-
|
|
61
|
+
border-color: var(--vmz-action-primary-background);
|
|
67
62
|
}
|
|
68
63
|
|
|
69
64
|
.vmz-ui-field__control:focus-visible {
|
|
70
|
-
|
|
71
|
-
|
|
65
|
+
border-color: var(--vmz-action-primary-background);
|
|
66
|
+
box-shadow: 0 0 0 2px var(--vmz-focus-ring);
|
|
72
67
|
}
|
|
73
68
|
|
|
74
69
|
.vmz-ui-field__control:disabled {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
70
|
+
opacity: 0.55;
|
|
71
|
+
cursor: not-allowed;
|
|
72
|
+
background: var(--vmz-surface-mist, #fafafa);
|
|
78
73
|
}
|
|
79
74
|
|
|
80
75
|
.vmz-ui-field__description {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
76
|
+
margin: 0;
|
|
77
|
+
color: var(--vmz-text-steel, #8c8c8c);
|
|
78
|
+
font-size: 0.875rem;
|
|
79
|
+
line-height: 1.4;
|
|
85
80
|
}
|
|
86
81
|
|
|
87
82
|
.vmz-ui-field__error {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
83
|
+
margin: 0;
|
|
84
|
+
color: var(--vmz-status-danger-foreground);
|
|
85
|
+
font-size: 0.875rem;
|
|
91
86
|
}
|
|
92
87
|
</style>
|
|
93
|
-
|
|
94
88
|
<script client>
|
|
95
89
|
/**
|
|
96
|
-
* VMZ UI — Field (UI1).
|
|
97
|
-
* Label / description / error association via for + aria-describedby.
|
|
98
|
-
* Colors only from Style Theme semantic tokens.
|
|
99
|
-
*/
|
|
90
|
+
* VMZ UI — Field (UI1).
|
|
91
|
+
* Label / description / error association via for + aria-describedby.
|
|
92
|
+
* Colors only from Style Theme semantic tokens.
|
|
93
|
+
*/
|
|
100
94
|
export default class Field {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
95
|
+
public label: string = "";
|
|
96
|
+
public description: string = "";
|
|
97
|
+
public error: string = "";
|
|
98
|
+
public value: string = "";
|
|
99
|
+
public type: string = "text";
|
|
100
|
+
public min: string = "";
|
|
101
|
+
public max: string = "";
|
|
102
|
+
public step: string = "";
|
|
103
|
+
public disabled: boolean = false;
|
|
104
|
+
public invalidAttr: string = "false";
|
|
105
|
+
public controlId: string = "vmz-field";
|
|
106
|
+
public descriptionId: string = "vmz-field-desc";
|
|
107
|
+
public errorId: string = "vmz-field-err";
|
|
108
|
+
public describedBy: string = "";
|
|
109
|
+
public onInput: ((e: Event) => void) | null = null;
|
|
110
|
+
onDomInput(e: Event) {
|
|
111
|
+
this.emit("input", e);
|
|
112
|
+
if (typeof this.onInput === "function") this.onInput(e);
|
|
113
|
+
}
|
|
120
114
|
}
|
|
121
115
|
</script>
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
<section data-vmz-ui="filter-bar" :aria-label="label" class="vmz-ui-filter-bar">
|
|
3
|
+
<slot />
|
|
4
4
|
</section>
|
|
5
5
|
</template>
|
|
6
|
-
|
|
7
6
|
<style>
|
|
8
|
-
|
|
7
|
+
.vmz-ui-filter-bar {
|
|
9
8
|
display: flex;
|
|
10
9
|
flex-wrap: wrap;
|
|
11
10
|
align-items: flex-end;
|
|
@@ -13,15 +12,14 @@
|
|
|
13
12
|
padding: 0.75rem 0.85rem;
|
|
14
13
|
border: 1px solid var(--vmz-line-default);
|
|
15
14
|
border-radius: var(--vmz-radius-md, 6px);
|
|
16
|
-
|
|
15
|
+
}
|
|
17
16
|
</style>
|
|
18
|
-
|
|
19
17
|
<script client>
|
|
20
18
|
/**
|
|
21
|
-
* VMZ UI — FilterBar (Console composition).
|
|
22
|
-
* Dense filter/query landmark; parent projects Field + action controls.
|
|
23
|
-
*/
|
|
19
|
+
* VMZ UI — FilterBar (Console composition).
|
|
20
|
+
* Dense filter/query landmark; parent projects Field + action controls.
|
|
21
|
+
*/
|
|
24
22
|
export default class FilterBar {
|
|
25
|
-
|
|
23
|
+
public label: string = "Filters";
|
|
26
24
|
}
|
|
27
25
|
</script>
|
package/src/components/Flex.vmz
CHANGED
|
@@ -1,12 +1,27 @@
|
|
|
1
|
-
<template
|
|
1
|
+
<template>
|
|
2
|
+
<div data-vmz-ui="flex" :data-vertical='vertical ? "true" : "false"' :data-wrap='wrap ? "true" : "false"' class="vmz-ui-flex">
|
|
3
|
+
<slot />
|
|
4
|
+
</div>
|
|
5
|
+
</template>
|
|
2
6
|
<style>
|
|
3
|
-
.vmz-ui-flex{
|
|
4
|
-
|
|
5
|
-
|
|
7
|
+
.vmz-ui-flex {
|
|
8
|
+
display: flex;
|
|
9
|
+
align-items: center;
|
|
10
|
+
justify-content: flex-start;
|
|
11
|
+
gap: 0.75rem;
|
|
12
|
+
min-width: 0;
|
|
13
|
+
}
|
|
14
|
+
.vmz-ui-flex[data-vertical="true"] {
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
align-items: stretch;
|
|
17
|
+
}
|
|
18
|
+
.vmz-ui-flex[data-wrap="true"] {
|
|
19
|
+
flex-wrap: wrap;
|
|
20
|
+
}
|
|
6
21
|
</style>
|
|
7
22
|
<script client>
|
|
8
23
|
export default class Flex {
|
|
9
|
-
|
|
10
|
-
|
|
24
|
+
public vertical: boolean = false;
|
|
25
|
+
public wrap: boolean = false;
|
|
11
26
|
}
|
|
12
27
|
</script>
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
2
|
+
<footer data-vmz-ui="footer" class="vmz-ui-footer">
|
|
3
|
+
<slot />
|
|
4
|
+
</footer>
|
|
3
5
|
</template>
|
|
4
|
-
|
|
5
6
|
<style>
|
|
6
|
-
|
|
7
|
+
.vmz-ui-footer {
|
|
8
|
+
padding: 1.5rem;
|
|
9
|
+
color: var(--vmz-text-steel, #646a73);
|
|
10
|
+
font-size: 0.875rem;
|
|
11
|
+
text-align: center;
|
|
12
|
+
}
|
|
7
13
|
</style>
|
|
8
|
-
|
|
9
14
|
<script client>
|
|
10
15
|
export default class Footer {}
|
|
11
16
|
</script>
|
package/src/components/Form.vmz
CHANGED
|
@@ -1,35 +1,25 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
:aria-label="label"
|
|
8
|
-
:aria-describedby="describedBy"
|
|
9
|
-
@submit="onSubmitGuard"
|
|
10
|
-
@reset="onResetGuard"
|
|
11
|
-
>
|
|
12
|
-
<div v-if="errorSummary" :id="summaryId" class="vmz-ui-form__summary" role="alert" data-vmz-form="summary">
|
|
13
|
-
{{ errorSummary }}
|
|
14
|
-
</div>
|
|
15
|
-
<slot />
|
|
2
|
+
<form data-vmz-ui="form" :data-disabled="disabledAttr" data-novalidate="true" :aria-label="label" :aria-describedby="describedBy" @submit="onSubmitGuard" @reset="onResetGuard" class="vmz-ui-form">
|
|
3
|
+
<div v-if="errorSummary" :id="summaryId" role="alert" data-vmz-form="summary" class="vmz-ui-form__summary">
|
|
4
|
+
{{ errorSummary }}
|
|
5
|
+
</div>
|
|
6
|
+
<slot />
|
|
16
7
|
</form>
|
|
17
8
|
</template>
|
|
18
|
-
|
|
19
9
|
<style>
|
|
20
|
-
|
|
10
|
+
.vmz-ui-form {
|
|
21
11
|
display: flex;
|
|
22
12
|
flex-direction: column;
|
|
23
13
|
gap: var(--vmz-density-control-gap);
|
|
24
14
|
max-width: 36rem;
|
|
25
|
-
|
|
15
|
+
}
|
|
26
16
|
|
|
27
|
-
|
|
17
|
+
.vmz-ui-form[data-disabled="true"] {
|
|
28
18
|
opacity: 0.72;
|
|
29
19
|
pointer-events: none;
|
|
30
|
-
|
|
20
|
+
}
|
|
31
21
|
|
|
32
|
-
|
|
22
|
+
.vmz-ui-form__summary {
|
|
33
23
|
margin: 0;
|
|
34
24
|
padding: var(--vmz-density-control-padding-y) var(--vmz-density-control-padding-x);
|
|
35
25
|
border: 1px solid var(--vmz-status-danger-accent);
|
|
@@ -38,35 +28,34 @@
|
|
|
38
28
|
background: color-mix(in srgb, var(--vmz-status-danger-accent) 12%, transparent);
|
|
39
29
|
color: var(--vmz-status-danger-foreground);
|
|
40
30
|
font-weight: 600;
|
|
41
|
-
|
|
31
|
+
}
|
|
42
32
|
</style>
|
|
43
|
-
|
|
44
33
|
<script client>
|
|
45
34
|
/**
|
|
46
|
-
* VMZ UI — Form (hand-written commercial form shell).
|
|
47
|
-
* Parent owns field values + validation presentation; no parallel form store.
|
|
48
|
-
* Native submit/reset guarded; browser HTML5 validation left off (data-novalidate + preventDefault).
|
|
49
|
-
*/
|
|
35
|
+
* VMZ UI — Form (hand-written commercial form shell).
|
|
36
|
+
* Parent owns field values + validation presentation; no parallel form store.
|
|
37
|
+
* Native submit/reset guarded; browser HTML5 validation left off (data-novalidate + preventDefault).
|
|
38
|
+
*/
|
|
50
39
|
export default class Form {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
40
|
+
public label: string = "Form";
|
|
41
|
+
public errorSummary: string = "";
|
|
42
|
+
public summaryId: string = "vmz-form-summary";
|
|
43
|
+
public describedBy: string = "";
|
|
44
|
+
public disabled: boolean = false;
|
|
45
|
+
public disabledAttr: string = "false";
|
|
46
|
+
public onSubmit: (() => void) | null = null;
|
|
47
|
+
public onReset: (() => void) | null = null;
|
|
48
|
+
onSubmitGuard(ev) {
|
|
49
|
+
if (ev && typeof ev.preventDefault === "function") ev.preventDefault();
|
|
50
|
+
if (this.disabled) return;
|
|
51
|
+
this.emit("submit");
|
|
52
|
+
if (typeof this.onSubmit === "function") this.onSubmit();
|
|
53
|
+
}
|
|
54
|
+
onResetGuard(ev) {
|
|
55
|
+
if (ev && typeof ev.preventDefault === "function") ev.preventDefault();
|
|
56
|
+
if (this.disabled) return;
|
|
57
|
+
this.emit("reset");
|
|
58
|
+
if (typeof this.onReset === "function") this.onReset();
|
|
59
|
+
}
|
|
71
60
|
}
|
|
72
61
|
</script>
|