@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.
Files changed (66) hide show
  1. package/README.md +8 -0
  2. package/contracts/token-requirements.v0.json +2 -6
  3. package/package.json +18 -2
  4. package/presets/web-surface.v0.json +24 -10
  5. package/src/components/Accordion.vmz +88 -89
  6. package/src/components/Alert.vmz +64 -63
  7. package/src/components/AppShell.vmz +64 -45
  8. package/src/components/Autocomplete.vmz +152 -151
  9. package/src/components/Avatar.vmz +16 -0
  10. package/src/components/Badge.vmz +46 -46
  11. package/src/components/Breadcrumb.vmz +52 -48
  12. package/src/components/BulkActions.vmz +37 -37
  13. package/src/components/Button.vmz +90 -75
  14. package/src/components/Callout.vmz +61 -61
  15. package/src/components/Card.vmz +58 -51
  16. package/src/components/Checkbox.vmz +56 -53
  17. package/src/components/CodeBlock.vmz +51 -51
  18. package/src/components/Collapse.vmz +20 -0
  19. package/src/components/ConsoleShell.vmz +134 -99
  20. package/src/components/Content.vmz +11 -0
  21. package/src/components/DataTable.vmz +197 -196
  22. package/src/components/DatePicker.vmz +613 -536
  23. package/src/components/Dialog.vmz +365 -384
  24. package/src/components/Divider.vmz +19 -0
  25. package/src/components/Drawer.vmz +361 -378
  26. package/src/components/Dropdown.vmz +22 -0
  27. package/src/components/Empty.vmz +36 -36
  28. package/src/components/Field.vmz +69 -40
  29. package/src/components/FilterBar.vmz +15 -15
  30. package/src/components/Flex.vmz +12 -0
  31. package/src/components/Footer.vmz +11 -0
  32. package/src/components/Form.vmz +56 -58
  33. package/src/components/FormItem.vmz +59 -59
  34. package/src/components/Grid.vmz +12 -0
  35. package/src/components/Header.vmz +11 -0
  36. package/src/components/Icon.vmz +86 -0
  37. package/src/components/Layout.vmz +11 -0
  38. package/src/components/Link.vmz +33 -33
  39. package/src/components/List.vmz +96 -96
  40. package/src/components/Menu.vmz +229 -240
  41. package/src/components/Notification.vmz +62 -62
  42. package/src/components/Pagination.vmz +63 -65
  43. package/src/components/Popover.vmz +202 -219
  44. package/src/components/Progress.vmz +18 -0
  45. package/src/components/Prose.vmz +61 -61
  46. package/src/components/QueryForm.vmz +26 -27
  47. package/src/components/RadioGroup.vmz +116 -113
  48. package/src/components/Result.vmz +63 -63
  49. package/src/components/Segmented.vmz +29 -0
  50. package/src/components/Select.vmz +462 -290
  51. package/src/components/Sider.vmz +6 -0
  52. package/src/components/Skeleton.vmz +58 -58
  53. package/src/components/Space.vmz +15 -0
  54. package/src/components/Spinner.vmz +29 -29
  55. package/src/components/Steps.vmz +86 -86
  56. package/src/components/Switch.vmz +86 -88
  57. package/src/components/Table.vmz +116 -114
  58. package/src/components/Tabs.vmz +113 -112
  59. package/src/components/Tag.vmz +8 -0
  60. package/src/components/TextArea.vmz +76 -49
  61. package/src/components/Timeline.vmz +55 -50
  62. package/src/components/Toc.vmz +64 -60
  63. package/src/components/Tooltip.vmz +51 -51
  64. package/src/components/Tree.vmz +184 -190
  65. package/src/components/Typography.vmz +9 -0
  66. package/src/components/Upload.vmz +1130 -1151
@@ -1,134 +1,136 @@
1
1
  <template>
2
2
  <div class="vmz-ui-table-wrap" data-vmz-ui="table" data-sort-key={sortKey} data-sort-dir={sortDir}>
