@vmz/ui 0.2.3 → 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.
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,50 +1,22 @@
1
1
  <template>
2
- <div class="vmz-ui-menu" data-vmz-ui="menu" :data-vmz-overlay-open="open">
3
- <button
4
- type="button"
5
- class="vmz-ui-menu__trigger"
6
- data-vmz-menu="trigger"
7
- aria-haspopup="menu"
8
- :aria-expanded="open ? 'true' : 'false'"
9
- :aria-controls="menuId"
10
- @click="toggle"
11
- :onKeyDown="onTriggerKeyDown"
12
- >
13
- {{ label }}
14
- </button>
15
- <div
16
- v-if="open"
17
- :id="menuId"
18
- class="vmz-ui-menu__panel"
19
- role="menu"
20
- data-vmz-overlay="menu"
21
- data-vmz-overlay-owner="menu"
22
- data-vmz-focus="enter"
23
- tabindex="-1"
24
- :onKeyDown="onMenuKeyDown"
25
- >
26
- <button
27
- v-for="item in items"
28
- :key="item.id"
29
- type="button"
30
- class="vmz-ui-menu__item"
31
- role="menuitem"
32
- :data-vmz-menu-item="item.id"
33
- @click="onItemClick"
34
- >
35
- {{ item.title }}
2
+ <div data-vmz-ui="menu" :data-vmz-overlay-open="open" class="vmz-ui-menu">
3
+ <button type="button" data-vmz-menu="trigger" aria-haspopup="menu" :aria-expanded='open ? "true" : "false"' :aria-controls="menuId" @click="toggle" :onKeyDown="onTriggerKeyDown" class="vmz-ui-menu__trigger">
4
+ {{ label }}
36
5
  </button>
37
- </div>
6
+ <div v-if="open" :id="menuId" role="menu" data-vmz-overlay="menu" data-vmz-overlay-owner="menu" data-vmz-focus="enter" tabindex="-1" :onKeyDown="onMenuKeyDown" class="vmz-ui-menu__panel">
7
+ <button v-for="item in items" :key="item.id" type="button" role="menuitem" :data-vmz-menu-item="item.id" @click="onItemClick" class="vmz-ui-menu__item">
8
+ {{ item.title }}
9
+ </button>
10
+ </div>
38
11
  </div>
39
12
  </template>
40
-
41
13
  <style>
42
- .vmz-ui-menu {
14
+ .vmz-ui-menu {
43
15
  position: relative;
44
16
  display: inline-block;
45
- }
17
+ }
46
18
 
