@vmz/ui 0.2.3 → 0.2.5

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.
Files changed (63) hide show
  1. package/package.json +1 -1
  2. package/src/components/Accordion.vmz +46 -63
  3. package/src/components/Alert.vmz +35 -38
  4. package/src/components/AppShell.vmz +92 -75
  5. package/src/components/Autocomplete.vmz +91 -119
  6. package/src/components/Avatar.vmz +37 -8
  7. package/src/components/Badge.vmz +29 -23
  8. package/src/components/Breadcrumb.vmz +36 -34
  9. package/src/components/BulkActions.vmz +22 -28
  10. package/src/components/Button.vmz +139 -121
  11. package/src/components/Callout.vmz +33 -36
  12. package/src/components/Card.vmz +68 -51
  13. package/src/components/Checkbox.vmz +28 -47
  14. package/src/components/CodeBlock.vmz +31 -25
  15. package/src/components/Collapse.vmz +34 -16
  16. package/src/components/ConsoleShell.vmz +107 -110
  17. package/src/components/Content.vmz +8 -4
  18. package/src/components/DataTable.vmz +124 -150
  19. package/src/components/DatePicker.vmz +526 -521
  20. package/src/components/Dialog.vmz +408 -327
  21. package/src/components/Divider.vmz +38 -11
  22. package/src/components/Drawer.vmz +325 -318
  23. package/src/components/Dropdown.vmz +53 -19
  24. package/src/components/Empty.vmz +23 -21
  25. package/src/components/Field.vmz +77 -83
  26. package/src/components/FilterBar.vmz +8 -10
  27. package/src/components/Flex.vmz +21 -6
  28. package/src/components/Footer.vmz +9 -4
  29. package/src/components/Form.vmz +35 -46
  30. package/src/components/FormItem.vmz +44 -43
  31. package/src/components/Grid.vmz +22 -6
  32. package/src/components/Header.vmz +11 -4
  33. package/src/components/Icon.vmz +43 -44
  34. package/src/components/Layout.vmz +9 -4
  35. package/src/components/Link.vmz +17 -25
  36. package/src/components/List.vmz +62 -75
  37. package/src/components/Menu.vmz +182 -197
  38. package/src/components/Notification.vmz +35 -38
  39. package/src/components/Pagination.vmz +37 -47
  40. package/src/components/Popover.vmz +157 -171
  41. package/src/components/Progress.vmz +36 -10
  42. package/src/components/Prose.vmz +29 -31
  43. package/src/components/QueryForm.vmz +14 -22
  44. package/src/components/RadioGroup.vmz +70 -84
  45. package/src/components/Result.vmz +36 -38
  46. package/src/components/Segmented.vmz +43 -22
  47. package/src/components/Select.vmz +404 -411
  48. package/src/components/Sider.vmz +21 -4
  49. package/src/components/Skeleton.vmz +34 -42
  50. package/src/components/Space.vmz +24 -9
  51. package/src/components/Spinner.vmz +17 -23
  52. package/src/components/Steps.vmz +48 -51
  53. package/src/components/Switch.vmz +50 -60
  54. package/src/components/Table.vmz +81 -84
  55. package/src/components/Tabs.vmz +66 -88
  56. package/src/components/Tag.vmz +36 -11
  57. package/src/components/TextArea.vmz +73 -77
  58. package/src/components/Timeline.vmz +36 -32
  59. package/src/components/Toc.vmz +31 -37
  60. package/src/components/Tooltip.vmz +25 -35
  61. package/src/components/Tree.vmz +127 -144
  62. package/src/components/Typography.vmz +33 -7
  63. package/src/components/Upload.vmz +1135 -1057
@@ -1,39 +1,26 @@
1
1
  <template>