3
- <table class="vmz-ui-table">
4
- <thead onClick={onHeadClick}>
5
- <tr>
6
- <th each={columns} as="col" key={col.id} scope="col" data-vmz-col={col.id}>
7
- <button type="button" class="vmz-ui-table__sort" data-vmz-sort={col.id}>
8
- {col.title}
9
- </button>
10
- </th>
11
- <th if={hasRowAction} scope="col">{actionTitle}</th>
12
- </tr>
13
- </thead>
14
- <tbody onClick={onBodyClick}>
15
- <tr each={rows} as="row" key={row.id} data-vmz-row={row.id}>
16
- <td each={row.cells} as="cell">{cell}</td>
17
- <td if={hasRowAction}>
18
- <button
19
- type="button"
20
- class="vmz-ui-table__row-action"
21
- data-vmz-row-action={row.id}
22
- disabled={rowActionDisabled}
23
- >
24
- {actionLabel}
25
- </button>
26
- </td>
27
- </tr>
28
- </tbody>
29
- </table>
30
- </div>
3
+ <table class="vmz-ui-table">
4
+ <thead onClick={onHeadClick}>
5
+ <tr>
6
+ <th each={columns} as="col" key={col.id} scope="col" data-vmz-col={col.id}>
7
+ <button type="button" class="vmz-ui-table__sort" data-vmz-sort={col.id}>
8
+ {col.title}
9
+ </button>
10
+ </th>
11
+ <th if={hasRowAction} scope="col">{actionTitle}</th>
12
+ </tr>
13
+ </thead>
14
+ <tbody onClick={onBodyClick}>
15
+ <tr each={rows} as="row" key={row.id} data-vmz-row={row.id}>
16
+ <td each={row.cells} as="cell">{cell}</td>
17
+ <td if={hasRowAction}>
18
+ <button
19
+ type="button"
20
+ class="vmz-ui-table__row-action"
21
+ data-vmz-row-action={row.id}
22
+ disabled={rowActionDisabled}
23
+ >
24
+ {actionLabel}
25
+ </button>
26
+ </td>
27
+ </tr>
28
+ </tbody>
29
+ </table>
30
+ </div>
31
31
  </template>
32
32
 
33
33
  <style>
34
- .vmz-ui-table-wrap {
35
- overflow-x: auto;
36
- border: 1px solid var(--vmz-action-primary-background);
37
- border-radius: 2px;
38
- }
34
+ .vmz-ui-table-wrap {
35
+ overflow-x: auto;
36
+ border: 1px solid var(--vmz-line-default);
37
+ border-radius: var(--vmz-radius-md, 6px);
38
+ }
39
39
 
40
- .vmz-ui-table {
41
- width: 100%;
42
- border-collapse: collapse;
43
- font: inherit;
44
- }
40
+ .vmz-ui-table {
41
+ width: 100%;
42
+ border-collapse: collapse;
43
+ font: inherit;
44
+ }
45
45
 
46
- .vmz-ui-table th,
47
- .vmz-ui-table td {
48
- padding: var(--vmz-density-compact-padding-y) var(--vmz-density-compact-padding-x);
49
- text-align: left;
50
- border-bottom: 1px solid var(--vmz-action-primary-background);
51
- vertical-align: middle;
52
- }
46
+ .vmz-ui-table th,
47
+ .vmz-ui-table td {
48
+ padding: var(--vmz-density-compact-padding-y) var(--vmz-density-compact-padding-x);
49
+ text-align: left;
50
+ border-bottom: 1px solid var(--vmz-line-subtle, var(--vmz-line-default));
51
+ vertical-align: middle;
52
+ }
53
53
 
54
- .vmz-ui-table th {
55
- font-weight: 700;
56
- color: var(--vmz-action-primary-active);
57
- background: transparent;
58
- }
54
+ .vmz-ui-table th {
55
+ font-weight: 700;
56
+ color: var(--vmz-action-primary-active);
57
+ background: transparent;
58
+ }
59
59
 
60
- .vmz-ui-table__sort {
61
- font: inherit;
62
- font-weight: 700;
63
- padding: 0;
64
- border: 0;
65
- background: transparent;
66
- color: inherit;
67
- cursor: pointer;
68
- outline: none;
69
- }
60
+ .vmz-ui-table__sort {
61
+ font: inherit;
62
+ font-weight: 700;
63
+ padding: 0;
64
+ border: 0;
65
+ background: transparent;
66
+ color: inherit;
67
+ cursor: pointer;
68
+ outline: none;
69
+ }
70
70
 