47
- .vmz-ui-menu__trigger {
19
+ .vmz-ui-menu__trigger {
48
20
  font: inherit;
49
21
  font-size: 0.875rem;
50
22
  font-weight: 400;
@@ -56,18 +28,18 @@
56
28
  background: var(--vmz-surface-paper, #fff);
57
29
  color: var(--vmz-text-ink);
58
30
  outline: none;
59
- }
31
+ }
60
32
 
61
- .vmz-ui-menu__trigger:hover {
33
+ .vmz-ui-menu__trigger:hover {
62
34
  color: var(--vmz-action-primary-background);
63
35
  border-color: var(--vmz-action-primary-background);
64
- }
36
+ }
65
37
 
66
- .vmz-ui-menu__trigger:focus-visible {
38
+ .vmz-ui-menu__trigger:focus-visible {
67
39
  box-shadow: 0 0 0 2px var(--vmz-focus-ring);
68
- }
40
+ }
69
41
 
70
- .vmz-ui-menu__panel {
42
+ .vmz-ui-menu__panel {
71
43
  position: absolute;
72
44
  z-index: 30;
73
45
  top: calc(100% + 0.25rem);
@@ -80,13 +52,13 @@
80
52
  color: var(--vmz-text-ink);
81
53
  box-shadow: var(--vmz-shadow-popup);
82
54
  outline: none;
83
- }
55
+ }
84
56
 
85
- .vmz-ui-menu__panel:focus-visible {
57
+ .vmz-ui-menu__panel:focus-visible {
86
58
  box-shadow: 0 0 0 2px var(--vmz-focus-ring);
87
- }
59
+ }
88
60
 
89
- .vmz-ui-menu__item {
61
+ .vmz-ui-menu__item {
90
62
  display: block;
91
63
  width: 100%;
92
64
  text-align: left;
@@ -98,161 +70,174 @@
98
70
  color: inherit;
99
71
  cursor: pointer;
100
72
  outline: none;
101
- }
73
+ }
102
74
 
103
- .vmz-ui-menu__item:hover,
104
- .vmz-ui-menu__item:focus-visible {
75
+ .vmz-ui-menu__item:hover,
76
+ .vmz-ui-menu__item:focus-visible {
105
77
  background: color-mix(in srgb, var(--vmz-action-primary-background) 18%, transparent);
106
- }
78
+ }
107
79
 
108
- .vmz-ui-menu__item:focus-visible {
80
+ .vmz-ui-menu__item:focus-visible {
109
81
  box-shadow: 0 0 0 2px var(--vmz-focus-ring);
110
- }
82
+ }
111
83
  </style>
112
-
113
84
  <script client>
114
85
  /**
115
- * VMZ UI — Menu (UI2).
116
- * Parent owns `open`; Escape / choose closes via onClose; focus restore to trigger.
117
- */
86
+ * VMZ UI — Menu (UI2).
87
+ * Parent owns `open`; Escape / choose closes via onClose; focus restore to trigger.
88
+ */
118
89
  export default class Menu {
119
- public label: string = "Menu";
120
- public open: boolean = false;
121
- public menuId: string = "vmz-menu";
122
- /** @type {{ id: string, title: string }[]} */
123
- public items: {
124
- id: string;
125
- title: string;
126
- }[] = [];
127
- public onOpenChange: ((open: boolean) => void) | null = null;
128
- public onSelect: ((id: string) => void) | null = null;
129
- _restoreFocus = null;
130
- _panel = null;
131
- _docKeyHandler = null;
132
- _docPointerHandler = null;
133
- _observer = null;
134
- async onMount() {
135
- if (typeof document === "undefined" || typeof MutationObserver === "undefined") return;
136
- const root = this.__vmzDomRoot;
137
- if (!root || typeof root.querySelector !== "function") return;
138
- this._observer = new MutationObserver(() => this._syncFromDom());
139
- this._observer.observe(root, {
140
- childList: true,
141
- subtree: true
142
- });
143
- this._syncFromDom();
144
- }
145
- onDestroy() {
146
- if (this._observer) {
147
- this._observer.disconnect();
148
- this._observer = null;
149
- }
150
- this._teardownDoc();
151
- this._panel = null;
152
- this._restoreFocus = null;
153
- }
154
- toggle() {
155
- if (typeof this.onOpenChange === "function") this.onOpenChange(!this.open);
156
- }
157
- close() {
158
- if (typeof this.onOpenChange === "function") this.onOpenChange(false);
159
- }
160
- choose(id) {
161
- if (typeof this.onSelect === "function") this.onSelect(id);
162
- this.close();
163
- }
164
- onItemClick(ev) {
165
- const el = ev?.currentTarget;
166
- const id = el && typeof el.getAttribute === "function" ? el.getAttribute("data-vmz-menu-item") : null;
167
- if (id) this.choose(id);
168
- }
169
- onTriggerKeyDown(ev) {
170
- if (!ev) return;
171
- if ((ev.key === "ArrowDown" || ev.key === "Enter" || ev.key === " ") && !this.open) {
172
- ev.preventDefault();
173
- if (typeof this.onOpenChange === "function") this.onOpenChange(true);
174
- }
175
- }
176
- onMenuKeyDown(ev) {
177
- if (!ev || !this._panel) return;
178
- if (ev.key === "Escape") {
179
- ev.preventDefault();
180
- this.close();
181
- return;
182
- }
183
- const nodes = [...this._panel.querySelectorAll("[role=\"menuitem\"]")].filter((n) => n instanceof HTMLElement && n.offsetParent !== null);
184
- if (!nodes.length) return;
185
- const idx = nodes.indexOf(document.activeElement);
186
- if (ev.key === "ArrowDown") {
187
- ev.preventDefault();
188
- nodes[(idx + 1 + nodes.length) % nodes.length].focus();
189
- } else if (ev.key === "ArrowUp") {
190
- ev.preventDefault();
191
- nodes[(idx - 1 + nodes.length) % nodes.length].focus();
192
- } else if (ev.key === "Home") {
193
- ev.preventDefault();
194
- nodes[0].focus();
195
- } else if (ev.key === "End") {
196
- ev.preventDefault();
197
- nodes[nodes.length - 1].focus();
198
- }
199
- }
200
- _syncFromDom() {
201
- const root = this.__vmzDomRoot;
202
- const panel = root && typeof root.querySelector === "function" ? root.querySelector("[data-vmz-overlay=\"menu\"][data-vmz-focus=\"enter\"]") : null;
203
- if (panel && !this._panel) this._enterFocus(panel);
204
- else if (!panel && this._panel) this._exitFocus();
205
- }
206
- _enterFocus(panel) {
207
- if (typeof document === "undefined") return;
208
- const root = this.__vmzDomRoot;
209
- const trigger = root && typeof root.querySelector === "function" ? root.querySelector("[data-vmz-menu=\"trigger\"]") : null;
210
- const active = document.activeElement;
211
- if (!this._restoreFocus) {
212
- if (trigger instanceof HTMLElement) this._restoreFocus = trigger;
213
- else if (active instanceof HTMLElement) this._restoreFocus = active;
214
- }
215
- this._panel = panel instanceof HTMLElement ? panel : null;
216
- const first = this._panel && typeof this._panel.querySelector === "function" ? this._panel.querySelector("[role=\"menuitem\"]") : null;
217
- if (first && typeof first.focus === "function") first.focus();
218
- else if (this._panel && typeof this._panel.focus === "function") this._panel.focus();
219
- if (!this._docKeyHandler) {
220
- this._docKeyHandler = (ev) => {
221
- if (ev.key === "Escape") {
222
- ev.preventDefault();
223
- this.close();
224
- }
225
- };
226
- document.addEventListener("keydown", this._docKeyHandler);
227
- }
228
- if (!this._docPointerHandler) {
229
- this._docPointerHandler = (ev) => {
230
- const t = ev.target;
231
- if (!(t instanceof Node)) return;
232
- if (root && typeof root.contains === "function" && root.contains(t)) return;
233
- this.close();
234
- };
235
- document.addEventListener("pointerdown", this._docPointerHandler, true);
236
- }
237
- }
238
- _exitFocus() {
239
- this._teardownDoc();
240
- this._panel = null;
241
- const restore = this._restoreFocus;
242
- this._restoreFocus = null;
243
- if (restore && typeof restore.focus === "function" && document.contains(restore)) {
244
- restore.focus();
245
- }
246
- }
247
- _teardownDoc() {
248
- if (typeof document !== "undefined") {
249
- if (this._docKeyHandler) document.removeEventListener("keydown", this._docKeyHandler);
250
- if (this._docPointerHandler) {
251
- document.removeEventListener("pointerdown", this._docPointerHandler, true);
252
- }
253
- }
254
- this._docKeyHandler = null;
255
- this._docPointerHandler = null;
256
- }
90
+ public label: string = "Menu";
91
+ public open: boolean = false;
92
+ public menuId: string = "vmz-menu";
93
+ /** @type {{ id: string, title: string }[]} */
94
+ public items: {
95
+ id: string;
96
+ title: string;
97
+ }[] = [];
98
+ public onOpenChange: ((open: boolean) => void) | null = null;
99
+ public onSelect: ((id: string) => void) | null = null;
100
+ _restoreFocus = null;
101
+ _panel = null;
102
+ _docKeyHandler = null;
103
+ _docPointerHandler = null;
104
+ _observer = null;
105
+ async onMount() {
106
+ if (typeof document === "undefined" || typeof MutationObserver === "undefined") return;
107
+ const root = this.__vmzDomRoot;
108
+ if (!root || typeof root.querySelector !== "function") return;
109
+ this._observer = new MutationObserver(() => this._syncFromDom());
110
+ this._observer.observe(root, {
111
+ childList: true,
112
+ subtree: true,
113
+ });
114
+ this._syncFromDom();
115
+ }
116
+ onDestroy() {
117
+ if (this._observer) {
118
+ this._observer.disconnect();
119
+ this._observer = null;
120
+ }
121
+ this._teardownDoc();
122
+ this._panel = null;
123
+ this._restoreFocus = null;
124
+ }
125
+ toggle() {
126
+ if (typeof this.onOpenChange === "function") this.onOpenChange(!this.open);
127
+ }
128
+ close() {
129
+ if (typeof this.onOpenChange === "function") this.onOpenChange(false);
130
+ }
131
+ choose(id) {
132
+ if (typeof this.onSelect === "function") this.onSelect(id);
133
+ this.close();
134
+ }
135
+ onItemClick(ev) {
136
+ const el = ev?.currentTarget;
137
+ const id =
138
+ el && typeof el.getAttribute === "function"
139
+ ? el.getAttribute("data-vmz-menu-item")
140
+ : null;
141
+ if (id) this.choose(id);
142
+ }
143
+ onTriggerKeyDown(ev) {
144
+ if (!ev) return;
145
+ if ((ev.key === "ArrowDown" || ev.key === "Enter" || ev.key === " ") && !this.open) {
146
+ ev.preventDefault();
147
+ if (typeof this.onOpenChange === "function") this.onOpenChange(true);
148
+ }
149
+ }
150
+ onMenuKeyDown(ev) {
151
+ if (!ev || !this._panel) return;
152
+ if (ev.key === "Escape") {
153
+ ev.preventDefault();
154
+ this.close();
155
+ return;
156
+ }
157
+ const nodes = [...this._panel.querySelectorAll('[role="menuitem"]')].filter(
158
+ (n) => n instanceof HTMLElement && n.offsetParent !== null,
159
+ );
160
+ if (!nodes.length) return;
161
+ const idx = nodes.indexOf(document.activeElement);
162
+ if (ev.key === "ArrowDown") {
163
+ ev.preventDefault();
164
+ nodes[(idx + 1 + nodes.length) % nodes.length].focus();
165
+ } else if (ev.key === "ArrowUp") {
166
+ ev.preventDefault();
167
+ nodes[(idx - 1 + nodes.length) % nodes.length].focus();
168
+ } else if (ev.key === "Home") {
169
+ ev.preventDefault();
170
+ nodes[0].focus();
171
+ } else if (ev.key === "End") {
172
+ ev.preventDefault();
173
+ nodes[nodes.length - 1].focus();
174
+ }
175
+ }
176
+ _syncFromDom() {
177
+ const root = this.__vmzDomRoot;
178
+ const panel =
179
+ root && typeof root.querySelector === "function"
180
+ ? root.querySelector('[data-vmz-overlay="menu"][data-vmz-focus="enter"]')
181
+ : null;
182
+ if (panel && !this._panel) this._enterFocus(panel);
183
+ else if (!panel && this._panel) this._exitFocus();
184
+ }
185
+ _enterFocus(panel) {
186
+ if (typeof document === "undefined") return;
187
+ const root = this.__vmzDomRoot;
188
+ const trigger =
189
+ root && typeof root.querySelector === "function"
190
+ ? root.querySelector('[data-vmz-menu="trigger"]')
191
+ : null;
192
+ const active = document.activeElement;
193
+ if (!this._restoreFocus) {
194
+ if (trigger instanceof HTMLElement) this._restoreFocus = trigger;
195
+ else if (active instanceof HTMLElement) this._restoreFocus = active;
196
+ }
197
+ this._panel = panel instanceof HTMLElement ? panel : null;
198
+ const first =
199
+ this._panel && typeof this._panel.querySelector === "function"
200
+ ? this._panel.querySelector('[role="menuitem"]')
201
+ : null;
202
+ if (first && typeof first.focus === "function") first.focus();
203
+ else if (this._panel && typeof this._panel.focus === "function") this._panel.focus();
204
+ if (!this._docKeyHandler) {
205
+ this._docKeyHandler = (ev) => {
206
+ if (ev.key === "Escape") {
207
+ ev.preventDefault();
208
+ this.close();
209
+ }
210
+ };
211
+ document.addEventListener("keydown", this._docKeyHandler);
212
+ }
213
+ if (!this._docPointerHandler) {
214
+ this._docPointerHandler = (ev) => {
215
+ const t = ev.target;
216
+ if (!(t instanceof Node)) return;
217
+ if (root && typeof root.contains === "function" && root.contains(t)) return;
218
+ this.close();
219
+ };
220
+ document.addEventListener("pointerdown", this._docPointerHandler, true);
221
+ }
222
+ }
223
+ _exitFocus() {
224
+ this._teardownDoc();
225
+ this._panel = null;
226
+ const restore = this._restoreFocus;
227
+ this._restoreFocus = null;
228
+ if (restore && typeof restore.focus === "function" && document.contains(restore)) {
229
+ restore.focus();
230
+ }
231
+ }
232
+ _teardownDoc() {
233
+ if (typeof document !== "undefined") {
234
+ if (this._docKeyHandler) document.removeEventListener("keydown", this._docKeyHandler);
235
+ if (this._docPointerHandler) {
236
+ document.removeEventListener("pointerdown", this._docPointerHandler, true);
237
+ }
238
+ }
239
+ this._docKeyHandler = null;
240
+ this._docPointerHandler = null;
241
+ }
257
242
  }
258
243
  </script>
@@ -1,20 +1,18 @@
1
1
  <template>
2
- <div
3
- class="vmz-ui-notification"
4
- data-vmz-ui="notification"
5
- :data-tone="tone"
6
- :role="roleName"
7
- >
8
- <p v-if="title" class="vmz-ui-notification__title">{{ title }}</p>
9
- <p v-if="description" class="vmz-ui-notification__description">{{ description }}</p>
10
- <div class="vmz-ui-notification__actions">
11
- <slot />
12
- </div>
2
+ <div data-vmz-ui="notification" :data-tone="tone" :role="roleName" class="vmz-ui-notification">
3
+ <p v-if="title" class="vmz-ui-notification__title">
4
+ {{ title }}
5
+ </p>
6
+ <p v-if="description" class="vmz-ui-notification__description">
7
+ {{ description }}
8
+ </p>
9
+ <div class="vmz-ui-notification__actions">
10
+ <slot />
11
+ </div>
13
12
  </div>
14
13
  </template>
15
-
16
14
  <style>
17
- .vmz-ui-notification {
15
+ .vmz-ui-notification {
18
16
  display: flex;
19
17
  flex-direction: column;
20
18
  gap: var(--vmz-density-control-gap);
@@ -23,61 +21,60 @@
23
21
  border-radius: var(--vmz-radius-md, 6px);
24
22
  background: color-mix(in srgb, var(--vmz-status-info-accent) 10%, transparent);
25
23
  color: var(--vmz-status-info-foreground);
26
- }
24
+ }
27
25
 
28
- .vmz-ui-notification[data-tone='info'] {
26
+ .vmz-ui-notification[data-tone="info"] {
29
27
  border-color: var(--vmz-status-info-accent);
30
28
  background: color-mix(in srgb, var(--vmz-status-info-accent) 10%, transparent);
31
29
  color: var(--vmz-status-info-foreground);
32
- }
30
+ }
33
31
 
34
- .vmz-ui-notification[data-tone='success'] {
32
+ .vmz-ui-notification[data-tone="success"] {
35
33
  border-color: var(--vmz-status-success-accent);
36
34
  background: color-mix(in srgb, var(--vmz-status-success-accent) 10%, transparent);
37
35
  color: var(--vmz-status-success-foreground);
38
- }
36
+ }
39
37
 
40
- .vmz-ui-notification[data-tone='warning'] {
38
+ .vmz-ui-notification[data-tone="warning"] {
41
39
  border-color: var(--vmz-status-warning-accent);
42
40
  background: color-mix(in srgb, var(--vmz-status-warning-accent) 10%, transparent);
43
41
  color: var(--vmz-status-warning-foreground);
44
- }
42
+ }
45
43
 
46
- .vmz-ui-notification[data-tone='danger'] {
44
+ .vmz-ui-notification[data-tone="danger"] {
47
45
  border-color: var(--vmz-status-danger-accent);
48
46
  background: color-mix(in srgb, var(--vmz-status-danger-accent) 10%, transparent);
49
47
  color: var(--vmz-status-danger-foreground);
50
- }
48
+ }
51
49
 
52
- :where([data-density='compact']) .vmz-ui-notification {
50
+ :where([data-density="compact"]) .vmz-ui-notification {
53
51
  gap: var(--vmz-density-compact-gap);
54
52
  padding: var(--vmz-density-compact-padding-y) var(--vmz-density-compact-padding-x);
55
- }
53
+ }
56
54
 
57
- .vmz-ui-notification__title {
55
+ .vmz-ui-notification__title {
58
56
  margin: 0;
59
57
  font-weight: 700;
60
- }
58
+ }
61
59
 
62
- .vmz-ui-notification__description {
60
+ .vmz-ui-notification__description {
63
61
  margin: 0;
64
62
  opacity: 0.9;
65
- }
63
+ }
66
64
 
67
- .vmz-ui-notification__actions:empty {
65
+ .vmz-ui-notification__actions:empty {
68
66
  display: none;
69
- }
67
+ }
70
68
  </style>
71
-
72
69
  <script client>
73
70
  /**
74
- * VMZ UI — Notification (UI4 Commercial Surface).
75
- * Ephemeral feedback surface; tones share status.* tokens with Alert.
76
- */
71
+ * VMZ UI — Notification (UI4 Commercial Surface).
72
+ * Ephemeral feedback surface; tones share status.* tokens with Alert.
73
+ */
77
74
  export default class Notification {
78
- public title: string = "";
79
- public description: string = "";
80
- public tone: string = "info";
81
- public roleName: string = "status";
75
+ public title: string = "";
76
+ public description: string = "";
77
+ public tone: string = "info";
78
+ public roleName: string = "status";
82
79
  }
83
80
  </script>
@@ -1,34 +1,25 @@
1
1
  <template>
2
- <nav class="vmz-ui-pagination" data-vmz-ui="pagination" :aria-label="label">
3
- <button
4
- type="button"
5
- class="vmz-ui-pagination__btn"
6
- :disabled="prevDisabled"
7
- @click="onPrevClick"
8
- >
9
- Previous
10
- </button>
11
- <p class="vmz-ui-pagination__status" data-vmz-fixture="page-status">{{ status }}</p>
12
- <button
13
- type="button"
14
- class="vmz-ui-pagination__btn"
15
- :disabled="nextDisabled"
16
- @click="onNextClick"
17
- >
18
- Next
19
- </button>
2
+ <nav data-vmz-ui="pagination" :aria-label="label" class="vmz-ui-pagination">
3
+ <button type="button" :disabled="prevDisabled" @click="onPrevClick" class="vmz-ui-pagination__btn">
4
+ Previous
5
+ </button>
6
+ <p data-vmz-fixture="page-status" class="vmz-ui-pagination__status">
7
+ {{ status }}
8
+ </p>
9
+ <button type="button" :disabled="nextDisabled" @click="onNextClick" class="vmz-ui-pagination__btn">
10
+ Next
11
+ </button>
20
12
  </nav>
21
13
  </template>
22
-
23
14
  <style>
24
- .vmz-ui-pagination {
15
+ .vmz-ui-pagination {
25
16
  display: flex;
26
17
  flex-wrap: wrap;
27
18
  align-items: center;
28
19
  gap: 0.65rem 1rem;
29
- }
20
+ }
30
21
 
31
- .vmz-ui-pagination__btn {
22
+ .vmz-ui-pagination__btn {
32
23
  font: inherit;
33
24
  font-weight: 600;
34
25
  padding: 0.35rem 0.7rem;
@@ -38,42 +29,41 @@
38
29
  color: var(--vmz-action-primary-active);
39
30
  cursor: pointer;
40
31
  outline: none;
41
- }
32
+ }
42
33
 
43
- .vmz-ui-pagination__btn:focus-visible {
34
+ .vmz-ui-pagination__btn:focus-visible {
44
35
  box-shadow: 0 0 0 2px var(--vmz-focus-ring);
45
- }
36
+ }
46
37
 
47
- .vmz-ui-pagination__btn:disabled {
38
+ .vmz-ui-pagination__btn:disabled {
48
39
  opacity: 0.55;
49
40
  cursor: not-allowed;
50
- }
41
+ }
51
42
 
52
- .vmz-ui-pagination__status {
43
+ .vmz-ui-pagination__status {
53
44
  margin: 0;
54
45
  font-weight: 600;
55
- }
46
+ }
56
47
  </style>
57
-
58
48
  <script client>
59
49
  /**
60
- * VMZ UI — Pagination (Console composition skeleton).
61
- * Parent owns page / pageCount; buttons call onPrev / onNext.
62
- */
50
+ * VMZ UI — Pagination (Console composition skeleton).
51
+ * Parent owns page / pageCount; buttons call onPrev / onNext.
52
+ */
63
53
  export default class Pagination {
64
- public label: string = "Pagination";
65
- public status: string = "Page 1 / 1";
66
- public prevDisabled: boolean = true;
67
- public nextDisabled: boolean = true;
68
- public onPrev: (() => void) | null = null;
69
- public onNext: (() => void) | null = null;
70
- onPrevClick() {
71
- if (this.prevDisabled) return;
72
- if (typeof this.onPrev === "function") this.onPrev();
73
- }
74
- onNextClick() {
75
- if (this.nextDisabled) return;
76
- if (typeof this.onNext === "function") this.onNext();
77
- }
54
+ public label: string = "Pagination";
55
+ public status: string = "Page 1 / 1";
56
+ public prevDisabled: boolean = true;
57
+ public nextDisabled: boolean = true;
58
+ public onPrev: (() => void) | null = null;
59
+ public onNext: (() => void) | null = null;
60
+ onPrevClick() {
61
+ if (this.prevDisabled) return;
62
+ if (typeof this.onPrev === "function") this.onPrev();
63
+ }
64
+ onNextClick() {
65
+ if (this.nextDisabled) return;
66
+ if (typeof this.onNext === "function") this.onNext();
67
+ }
78
68
  }
79
69
  </script>