@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,16 +1,21 @@
1
1
  <template>
2
2
  <button
3
- type={type}
4
- class="vmz-ui-btn"
5
- data-vmz-ui="button"
6
- data-vmz-motion="control"
7
- data-vmz-motion-token="motion.control"
8
- data-variant={variant}
9
- disabled={disabled}
10
- onClick={onClick}
11
- >
12
- <slot />
13
- </button>
3
+ type={type}
4
+ class="vmz-ui-btn"
5
+ data-vmz-ui="button"
6
+ data-vmz-motion="control"
7
+ data-vmz-motion-token="motion.control"
8
+ data-variant={variant}
9
+ data-size={size}
10
+ data-block={block ? 'true' : 'false'}
11
+ data-loading={loading ? 'true' : 'false'}
12
+ disabled={disabled}
13
+ aria-busy={loading ? 'true' : 'false'}
14
+ onClick={onClick}
15
+ >
16
+ <span if={loading} class="vmz-ui-btn__spinner" aria-hidden="true"></span>
17
+ <slot />
18
+ </button>
14
19
  </template>
15
20
 
16
21
  <style>
@@ -19,25 +24,32 @@
19
24
  align-items: center;
20
25
  justify-content: center;
21
26
  gap: 0.35rem;
22
- min-height: 2.25rem;
27
+ min-height: var(--vmz-control-height, 2rem);
23
28
  padding: var(--vmz-density-control-padding-y) var(--vmz-density-control-padding-x);
24
29
  border: 1px solid transparent;
25
- border-radius: 7px;
30
+ border-radius: var(--vmz-radius-md, 6px);
26
31
  font: inherit;
27
- font-weight: 600;
28
- line-height: 1.2;
32
+ font-size: 0.875rem;
33
+ font-weight: 400;
34
+ line-height: 1.5715;
29
35
  cursor: pointer;
30
36
  background: var(--vmz-action-primary-background);
31
37
  color: var(--vmz-action-primary-foreground);
32
38
  outline: none;
39
+ box-shadow: none;
33
40
  transition:
34
41
  background-color var(--vmz-motion-control-duration) var(--vmz-motion-control-easing),
35
42
  border-color var(--vmz-motion-control-duration) var(--vmz-motion-control-easing),
36
- color var(--vmz-motion-control-duration) var(--vmz-motion-control-easing),
37
- box-shadow var(--vmz-motion-control-duration) var(--vmz-motion-control-easing);
38
- box-shadow: 0 1px 2px rgba(16,24,40,.08);
43
+ color var(--vmz-motion-control-duration) var(--vmz-motion-control-easing);
39
44
  }
40
45
 
46
+ .vmz-ui-btn[data-size='small'] { min-height: var(--vmz-control-height-sm, 1.5rem); padding: 0 0.5rem; font-size: 0.875rem; }
47
+ .vmz-ui-btn[data-size='large'] { min-height: var(--vmz-control-height-lg, 2.5rem); padding: 0.4rem 1rem; font-size: 1rem; }
48
+ .vmz-ui-btn[data-block='true'] { width: 100%; }
49
+ .vmz-ui-btn[data-loading='true'] { cursor: wait; }
50
+ .vmz-ui-btn__spinner { width: 1em; height: 1em; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: vmz-btn-spin .7s linear infinite; }
51
+ @keyframes vmz-btn-spin { to { transform: rotate(360deg); } }
52
+
41
53
  .vmz-ui-btn:hover:not(:disabled) {
42
54
  background: var(--vmz-action-primary-hover);
43
55
  }
@@ -51,82 +63,85 @@
51
63
  color: var(--vmz-action-secondary-foreground);
52
64
  border-color: var(--vmz-action-secondary-border);
53
65
  }