71
- .vmz-ui-table__sort:focus-visible {
72
- box-shadow: 0 0 0 2px var(--vmz-focus-ring);
73
- }
71
+ .vmz-ui-table__sort:focus-visible {
72
+ box-shadow: 0 0 0 2px var(--vmz-focus-ring);
73
+ }
74
74
 
75
- .vmz-ui-table__row-action {
76
- font: inherit;
77
- font-weight: 600;
78
- padding: 0.3rem 0.55rem;
79
- border: 1px solid var(--vmz-action-primary-background);
80
- border-radius: 2px;
81
- background: transparent;
82
- color: var(--vmz-action-primary-active);
83
- cursor: pointer;
84
- outline: none;
85
- }
75
+ .vmz-ui-table__row-action {
76
+ font: inherit;
77
+ font-weight: 600;
78
+ padding: 0.3rem 0.55rem;
79
+ border: 1px solid var(--vmz-line-default);
80
+ border-radius: var(--vmz-radius-md, 6px);
81
+ background: transparent;
82
+ color: var(--vmz-action-primary-active);
83
+ cursor: pointer;
84
+ outline: none;
85
+ }
86
86
 
87
- .vmz-ui-table__row-action:focus-visible {
88
- box-shadow: 0 0 0 2px var(--vmz-focus-ring);
89
- }
87
+ .vmz-ui-table__row-action:focus-visible {
88
+ box-shadow: 0 0 0 2px var(--vmz-focus-ring);
89
+ }
90
90
 
91
- .vmz-ui-table__row-action:disabled {
92
- opacity: 0.55;
93
- cursor: not-allowed;
94
- }
91
+ .vmz-ui-table__row-action:disabled {
92
+ opacity: 0.55;
93
+ cursor: not-allowed;
94
+ }
95
95
  </style>
96
96
 
97
97
  <script client>
98
98
  /**
99
- * VMZ UI — Table (UI5 Console Surface).
100
- * Column header click → onSort; row action → onRowAction; permission via rowActionDisabled.
101
- */
99
+ * VMZ UI — Table (UI5 Console Surface).
100
+ * Column header click → onSort; row action → onRowAction; permission via rowActionDisabled.
101
+ */
102
102
  export default class Table {
103
- /** @type {{ id: string, title: string }[]} */
104
- public columns: { id: string; title: string }[] = [];
105
- /** @type {{ id: string, cells: string[] }[]} */
106
- public rows: { id: string; cells: string[] }[] = [];
107
- public hasRowAction: boolean = false;
108
- public rowActionDisabled: boolean = false;
109
- public actionTitle: string = 'Action';
110
- public actionLabel: string = 'Open';
111
- public sortKey: string = '';
112
- public sortDir: string = 'asc';
113
- public onRowAction: ((rowId: string) => void) | null = null;
114
- public onSort: ((columnId: string) => void) | null = null;
115
-
116
- onBodyClick(ev) {
117
- const t = ev && ev.target;
118
- const el =
119
- t && typeof t.closest === 'function' ? t.closest('[data-vmz-row-action]') : null;
120
- if (!el || el.disabled) return;
121
- const id = el.getAttribute('data-vmz-row-action');
122
- if (id && typeof this.onRowAction === 'function') this.onRowAction(id);
123
- }
124
-
125
- onHeadClick(ev) {
126
- const t = ev && ev.target;
127
- const el =
128
- t && typeof t.closest === 'function' ? t.closest('[data-vmz-sort]') : null;
129
- if (!el) return;
130
- const id = el.getAttribute('data-vmz-sort');
131
- if (id && typeof this.onSort === 'function') this.onSort(id);
132
- }
103
+ /** @type {{ id: string, title: string }[]} */
104
+ public columns: {
105
+ id: string;
106
+ title: string;
107
+ }[] = [];
108
+ /** @type {{ id: string, cells: string[] }[]} */
109
+ public rows: {
110
+ id: string;
111
+ cells: string[];
112
+ }[] = [];
113
+ public hasRowAction: boolean = false;
114
+ public rowActionDisabled: boolean = false;
115
+ public actionTitle: string = "Action";
116
+ public actionLabel: string = "Open";
117
+ public sortKey: string = "";
118
+ public sortDir: string = "asc";
119
+ public onRowAction: ((rowId: string) => void) | null = null;
120
+ public onSort: ((columnId: string) => void) | null = null;
121
+ onBodyClick(ev) {
122
+ const t = ev && ev.target;
123
+ const el = t && typeof t.closest === "function" ? t.closest("[data-vmz-row-action]") : null;
124
+ if (!el || el.disabled) return;
125
+ const id = el.getAttribute("data-vmz-row-action");
126
+ if (id && typeof this.onRowAction === "function") this.onRowAction(id);
127
+ }
128
+ onHeadClick(ev) {
129
+ const t = ev && ev.target;
130
+ const el = t && typeof t.closest === "function" ? t.closest("[data-vmz-sort]") : null;
131
+ if (!el) return;
132
+ const id = el.getAttribute("data-vmz-sort");
133
+ if (id && typeof this.onSort === "function") this.onSort(id);
134
+ }
133
135
  }
