@vmz/ui 0.1.0 → 0.1.2
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 +8 -0
- package/contracts/token-requirements.v0.json +2 -6
- package/package.json +18 -2
- package/presets/web-surface.v0.json +24 -10
- package/src/components/Accordion.vmz +88 -89
- package/src/components/Alert.vmz +64 -63
- package/src/components/AppShell.vmz +64 -45
- package/src/components/Autocomplete.vmz +152 -151
- package/src/components/Avatar.vmz +16 -0
- package/src/components/Badge.vmz +46 -46
- package/src/components/Breadcrumb.vmz +52 -48
- package/src/components/BulkActions.vmz +37 -37
- package/src/components/Button.vmz +90 -75
- package/src/components/Callout.vmz +61 -61
- package/src/components/Card.vmz +58 -51
- package/src/components/Checkbox.vmz +56 -53
- package/src/components/CodeBlock.vmz +51 -51
- package/src/components/Collapse.vmz +20 -0
- package/src/components/ConsoleShell.vmz +134 -99
- package/src/components/Content.vmz +11 -0
- package/src/components/DataTable.vmz +197 -196
- package/src/components/DatePicker.vmz +613 -536
- package/src/components/Dialog.vmz +365 -384
- package/src/components/Divider.vmz +19 -0
- package/src/components/Drawer.vmz +361 -378
- package/src/components/Dropdown.vmz +22 -0
- package/src/components/Empty.vmz +36 -36
- package/src/components/Field.vmz +69 -40
- package/src/components/FilterBar.vmz +15 -15
- package/src/components/Flex.vmz +12 -0
- package/src/components/Footer.vmz +11 -0
- package/src/components/Form.vmz +56 -58
- package/src/components/FormItem.vmz +59 -59
- package/src/components/Grid.vmz +12 -0
- package/src/components/Header.vmz +11 -0
- package/src/components/Icon.vmz +86 -0
- package/src/components/Layout.vmz +11 -0
- package/src/components/Link.vmz +33 -33
- package/src/components/List.vmz +96 -96
- package/src/components/Menu.vmz +229 -240
- package/src/components/Notification.vmz +62 -62
- package/src/components/Pagination.vmz +63 -65
- package/src/components/Popover.vmz +202 -219
- package/src/components/Progress.vmz +18 -0
- package/src/components/Prose.vmz +61 -61
- package/src/components/QueryForm.vmz +26 -27
- package/src/components/RadioGroup.vmz +116 -113
- package/src/components/Result.vmz +63 -63
- package/src/components/Segmented.vmz +29 -0
- package/src/components/Select.vmz +462 -290
- package/src/components/Sider.vmz +6 -0
- package/src/components/Skeleton.vmz +58 -58
- package/src/components/Space.vmz +15 -0
- package/src/components/Spinner.vmz +29 -29
- package/src/components/Steps.vmz +86 -86
- package/src/components/Switch.vmz +86 -88
- package/src/components/Table.vmz +116 -114
- package/src/components/Tabs.vmz +113 -112
- package/src/components/Tag.vmz +8 -0
- package/src/components/TextArea.vmz +76 -49
- package/src/components/Timeline.vmz +55 -50
- package/src/components/Toc.vmz +64 -60
- package/src/components/Tooltip.vmz +51 -51
- package/src/components/Tree.vmz +184 -190
- package/src/components/Typography.vmz +9 -0
- package/src/components/Upload.vmz +1130 -1151
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<details class="vmz-ui-dropdown" data-vmz-ui="dropdown">
|
|
3
|
+
<summary>{label}</summary>
|
|
4
|
+
<div class="vmz-ui-dropdown__menu">
|
|
5
|
+
<a each={items} as="item" key={item.id} href={item.href}>{item.title}</a>
|
|
6
|
+
</div>
|
|
7
|
+
</details>
|
|
8
|
+
</template>
|
|
9
|
+
<style>
|
|
10
|
+
.vmz-ui-dropdown{position:relative;display:inline-block}
|
|
11
|
+
.vmz-ui-dropdown summary{list-style:none;min-height:2.5rem;display:inline-flex;align-items:center;padding:0 .85rem;border:1px solid var(--vmz-line-default);border-radius:var(--vmz-radius-md,6px);background:var(--vmz-surface-paper);cursor:pointer;font-weight:550}
|
|
12
|
+
.vmz-ui-dropdown summary::-webkit-details-marker{display:none}
|
|
13
|
+
.vmz-ui-dropdown__menu{position:absolute;top:calc(100% + .35rem);right:0;z-index:50;min-width:11rem;padding:.3rem;border:1px solid var(--vmz-line-default);border-radius:var(--vmz-radius-lg,8px);background:var(--vmz-surface-paper);box-shadow:var(--vmz-shadow-popup)}
|
|
14
|
+
.vmz-ui-dropdown__menu a{display:block;padding:.55rem .7rem;border-radius:var(--vmz-radius-sm,2px);color:var(--vmz-text-ink);text-decoration:none}
|
|
15
|
+
.vmz-ui-dropdown__menu a:hover{background:var(--vmz-surface-mist)}
|
|
16
|
+
</style>
|
|
17
|
+
<script client>
|
|
18
|
+
export default class Dropdown {
|
|
19
|
+
public label: string = 'Menu';
|
|
20
|
+
public items: Array<{ id: string; title: string; href: string }> = [];
|
|
21
|
+
}
|
|
22
|
+
</script>
|
package/src/components/Empty.vmz
CHANGED
|
@@ -1,52 +1,52 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="vmz-ui-empty" data-vmz-ui="empty">
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
<h2 class="vmz-ui-empty__title">{title}</h2>
|
|
4
|
+
<p if={description} class="vmz-ui-empty__description">{description}</p>
|
|
5
|
+
<div class="vmz-ui-empty__actions">
|
|
6
|
+
<slot />
|
|
7
|
+
</div>
|
|
7
8
|
</div>
|
|
8
|
-
</div>
|
|
9
9
|
</template>
|
|
10
10
|
|
|
11
11
|
<style>
|
|
12
|
-
.vmz-ui-empty {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
12
|
+
.vmz-ui-empty {
|
|
13
|
+
display: flex;
|
|
14
|
+
flex-direction: column;
|
|
15
|
+
align-items: flex-start;
|
|
16
|
+
gap: 0.65rem;
|
|
17
|
+
padding: 1.5rem 1.15rem;
|
|
18
|
+
border: 1px dashed var(--vmz-line-default);
|
|
19
|
+
border-radius: var(--vmz-radius-md, 6px);
|
|
20
|
+
background: color-mix(in srgb, var(--vmz-surface-mist) 70%, var(--vmz-surface-paper));
|
|
21
|
+
color: var(--vmz-text-ink);
|
|
22
|
+
}
|
|
23
23
|
|
|
24
|
-
.vmz-ui-empty__title {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
24
|
+
.vmz-ui-empty__title {
|
|
25
|
+
margin: 0;
|
|
26
|
+
font-family: var(--vmz-font-display);
|
|
27
|
+
font-size: 1.1rem;
|
|
28
|
+
font-weight: 700;
|
|
29
|
+
}
|
|
30
30
|
|
|
31
|
-
.vmz-ui-empty__description {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
31
|
+
.vmz-ui-empty__description {
|
|
32
|
+
margin: 0;
|
|
33
|
+
color: var(--vmz-text-steel);
|
|
34
|
+
max-width: 36rem;
|
|
35
|
+
line-height: 1.45;
|
|
36
|
+
}
|
|
37
37
|
|
|
38
|
-
.vmz-ui-empty__actions:empty {
|
|
39
|
-
|
|
40
|
-
}
|
|
38
|
+
.vmz-ui-empty__actions:empty {
|
|
39
|
+
display: none;
|
|
40
|
+
}
|
|
41
41
|
</style>
|
|
42
42
|
|
|
43
43
|
<script client>
|
|
44
44
|
/**
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
* VMZ UI — Empty (Commercial composition).
|
|
46
|
+
* Empty / zero-state surface with optional action slot.
|
|
47
|
+
*/
|
|
48
48
|
export default class Empty {
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
public title: string = "Nothing here yet";
|
|
50
|
+
public description: string = "";
|
|
51
51
|
}
|
|
52
52
|
</script>
|
package/src/components/Field.vmz
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="vmz-ui-field" data-vmz-ui="field" data-invalid={invalidAttr}>
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
3
|
+
<label if={label} class="vmz-ui-field__label" for={controlId}>{label}</label>
|
|
4
|
+
<input
|
|
5
|
+
id={controlId}
|
|
6
|
+
class="vmz-ui-field__control"
|
|
7
|
+
type={type}
|
|
8
|
+
value={value}
|
|
9
|
+
min={min}
|
|
10
|
+
max={max}
|
|
11
|
+
step={step}
|
|
12
|
+
disabled={disabled}
|
|
13
|
+
aria-invalid={error ? 'true' : 'false'}
|
|
14
|
+
aria-describedby={describedBy}
|
|
15
|
+
onInput={onInput}
|
|
16
|
+
/>
|
|
17
|
+
<p if={description} id={descriptionId} class="vmz-ui-field__description">{description}</p>
|
|
18
|
+
<p if={error} id={errorId} class="vmz-ui-field__error" role="alert">{error}</p>
|
|
19
|
+
</div>
|
|
17
20
|
</template>
|
|
18
21
|
|
|
19
22
|
<style>
|
|
@@ -26,63 +29,89 @@
|
|
|
26
29
|
|
|
27
30
|
.vmz-ui-field__label {
|
|
28
31
|
font: inherit;
|
|
29
|
-
font-weight:
|
|
32
|
+
font-weight: 500;
|
|
33
|
+
font-size: 0.875rem;
|
|
34
|
+
color: var(--vmz-text-ink, inherit);
|
|
30
35
|
}
|
|
31
36
|
|
|
32
37
|
.vmz-ui-field__control {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
box-sizing: border-box;
|
|
39
|
+
width: 100%;
|
|
40
|
+
min-height: var(--vmz-control-height, 2rem);
|
|
41
|
+
font-family: var(--vmz-font-sans, inherit);
|
|
42
|
+
font-size: 0.875rem;
|
|
43
|
+
line-height: 1.5715;
|
|
44
|
+
padding: var(--vmz-density-control-padding-y, 0.25rem)
|
|
45
|
+
var(--vmz-density-control-padding-x, 0.75rem);
|
|
46
|
+
border: 1px solid var(--vmz-line-default, #d9d9d9);
|
|
47
|
+
border-radius: var(--vmz-radius-md, 6px);
|
|
48
|
+
background: var(--vmz-surface-paper, #fff);
|
|
49
|
+
color: var(--vmz-text-ink, inherit);
|
|
39
50
|
outline: none;
|
|
51
|
+
transition:
|
|
52
|
+
border-color var(--vmz-motion-control-duration, 120ms) var(--vmz-motion-control-easing, linear),
|
|
53
|
+
box-shadow var(--vmz-motion-control-duration, 120ms) var(--vmz-motion-control-easing, linear);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.vmz-ui-field__control::placeholder {
|
|
57
|
+
color: var(--vmz-text-steel, #8c8c8c);
|
|
58
|
+
opacity: 1;
|
|
40
59
|
}
|
|
41
60
|
|
|
42
61
|
.vmz-ui-field[data-invalid='true'] .vmz-ui-field__control {
|
|
43
62
|
border-color: var(--vmz-status-danger-accent);
|
|
44
63
|
}
|
|
45
64
|
|
|
65
|
+
.vmz-ui-field__control:hover:not(:disabled):not(:focus-visible) {
|
|
66
|
+
border-color: var(--vmz-action-primary-background);
|
|
67
|
+
}
|
|
68
|
+
|
|
46
69
|
.vmz-ui-field__control:focus-visible {
|
|
70
|
+
border-color: var(--vmz-action-primary-background);
|
|
47
71
|
box-shadow: 0 0 0 2px var(--vmz-focus-ring);
|
|
48
72
|
}
|
|
49
73
|
|
|
50
74
|
.vmz-ui-field__control:disabled {
|
|
51
75
|
opacity: 0.55;
|
|
52
76
|
cursor: not-allowed;
|
|
77
|
+
background: var(--vmz-surface-mist, #fafafa);
|
|
53
78
|
}
|
|
54
79
|
|
|
55
80
|
.vmz-ui-field__description {
|
|
56
81
|
margin: 0;
|
|
57
|
-
|
|
58
|
-
font-size: 0.
|
|
82
|
+
color: var(--vmz-text-steel, #8c8c8c);
|
|
83
|
+
font-size: 0.875rem;
|
|
84
|
+
line-height: 1.4;
|
|
59
85
|
}
|
|
60
86
|
|
|
61
87
|
.vmz-ui-field__error {
|
|
62
88
|
margin: 0;
|
|
63
89
|
color: var(--vmz-status-danger-foreground);
|
|
64
|
-
font-size: 0.
|
|
90
|
+
font-size: 0.875rem;
|
|
65
91
|
}
|
|
66
92
|
</style>
|
|
67
93
|
|
|
68
94
|
<script client>
|
|
69
95
|
/**
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
96
|
+
* VMZ UI — Field (UI1).
|
|
97
|
+
* Label / description / error association via for + aria-describedby.
|
|
98
|
+
* Colors only from Style Theme semantic tokens.
|
|
99
|
+
*/
|
|
74
100
|
export default class Field {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
101
|
+
public label: string = "";
|
|
102
|
+
public description: string = "";
|
|
103
|
+
public error: string = "";
|
|
104
|
+
public value: string = "";
|
|
105
|
+
public type: string = "text";
|
|
106
|
+
public min: string = "";
|
|
107
|
+
public max: string = "";
|
|
108
|
+
public step: string = "";
|
|
109
|
+
public disabled: boolean = false;
|
|
110
|
+
public invalidAttr: string = "false";
|
|
111
|
+
public controlId: string = "vmz-field";
|
|
112
|
+
public descriptionId: string = "vmz-field-desc";
|
|
113
|
+
public errorId: string = "vmz-field-err";
|
|
114
|
+
public describedBy: string = "";
|
|
115
|
+
public onInput: ((e: Event) => void) | null = null;
|
|
87
116
|
}
|
|
88
117
|
</script>
|
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<section class="vmz-ui-filter-bar" data-vmz-ui="filter-bar" aria-label={label}>
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
<slot />
|
|
4
|
+
</section>
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
7
|
<style>
|
|
8
|
-
.vmz-ui-filter-bar {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
8
|
+
.vmz-ui-filter-bar {
|
|
9
|
+
display: flex;
|
|
10
|
+
flex-wrap: wrap;
|
|
11
|
+
align-items: flex-end;
|
|
12
|
+
gap: 0.75rem 1rem;
|
|
13
|
+
padding: 0.75rem 0.85rem;
|
|
14
|
+
border: 1px solid var(--vmz-line-default);
|
|
15
|
+
border-radius: var(--vmz-radius-md, 6px);
|
|
16
|
+
}
|
|
17
17
|
</style>
|
|
18
18
|
|
|
19
19
|
<script client>
|
|
20
20
|
/**
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
* VMZ UI — FilterBar (Console composition).
|
|
22
|
+
* Dense filter/query landmark; parent projects Field + action controls.
|
|
23
|
+
*/
|
|
24
24
|
export default class FilterBar {
|
|
25
|
-
|
|
25
|
+
public label: string = "Filters";
|
|
26
26
|
}
|
|
27
27
|
</script>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<template><div class="vmz-ui-flex" data-vmz-ui="flex" data-vertical={vertical?'true':'false'} data-wrap={wrap?'true':'false'}><slot /></div></template>
|
|
2
|
+
<style>
|
|
3
|
+
.vmz-ui-flex{display:flex;align-items:center;justify-content:flex-start;gap:.75rem;min-width:0}
|
|
4
|
+
.vmz-ui-flex[data-vertical='true']{flex-direction:column;align-items:stretch}
|
|
5
|
+
.vmz-ui-flex[data-wrap='true']{flex-wrap:wrap}
|
|
6
|
+
</style>
|
|
7
|
+
<script client>
|
|
8
|
+
export default class Flex {
|
|
9
|
+
public vertical: boolean = false;
|
|
10
|
+
public wrap: boolean = false;
|
|
11
|
+
}
|
|
12
|
+
</script>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<footer class="vmz-ui-footer" data-vmz-ui="footer"><slot /></footer>
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<style>
|
|
6
|
+
.vmz-ui-footer{padding:1.5rem;color:var(--vmz-text-steel,#646a73);font-size:.875rem;text-align:center}
|
|
7
|
+
</style>
|
|
8
|
+
|
|
9
|
+
<script client>
|
|
10
|
+
export default class Footer {}
|
|
11
|
+
</script>
|
package/src/components/Form.vmz
CHANGED
|
@@ -1,72 +1,70 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<form
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
3
|
+
class="vmz-ui-form"
|
|
4
|
+
data-vmz-ui="form"
|
|
5
|
+
data-disabled={disabledAttr}
|
|
6
|
+
data-novalidate="true"
|
|
7
|
+
aria-label={label}
|
|
8
|
+
aria-describedby={describedBy}
|
|
9
|
+
onSubmit={onSubmitGuard}
|
|
10
|
+
onReset={onResetGuard}
|
|
11
|
+
>
|
|
12
|
+
<div if={errorSummary} id={summaryId} class="vmz-ui-form__summary" role="alert" data-vmz-form="summary">
|
|
13
|
+
{errorSummary}
|
|
14
|
+
</div>
|
|
15
|
+
<slot />
|
|
16
|
+
</form>
|
|
17
17
|
</template>
|
|
18
18
|
|
|
19
19
|
<style>
|
|
20
|
-
.vmz-ui-form {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
20
|
+
.vmz-ui-form {
|
|
21
|
+
display: flex;
|
|
22
|
+
flex-direction: column;
|
|
23
|
+
gap: var(--vmz-density-control-gap);
|
|
24
|
+
max-width: 36rem;
|
|
25
|
+
}
|
|
26
26
|
|
|
27
|
-
.vmz-ui-form[data-disabled='true'] {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
27
|
+
.vmz-ui-form[data-disabled='true'] {
|
|
28
|
+
opacity: 0.72;
|
|
29
|
+
pointer-events: none;
|
|
30
|
+
}
|
|
31
31
|
|
|
32
|
-
.vmz-ui-form__summary {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
32
|
+
.vmz-ui-form__summary {
|
|
33
|
+
margin: 0;
|
|
34
|
+
padding: var(--vmz-density-control-padding-y) var(--vmz-density-control-padding-x);
|
|
35
|
+
border: 1px solid var(--vmz-status-danger-accent);
|
|
36
|
+
border-left-width: 1px;
|
|
37
|
+
border-radius: var(--vmz-radius-md, 6px);
|
|
38
|
+
background: color-mix(in srgb, var(--vmz-status-danger-accent) 12%, transparent);
|
|
39
|
+
color: var(--vmz-status-danger-foreground);
|
|
40
|
+
font-weight: 600;
|
|
41
|
+
}
|
|
42
42
|
</style>
|
|
43
43
|
|
|
44
44
|
<script client>
|
|
45
45
|
/**
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
+
*/
|
|
50
50
|
export default class Form {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (typeof this.onReset === 'function') this.onReset();
|
|
70
|
-
}
|
|
51
|
+
public label: string = "Form";
|
|
52
|
+
public errorSummary: string = "";
|
|
53
|
+
public summaryId: string = "vmz-form-summary";
|
|
54
|
+
public describedBy: string = "";
|
|
55
|
+
public disabled: boolean = false;
|
|
56
|
+
public disabledAttr: string = "false";
|
|
57
|
+
public onSubmit: (() => void) | null = null;
|
|
58
|
+
public onReset: (() => void) | null = null;
|
|
59
|
+
onSubmitGuard(ev) {
|
|
60
|
+
if (ev && typeof ev.preventDefault === "function") ev.preventDefault();
|
|
61
|
+
if (this.disabled) return;
|
|
62
|
+
if (typeof this.onSubmit === "function") this.onSubmit();
|
|
63
|
+
}
|
|
64
|
+
onResetGuard(ev) {
|
|
65
|
+
if (ev && typeof ev.preventDefault === "function") ev.preventDefault();
|
|
66
|
+
if (this.disabled) return;
|
|
67
|
+
if (typeof this.onReset === "function") this.onReset();
|
|
68
|
+
}
|
|
71
69
|
}
|
|
72
70
|
</script>
|
|
@@ -1,78 +1,78 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
3
|
+
class="vmz-ui-form-item"
|
|
4
|
+
data-vmz-ui="form-item"
|
|
5
|
+
data-required={requiredAttr}
|
|
6
|
+
data-invalid={invalidAttr}
|
|
7
|
+
>
|
|
8
|
+
<label if={label} class="vmz-ui-form-item__label" for={controlId}>
|
|
9
|
+
<span>{label}</span>
|
|
10
|
+
<span if={required} class="vmz-ui-form-item__required" aria-hidden="true">*</span>
|
|
11
|
+
</label>
|
|
12
|
+
<div class="vmz-ui-form-item__control">
|
|
13
|
+
<slot />
|
|
14
|
+
</div>
|
|
15
|
+
<p if={description} id={descriptionId} class="vmz-ui-form-item__description">{description}</p>
|
|
16
|
+
<p if={error} id={errorId} class="vmz-ui-form-item__error" role="alert">{error}</p>
|
|
14
17
|
</div>
|
|
15
|
-
<p if={description} id={descriptionId} class="vmz-ui-form-item__description">{description}</p>
|
|
16
|
-
<p if={error} id={errorId} class="vmz-ui-form-item__error" role="alert">{error}</p>
|
|
17
|
-
</div>
|
|
18
18
|
</template>
|
|
19
19
|
|
|
20
20
|
<style>
|
|
21
|
-
.vmz-ui-form-item {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
21
|
+
.vmz-ui-form-item {
|
|
22
|
+
display: flex;
|
|
23
|
+
flex-direction: column;
|
|
24
|
+
gap: 0.35rem;
|
|
25
|
+
max-width: 28rem;
|
|
26
|
+
}
|
|
27
27
|
|
|
28
|
-
.vmz-ui-form-item__label {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
28
|
+
.vmz-ui-form-item__label {
|
|
29
|
+
display: inline-flex;
|
|
30
|
+
align-items: baseline;
|
|
31
|
+
gap: 0.25rem;
|
|
32
|
+
font: inherit;
|
|
33
|
+
font-weight: 600;
|
|
34
|
+
}
|
|
35
35
|
|
|
36
|
-
.vmz-ui-form-item__required {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
36
|
+
.vmz-ui-form-item__required {
|
|
37
|
+
color: var(--vmz-status-danger-accent);
|
|
38
|
+
font-weight: 700;
|
|
39
|
+
}
|
|
40
40
|
|
|
41
|
-
.vmz-ui-form-item__control {
|
|
42
|
-
|
|
43
|
-
}
|
|
41
|
+
.vmz-ui-form-item__control {
|
|
42
|
+
min-width: 0;
|
|
43
|
+
}
|
|
44
44
|
|
|
45
|
-
.vmz-ui-form-item__description {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
45
|
+
.vmz-ui-form-item__description {
|
|
46
|
+
margin: 0;
|
|
47
|
+
opacity: 0.75;
|
|
48
|
+
font-size: 0.9em;
|
|
49
|
+
}
|
|
50
50
|
|
|
51
|
-
.vmz-ui-form-item__error {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
51
|
+
.vmz-ui-form-item__error {
|
|
52
|
+
margin: 0;
|
|
53
|
+
color: var(--vmz-status-danger-foreground);
|
|
54
|
+
font-size: 0.9em;
|
|
55
|
+
}
|
|
56
56
|
|
|
57
|
-
.vmz-ui-form-item[data-invalid='true'] .vmz-ui-form-item__control :where(input, select, textarea) {
|
|
58
|
-
|
|
59
|
-
}
|
|
57
|
+
.vmz-ui-form-item[data-invalid='true'] .vmz-ui-form-item__control :where(input, select, textarea) {
|
|
58
|
+
border-color: var(--vmz-status-danger-accent);
|
|
59
|
+
}
|
|
60
60
|
</style>
|
|
61
61
|
|
|
62
62
|
<script client>
|
|
63
63
|
/**
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
* VMZ UI — FormItem.
|
|
65
|
+
* Label / description / error shell for slotted controls; parent owns validation strings.
|
|
66
|
+
*/
|
|
67
67
|
export default class FormItem {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
68
|
+
public label: string = "";
|
|
69
|
+
public description: string = "";
|
|
70
|
+
public error: string = "";
|
|
71
|
+
public required: boolean = false;
|
|
72
|
+
public requiredAttr: string = "false";
|
|
73
|
+
public invalidAttr: string = "false";
|
|
74
|
+
public controlId: string = "vmz-form-item";
|
|
75
|
+
public descriptionId: string = "vmz-form-item-desc";
|
|
76
|
+
public errorId: string = "vmz-form-item-err";
|
|
77
77
|
}
|
|
78
78
|
</script>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<template><div class="vmz-ui-grid" data-vmz-ui="grid" style={'--ui-grid-columns:' + columns + ';--ui-grid-gap:' + gap}><slot /></div></template>
|
|
2
|
+
<style>
|
|
3
|
+
.vmz-ui-grid{display:grid;grid-template-columns:repeat(var(--ui-grid-columns,3),minmax(0,1fr));gap:var(--ui-grid-gap,1rem)}
|
|
4
|
+
@media(max-width:900px){.vmz-ui-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
|
|
5
|
+
@media(max-width:600px){.vmz-ui-grid{grid-template-columns:1fr}}
|
|
6
|
+
</style>
|
|
7
|
+
<script client>
|
|
8
|
+
export default class Grid {
|
|
9
|
+
public columns: number = 3;
|
|
10
|
+
public gap: string = '1rem';
|
|
11
|
+
}
|
|
12
|
+
</script>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<header class="vmz-ui-header" data-vmz-ui="header"><slot /></header>
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<style>
|
|
6
|
+
.vmz-ui-header{min-height:4rem;display:flex;align-items:center;padding:0 1.5rem;border-bottom:1px solid var(--vmz-line-default,#d9d9d9);background:var(--vmz-surface-paper,#fff)}
|
|
7
|
+
</style>
|
|
8
|
+
|
|
9
|
+
<script client>
|
|
10
|
+
export default class Header {}
|
|
11
|
+
</script>
|