54
- .vmz-ui-btn[data-variant='default'] { background:#fff; color:var(--vmz-text-ink); border-color:var(--vmz-line-default); }
55
- .vmz-ui-btn[data-variant='default']:hover:not(:disabled) { color:var(--vmz-action-primary-background); border-color:var(--vmz-action-primary-background); background:#f5faff; }
56
- .vmz-ui-btn[data-variant='text'], .vmz-ui-btn[data-variant='link'] { min-height:auto; padding:.35rem .45rem; border-color:transparent; background:transparent; color:var(--vmz-action-primary-background); box-shadow:none; }
66
+ .vmz-ui-btn[data-variant='default'] { background:#fff; color:var(--vmz-text-ink); border-color:var(--vmz-line-default); box-shadow:none; }
67
+ .vmz-ui-btn[data-variant='default']:hover:not(:disabled) { color:var(--vmz-action-primary-background); border-color:var(--vmz-action-primary-background); background:#fff; }
68
+ .vmz-ui-btn[data-variant='text'], .vmz-ui-btn[data-variant='link'] { min-height:auto; padding:.25rem .35rem; border-color:transparent; background:transparent; color:var(--vmz-action-primary-background); box-shadow:none; }
57
69
  .vmz-ui-btn[data-variant='dashed'] { background:#fff; color:var(--vmz-text-ink); border:1px dashed var(--vmz-line-default); box-shadow:none; }
58
70
 
59
- .vmz-ui-btn[data-variant='secondary']:hover:not(:disabled) {
60
- background: var(--vmz-action-secondary-hover);
61
- }
71
+ .vmz-ui-btn[data-variant='secondary']:hover:not(:disabled) {
72
+ background: var(--vmz-action-secondary-hover);
73
+ }
62
74
 
63
- .vmz-ui-btn[data-variant='secondary']:active:not(:disabled) {
64
- background: var(--vmz-action-secondary-hover);
65
- border-color: var(--vmz-action-primary-active);
66
- }
75
+ .vmz-ui-btn[data-variant='secondary']:active:not(:disabled) {
76
+ background: var(--vmz-action-secondary-hover);
77
+ border-color: var(--vmz-action-primary-active);
78
+ }
67
79
 
68
- .vmz-ui-btn[data-variant='ghost'] {
69
- background: transparent;
70
- color: var(--vmz-text-ink);
71
- border-color: transparent;
72
- }
80
+ .vmz-ui-btn[data-variant='ghost'] {
81
+ background: transparent;
82
+ color: var(--vmz-text-ink);
83
+ border-color: transparent;
84
+ }
73
85
 
74
- .vmz-ui-btn[data-variant='ghost']:hover:not(:disabled) {
75
- background: color-mix(in srgb, var(--vmz-surface-mist) 85%, transparent);
76
- }
86
+ .vmz-ui-btn[data-variant='ghost']:hover:not(:disabled) {
87
+ background: color-mix(in srgb, var(--vmz-surface-mist) 85%, transparent);
88
+ }
77
89
 
78
- .vmz-ui-btn[data-variant='ghost']:active:not(:disabled) {
79
- background: var(--vmz-surface-mist);
80
- }
90
+ .vmz-ui-btn[data-variant='ghost']:active:not(:disabled) {
91
+ background: var(--vmz-surface-mist);
92
+ }
81
93
 
82
- .vmz-ui-btn[data-variant='danger'] {
83
- background: var(--vmz-status-danger-accent);
84
- color: var(--vmz-action-primary-foreground);
85
- border-color: transparent;
86
- }
94
+ .vmz-ui-btn[data-variant='danger'] {
95
+ background: var(--vmz-status-danger-accent);
96
+ color: var(--vmz-action-primary-foreground);
97
+ border-color: transparent;
98
+ }
87
99
 
88
- .vmz-ui-btn[data-variant='danger']:hover:not(:disabled) {
89
- background: color-mix(in srgb, var(--vmz-status-danger-accent) 82%, var(--vmz-text-ink));
90
- }
100
+ .vmz-ui-btn[data-variant='danger']:hover:not(:disabled) {
101
+ background: color-mix(in srgb, var(--vmz-status-danger-accent) 82%, var(--vmz-text-ink));
102
+ }
91
103
 
92
- .vmz-ui-btn[data-variant='danger']:active:not(:disabled) {
93
- background: var(--vmz-status-danger-foreground);
94
- }
104
+ .vmz-ui-btn[data-variant='danger']:active:not(:disabled) {
105
+ background: var(--vmz-status-danger-foreground);
106
+ }
95
107
 
96
- .vmz-ui-btn:focus-visible {
97
- box-shadow: 0 0 0 2px var(--vmz-focus-ring);
98
- }
108
+ .vmz-ui-btn:focus-visible {
109
+ box-shadow: 0 0 0 2px var(--vmz-focus-ring);
110
+ }
99
111
 
100
- .vmz-ui-btn:disabled {
101
- opacity: 0.55;
102
- cursor: not-allowed;
103
- }
112
+ .vmz-ui-btn:disabled {
113
+ opacity: 0.55;
114
+ cursor: not-allowed;
115
+ }
104
116
 
105
- :where([data-density='compact']) .vmz-ui-btn {
106
- padding: var(--vmz-density-compact-padding-y) var(--vmz-density-compact-padding-x);
107
- }
117
+ :where([data-density='compact']) .vmz-ui-btn {
118
+ padding: var(--vmz-density-compact-padding-y) var(--vmz-density-compact-padding-x);
119
+ }
108
120
 
109
- :where([data-density='dense']) .vmz-ui-btn {
110
- padding: var(--vmz-density-dense-padding-y) var(--vmz-density-dense-padding-x);
111
- }
121
+ :where([data-density='dense']) .vmz-ui-btn {
122
+ padding: var(--vmz-density-dense-padding-y) var(--vmz-density-dense-padding-x);
123
+ }
112
124
 
113
- @media (prefers-reduced-motion: reduce) {
114
- .vmz-ui-btn {
115
- transition: none;
125
+ @media (prefers-reduced-motion: reduce) {
126
+ .vmz-ui-btn {
127
+ transition: none;
128
+ }
116
129
  }
117
- }
118
130
  </style>
119
131
 
120
132
  <script client>
121
133
  /**
122
- * VMZ UI — Button (variants + motion control feedback).
123
- * Colors / motion come only from Style Theme semantic tokens — never brand hex.
124
- * Variants: primary | secondary | ghost | danger
125
- */
134
+ * VMZ UI — Button (variants + motion control feedback).
135
+ * Colors / motion come only from Style Theme semantic tokens — never brand hex.
136
+ * Variants: primary | secondary | ghost | danger
137
+ */
126
138
  export default class Button {
127
- public type: string = 'button';
128
- public variant: string = 'primary';
129
- public disabled: boolean = false;
130
- public onClick: ((e: Event) => void) | null = null;
139
+ public type: string = "button";
140
+ public variant: string = "primary";
141
+ public disabled: boolean = false;
142
+ public loading: boolean = false;
143
+ public block: boolean = false;
144
+ public size: string = "middle";
145
+ public onClick: ((e: Event) => void) | null = null;
131
146
  }
132
147
  </script>
@@ -1,80 +1,80 @@
1
1
  <template>
2
2
  <aside
3
- class="vmz-ui-callout"
4
- data-vmz-ui="callout"
5
- data-tone={tone}
6
- role={roleName}
7
- >
8
- <p if={title} class="vmz-ui-callout__title">{title}</p>
9
- <p if={description} class="vmz-ui-callout__description">{description}</p>
10
- <div class="vmz-ui-callout__body">
11
- <slot />
12
- </div>
13
- </aside>
3
+ class="vmz-ui-callout"
4
+ data-vmz-ui="callout"
5
+ data-tone={tone}
6
+ role={roleName}
7
+ >
8
+ <p if={title} class="vmz-ui-callout__title">{title}</p>
9
+ <p if={description} class="vmz-ui-callout__description">{description}</p>
10
+ <div class="vmz-ui-callout__body">
11
+ <slot />
12
+ </div>
13
+ </aside>
14
14
  </template>
15
15
 
16
16
  <style>
17
- .vmz-ui-callout {
18
- display: flex;
19
- flex-direction: column;
20
- gap: 0.45rem;
21
- padding: var(--vmz-density-control-padding-y) var(--vmz-density-control-padding-x);
22
- border: 1px solid var(--vmz-status-info-accent);
23
- border-left-width: 4px;
24
- border-radius: 2px;
25
- background: color-mix(in srgb, var(--vmz-status-info-accent) 10%, var(--vmz-surface-paper));
26
- color: var(--vmz-status-info-foreground);
27
- }
17
+ .vmz-ui-callout {
18
+ display: flex;
19
+ flex-direction: column;
20
+ gap: 0.45rem;
21
+ padding: var(--vmz-density-control-padding-y) var(--vmz-density-control-padding-x);
22
+ border: 1px solid var(--vmz-status-info-accent);
23
+ border-left-width: 1px;
24
+ border-radius: var(--vmz-radius-md, 6px);
25
+ background: color-mix(in srgb, var(--vmz-status-info-accent) 10%, var(--vmz-surface-paper));
26
+ color: var(--vmz-status-info-foreground);
27
+ }
28
28
 
29
- .vmz-ui-callout[data-tone='info'] {
30
- border-color: var(--vmz-status-info-accent);
31
- background: color-mix(in srgb, var(--vmz-status-info-accent) 10%, var(--vmz-surface-paper));
32
- color: var(--vmz-status-info-foreground);
33
- }
29
+ .vmz-ui-callout[data-tone='info'] {
30
+ border-color: var(--vmz-status-info-accent);
31
+ background: color-mix(in srgb, var(--vmz-status-info-accent) 10%, var(--vmz-surface-paper));
32
+ color: var(--vmz-status-info-foreground);
33
+ }
34
34
 
35
- .vmz-ui-callout[data-tone='success'] {
36
- border-color: var(--vmz-status-success-accent);
37
- background: color-mix(in srgb, var(--vmz-status-success-accent) 10%, var(--vmz-surface-paper));
38
- color: var(--vmz-status-success-foreground);
39
- }
35
+ .vmz-ui-callout[data-tone='success'] {
36
+ border-color: var(--vmz-status-success-accent);
37
+ background: color-mix(in srgb, var(--vmz-status-success-accent) 10%, var(--vmz-surface-paper));
38
+ color: var(--vmz-status-success-foreground);
39
+ }
40
40
 
41
- .vmz-ui-callout[data-tone='warning'] {
42
- border-color: var(--vmz-status-warning-accent);
43
- background: color-mix(in srgb, var(--vmz-status-warning-accent) 10%, var(--vmz-surface-paper));
44
- color: var(--vmz-status-warning-foreground);
45
- }
41
+ .vmz-ui-callout[data-tone='warning'] {
42
+ border-color: var(--vmz-status-warning-accent);
43
+ background: color-mix(in srgb, var(--vmz-status-warning-accent) 10%, var(--vmz-surface-paper));
44
+ color: var(--vmz-status-warning-foreground);
45
+ }
46
46
 
47
- .vmz-ui-callout[data-tone='danger'] {
48
- border-color: var(--vmz-status-danger-accent);
49
- background: color-mix(in srgb, var(--vmz-status-danger-accent) 10%, var(--vmz-surface-paper));
50
- color: var(--vmz-status-danger-foreground);
51
- }
47
+ .vmz-ui-callout[data-tone='danger'] {
48
+ border-color: var(--vmz-status-danger-accent);
49
+ background: color-mix(in srgb, var(--vmz-status-danger-accent) 10%, var(--vmz-surface-paper));
50
+ color: var(--vmz-status-danger-foreground);
51
+ }
52
52
 
53
- .vmz-ui-callout__title {
54
- margin: 0;
55
- font-family: var(--vmz-font-display);
56
- font-weight: 700;
57
- }
53
+ .vmz-ui-callout__title {
54
+ margin: 0;
55
+ font-family: var(--vmz-font-display);
56
+ font-weight: 700;
57
+ }
58
58
 
59
- .vmz-ui-callout__description {
60
- margin: 0;
61
- line-height: 1.5;
62
- }
59
+ .vmz-ui-callout__description {
60
+ margin: 0;
61
+ line-height: 1.5;
62
+ }
63
63
 
64
- .vmz-ui-callout__body:empty {
65
- display: none;
66
- }
64
+ .vmz-ui-callout__body:empty {
65
+ display: none;
66
+ }
67
67
  </style>
68
68
 
69
69
  <script client>
70
70
  /**
71
- * VMZ UI — Callout (Document/Product composition).
72
- * Inline guidance block for prose; shares status.* tones with Alert.
73
- */
71
+ * VMZ UI — Callout (Document/Product composition).
72
+ * Inline guidance block for prose; shares status.* tones with Alert.
73
+ */
74
74
  export default class Callout {
75
- public title: string = '';
76
- public description: string = '';
77
- public tone: string = 'info';
78
- public roleName: string = 'note';
75
+ public title: string = "";
76
+ public description: string = "";
77
+ public tone: string = "info";
78
+ public roleName: string = "note";
79
79
  }
80
80
  </script>
@@ -1,80 +1,87 @@
1
1
  <template>
2
- <section class="vmz-ui-card" data-vmz-ui="card">
3
- <header if={title} class="vmz-ui-card__header">
4
- <h2 class="vmz-ui-card__title">{title}</h2>
5
- <p if={description} class="vmz-ui-card__description">{description}</p>
6
- </header>
7
- <div class="vmz-ui-card__body">
8
- <slot />
9
- </div>
10
- </section>
2
+ <section class="vmz-ui-card" data-vmz-ui="card" data-size={size} data-bordered={bordered ? 'true' : 'false'} data-hoverable={hoverable ? 'true' : 'false'}>
3
+ <header if={title} class="vmz-ui-card__header">
4
+ <h2 class="vmz-ui-card__title">{title}</h2>
5
+ <p if={description} class="vmz-ui-card__description">{description}</p>
6
+ </header>
7
+ <div class="vmz-ui-card__body">
8
+ <slot />
9
+ </div>
10
+ </section>
11
11
  </template>
12
12
 
13
13
  <style>
14
14
  .vmz-ui-card {
15
15
  display: flex;
16
16
  flex-direction: column;
17
- gap: 1rem;
18
- padding: 1.25rem;
19
- border: 1px solid var(--vmz-line-default);
20
- border-radius: 10px;
17
+ gap: 0.75rem;
18
+ padding: 1rem 1.25rem;
19
+ border: 1px solid var(--vmz-line-subtle, var(--vmz-line-default));
20
+ border-radius: var(--vmz-radius-lg, 8px);
21
21
  background: var(--vmz-surface-paper);
22
22
  color: var(--vmz-text-ink);
23
- box-shadow: 0 1px 3px rgba(16,24,40,.06);
23
+ box-shadow: var(--vmz-shadow-card, none);
24
24
  }
25
+ .vmz-ui-card[data-bordered='false'] { border-color: transparent; }
26
+ .vmz-ui-card[data-hoverable='true'] { transition: border-color var(--vmz-motion-control-duration, .16s), box-shadow var(--vmz-motion-control-duration, .16s); }
27
+ .vmz-ui-card[data-hoverable='true']:hover { box-shadow: var(--vmz-shadow-card-hover, 0 1px 2px -2px rgba(0,0,0,.08), 0 3px 6px 0 rgba(0,0,0,.06)); }
28
+ .vmz-ui-card[data-size='small'] { gap: .5rem; padding: .75rem 1rem; }
25
29
 
26
- :where([data-density='compact']) .vmz-ui-card {
27
- gap: var(--vmz-density-compact-gap);
28
- padding: var(--vmz-density-compact-padding-y) var(--vmz-density-compact-padding-x);
29
- }
30
+ :where([data-density='compact']) .vmz-ui-card {
31
+ gap: var(--vmz-density-compact-gap);
32
+ padding: var(--vmz-density-compact-padding-y) var(--vmz-density-compact-padding-x);
33
+ }
30
34
 
31
- :where([data-density='dense']) .vmz-ui-card {
32
- gap: var(--vmz-density-dense-gap);
33
- padding: var(--vmz-density-dense-padding-y) var(--vmz-density-dense-padding-x);
34
- }
35
+ :where([data-density='dense']) .vmz-ui-card {
36
+ gap: var(--vmz-density-dense-gap);
37
+ padding: var(--vmz-density-dense-padding-y) var(--vmz-density-dense-padding-x);
38
+ }
35
39
 
36
- .vmz-ui-card__header {
37
- display: flex;
38
- flex-direction: column;
39
- gap: 0.35rem;
40
- }
40
+ .vmz-ui-card__header {
41
+ display: flex;
42
+ flex-direction: column;
43
+ gap: 0.35rem;
44
+ }
41
45
 
42
46
  .vmz-ui-card__title {
43
47
  margin: 0;
44
- font-family: var(--vmz-font-display);
45
- font-size: 1.1rem;
46
- font-weight: 700;
48
+ font-family: var(--vmz-font-sans, inherit);
49
+ font-size: 1rem;
50
+ font-weight: 600;
47
51
  color: var(--vmz-text-ink);
48
52
  }
49
53
 
50
- .vmz-ui-card__description {
51
- margin: 0;
52
- color: var(--vmz-text-steel);
53
- line-height: 1.45;
54
- }
54
+ .vmz-ui-card__description {
55
+ margin: 0;
56
+ color: var(--vmz-text-steel);
57
+ line-height: 1.45;
58
+ }
55
59
 
56
- .vmz-ui-card__body {
57
- display: flex;
58
- flex-direction: column;
59
- gap: var(--vmz-density-control-gap);
60
- }
60
+ .vmz-ui-card__body {
61
+ display: flex;
62
+ flex-direction: column;
63
+ gap: var(--vmz-density-control-gap);
64
+ }
61
65
 
62
- :where([data-density='compact']) .vmz-ui-card__body {
63
- gap: var(--vmz-density-compact-gap);
64
- }
66
+ :where([data-density='compact']) .vmz-ui-card__body {
67
+ gap: var(--vmz-density-compact-gap);
68
+ }
65
69
 
66
- :where([data-density='dense']) .vmz-ui-card__body {
67
- gap: var(--vmz-density-dense-gap);
68
- }
70
+ :where([data-density='dense']) .vmz-ui-card__body {
71
+ gap: var(--vmz-density-dense-gap);
72
+ }
69
73
  </style>
70
74
 
71
75
  <script client>
72
76
  /**
73
- * VMZ UI — Card (Commercial Surface).
74
- * Surface container; spacing from density.*; chrome from surface/line/text.
75
- */
77
+ * VMZ UI — Card (Commercial Surface).
78
+ * Surface container; spacing from density.*; chrome from surface/line/text.
79
+ */
76
80
  export default class Card {
77
- public title: string = '';
78
- public description: string = '';
81
+ public title: string = "";
82
+ public description: string = "";
83
+ public size: string = "middle";
84
+ public bordered: boolean = true;
85
+ public hoverable: boolean = false;
79
86
  }
80
87
  </script>
@@ -1,69 +1,72 @@
1
1
  <template>
2
2
  <label class="vmz-ui-checkbox" data-vmz-ui="checkbox" for={controlId}>
3
- <input
4
- id={controlId}
5
- class="vmz-ui-checkbox__input"
6
- type="checkbox"
7
- checked={checked}
8
- disabled={disabled}
9
- aria-describedby={describedBy}
10
- onClick={onToggle}
11
- />
12
- <span class="vmz-ui-checkbox__label">{label}</span>
13
- </label>
3
+ <input
4
+ id={controlId}
5
+ class="vmz-ui-checkbox__input"
6
+ type="checkbox"
7
+ checked={checked}
8
+ disabled={disabled}
9
+ aria-describedby={describedBy}
10
+ onClick={onToggle}
11
+ />
12
+ <span class="vmz-ui-checkbox__label">{label}</span>
13
+ </label>
14
14
  </template>
15
15
 
16
16
  <style>
17
- .vmz-ui-checkbox {
18
- display: inline-flex;
19
- align-items: center;
20
- gap: 0.45rem;
21
- font: inherit;
22
- cursor: pointer;
23
- }
17
+ .vmz-ui-checkbox {
18
+ display: inline-flex;
19
+ align-items: center;
20
+ gap: 0.45rem;
21
+ font: inherit;
22
+ cursor: pointer;
23
+ }
24
24
 
25
- .vmz-ui-checkbox__input {
26
- width: 1rem;
27
- height: 1rem;
28
- accent-color: var(--vmz-action-primary-background);
29
- outline: none;
30
- }
25
+ .vmz-ui-checkbox__input {
26
+ width: 1rem;
27
+ height: 1rem;
28
+ accent-color: var(--vmz-action-primary-background);
29
+ outline: none;
30
+ }
31
31
 
32
- .vmz-ui-checkbox__input:focus-visible {
33
- box-shadow: 0 0 0 2px var(--vmz-focus-ring);
34
- }
32
+ .vmz-ui-checkbox__input:focus-visible {
33
+ box-shadow: 0 0 0 2px var(--vmz-focus-ring);
34
+ }
35
35
 
36
- .vmz-ui-checkbox__input:disabled {
37
- opacity: 0.55;
38
- cursor: not-allowed;
39
- }
36
+ .vmz-ui-checkbox__input:disabled {
37
+ opacity: 0.55;
38
+ cursor: not-allowed;
39
+ }
40
40
 
41
- .vmz-ui-checkbox__label {
42
- font-weight: 600;
43
- }
41
+ .vmz-ui-checkbox__label {
42
+ font-weight: 600;
43
+ }
44
44
  </style>
45
45
 
46
46
  <script client>
47
47
  /**
48
- * VMZ UI — Checkbox (UI2).
49
- * Label association via wrapping label + for/id; parent owns checked (no parallel form store).
50
- * Toggle goes through onChange so live `checked` prop stays authoritative.
51
- */
48
+ * VMZ UI — Checkbox (UI2).
49
+ * Label association via wrapping label + for/id; parent owns checked (no parallel form store).
50
+ * Toggle goes through onChange so live `checked` prop stays authoritative.
51
+ */
52
52
  export default class Checkbox {
53
- public label: string = '';
54
- public checked: boolean = false;
55
- public disabled: boolean = false;
56
- public controlId: string = 'vmz-checkbox';
57
- public describedBy: string = '';
58
- public onChange: ((e: { target: { checked: boolean } }) => void) | null = null;
59
-
60
- onToggle(ev) {
61
- if (this.disabled) return;
62
- if (ev && typeof ev.preventDefault === 'function') ev.preventDefault();
63
- const next = !this.checked;
64
- if (typeof this.onChange === 'function') {
65
- this.onChange({ target: { checked: next } });
66
- }
67
- }
53
+ public label: string = "";
54
+ public checked: boolean = false;
55
+ public disabled: boolean = false;
56
+ public controlId: string = "vmz-checkbox";
57
+ public describedBy: string = "";
58
+ public onChange: ((e: {
59
+ target: {
60
+ checked: boolean;
61
+ };
62
+ }) => void) | null = null;
63
+ onToggle(ev) {
64
+ if (this.disabled) return;
65
+ if (ev && typeof ev.preventDefault === "function") ev.preventDefault();
66
+ const next = !this.checked;
67
+ if (typeof this.onChange === "function") {
68
+ this.onChange({ target: { checked: next } });
69
+ }
70
+ }
68
71
  }
69
72
  </script>