134
136
  </script>
@@ -1,132 +1,133 @@
1
1
  <template>
2
2
  <div class="vmz-ui-tabs" data-vmz-ui="tabs">
3
- <div
4
- class="vmz-ui-tabs__list"
5
- role="tablist"
6
- aria-label={label}
7
- onKeyDown={onListKeyDown}
8
- onClick={onListClick}
9
- >
10
- <button
11
- each={items}
12
- as="item"
13
- key={item.id}
14
- type="button"
15
- class="vmz-ui-tabs__tab"
16
- role="tab"
17
- id={item.id}
18
- data-vmz-tab={item.id}
19
- aria-selected={selected === item.id ? 'true' : 'false'}
20
- aria-controls={item.controls}
21
- tabindex={selected === item.id ? 0 : -1}
3
+ <div
4
+ class="vmz-ui-tabs__list"
5
+ role="tablist"
6
+ aria-label={label}
7
+ onKeyDown={onListKeyDown}
8
+ onClick={onListClick}
22
9
  >
23
- {item.title}
24
- </button>
25
- </div>
26
- <div
27
- class="vmz-ui-tabs__panel"
28
- role="tabpanel"
29
- id={panelId}
30
- data-vmz-tab-panel={selected}
31
- aria-labelledby={selected}
32
- tabindex="0"
33
- >
34
- <slot />
10
+ <button
11
+ each={items}
12
+ as="item"
13
+ key={item.id}
14
+ type="button"
15
+ class="vmz-ui-tabs__tab"
16
+ role="tab"
17
+ id={item.id}
18
+ data-vmz-tab={item.id}
19
+ aria-selected={selected === item.id ? 'true' : 'false'}
20
+ aria-controls={item.controls}
21
+ tabindex={selected === item.id ? 0 : -1}
22
+ >
23
+ {item.title}
24
+ </button>
25
+ </div>
26
+ <div
27
+ class="vmz-ui-tabs__panel"
28
+ role="tabpanel"
29
+ id={panelId}
30
+ data-vmz-tab-panel={selected}
31
+ aria-labelledby={selected}
32
+ tabindex="0"
33
+ >
34
+ <slot />
35
+ </div>
35
36
  </div>
36
- </div>
37
37
  </template>
38
38
 
39
39
  <style>
40
- .vmz-ui-tabs {
41
- display: flex;
42
- flex-direction: column;
43
- gap: 0.65rem;
44
- max-width: 36rem;
45
- }
40
+ .vmz-ui-tabs {
41
+ display: flex;
42
+ flex-direction: column;
43
+ gap: 0.65rem;
44
+ max-width: 36rem;
45
+ }
46
46
 