2
- <fieldset
3
- class="vmz-ui-radio-group"
4
- data-vmz-ui="radio-group"
5
- :data-invalid="invalidAttr"
6
- :aria-describedby="describedBy"
7
- :disabled="disabled"
8
- >
9
- <legend class="vmz-ui-radio-group__legend">{{ label }}</legend>
10
- <div class="vmz-ui-radio-group__list" role="radiogroup" :aria-label="label" @click="onListClick">
11
- <label
12
- v-for="item in items"
13
- :key="item.value"
14
- class="vmz-ui-radio-group__option"
15
- :for="item.id"
16
- >
17
- <input
18
- :id="item.id"
19
- class="vmz-ui-radio-group__input"
20
- type="radio"
21
- :name="name"
22
- :value="item.value"
23
- :checked="value === item.value"
24
- :disabled="disabled"
25
- :data-vmz-radio="item.value"
26
- />
27
- <span class="vmz-ui-radio-group__text">{{ item.label }}</span>
28
- </label>
29
- </div>
30
- <p v-if="description" :id="descriptionId" class="vmz-ui-radio-group__description">{{ description }}</p>
31
- <p v-if="error" :id="errorId" class="vmz-ui-radio-group__error" role="alert">{{ error }}</p>
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>
32
20
  </fieldset>
33
21
  </template>
34
-
35
22
  <style>
36
- .vmz-ui-radio-group {
23
+ .vmz-ui-radio-group {
37
24
  display: flex;
38
25
  flex-direction: column;
39
26
  gap: 0.45rem;
@@ -42,97 +29,96 @@
42
29
  padding: 0;
43
30
  border: 0;
44
31
  min-width: 0;
45
- }
32
+ }
46
33
 
47
- .vmz-ui-radio-group__legend {
34
+ .vmz-ui-radio-group__legend {
48
35
  padding: 0;
49
36
  font: inherit;
50
37
  font-weight: 600;
51
- }
38
+ }
52
39
 
53
- .vmz-ui-radio-group__list {
40
+ .vmz-ui-radio-group__list {
54
41
  display: flex;
55
42
  flex-direction: column;
56
43
  gap: 0.35rem;
57
- }
44
+ }
58
45
 
59
- .vmz-ui-radio-group__option {
46
+ .vmz-ui-radio-group__option {
60
47
  display: inline-flex;
61
48
  align-items: center;
62
49
  gap: 0.45rem;
63
50
  font: inherit;
64
51
  cursor: pointer;
65
- }
52
+ }
66
53
 
67
- .vmz-ui-radio-group__input {
54
+ .vmz-ui-radio-group__input {
68
55
  width: 1rem;
69
56
  height: 1rem;
70
57
  accent-color: var(--vmz-action-primary-background);
71
58
  outline: none;
72
- }
59
+ }
73
60
 
74
- .vmz-ui-radio-group__input:focus-visible {
61
+ .vmz-ui-radio-group__input:focus-visible {
75
62
  box-shadow: 0 0 0 2px var(--vmz-focus-ring);
76
- }
63
+ }
77
64
 
78
- .vmz-ui-radio-group__input:disabled {
65
+ .vmz-ui-radio-group__input:disabled {
79
66
  opacity: 0.55;
80
67
  cursor: not-allowed;
81
- }
68
+ }
82
69
 
83
- .vmz-ui-radio-group__text {
70
+ .vmz-ui-radio-group__text {
84
71
  font-weight: 600;
85
- }
72
+ }
86
73
 
87
- .vmz-ui-radio-group__description {
74
+ .vmz-ui-radio-group__description {
88
75
  margin: 0;
89
76
  opacity: 0.75;
90
77
  font-size: 0.9em;
91
- }
78
+ }
92
79
 
93
- .vmz-ui-radio-group__error {
80
+ .vmz-ui-radio-group__error {
94
81
  margin: 0;
95
82
  color: var(--vmz-status-danger-foreground);
96
83
  font-size: 0.9em;
97
- }
84
+ }
98
85
 
