@vmz/ui 0.3.6 → 0.3.8

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 (68) hide show
  1. package/README.md +53 -51
  2. package/contracts/token-requirements.v0.json +58 -1
  3. package/package.json +5 -2
  4. package/presets/web-surface.v0.json +14 -12
  5. package/src/components/Accordion.vmz +127 -94
  6. package/src/components/Alert.vmz +125 -28
  7. package/src/components/AppShell.vmz +125 -57
  8. package/src/components/Autocomplete.vmz +261 -154
  9. package/src/components/Avatar.vmz +20 -12
  10. package/src/components/Badge.vmz +62 -70
  11. package/src/components/Breadcrumb.vmz +86 -72
  12. package/src/components/BulkActions.vmz +56 -51
  13. package/src/components/Button.vmz +237 -211
  14. package/src/components/Callout.vmz +178 -77
  15. package/src/components/Card.vmz +141 -120
  16. package/src/components/Checkbox.vmz +131 -55
  17. package/src/components/CodeBlock.vmz +77 -30
  18. package/src/components/Collapse.vmz +64 -11
  19. package/src/components/ConsoleShell.vmz +405 -251
  20. package/src/components/Content.vmz +15 -1
  21. package/src/components/DataTable.vmz +294 -194
  22. package/src/components/DatePicker.vmz +766 -674
  23. package/src/components/Descriptions.vmz +90 -0
  24. package/src/components/Dialog.vmz +137 -38
  25. package/src/components/Divider.vmz +8 -1
  26. package/src/components/Drawer.vmz +518 -427
  27. package/src/components/Dropdown.vmz +195 -51
  28. package/src/components/Empty.vmz +96 -54
  29. package/src/components/Field.vmz +170 -115
  30. package/src/components/FilterBar.vmz +34 -4
  31. package/src/components/Flex.vmz +3 -1
  32. package/src/components/Footer.vmz +6 -3
  33. package/src/components/Form.vmz +41 -0
  34. package/src/components/FormItem.vmz +78 -79
  35. package/src/components/Grid.vmz +6 -3
  36. package/src/components/Header.vmz +193 -6
  37. package/src/components/Layout.vmz +3 -1
  38. package/src/components/Link.vmz +25 -10
  39. package/src/components/List.vmz +124 -102
  40. package/src/components/Menu.vmz +416 -243
  41. package/src/components/Message.vmz +167 -0
  42. package/src/components/Notification.vmz +132 -37
  43. package/src/components/Pagination.vmz +237 -69
  44. package/src/components/Popconfirm.vmz +287 -0
  45. package/src/components/Popover.vmz +341 -223
  46. package/src/components/Progress.vmz +16 -5
  47. package/src/components/Prose.vmz +180 -81
  48. package/src/components/QueryForm.vmz +31 -9
  49. package/src/components/RadioGroup.vmz +204 -124
  50. package/src/components/Result.vmz +60 -27
  51. package/src/components/Segmented.vmz +86 -51
  52. package/src/components/Select.vmz +620 -533
  53. package/src/components/Sider.vmz +120 -7
  54. package/src/components/Skeleton.vmz +9 -7
  55. package/src/components/Space.vmz +9 -3
  56. package/src/components/Spinner.vmz +5 -4
  57. package/src/components/Steps.vmz +118 -103
  58. package/src/components/Switch.vmz +131 -98
  59. package/src/components/Table.vmz +270 -165
  60. package/src/components/Tabs.vmz +125 -110
  61. package/src/components/Tag.vmz +60 -43
  62. package/src/components/TextArea.vmz +125 -118
  63. package/src/components/Timeline.vmz +111 -76
  64. package/src/components/Toc.vmz +90 -74
  65. package/src/components/Tooltip.vmz +107 -58
  66. package/src/components/Tree.vmz +214 -191
  67. package/src/components/Typography.vmz +23 -8
  68. package/src/components/Upload.vmz +1394 -1289