47
- .vmz-ui-tabs__list {
48
- display: flex;
49
- flex-wrap: wrap;
50
- gap: 0.25rem;
51
- border-bottom: 1px solid var(--vmz-action-primary-background);
52
- }
47
+ .vmz-ui-tabs__list {
48
+ display: flex;
49
+ flex-wrap: wrap;
50
+ gap: 0.25rem;
51
+ border-bottom: 1px solid var(--vmz-line-subtle, var(--vmz-line-default));
52
+ }
53
53
 
54
- .vmz-ui-tabs__tab {
55
- font: inherit;
56
- font-weight: 600;
57
- padding: 0.45rem 0.75rem;
58
- border: 1px solid transparent;
59
- border-bottom: none;
60
- border-radius: 2px 2px 0 0;
61
- background: transparent;
62
- color: inherit;
63
- cursor: pointer;
64
- outline: none;
65
- }
54
+ .vmz-ui-tabs__tab {
55
+ font: inherit;
56
+ font-size: 0.875rem;
57
+ font-weight: 400;
58
+ padding: 0.5rem 0;
59
+ margin: 0 1rem 0 0;
60
+ border: 0;
61
+ border-bottom: 2px solid transparent;
62
+ border-radius: 0;
63
+ background: transparent;
64
+ color: var(--vmz-text-ink);
65
+ cursor: pointer;
66
+ outline: none;
67
+ }
66
68
 
67
- .vmz-ui-tabs__tab[aria-selected='true'] {
68
- background: var(--vmz-action-primary-background);
69
- color: var(--vmz-action-primary-foreground);
70
- }
69
+ .vmz-ui-tabs__tab[aria-selected='true'] {
70
+ background: transparent;
71
+ color: var(--vmz-action-primary-background);
72
+ font-weight: 500;
73
+ border-bottom-color: var(--vmz-action-primary-background);
74
+ }
71
75
 
72
- .vmz-ui-tabs__tab:focus-visible {
73
- box-shadow: 0 0 0 2px var(--vmz-focus-ring);
74
- }
76
+ .vmz-ui-tabs__tab:focus-visible {
77
+ box-shadow: 0 0 0 2px var(--vmz-focus-ring);
78
+ }
75
79
 
76
- .vmz-ui-tabs__panel {
77
- min-height: 2.5rem;
78
- outline: none;
79
- }
80
+ .vmz-ui-tabs__panel {
81
+ min-height: 2.5rem;
82
+ outline: none;
83
+ }
80
84
 
81
- .vmz-ui-tabs__panel:focus-visible {
82
- box-shadow: 0 0 0 2px var(--vmz-focus-ring);
83
- }
85
+ .vmz-ui-tabs__panel:focus-visible {
86
+ box-shadow: 0 0 0 2px var(--vmz-focus-ring);
87
+ }
84
88
  </style>
85
89
 
86
90
  <script client>