99
- .vmz-ui-radio-group[data-invalid='true'] .vmz-ui-radio-group__legend {
86
+ .vmz-ui-radio-group[data-invalid="true"] .vmz-ui-radio-group__legend {
100
87
  color: var(--vmz-status-danger-foreground);
101
- }
88
+ }
102
89
  </style>
103
-
104
90
  <script client>
105
91
  /**
106
- * VMZ UI — RadioGroup.
107
- * Parent owns selected value; click path updates via onChange (live prop remains authoritative).
108
- */
92
+ * VMZ UI — RadioGroup.
93
+ * Parent owns selected value; click path updates via onChange (live prop remains authoritative).
94
+ */
109
95
  export default class RadioGroup {
110
- public label: string = "";
111
- public description: string = "";
112
- public error: string = "";
113
- public name: string = "vmz-radio";
114
- public value: string = "";
115
- public items: Array<{
116
- id: string;
117
- value: string;
118
- label: string;
119
- }> = [];
120
- public disabled: boolean = false;
121
- public invalidAttr: string = "false";
122
- public descriptionId: string = "vmz-radio-desc";
123
- public errorId: string = "vmz-radio-err";
124
- public describedBy: string = "";
125
- public onChange: ((value: string) => void) | null = null;
126
- onListClick(ev) {
127
- if (this.disabled) return;
128
- const t = ev && ev.target;
129
- if (!t || typeof t.closest !== "function") return;
130
- const input = t.closest("input[data-vmz-radio]");
131
- if (!input) return;
132
- const next = input.getAttribute("data-vmz-radio") || input.value || "";
133
- if (!next || next === this.value) return;
134
- this.emit("change", next);
135
- if (typeof this.onChange === "function") this.onChange(next);
136
- }
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
+ }
137
123
  }
138
124
  </script>
@@ -1,19 +1,18 @@
1
1
  <template>
2
- <section
3
- class="vmz-ui-result"
4
- data-vmz-ui="result"
5
- :data-status="status"
6
- >
7
- <p class="vmz-ui-result__title">{{ title }}</p>
8
- <p v-if="description" class="vmz-ui-result__description">{{ description }}</p>
9
- <div class="vmz-ui-result__actions">
10
- <slot />
11
- </div>
2
+ <section data-vmz-ui="result" :data-status="status" class="vmz-ui-result">
3
+ <p class="vmz-ui-result__title">
4
+ {{ title }}
5
+ </p>
6
+ <p v-if="description" class="vmz-ui-result__description">
7
+ {{ description }}
8
+ </p>
9
+ <div class="vmz-ui-result__actions">
10
+ <slot />
11
+ </div>
12
12
  </section>
13
13
  </template>
14
-
15
14
  <style>
16
- .vmz-ui-result {
15
+ .vmz-ui-result {
17
16
  display: flex;
18
17
  flex-direction: column;
19
18
  align-items: flex-start;
@@ -22,63 +21,62 @@
22
21
  border: 1px solid var(--vmz-status-info-accent);
23
22
  border-radius: var(--vmz-radius-md, 6px);
24
23
  color: var(--vmz-status-info-foreground);
25
- }
24
+ }
26
25
 
27
- .vmz-ui-result[data-status='info'] {
26
+ .vmz-ui-result[data-status="info"] {
28
27
  border-color: var(--vmz-status-info-accent);
29
28
  color: var(--vmz-status-info-foreground);
30
- }
29
+ }
31
30
 
32
- .vmz-ui-result[data-status='success'] {
31
+ .vmz-ui-result[data-status="success"] {
33
32
  border-color: var(--vmz-status-success-accent);
34
33
  color: var(--vmz-status-success-foreground);
35
- }
34
+ }
36
35
 
37
- .vmz-ui-result[data-status='warning'] {
36
+ .vmz-ui-result[data-status="warning"] {
38
37
  border-color: var(--vmz-status-warning-accent);
39
38
  color: var(--vmz-status-warning-foreground);
40
- }
39
+ }
41
40
 
