@vmz/ui 0.2.1 → 0.2.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vmz/ui",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "type": "module",
5
5
  "description": "VMZ UI — official UI framework (component contracts + semantic token requirements). Not a theme. Not a plugin.",
6
6
  "license": "MIT",
@@ -68,7 +68,8 @@
68
68
  "./Header": "./src/components/Header.vmz",
69
69
  "./Sider": "./src/components/Sider.vmz",
70
70
  "./Content": "./src/components/Content.vmz",
71
- "./Footer": "./src/components/Footer.vmz"
71
+ "./Footer": "./src/components/Footer.vmz",
72
+ "./Icon": "./src/components/Icon.vmz"
72
73
  },
73
74
  "files": [
74
75
  "src",
@@ -1,87 +1,78 @@
1
1
  <template>
2
- <span
3
- class="vmz-ui-icon"
4
- data-vmz-ui="icon"
5
- :data-name="name"
6
- :data-size="size"
7
- :role="decorative ? 'presentation' : 'img'"
8
- :aria-hidden="decorative ? 'true' : 'false'"
9
- :aria-label="decorative ? '' : label"
10
- >
11
- <svg class="vmz-ui-icon__svg" viewBox="0 0 24 24" focusable="false" aria-hidden="true">
12
- <path v-if="isCheck" fill="currentColor" d="M9.2 16.6 4.8 12.2l1.4-1.4 3 3 8-8 1.4 1.4z" />
13
- <path v-if="isClose" fill="currentColor" d="M6.4 7.8 7.8 6.4 12 10.6 16.2 6.4 17.6 7.8 13.4 12 17.6 16.2 16.2 17.6 12 13.4 7.8 17.6 6.4 16.2 10.6 12z" />
14
- <path v-if="isSearch" fill="currentColor" d="M10.5 3a7.5 7.5 0 0 1 5.9 12.1l4 4-1.4 1.4-4-4A7.5 7.5 0 1 1 10.5 3zm0 2a5.5 5.5 0 1 0 0 11 5.5 5.5 0 0 0 0-11z" />
15
- <path v-if="isChevronDown" fill="currentColor" d="M7.4 9.1 12 13.7l4.6-4.6 1.4 1.4L12 16.5 6 10.5z" />
16
- <path v-if="isChevronRight" fill="currentColor" d="M9.1 6 15.1 12l-6 6-1.4-1.4L12.3 12 7.7 7.4z" />
17
- <path v-if="isInfo" fill="currentColor" d="M12 2a10 10 0 1 1 0 20 10 10 0 0 1 0-20zm0 8.2a1 1 0 0 0-1 1V17a1 1 0 1 0 2 0v-5.8a1 1 0 0 0-1-1zm0-3.7a1.2 1.2 0 1 0 0 2.4 1.2 1.2 0 0 0 0-2.4z" />
18
- <path v-if="isWarning" fill="currentColor" d="M12 3.2 21 19H3L12 3.2zm0 5.3a1 1 0 0 0-1 1v4.2a1 1 0 1 0 2 0V9.5a1 1 0 0 0-1-1zm0 8.1a1.2 1.2 0 1 0 0 2.4 1.2 1.2 0 0 0 0-2.4z" />
19
- <path v-if="isSuccess" fill="currentColor" d="M12 2a10 10 0 1 1 0 20 10 10 0 0 1 0-20zm-2.5 10.3-2-2 1.4-1.4 2 2 5-5 1.4 1.4z" />
20
- <path v-if="isDanger" fill="currentColor" d="M12 2a10 10 0 1 1 0 20 10 10 0 0 1 0-20zm-1 5h2v6h-2zm0 8h2v2h-2z" />
21
- <path v-if="isMenu" fill="currentColor" d="M4 7h16v2H4zm0 4h16v2H4zm0 4h16v2H4z" />
22
- <path v-if="isPlus" fill="currentColor" d="M11 5h2v6h6v2h-6v6h-2v-6H5v-2h6z" />
23
- <path v-if="isFallback" fill="currentColor" d="M12 2a10 10 0 1 1 0 20 10 10 0 0 1 0-20zm1 5h-2v2h2zm0 4h-2v7h2z" />
24
- </svg>
2
+ <span data-vmz-ui="icon" :data-name="name" :data-size="size" :role='decorative ? "presentation" : "img"' :aria-hidden='decorative ? "true" : "false"' :aria-label='decorative ? "" : label' class="vmz-ui-icon">
3
+ <svg viewBox="0 0 24 24" focusable="false" aria-hidden="true" class="vmz-ui-icon__svg">
4
+ <path fill="currentColor" :d="iconPath()" />
5
+ </svg>
25
6
  </span>
26
7
  </template>
27
-
28
8
  <style>
29
- .vmz-ui-icon {
30
- display: inline-flex;
31
- align-items: center;
32
- justify-content: center;
33
- width: 1em;
34
- height: 1em;
35
- vertical-align: -0.125em;
36
- color: inherit;
37
- line-height: 1;
38
- }
39
- .vmz-ui-icon[data-size='sm'] { font-size: 0.875rem; }
40
- .vmz-ui-icon[data-size='md'] { font-size: 1rem; }
41
- .vmz-ui-icon[data-size='lg'] { font-size: 1.25rem; }
42
- .vmz-ui-icon__svg { width: 1em; height: 1em; display: block; }
9
+ .vmz-ui-icon {
10
+ display: inline-flex;
11
+ align-items: center;
12
+ justify-content: center;
13
+ width: 1em;
14
+ height: 1em;
15
+ vertical-align: -0.125em;
16
+ color: inherit;
17
+ line-height: 1;
18
+ }
19
+ .vmz-ui-icon[data-size="sm"] {
20
+ font-size: 0.875rem;
21
+ }
22
+ .vmz-ui-icon[data-size="md"] {
23
+ font-size: 1rem;
24
+ }
25
+ .vmz-ui-icon[data-size="lg"] {
26
+ font-size: 1.25rem;
27
+ }
28
+ .vmz-ui-icon__svg {
29
+ width: 1em;
30
+ height: 1em;
31
+ display: block;
32
+ }
43
33
  </style>
44
-
45
34
  <script client>
46
35
  /**
47
- * VMZ UI — Icon (minimal official set).
48
- * Parent picks `name`; no useIcon/createIcon. Unknown names render fallback glyph.
49
- */
36
+ * VMZ UI Icon — shell for UI chrome and author-supplied glyphs.
37
+ * Pass `pathD` for custom SVG paths, or `name` for the built-in chrome set.
38
+ * Full semantic registries live in optional `@vmz/ui-icons`.
39
+ */
40
+ const FALLBACK_PATH =
41
+ 'M12 2a10 10 0 1 1 0 20 10 10 0 0 1 0-20zm1 5h-2v2h2zm0 4h-2v7h2z';
42
+
43
+ const CHROME_PATHS = {
44
+ check: 'M9.2 16.6 4.8 12.2l1.4-1.4 3 3 8-8 1.4 1.4z',
45
+ close: 'M6.4 7.8 7.8 6.4 12 10.6 16.2 6.4 17.6 7.8 13.4 12 17.6 16.2 16.2 17.6 12 13.4 7.8 17.6 6.4 16.2 10.6 12z',
46
+ search: 'M10.5 3a7.5 7.5 0 0 1 5.9 12.1l4 4-1.4 1.4-4-4A7.5 7.5 0 1 1 10.5 3zm0 2a5.5 5.5 0 1 0 0 11 5.5 5.5 0 0 0 0-11z',
47
+ 'chevron-down': 'M7.4 9.1 12 13.7l4.6-4.6 1.4 1.4L12 16.5 6 10.5z',
48
+ 'chevron-right': 'M9.1 6 15.1 12l-6 6-1.4-1.4L12.3 12 7.7 7.4z',
49
+ info: 'M12 2a10 10 0 1 1 0 20 10 10 0 0 1 0-20zm0 8.2a1 1 0 0 0-1 1V17a1 1 0 1 0 2 0v-5.8a1 1 0 0 0-1-1zm0-3.7a1.2 1.2 0 1 0 0 2.4 1.2 1.2 0 0 0 0-2.4z',
50
+ warning:
51
+ 'M12 3.2 21 19H3L12 3.2zm0 5.3a1 1 0 0 0-1 1v4.2a1 1 0 1 0 2 0V9.5a1 1 0 0 0-1-1zm0 8.1a1.2 1.2 0 1 0 0 2.4 1.2 1.2 0 0 0 0-2.4z',
52
+ success: 'M12 2a10 10 0 1 1 0 20 10 10 0 0 1 0-20zm-2.5 10.3-2-2 1.4-1.4 2 2 5-5 1.4 1.4z',
53
+ danger: 'M12 2a10 10 0 1 1 0 20 10 10 0 0 1 0-20zm-1 5h2v6h-2zm0 8h2v2h-2z',
54
+ menu: 'M4 7h16v2H4zm0 4h16v2H4zm0 4h16v2H4z',
55
+ plus: 'M11 5h2v6h6v2h-6v6h-2v-6H5v-2h6z',
56
+ };
57
+
58
+ function resolveChromePath(name) {
59
+ const key = String(name || '').trim();
60
+ if (!key) return FALLBACK_PATH;
61
+ return CHROME_PATHS[key] || FALLBACK_PATH;
62
+ }
63
+
50
64
  export default class Icon {
51
- static __vmzHostBox = 'contents';
52
- public name: string = "info";
53
- public size: string = "md";
54
- public label: string = "";
55
- public decorative: boolean = true;
56
- isCheck = false;
57
- isClose = false;
58
- isSearch = false;
59
- isChevronDown = false;
60
- isChevronRight = false;
61
- isInfo = false;
62
- isWarning = false;
63
- isSuccess = false;
64
- isDanger = false;
65
- isMenu = false;
66
- isPlus = false;
67
- isFallback = false;
68
- onMount() {
69
- this._sync();
70
- }
71
- _sync() {
72
- const n = String(this.name || "");
73
- this.isCheck = n === "check";
74
- this.isClose = n === "close";
75
- this.isSearch = n === "search";
76
- this.isChevronDown = n === "chevron-down";
77
- this.isChevronRight = n === "chevron-right";
78
- this.isInfo = n === "info";
79
- this.isWarning = n === "warning";
80
- this.isSuccess = n === "success";
81
- this.isDanger = n === "danger";
82
- this.isMenu = n === "menu";
83
- this.isPlus = n === "plus";
84
- this.isFallback = !(this.isCheck || this.isClose || this.isSearch || this.isChevronDown || this.isChevronRight || this.isInfo || this.isWarning || this.isSuccess || this.isDanger || this.isMenu || this.isPlus);
85
- }
65
+ static __vmzHostBox = 'contents';
66
+ public name: string = 'info';
67
+ public size: string = 'md';
68
+ public label: string = '';
69
+ public decorative: boolean = true;
70
+ /** Optional author SVG path override. When set, `name` is ignored for rendering. */
71
+ public pathD: string = '';
72
+
73
+ iconPath() {
74
+ const explicit = String(this.pathD || '').trim();
75
+ return explicit || resolveChromePath(this.name);
76
+ }
86
77
  }
87
78
  </script>