87
91
  /**
88
- * VMZ UI — Tabs (UI2).
89
- * Parent owns `selected` id; keyboard Left/Right/Home/End on the tablist.
90
- * Panel content is the default slot (page chooses which body to show).
91
- */
92
+ * VMZ UI — Tabs (UI2).
93
+ * Parent owns `selected` id; keyboard Left/Right/Home/End on the tablist.
94
+ * Panel content is the default slot (page chooses which body to show).
95
+ */
92
96
  export default class Tabs {
93
- public label: string = 'Tabs';
94
- public selected: string = '';
95
- public panelId: string = '';
96
- /** @type {{ id: string, title: string, controls?: string }[]} */
97
- public items: { id: string; title: string; controls?: string }[] = [];
98
- public onSelect: ((id: string) => void) | null = null;
99
-
100
- select(id) {
101
- if (typeof this.onSelect === 'function') this.onSelect(id);
102
- }
103
-
104
- onListClick(ev) {
105
- const t = ev && ev.target;
106
- const el =
107
- t && typeof t.closest === 'function' ? t.closest('[data-vmz-tab]') : null;
108
- const id = el && typeof el.getAttribute === 'function' ? el.getAttribute('data-vmz-tab') : null;
109
- if (id) this.select(id);
110
- }
111
-
112
- onListKeyDown(ev) {
113
- if (!ev || !this.items?.length) return;
114
- const ids = this.items.map((it) => it.id);
115
- const idx = Math.max(0, ids.indexOf(this.selected));
116
- let next = idx;
117
- if (ev.key === 'ArrowRight') next = (idx + 1) % ids.length;
118
- else if (ev.key === 'ArrowLeft') next = (idx - 1 + ids.length) % ids.length;
119
- else if (ev.key === 'Home') next = 0;
120
- else if (ev.key === 'End') next = ids.length - 1;
121
- else return;
122
- ev.preventDefault();
123
- this.select(ids[next]);
124
- const root = this.__vmzDomRoot;
125
- const btn =
126
- root && typeof root.querySelector === 'function'
127
- ? root.querySelector(`[data-vmz-tab="${ids[next]}"]`)
128
- : null;
129
- if (btn && typeof btn.focus === 'function') btn.focus();
130
- }
97
+ public label: string = "Tabs";
98
+ public selected: string = "";
99
+ public panelId: string = "";
100
+ /** @type {{ id: string, title: string, controls?: string }[]} */
101
+ public items: {
102
+ id: string;
103
+ title: string;
104
+ controls?: string;
105
+ }[] = [];
106
+ public onSelect: ((id: string) => void) | null = null;
107
+ select(id) {
108
+ if (typeof this.onSelect === "function") this.onSelect(id);
109
+ }
110
+ onListClick(ev) {
111
+ const t = ev && ev.target;
112
+ const el = t && typeof t.closest === "function" ? t.closest("[data-vmz-tab]") : null;
113
+ const id = el && typeof el.getAttribute === "function" ? el.getAttribute("data-vmz-tab") : null;
114
+ if (id) this.select(id);
115
+ }
116
+ onListKeyDown(ev) {
117
+ if (!ev || !this.items?.length) return;
118
+ const ids = this.items.map((it) => it.id);
119
+ const idx = Math.max(0, ids.indexOf(this.selected));
120
+ let next = idx;
121
+ if (ev.key === "ArrowRight") next = (idx + 1) % ids.length;
122
+ else if (ev.key === "ArrowLeft") next = (idx - 1 + ids.length) % ids.length;
123
+ else if (ev.key === "Home") next = 0;
124
+ else if (ev.key === "End") next = ids.length - 1;
125
+ else return;
126
+ ev.preventDefault();
127
+ this.select(ids[next]);
128
+ const root = this.__vmzDomRoot;
129
+ const btn = root && typeof root.querySelector === "function" ? root.querySelector(`[data-vmz-tab="${ids[next]}"]`) : null;
130
+ if (btn && typeof btn.focus === "function") btn.focus();
131
+ }
131
132
  }
132
133
  </script>
@@ -0,0 +1,8 @@
1
+ <template><span class="vmz-ui-tag" data-vmz-ui="tag" data-status={status||undefined}><slot /></span></template>
2
+ <style>
3
+ .vmz-ui-tag{display:inline-flex;align-items:center;min-height:1.5rem;padding:0 .45rem;border:1px solid var(--vmz-line-default);border-radius:var(--vmz-radius-sm,2px);background:var(--vmz-surface-mist);color:var(--vmz-text-steel);font-size:.75rem;line-height:1}
4
+ .vmz-ui-tag[data-status='success']{color:var(--vmz-status-success-foreground);background:color-mix(in srgb,var(--vmz-status-success-accent) 12%,var(--vmz-surface-paper));border-color:color-mix(in srgb,var(--vmz-status-success-accent) 45%,var(--vmz-line-default))}
5
+ .vmz-ui-tag[data-status='warning']{color:var(--vmz-status-warning-foreground);background:color-mix(in srgb,var(--vmz-status-warning-accent) 12%,var(--vmz-surface-paper));border-color:color-mix(in srgb,var(--vmz-status-warning-accent) 45%,var(--vmz-line-default))}
6
+ .vmz-ui-tag[data-status='error']{color:var(--vmz-status-danger-foreground);background:color-mix(in srgb,var(--vmz-status-danger-accent) 12%,var(--vmz-surface-paper));border-color:color-mix(in srgb,var(--vmz-status-danger-accent) 45%,var(--vmz-line-default))}
7
+ </style>
8
+ <script client>export default class Tag { public status: string = ''; }</script>