42
- .vmz-ui-result[data-status='danger'] {
41
+ .vmz-ui-result[data-status="danger"] {
43
42
  border-color: var(--vmz-status-danger-accent);
44
43
  color: var(--vmz-status-danger-foreground);
45
- }
44
+ }
46
45
 
47
- :where([data-density='compact']) .vmz-ui-result {
46
+ :where([data-density="compact"]) .vmz-ui-result {
48
47
  gap: var(--vmz-density-compact-gap);
49
48
  padding: var(--vmz-density-compact-padding-y) var(--vmz-density-compact-padding-x);
50
- }
49
+ }
51
50
 
52
- .vmz-ui-result__title {
51
+ .vmz-ui-result__title {
53
52
  margin: 0;
54
53
  font-size: 1.15rem;
55
54
  font-weight: 700;
56
- }
55
+ }
57
56
 
58
- .vmz-ui-result__description {
57
+ .vmz-ui-result__description {
59
58
  margin: 0;
60
59
  opacity: 0.9;
61
- }
60
+ }
62
61
 
63
- .vmz-ui-result__actions {
62
+ .vmz-ui-result__actions {
64
63
  display: flex;
65
64
  flex-wrap: wrap;
66
65
  gap: 0.5rem;
67
- }
66
+ }
68
67
 
69
- .vmz-ui-result__actions:empty {
68
+ .vmz-ui-result__actions:empty {
70
69
  display: none;
71
- }
70
+ }
72
71
  </style>
73
-
74
72
  <script client>
75
73
  /**
76
- * VMZ UI — Result (UI4 Commercial Surface).
77
- * Outcome block for success/error flows; status → status.* tokens.
78
- */
74
+ * VMZ UI — Result (UI4 Commercial Surface).
75
+ * Outcome block for success/error flows; status → status.* tokens.
76
+ */
79
77
  export default class Result {
80
- public title: string = "";
81
- public description: string = "";
82
- public status: string = "info";
78
+ public title: string = "";
79
+ public description: string = "";
80
+ public status: string = "info";
83
81
  }
84
82
  </script>
@@ -1,30 +1,51 @@
1
1
  <template>
2
- <div class="vmz-ui-segmented" data-vmz-ui="segmented" role="group" :aria-label="label">
3
- <button
4
- v-for="opt in options"
5
- :key="opt.value"
6
- type="button"
7
- :data-vmz-segment="opt.value"
8
- :aria-pressed="opt.value === value ? 'true' : 'false'"
9
- @click="() => onPick(opt.value)"
10
- >{{ opt.label }}</button>
11
- </div>
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>
12
7
  </template>
13
8
  <style>
14
- .vmz-ui-segmented{display:inline-flex;max-width:100%;padding:.2rem;border-radius:var(--vmz-radius-md,6px);background:var(--vmz-surface-mist);overflow-x:auto}
15
- .vmz-ui-segmented button{min-height:2rem;padding:.3rem .75rem;border:0;border-radius:calc(var(--vmz-radius-md,6px) - 2px);background:transparent;color:var(--vmz-text-steel);font:inherit;font-size:.875rem;font-weight:550;white-space:nowrap;cursor:pointer}
16
- .vmz-ui-segmented button[aria-pressed='true']{background:var(--vmz-surface-paper);color:var(--vmz-text-ink);box-shadow:0 1px 3px rgba(0,0,0,.1)}
17
- .vmz-ui-segmented button:focus-visible{outline:2px solid var(--vmz-focus-ring);outline-offset:-2px}
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.3rem 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
+ }
18
39
  </style>
19
40
  <script client>
20
41
  export default class Segmented {
21
- public label: string = 'Segments';
22
- public value: string = '';
23
- public options: Array<{ value: string; label: string }> = [];
24
- public onChange: ((value: string) => void) | null = null;
25
- onPick(next: string) {
26
- this.emit('change', next);
27
- if (typeof this.onChange === 'function') this.onChange(next);
28
- }
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
+ }
29
50
  }
30
51
  </script>