@@ -7,7 +7,21 @@
7
7
  .vmz-ui-content {
8
8
  flex: 1;
9
9
  min-width: 0;
10
- padding: 1.5rem;
10
+ box-sizing: border-box;
11
+ width: 100%;
12
+ max-width: var(--vmz-layout-max-width, 75rem);
13
+ margin: 0 auto;
14
+ padding: var(--vmz-space-6, 2rem) var(--vmz-layout-gutter, 1rem);
15
+ display: flex;
16
+ flex-direction: column;
17
+ gap: var(--vmz-space-6, 2rem);
18
+ color: var(--vmz-text-ink);
19
+ }
20
+ @media (max-width: 720px) {
21
+ .vmz-ui-content {
22
+ padding: var(--vmz-space-5, 1.5rem) var(--vmz-space-4, 1rem);
23
+ gap: var(--vmz-space-5, 1.5rem);
24
+ }
11
25
  }
12
26
  </style>
13
27
  <script client>
@@ -1,194 +1,294 @@
1
- <template>
2
- <div data-vmz-ui="data-table" :data-sort-key="sortKey" :data-sort-dir="sortDir" :data-selected-count="selectedCount" class="vmz-ui-datatable-wrap">
3
- <table class="vmz-ui-datatable">
4
- <thead @click="onHeadClick">
5
- <tr>
6
- <th scope="col" class="vmz-ui-datatable__check">
7
- <input type="checkbox" data-vmz-select-all="true" :aria-label="selectAllLabel" :checked="allSelected" class="vmz-ui-datatable__box" />
8
- </th>
9
- <th v-for="col in columns" :key="col.id" scope="col" :data-vmz-col="col.id">
10
- <button type="button" :data-vmz-sort="col.id" class="vmz-ui-datatable__sort">
11
- {{ col.title }}
12
- </button>
13
- </th>
14
- <th v-if="hasRowAction" scope="col">
15
- {{ actionTitle }}
16
- </th>
17
- </tr>
18
- </thead>
19
- <tbody @click="onBodyClick">
20
- <tr v-for="row in rows" :key="row.id" :data-vmz-row="row.id" :data-selected="row.selectedAttr">
21
- <td class="vmz-ui-datatable__check">
22
- <input type="checkbox" :data-vmz-select="row.id" :aria-label="row.selectLabel" :checked="row.selected" class="vmz-ui-datatable__box" />
23
- </td>
24
- <td v-for="cell in row.cells">
25
- {{ cell }}
26
- </td>
27
- <td v-if="hasRowAction">
28
- <button type="button" :data-vmz-row-action="row.id" :disabled="rowActionDisabled" class="vmz-ui-datatable__row-action">
29
- {{ actionLabel }}
30
- </button>
31
- </td>
32
- </tr>
33
- </tbody>
34
- </table>
35
- </div>
36
- </template>
37
- <style>
38
- .vmz-ui-datatable-wrap {
39
- max-height: 16rem;
40
- overflow: auto;
41
- border: 1px solid var(--vmz-line-default);
42
- border-radius: var(--vmz-radius-md, 6px);
43
- background: var(--vmz-surface-paper);
44
- color: var(--vmz-text-ink);
45
- }
46
-
47
- .vmz-ui-datatable {
48
- width: 100%;
49
- border-collapse: collapse;
50
- font: inherit;
51
- }
52
-
53
- .vmz-ui-datatable th,
54
- .vmz-ui-datatable td {
55
- padding: var(--vmz-density-compact-padding-y) var(--vmz-density-compact-padding-x);
56
- text-align: left;
57
- border-bottom: 1px solid var(--vmz-line-default);
58
- vertical-align: middle;
59
- }
60
-
61
- .vmz-ui-datatable thead th {
62
- position: sticky;
63
- top: 0;
64
- z-index: 1;
65
- font-weight: 700;
66
- color: var(--vmz-action-primary-active);
67
- background: var(--vmz-surface-mist);
68
- box-shadow: 0 1px 0 var(--vmz-line-default);
69
- }
70
-
71
- .vmz-ui-datatable__check {
72
- width: 2.25rem;
73
- }
74
-
75
- .vmz-ui-datatable__box {
76
- width: 1rem;
77
- height: 1rem;
78
- accent-color: var(--vmz-action-primary-background);
79
- outline: none;
80
- }
81
-
82
- .vmz-ui-datatable__box:focus-visible {
83
- box-shadow: 0 0 0 3px var(--vmz-focus-ring);
84
- }
85
-
86
- .vmz-ui-datatable tr[data-selected="true"] {
87
- background: color-mix(in srgb, var(--vmz-action-primary-background) 12%, transparent);
88
- }
89
-
90
- .vmz-ui-datatable__sort {
91
- font: inherit;
92
- font-weight: 700;
93
- padding: 0;
94
- border: 0;
95
- background: transparent;
96
- color: inherit;
97
- cursor: pointer;
98
- outline: none;
99
- }
100
-
101
- .vmz-ui-datatable__sort:focus-visible {
102
- box-shadow: 0 0 0 3px var(--vmz-focus-ring);
103
- }
104
-
105
- .vmz-ui-datatable__row-action {
106
- font: inherit;
107
- font-weight: 600;
108
- padding: 0.25rem 0.5rem;
109
- border: 1px solid var(--vmz-line-default);
110
- border-radius: var(--vmz-radius-md, 6px);
111
- background: transparent;
112
- color: var(--vmz-action-primary-active);
113
- cursor: pointer;
114
- outline: none;
115
- }
116
-
117
- .vmz-ui-datatable__row-action:focus-visible {
118
- box-shadow: 0 0 0 3px var(--vmz-focus-ring);
119
- }
120
-
121
- .vmz-ui-datatable__row-action:disabled {
122
- opacity: 0.55;
123
- cursor: not-allowed;
124
- }
125
- </style>
126
- <script client>
127
- /**
128
- * VMZ UI — DataTable (ordinary Console table).
129
- * Parent owns rows + selection + sort. Sticky header.
130
- * Large-grid features live outside this package.
131
- */
132
- export default class DataTable {
133
- /** @type {{ id: string, title: string }[]} */
134
- public columns: {
135
- id: string;
136
- title: string;
137
- }[] = [];
138
- /**
139
- * @type {{
140
- * id: string,
141
- * cells: string[],
142
- * selected: boolean,
143
- * selectedAttr: string,
144
- * selectLabel: string
145
- * }[]}
146
- */
147
- public rows: {
148
- id: string;
149
- cells: string[];
150
- selected: boolean;
151
- selectedAttr: string;
152
- selectLabel: string;
153
- }[] = [];
154
- public hasRowAction: boolean = false;
155
- public rowActionDisabled: boolean = false;
156
- public actionTitle: string = "Action";
157
- public actionLabel: string = "Open";
158
- public sortKey: string = "";
159
- public sortDir: string = "asc";
160
- public selectedCount: string = "0";
161
- public allSelected: boolean = false;
162
- public selectAllLabel: string = "Select all rows";
163
- public onRowAction: ((rowId: string) => void) | null = null;
164
- public onSort: ((columnId: string) => void) | null = null;
165
- public onToggleRow: ((rowId: string) => void) | null = null;
166
- public onToggleAll: (() => void) | null = null;
167
- onBodyClick(ev) {
168
- const t = ev && ev.target;
169
- if (!t || typeof t.closest !== "function") return;
170
- const select = t.closest("[data-vmz-select]");
171
- if (select) {
172
- const id = select.getAttribute("data-vmz-select");
173
- if (id && typeof this.onToggleRow === "function") this.onToggleRow(id);
174
- return;
175
- }
176
- const action = t.closest("[data-vmz-row-action]");
177
- if (!action || action.disabled) return;
178
- const id = action.getAttribute("data-vmz-row-action");
179
- if (id && typeof this.onRowAction === "function") this.onRowAction(id);
180
- }
181
- onHeadClick(ev) {
182
- const t = ev && ev.target;
183
- if (!t || typeof t.closest !== "function") return;
184
- if (t.closest("[data-vmz-select-all]")) {
185
- if (typeof this.onToggleAll === "function") this.onToggleAll();
186
- return;
187
- }
188
- const sort = t.closest("[data-vmz-sort]");
189
- if (!sort) return;
190
- const id = sort.getAttribute("data-vmz-sort");
191
- if (id && typeof this.onSort === "function") this.onSort(id);
192
- }
193
- }
194
- </script>
1
+ <template>
2
+ <div data-vmz-ui="data-table" :data-sort-key="sortKey" :data-sort-dir="sortDir" :data-selected-count="selectedCount" class="vmz-ui-datatable-wrap">
3
+ <table class="vmz-ui-datatable">
4
+ <thead @click="onHeadClick">
5
+ <tr>
6
+ <th scope="col" class="vmz-ui-datatable__check">
7
+ <input type="checkbox" data-vmz-select-all="true" :aria-label="selectAllLabel" :checked="allSelected" class="vmz-ui-datatable__box" />
8
+ </th>
9
+ <th v-for="col in columns" :key="col.id" scope="col" :data-vmz-col="col.id" :data-align="columnAlign(col)" :aria-sort="sortAria(col.id)">
10
+ <button type="button" :data-vmz-sort="col.id" :data-active="col.id === sortKey ? 'true' : 'false'" class="vmz-ui-datatable__sort">
11
+ <span class="vmz-ui-datatable__title">
12
+ {{ col.title }}
13
+ </span>
14
+ <span class="vmz-ui-datatable__sort-icon">
15
+ <Icon v-if="col.id === sortKey && sortDir === 'asc'" name="action.sort-asc" size="sm" decorative />
16
+ <Icon v-else-if="col.id === sortKey && sortDir === 'desc'" name="action.sort-desc" size="sm" decorative />
17
+ <Icon v-else name="action.sort" size="sm" decorative />
18
+ </span>
19
+ </button>
20
+ </th>
21
+ <th v-if="hasRowAction" scope="col">
22
+ {{ actionTitle }}
23
+ </th>
24
+ </tr>
25
+ </thead>
26
+ <tbody @click="onBodyClick">
27
+ <tr v-for="row in rows" :key="row.id" :data-vmz-row="row.id" :data-selected="row.selectedAttr">
28
+ <td class="vmz-ui-datatable__check">
29
+ <input type="checkbox" :data-vmz-select="row.id" :aria-label="row.selectLabel" :checked="row.selected" class="vmz-ui-datatable__box" />
30
+ </td>
31
+ <td v-for="(cell, index) in row.cells" :key="index" :data-align="cellAlign(index, cell)">
32
+ {{ cell }}
33
+ </td>
34
+ <td v-if="hasRowAction">
35
+ <button type="button" :data-vmz-row-action="row.id" :disabled="rowActionDisabled" class="vmz-ui-datatable__row-action">
36
+ {{ actionLabel }}
37
+ </button>
38
+ </td>
39
+ </tr>
40
+ </tbody>
41
+ </table>
42
+ </div>
43
+ </template>
44
+ <style>
45
+ .vmz-ui-datatable-wrap {
46
+ max-height: 16rem;
47
+ margin-bottom: 1rem;
48
+ overflow: auto;
49
+ border: 1px solid var(--vmz-line-default);
50
+ border-radius: var(--vmz-radius-lg, 8px);
51
+ background: var(--vmz-surface-paper);
52
+ color: var(--vmz-text-ink);
53
+ }
54
+
55
+ .vmz-ui-datatable {
56
+ width: 100%;
57
+ border-collapse: collapse;
58
+ font: inherit;
59
+ font-size: 0.875rem;
60
+ }
61
+
62
+ .vmz-ui-datatable th,
63
+ .vmz-ui-datatable td {
64
+ height: 3rem;
65
+ padding: 0 1rem;
66
+ text-align: left;
67
+ vertical-align: middle;
68
+ border: 0;
69
+ border-bottom: 1px solid var(--vmz-line-subtle);
70
+ white-space: nowrap;
71
+ }
72
+
73
+ .vmz-ui-datatable thead th {
74
+ position: sticky;
75
+ top: 0;
76
+ z-index: 1;
77
+ height: 2.75rem;
78
+ font-size: 0.75rem;
79
+ font-weight: 600;
80
+ color: var(--vmz-text-tertiary);
81
+ background: var(--vmz-surface-mist);
82
+ border-bottom: 0;
83
+ box-shadow: inset 0 -1px 0 var(--vmz-line-subtle);
84
+ }
85
+
86
+ .vmz-ui-datatable td[data-align="right"],
87
+ .vmz-ui-datatable th[data-align="right"] {
88
+ text-align: right;
89
+ font-variant-numeric: tabular-nums;
90
+ }
91
+
92
+ .vmz-ui-datatable td[data-align="center"],
93
+ .vmz-ui-datatable th[data-align="center"] {
94
+ text-align: center;
95
+ }
96
+
97
+ .vmz-ui-datatable tbody tr {
98
+ transition: background-color var(--vmz-motion-control-duration, 150ms)
99
+ var(--vmz-motion-control-easing, cubic-bezier(0.4, 0, 0.2, 1));
100
+ }
101
+
102
+ .vmz-ui-datatable tbody tr:hover {
103
+ background: var(--vmz-surface-fill);
104
+ }
105
+
106
+ .vmz-ui-datatable tbody tr:last-child td {
107
+ border-bottom: 0;
108
+ }
109
+
110
+ .vmz-ui-datatable th.vmz-ui-datatable__check,
111
+ .vmz-ui-datatable td.vmz-ui-datatable__check {
112
+ width: 3rem;
113
+ padding-right: 0;
114
+ }
115
+
116
+ .vmz-ui-datatable__box {
117
+ width: 1rem;
118
+ height: 1rem;
119
+ margin: 0;
120
+ accent-color: var(--vmz-action-primary-background);
121
+ outline: none;
122
+ cursor: pointer;
123
+ }
124
+
125
+ .vmz-ui-datatable__box:focus-visible {
126
+ box-shadow: 0 0 0 3px var(--vmz-focus-ring);
127
+ }
128
+
129
+ .vmz-ui-datatable tr[data-selected="true"] {
130
+ background: var(--vmz-action-primary-soft);
131
+ }
132
+
133
+ .vmz-ui-datatable__sort {
134
+ display: inline-flex;
135
+ align-items: center;
136
+ justify-content: flex-start;
137
+ gap: 0.25rem;
138
+ width: 100%;
139
+ padding: 0;
140
+ border: 0;
141
+ background: transparent;
142
+ color: inherit;
143
+ font: inherit;
144
+ font-size: 0.75rem;
145
+ font-weight: 600;
146
+ cursor: pointer;
147
+ outline: none;
148
+ border-radius: var(--vmz-radius-xs, 2px);
149
+ }
150
+
151
+ .vmz-ui-datatable th[data-align="right"] .vmz-ui-datatable__sort {
152
+ justify-content: flex-end;
153
+ }
154
+
155
+ .vmz-ui-datatable th[data-align="center"] .vmz-ui-datatable__sort {
156
+ justify-content: center;
157
+ }
158
+
159
+ .vmz-ui-datatable__sort:hover {
160
+ color: var(--vmz-action-primary-background);
161
+ }
162
+
163
+ .vmz-ui-datatable__sort:focus-visible {
164
+ box-shadow: 0 0 0 3px var(--vmz-focus-ring);
165
+ }
166
+
167
+ .vmz-ui-datatable__sort-icon {
168
+ display: inline-flex;
169
+ align-items: center;
170
+ color: var(--vmz-text-tertiary);
171
+ font-size: 0.875rem;
172
+ }
173
+
174
+ .vmz-ui-datatable__sort:hover .vmz-ui-datatable__sort-icon,
175
+ .vmz-ui-datatable__sort[data-active="true"] .vmz-ui-datatable__sort-icon {
176
+ color: var(--vmz-action-primary-background);
177
+ }
178
+
179
+ .vmz-ui-datatable__row-action {
180
+ height: 2rem;
181
+ padding: 0 0.5rem;
182
+ font: inherit;
183
+ font-size: 0.875rem;
184
+ font-weight: 500;
185
+ border: 0;
186
+ border-radius: var(--vmz-radius-md, 6px);
187
+ background: transparent;
188
+ color: var(--vmz-action-primary-background);
189
+ cursor: pointer;
190
+ outline: none;
191
+ transition:
192
+ color var(--vmz-motion-control-duration, 150ms) var(--vmz-motion-control-easing, cubic-bezier(0.4, 0, 0.2, 1)),
193
+ background-color var(--vmz-motion-control-duration, 150ms) var(--vmz-motion-control-easing, cubic-bezier(0.4, 0, 0.2, 1));
194
+ }
195
+
196
+ .vmz-ui-datatable__row-action:hover:not(:disabled) {
197
+ background: var(--vmz-action-primary-soft);
198
+ color: var(--vmz-action-primary-hover);
199
+ }
200
+
201
+ .vmz-ui-datatable__row-action:focus-visible {
202
+ box-shadow: 0 0 0 3px var(--vmz-focus-ring);
203
+ }
204
+
205
+ .vmz-ui-datatable__row-action:disabled {
206
+ opacity: 0.55;
207
+ cursor: not-allowed;
208
+ color: var(--vmz-text-tertiary);
209
+ }
210
+ </style>
211
+ <script client>
212
+ /**
213
+ * VMZ UI — DataTable (ordinary Console table).
214
+ * Parent owns rows + selection + sort. Sticky header.
215
+ * Large-grid features live outside this package.
216
+ */
217
+ export default class DataTable {
218
+ /** @type {{ id: string, title: string, align?: string }[]} */
219
+ public columns: {
220
+ id: string;
221
+ title: string;
222
+ align?: string;
223
+ }[] = [];
224
+ /**
225
+ * @type {{
226
+ * id: string,
227
+ * cells: string[],
228
+ * selected: boolean,
229
+ * selectedAttr: string,
230
+ * selectLabel: string
231
+ * }[]}
232
+ */
233
+ public rows: {
234
+ id: string;
235
+ cells: string[];
236
+ selected: boolean;
237
+ selectedAttr: string;
238
+ selectLabel: string;
239
+ }[] = [];
240
+ public hasRowAction: boolean = false;
241
+ public rowActionDisabled: boolean = false;
242
+ public actionTitle: string = "";
243
+ public actionLabel: string = "";
244
+ public sortKey: string = "";
245
+ public sortDir: string = "asc";
246
+ public selectedCount: string = "0";
247
+ public allSelected: boolean = false;
248
+ public selectAllLabel: string = "";
249
+ public onRowAction: ((rowId: string) => void) | null = null;
250
+ public onSort: ((columnId: string) => void) | null = null;
251
+ public onToggleRow: ((rowId: string) => void) | null = null;
252
+ public onToggleAll: (() => void) | null = null;
253
+ columnAlign(col) {
254
+ return col && col.align ? col.align : "left";
255
+ }
256
+ cellAlign(index, cell) {
257
+ const col = (this.columns || [])[index];
258
+ if (col && col.align) return col.align;
259
+ const text = String(cell == null ? "" : cell).trim();
260
+ if (!text) return "left";
261
+ return /^[-+]?[\d.,%]+$/.test(text) ? "right" : "left";
262
+ }
263
+ sortAria(id) {
264
+ if (id !== this.sortKey) return null;
265
+ return this.sortDir === "desc" ? "descending" : "ascending";
266
+ }
267
+ onBodyClick(ev) {
268
+ const t = ev && ev.target;
269
+ if (!t || typeof t.closest !== "function") return;
270
+ const select = t.closest("[data-vmz-select]");
271
+ if (select) {
272
+ const id = select.getAttribute("data-vmz-select");
273
+ if (id && typeof this.onToggleRow === "function") this.onToggleRow(id);
274
+ return;
275
+ }
276
+ const action = t.closest("[data-vmz-row-action]");
277
+ if (!action || action.disabled) return;
278
+ const id = action.getAttribute("data-vmz-row-action");
279
+ if (id && typeof this.onRowAction === "function") this.onRowAction(id);
280
+ }
281
+ onHeadClick(ev) {
282
+ const t = ev && ev.target;
283
+ if (!t || typeof t.closest !== "function") return;
284
+ if (t.closest("[data-vmz-select-all]")) {
285
+ if (typeof this.onToggleAll === "function") this.onToggleAll();
286
+ return;
287
+ }
288
+ const sort = t.closest("[data-vmz-sort]");
289
+ if (!sort) return;
290
+ const id = sort.getAttribute("data-vmz-sort");
291
+ if (id && typeof this.onSort === "function") this.onSort(id);
292
+ }
293
+ }
294
+ </script>