@vc-shell/framework 1.1.3 → 1.1.5

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 (136) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/core/directives/loading/styles.css +1 -1
  3. package/core/plugins/modularity/README.md +347 -17
  4. package/core/plugins/modularity/loader.ts +217 -3
  5. package/dist/core/plugins/modularity/loader.d.ts +4 -0
  6. package/dist/core/plugins/modularity/loader.d.ts.map +1 -1
  7. package/dist/framework.js +1 -1
  8. package/dist/{index-DRL7VovM.js → index-BBHl6nap.js} +1 -1
  9. package/dist/{index-BKR3ecN5.js → index-BG6N4UCY.js} +1 -1
  10. package/dist/{index-Cv6c_1IG.js → index-Bv5as3SI.js} +1 -1
  11. package/dist/{index-BUHouW8T.js → index-C4VyqVxv.js} +1 -1
  12. package/dist/{index-Ek7_XgGk.js → index-CKLiFGZ-.js} +1 -1
  13. package/dist/{index-B83didIY.js → index-CTmAMa_1.js} +1 -1
  14. package/dist/{index-C6tcHNVl.js → index-CtGZgIiV.js} +1 -1
  15. package/dist/{index-DyGIijU2.js → index-D13Jcezf.js} +1 -1
  16. package/dist/{index-CnQ56kqq.js → index-DbpKygJh.js} +1 -1
  17. package/dist/{index-Dfcy8w9c.js → index-DgCtSr4P.js} +1 -1
  18. package/dist/{index-TSGli7LX.js → index-Dh1XjfgY.js} +1 -1
  19. package/dist/{index-BW3krAiY.js → index-DpDbQQg6.js} +1 -1
  20. package/dist/{index-CxMfHOup.js → index-DwuQbDJG.js} +1 -1
  21. package/dist/{index-xFQltarK.js → index-Fhuqbkq2.js} +1 -1
  22. package/dist/{index-BN-_cebP.js → index-JTAZpxKF.js} +1 -1
  23. package/dist/{index-UnPPbmRc.js → index-MKD2CP5c.js} +49617 -48276
  24. package/dist/{index-CGyGGihY.js → index-Q3k1PYzc.js} +1 -1
  25. package/dist/index.css +3 -3
  26. package/dist/shared/components/generic-dropdown/generic-dropdown.vue.d.ts.map +1 -1
  27. package/dist/shared/components/settings-menu-item/settings-menu-item.vue.d.ts.map +1 -1
  28. package/dist/tsconfig.tsbuildinfo +1 -1
  29. package/dist/ui/components/atoms/vc-icon/composables/index.d.ts +3 -0
  30. package/dist/ui/components/atoms/vc-icon/composables/index.d.ts.map +1 -0
  31. package/dist/ui/components/atoms/vc-icon/composables/use-icon-type.d.ts +22 -0
  32. package/dist/ui/components/atoms/vc-icon/composables/use-icon-type.d.ts.map +1 -0
  33. package/dist/ui/components/atoms/vc-icon/composables/use-icon.d.ts +30 -0
  34. package/dist/ui/components/atoms/vc-icon/composables/use-icon.d.ts.map +1 -0
  35. package/dist/ui/components/atoms/vc-icon/index.d.ts +1 -0
  36. package/dist/ui/components/atoms/vc-icon/index.d.ts.map +1 -1
  37. package/dist/ui/components/atoms/vc-icon/types.d.ts +31 -0
  38. package/dist/ui/components/atoms/vc-icon/types.d.ts.map +1 -0
  39. package/dist/ui/components/atoms/vc-icon/vc-bootstrap-icon.vue.d.ts +18 -4
  40. package/dist/ui/components/atoms/vc-icon/vc-bootstrap-icon.vue.d.ts.map +1 -1
  41. package/dist/ui/components/atoms/vc-icon/vc-fontawesome-icon.vue.d.ts +15 -2
  42. package/dist/ui/components/atoms/vc-icon/vc-fontawesome-icon.vue.d.ts.map +1 -1
  43. package/dist/ui/components/atoms/vc-icon/vc-icon-examples.vue.d.ts.map +1 -1
  44. package/dist/ui/components/atoms/vc-icon/vc-icon-test.vue.d.ts.map +1 -1
  45. package/dist/ui/components/atoms/vc-icon/vc-icon.vue.d.ts +11 -6
  46. package/dist/ui/components/atoms/vc-icon/vc-icon.vue.d.ts.map +1 -1
  47. package/dist/ui/components/atoms/vc-icon/vc-lucide-icon.vue.d.ts +21 -4
  48. package/dist/ui/components/atoms/vc-icon/vc-lucide-icon.vue.d.ts.map +1 -1
  49. package/dist/ui/components/atoms/vc-icon/vc-material-icon.vue.d.ts +30 -4
  50. package/dist/ui/components/atoms/vc-icon/vc-material-icon.vue.d.ts.map +1 -1
  51. package/dist/ui/components/atoms/vc-icon/vc-svg-icon.vue.d.ts +33 -0
  52. package/dist/ui/components/atoms/vc-icon/vc-svg-icon.vue.d.ts.map +1 -0
  53. package/dist/ui/components/atoms/vc-widget/vc-widget.vue.d.ts.map +1 -1
  54. package/dist/ui/components/molecules/vc-pagination/vc-pagination.vue.d.ts.map +1 -1
  55. package/dist/ui/components/organisms/vc-app/_internal/vc-app-bar/vc-app-bar.vue.d.ts.map +1 -1
  56. package/dist/ui/components/organisms/vc-blade/_internal/vc-blade-toolbar/_internal/vc-blade-toolbar-buttons/_internal/vc-blade-toolbar-button/props.d.ts +14 -0
  57. package/dist/ui/components/organisms/vc-blade/_internal/vc-blade-toolbar/_internal/vc-blade-toolbar-buttons/_internal/vc-blade-toolbar-button/props.d.ts.map +1 -0
  58. package/dist/ui/components/organisms/vc-blade/_internal/vc-blade-toolbar/_internal/vc-blade-toolbar-buttons/_internal/vc-blade-toolbar-button/vc-blade-toolbar-base-button.vue.d.ts +2 -13
  59. package/dist/ui/components/organisms/vc-blade/_internal/vc-blade-toolbar/_internal/vc-blade-toolbar-buttons/_internal/vc-blade-toolbar-button/vc-blade-toolbar-base-button.vue.d.ts.map +1 -1
  60. package/dist/ui/components/organisms/vc-blade/_internal/vc-blade-toolbar/_internal/vc-blade-toolbar-buttons/_internal/vc-blade-toolbar-button/vc-blade-toolbar-circle-button.vue.d.ts +1 -1
  61. package/dist/ui/components/organisms/vc-blade/_internal/vc-blade-toolbar/_internal/vc-blade-toolbar-buttons/_internal/vc-blade-toolbar-button/vc-blade-toolbar-circle-button.vue.d.ts.map +1 -1
  62. package/dist/ui/components/organisms/vc-blade/_internal/vc-blade-toolbar/vc-blade-toolbar.vue.d.ts.map +1 -1
  63. package/dist/ui/components/organisms/vc-table/_internal/vc-table-cell/vc-table-cell.vue.d.ts +1 -1
  64. package/dist/ui/components/organisms/vc-table/_internal/vc-table-cell/vc-table-cell.vue.d.ts.map +1 -1
  65. package/dist/ui/components/organisms/vc-table/_internal/vc-table-column-switcher/vc-table-column-switcher.vue.d.ts +1 -1
  66. package/dist/ui/components/organisms/vc-table/_internal/vc-table-column-switcher/vc-table-column-switcher.vue.d.ts.map +1 -1
  67. package/dist/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/_internal/vc-table-body/vc-table-body.vue.d.ts +1 -1
  68. package/dist/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/_internal/vc-table-body/vc-table-body.vue.d.ts.map +1 -1
  69. package/dist/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/_internal/vc-table-columns-header/vc-table-columns-header.vue.d.ts +1 -1
  70. package/dist/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/_internal/vc-table-columns-header/vc-table-columns-header.vue.d.ts.map +1 -1
  71. package/dist/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/_internal/vc-table-row/vc-table-row.vue.d.ts +1 -1
  72. package/dist/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/_internal/vc-table-row/vc-table-row.vue.d.ts.map +1 -1
  73. package/dist/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/vc-table-desktop-view.vue.d.ts +1 -1
  74. package/dist/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/vc-table-desktop-view.vue.d.ts.map +1 -1
  75. package/dist/ui/components/organisms/vc-table/_internal/vc-table-mobile-view/vc-table-mobile-view.vue.d.ts +1 -1
  76. package/dist/ui/components/organisms/vc-table/_internal/vc-table-mobile-view/vc-table-mobile-view.vue.d.ts.map +1 -1
  77. package/dist/ui/components/organisms/vc-table/composables/useTableActions.d.ts +1 -1
  78. package/dist/ui/components/organisms/vc-table/composables/useTableActions.d.ts.map +1 -1
  79. package/dist/ui/components/organisms/vc-table/composables/useTableColumnReorder.d.ts +1 -1
  80. package/dist/ui/components/organisms/vc-table/composables/useTableColumnReorder.d.ts.map +1 -1
  81. package/dist/ui/components/organisms/vc-table/composables/useTableColumnResize.d.ts +1 -1
  82. package/dist/ui/components/organisms/vc-table/composables/useTableColumnResize.d.ts.map +1 -1
  83. package/dist/ui/components/organisms/vc-table/composables/useTableRowReorder.d.ts +1 -1
  84. package/dist/ui/components/organisms/vc-table/composables/useTableRowReorder.d.ts.map +1 -1
  85. package/dist/ui/components/organisms/vc-table/composables/useTableSelection.d.ts +1 -1
  86. package/dist/ui/components/organisms/vc-table/composables/useTableSelection.d.ts.map +1 -1
  87. package/dist/ui/components/organisms/vc-table/composables/useTableState.d.ts +1 -1
  88. package/dist/ui/components/organisms/vc-table/composables/useTableState.d.ts.map +1 -1
  89. package/dist/ui/components/organisms/vc-table/types.d.ts +36 -0
  90. package/dist/ui/components/organisms/vc-table/types.d.ts.map +1 -0
  91. package/dist/ui/components/organisms/vc-table/vc-table.vue.d.ts +2 -34
  92. package/dist/ui/components/organisms/vc-table/vc-table.vue.d.ts.map +1 -1
  93. package/package.json +4 -4
  94. package/shared/components/generic-dropdown/generic-dropdown.vue +1 -1
  95. package/shared/components/settings-menu-item/settings-menu-item.vue +1 -6
  96. package/shared/components/user-dropdown-button/_internal/user-info.vue +3 -3
  97. package/ui/components/atoms/vc-icon/README.md +198 -220
  98. package/ui/components/atoms/vc-icon/composables/index.ts +2 -0
  99. package/ui/components/atoms/vc-icon/composables/use-icon-type.ts +83 -0
  100. package/ui/components/atoms/vc-icon/composables/use-icon.ts +129 -0
  101. package/ui/components/atoms/vc-icon/index.ts +1 -0
  102. package/ui/components/atoms/vc-icon/types.ts +36 -0
  103. package/ui/components/atoms/vc-icon/vc-bootstrap-icon.vue +111 -10
  104. package/ui/components/atoms/vc-icon/vc-fontawesome-icon.vue +119 -17
  105. package/ui/components/atoms/vc-icon/vc-icon-examples.vue +485 -124
  106. package/ui/components/atoms/vc-icon/vc-icon-test.vue +399 -209
  107. package/ui/components/atoms/vc-icon/vc-icon.stories.ts +502 -56
  108. package/ui/components/atoms/vc-icon/vc-icon.vue +240 -155
  109. package/ui/components/atoms/vc-icon/vc-lucide-icon.vue +163 -33
  110. package/ui/components/atoms/vc-icon/vc-material-icon.vue +136 -30
  111. package/ui/components/atoms/vc-icon/vc-svg-icon.vue +168 -0
  112. package/ui/components/atoms/vc-widget/vc-widget.stories.ts +13 -0
  113. package/ui/components/atoms/vc-widget/vc-widget.vue +2 -0
  114. package/ui/components/molecules/vc-multivalue/vc-multivalue.vue +1 -1
  115. package/ui/components/molecules/vc-pagination/vc-pagination.vue +23 -14
  116. package/ui/components/organisms/vc-app/_internal/vc-app-bar/_internal/AppBarHeader.vue +2 -2
  117. package/ui/components/organisms/vc-app/_internal/vc-app-bar/vc-app-bar.vue +2 -3
  118. package/ui/components/organisms/vc-blade/_internal/vc-blade-toolbar/_internal/vc-blade-toolbar-buttons/_internal/vc-blade-toolbar-button/props.ts +14 -0
  119. package/ui/components/organisms/vc-blade/_internal/vc-blade-toolbar/_internal/vc-blade-toolbar-buttons/_internal/vc-blade-toolbar-button/vc-blade-toolbar-base-button.vue +1 -12
  120. package/ui/components/organisms/vc-blade/_internal/vc-blade-toolbar/_internal/vc-blade-toolbar-buttons/_internal/vc-blade-toolbar-button/vc-blade-toolbar-circle-button.vue +1 -1
  121. package/ui/components/organisms/vc-blade/_internal/vc-blade-toolbar/vc-blade-toolbar.vue +65 -32
  122. package/ui/components/organisms/vc-table/_internal/vc-table-cell/vc-table-cell.vue +1 -1
  123. package/ui/components/organisms/vc-table/_internal/vc-table-column-switcher/vc-table-column-switcher.vue +1 -1
  124. package/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/_internal/vc-table-body/vc-table-body.vue +1 -1
  125. package/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/_internal/vc-table-columns-header/vc-table-columns-header.vue +1 -1
  126. package/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/_internal/vc-table-row/vc-table-row.vue +1 -1
  127. package/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/vc-table-desktop-view.vue +1 -1
  128. package/ui/components/organisms/vc-table/_internal/vc-table-mobile-view/vc-table-mobile-view.vue +1 -1
  129. package/ui/components/organisms/vc-table/composables/useTableActions.ts +1 -1
  130. package/ui/components/organisms/vc-table/composables/useTableColumnReorder.ts +1 -1
  131. package/ui/components/organisms/vc-table/composables/useTableColumnResize.ts +1 -1
  132. package/ui/components/organisms/vc-table/composables/useTableRowReorder.ts +1 -1
  133. package/ui/components/organisms/vc-table/composables/useTableSelection.ts +1 -1
  134. package/ui/components/organisms/vc-table/composables/useTableState.ts +1 -1
  135. package/ui/components/organisms/vc-table/types.ts +32 -0
  136. package/ui/components/organisms/vc-table/vc-table.vue +2 -30
@@ -2,27 +2,37 @@
2
2
  <div
3
3
  v-if="useContainer"
4
4
  :class="['vc-icon-container', `vc-icon-container_${size}`]"
5
+ :style="containerStyle"
6
+ v-bind="$attrs"
5
7
  >
6
- <DefineTemplate>
7
- <component
8
- :is="renderComponent"
9
- :class="[
10
- 'vc-icon',
11
- `vc-icon_${size}`,
12
- variant ? `vc-icon_${variant}` : '',
13
- !isCustomIcon && !isMaterialIcon && !isLucideIcon && !isBootstrapIcon && !isFontAwesomeIcon
14
- ? (icon as string).toLowerCase()
15
- : '',
16
- ]"
17
- v-bind="componentProps"
18
- />
19
- </DefineTemplate>
20
- <ReuseTemplate v-bind="$attrs" />
8
+ <component
9
+ :is="renderComponent"
10
+ :class="[
11
+ 'vc-icon',
12
+ `vc-icon_${size}`,
13
+ variant ? `vc-icon_${variant}` : '',
14
+ !isCustomIcon && !isMaterialIcon && !isLucideIcon && !isBootstrapIcon && !isFontAwesomeIcon
15
+ ? (icon as string).toLowerCase()
16
+ : '',
17
+ ]"
18
+ :style="iconStyle"
19
+ v-bind="componentProps"
20
+ />
21
21
  </div>
22
22
 
23
- <ReuseTemplate
23
+ <component
24
+ :is="renderComponent"
24
25
  v-else
25
- v-bind="$attrs"
26
+ :class="[
27
+ 'vc-icon',
28
+ `vc-icon_${size}`,
29
+ variant ? `vc-icon_${variant}` : '',
30
+ !isCustomIcon && !isMaterialIcon && !isLucideIcon && !isBootstrapIcon && !isFontAwesomeIcon
31
+ ? (icon as string).toLowerCase()
32
+ : '',
33
+ ]"
34
+ :style="iconStyle"
35
+ v-bind="{ ...componentProps, ...$attrs }"
26
36
  />
27
37
  </template>
28
38
 
@@ -33,28 +43,28 @@ import VcMaterialIcon from "./vc-material-icon.vue";
33
43
  import VcBootstrapIcon from "./vc-bootstrap-icon.vue";
34
44
  import VcLucideIcon from "./vc-lucide-icon.vue";
35
45
  import VcFontawesomeIcon from "./vc-fontawesome-icon.vue";
36
- import { createReusableTemplate } from "@vueuse/core";
46
+ import VcSvgIcon from "./vc-svg-icon.vue";
37
47
 
38
- export type IconType = "fontawesome" | "material" | "bootstrap" | "lucide" | "custom";
48
+ export type IconType = "fontawesome" | "material" | "bootstrap" | "lucide" | "custom" | "svg";
39
49
  export type IconSize = "xs" | "s" | "m" | "l" | "xl" | "xxl" | "xxxl";
40
50
  export type IconVariant = "warning" | "danger" | "success";
41
51
 
42
52
  export interface Props {
43
53
  /**
44
- * The icon to display. Can be a string identifier or a component instance.
54
+ * Icon to display. Can be a string identifier or a component instance.
45
55
  * For string identifiers, use the following format:
46
56
  * - "fa-*" or "fas fa-*" for Font Awesome icons (e.g. "fas fa-home")
47
57
  * - "bi-*" for Bootstrap icons (e.g. "bi-house")
48
58
  * - "material-*" for Material icons (e.g. "material-home")
49
59
  * - "lucide-*" for Lucide icons (e.g. "lucide-home")
50
- * All icons must use the appropriate prefix to identify their type.
60
+ * - "svg:path/to/icon.svg" for SVG icons
61
+ * All icons must use the corresponding prefix to determine their type.
51
62
  */
52
63
  icon?: string | Component;
53
64
 
54
65
  /**
55
- * Size of the icon. The component provides predefined sizes from xs to xxxl.
56
- * Each size corresponds to a specific pixel size as defined in the CSS variables.
57
- * You can also use external CSS to set font-size for more flexibility.
66
+ * Icon size. The component provides predefined sizes from xs to xxxl.
67
+ * Each size corresponds to a specific size in pixels, as defined in the CSS variables.
58
68
  */
59
69
  size?: IconSize;
60
70
 
@@ -75,15 +85,40 @@ export interface Props {
75
85
  * This is useful when you need a specific size that's not in the predefined sizes.
76
86
  */
77
87
  customSize?: number;
88
+
89
+ /**
90
+ * Base path to SVG icons (only for SVG icons)
91
+ */
92
+ basePath?: string;
78
93
  }
79
94
 
80
95
  const props = withDefaults(defineProps<Props>(), {
81
96
  icon: "fas fa-square-full",
82
97
  size: "m",
83
98
  useContainer: true,
99
+ basePath: "/assets/icons",
84
100
  });
85
101
 
86
- const [DefineTemplate, ReuseTemplate] = createReusableTemplate();
102
+ // Sizes in px for each size value
103
+ const sizeMap = {
104
+ xs: 12,
105
+ s: 14,
106
+ m: 18,
107
+ l: 20,
108
+ xl: 22,
109
+ xxl: 30,
110
+ xxxl: 64,
111
+ } as const;
112
+
113
+ // Scaling factors for different icon types to make them visually equal
114
+ const scalingFactors = {
115
+ fontawesome: 1, // base reference
116
+ material: 1.1,
117
+ bootstrap: 0.95,
118
+ lucide: 1.2,
119
+ custom: 1,
120
+ svg: 1,
121
+ };
87
122
 
88
123
  // Function to detect icon type if not explicitly specified
89
124
  const detectIconType = computed((): IconType => {
@@ -108,6 +143,11 @@ const detectIconType = computed((): IconType => {
108
143
  return "material";
109
144
  }
110
145
 
146
+ // SVG icon prefix
147
+ if (props.icon.startsWith("svg:")) {
148
+ return "svg";
149
+ }
150
+
111
151
  // For backward compatibility with Lucide icons ending with Icon
112
152
  if (props.icon.endsWith("Icon")) {
113
153
  return "lucide";
@@ -222,9 +262,57 @@ const renderComponent = computed(() => {
222
262
  return VcFontawesomeIcon;
223
263
  }
224
264
 
265
+ if (isSvgIcon.value) {
266
+ return VcSvgIcon;
267
+ }
268
+
225
269
  return isCustomIcon.value ? safeIcon.value : "i";
226
270
  });
227
271
 
272
+ // Calculate the actual pixel size based on props
273
+ const calculatedSize = computed(() => {
274
+ if (props.customSize) {
275
+ return props.customSize;
276
+ }
277
+ return sizeMap[props.size];
278
+ });
279
+
280
+ // Icon styles
281
+ const iconStyle = computed(() => {
282
+ const styles: Record<string, string> = {};
283
+
284
+ // If the size is set through customSize, apply it directly
285
+ if (props.customSize) {
286
+ // For text icons (FontAwesome, Bootstrap, Material) use font-size
287
+ if (isFontAwesomeIcon.value || isBootstrapIcon.value || isMaterialIcon.value) {
288
+ styles.fontSize = `${props.customSize}px`;
289
+ }
290
+
291
+ // For SVG and component icons, set explicit width and height
292
+ if (isCustomIcon.value || isLucideIcon.value || isSvgIcon.value) {
293
+ styles.width = `${props.customSize}px`;
294
+ styles.height = `${props.customSize}px`;
295
+ }
296
+ } else {
297
+ // For text icons, set font-size: inherit to inherit from the container
298
+ if (isFontAwesomeIcon.value || isBootstrapIcon.value || isMaterialIcon.value || isLucideIcon.value) {
299
+ styles.fontSize = "inherit";
300
+ }
301
+ }
302
+
303
+ return styles;
304
+ });
305
+
306
+ // Container styles
307
+ const containerStyle = computed(() => {
308
+ if (props.customSize) {
309
+ return {
310
+ fontSize: `${props.customSize}px`,
311
+ };
312
+ }
313
+ return {};
314
+ });
315
+
228
316
  // Prepare props for the rendered component
229
317
  const componentProps = computed(() => {
230
318
  if (isMaterialIcon.value) {
@@ -242,7 +330,7 @@ const componentProps = computed(() => {
242
330
  fill: 0,
243
331
  weight: 300,
244
332
  grade: 0,
245
- customSize: props.customSize,
333
+ customSize: props.customSize, // Set custom size without scaling
246
334
  };
247
335
  }
248
336
 
@@ -254,7 +342,7 @@ const componentProps = computed(() => {
254
342
  icon: iconName,
255
343
  size: props.size,
256
344
  variant: props.variant,
257
- customSize: props.customSize,
345
+ customSize: props.customSize, // Set custom size without scaling
258
346
  };
259
347
  }
260
348
 
@@ -267,8 +355,8 @@ const componentProps = computed(() => {
267
355
  icon: iconName,
268
356
  size: props.size,
269
357
  variant: props.variant,
270
- strokeWidth: 1.25,
271
- customSize: props.customSize,
358
+ strokeWidth: 1.5,
359
+ customSize: props.customSize, // Set custom size without scaling
272
360
  };
273
361
  }
274
362
 
@@ -278,14 +366,26 @@ const componentProps = computed(() => {
278
366
  icon: typeof props.icon === "string" ? props.icon : "",
279
367
  size: props.size,
280
368
  variant: props.variant,
281
- customSize: props.customSize,
369
+ customSize: props.customSize, // Set custom size without scaling
370
+ };
371
+ }
372
+
373
+ if (isSvgIcon.value) {
374
+ return {
375
+ icon: svgPath.value,
376
+ size: props.size,
377
+ variant: props.variant,
378
+ strokeWidth: 1.5,
379
+ customSize: props.customSize, // Set custom size without scaling
380
+ basePath: props.basePath,
282
381
  };
283
382
  }
284
383
 
285
384
  if (isCustomIcon.value) {
286
385
  return {
287
- width: props.customSize || iconSize.value,
288
- height: props.customSize || iconSize.value,
386
+ size: props.size,
387
+ width: calculatedSize.value,
388
+ height: calculatedSize.value,
289
389
  color: props.variant ? `var(--icon-color-${props.variant})` : "currentColor",
290
390
  };
291
391
  }
@@ -293,23 +393,24 @@ const componentProps = computed(() => {
293
393
  return {};
294
394
  });
295
395
 
296
- const sizeMap = {
297
- xs: 12,
298
- s: 14,
299
- m: 18,
300
- l: 20,
301
- xl: 22,
302
- xxl: 30,
303
- xxxl: 64,
304
- } as const;
396
+ // Check if icon is an SVG icon
397
+ const isSvgIcon = computed(() => detectIconType.value === "svg");
305
398
 
306
- // Calculate icon size based on props
307
- const iconSize = computed(() => props.customSize || sizeMap[props.size]);
399
+ // Get the path to the SVG if it's an SVG icon
400
+ const svgPath = computed(() => {
401
+ if (!isSvgIcon.value || typeof props.icon !== "string") {
402
+ return "";
403
+ }
404
+
405
+ // Remove the svg: prefix if present
406
+ return props.icon.startsWith("svg:") ? props.icon.substring(4) : props.icon;
407
+ });
308
408
  </script>
309
409
 
310
410
  <style lang="scss">
311
411
  /* Base sizes */
312
- :deep(.vc-icon) {
412
+ :root {
413
+ /* Define icon sizes */
313
414
  --icon-size-xs: 12px;
314
415
  --icon-size-s: 14px;
315
416
  --icon-size-m: 18px;
@@ -318,127 +419,127 @@ const iconSize = computed(() => props.customSize || sizeMap[props.size]);
318
419
  --icon-size-xxl: 30px;
319
420
  --icon-size-xxxl: 64px;
320
421
 
321
- /* Container sizes (10% larger than icon) */
322
- --icon-container-xs: calc(var(--icon-size-xs) * 1.1);
323
- --icon-container-s: calc(var(--icon-size-s) * 1.1);
324
- --icon-container-m: calc(var(--icon-size-m) * 1.1);
325
- --icon-container-l: calc(var(--icon-size-l) * 1.1);
326
- --icon-container-xl: calc(var(--icon-size-xl) * 1.1);
327
- --icon-container-xxl: calc(var(--icon-size-xxl) * 1.1);
328
- --icon-container-xxxl: calc(var(--icon-size-xxxl) * 1.1);
329
-
330
- /* Optical adjustments for different icon libraries */
331
- --material-icons-scale: 1.2; /* Material icons need to be larger */
332
- --fontawesome-icons-scale: 0.9; /* FontAwesome icons need to be smaller */
333
- --bootstrap-icons-scale: 1; /* Bootstrap icons are our baseline */
334
- --lucide-icons-scale: 1; /* Lucide icons match bootstrap */
335
-
336
422
  /* Colors for variants */
337
423
  --icon-color-success: var(--success-500);
338
424
  --icon-color-danger: var(--danger-500);
339
425
  --icon-color-warning: var(--warning-500);
426
+ }
340
427
 
428
+ /* Base styles for all icons */
429
+ .vc-icon {
341
430
  display: inline-flex;
342
431
  align-items: center;
343
432
  justify-content: center;
344
- transition: color 0.2s ease-in-out;
433
+ flex-shrink: 0;
434
+ line-height: 1;
345
435
 
346
- /* Allow font-size to control icon size by default */
347
- width: 1em;
348
- height: 1em;
349
- font-size: inherit;
436
+ /* Ensure SVG icons respect font-size */
437
+ svg {
438
+ width: 1em;
439
+ height: 1em;
440
+ display: block;
441
+ }
350
442
  }
351
443
 
352
- /* Size classes - these can be overridden by external CSS */
353
- :deep(.vc-icon_xs) {
444
+ /* Size classes - these use CSS variables */
445
+ .vc-icon_xs {
354
446
  font-size: var(--icon-size-xs);
355
447
  }
356
448
 
357
- :deep(.vc-icon_s) {
449
+ .vc-icon_s {
358
450
  font-size: var(--icon-size-s);
359
451
  }
360
452
 
361
- :deep(.vc-icon_m) {
453
+ .vc-icon_m {
362
454
  font-size: var(--icon-size-m);
363
455
  }
364
456
 
365
- :deep(.vc-icon_l) {
457
+ .vc-icon_l {
366
458
  font-size: var(--icon-size-l);
367
459
  }
368
460
 
369
- :deep(.vc-icon_xl) {
461
+ .vc-icon_xl {
370
462
  font-size: var(--icon-size-xl);
371
463
  }
372
464
 
373
- :deep(.vc-icon_xxl) {
465
+ .vc-icon_xxl {
374
466
  font-size: var(--icon-size-xxl);
375
467
  }
376
468
 
377
- :deep(.vc-icon_xxxl) {
469
+ .vc-icon_xxxl {
378
470
  font-size: var(--icon-size-xxxl);
379
471
  }
380
472
 
381
- .vc-icon {
382
- &-container {
383
- display: flex;
384
- align-items: center;
385
- justify-content: center;
386
- }
473
+ /* Variants */
474
+ .vc-icon_warning {
475
+ color: var(--icon-color-warning);
476
+ }
387
477
 
388
- &-container_xs {
389
- width: var(--icon-container-xs);
390
- height: var(--icon-container-xs);
391
- }
478
+ .vc-icon_danger {
479
+ color: var(--icon-color-danger);
480
+ }
392
481
 
393
- &-container_s {
394
- width: var(--icon-container-s);
395
- height: var(--icon-container-s);
396
- }
482
+ .vc-icon_success {
483
+ color: var(--icon-color-success);
484
+ }
397
485
 
398
- &-container_m {
399
- width: var(--icon-container-m);
400
- height: var(--icon-container-m);
401
- }
486
+ /* Styles for the container */
487
+ .vc-icon-container {
488
+ display: flex;
489
+ align-items: center;
490
+ justify-content: center;
491
+ flex-shrink: 0;
492
+ line-height: 1;
493
+ font-size: inherit; /* Inherit font-size from the parent */
494
+ }
402
495
 
403
- &-container_l {
404
- width: var(--icon-container-l);
405
- height: var(--icon-container-l);
406
- }
496
+ .vc-icon-container_xs {
497
+ min-width: calc(var(--icon-size-xs) * 1.33);
498
+ min-height: calc(var(--icon-size-xs) * 1.33);
499
+ font-size: var(--icon-size-xs); /* Set font-size for the container */
500
+ }
407
501
 
408
- &-container_xl {
409
- width: var(--icon-container-xl);
410
- height: var(--icon-container-xl);
411
- }
502
+ .vc-icon-container_s {
503
+ min-width: calc(var(--icon-size-s) * 1.33);
504
+ min-height: calc(var(--icon-size-s) * 1.33);
505
+ font-size: var(--icon-size-s); /* Set font-size for the container */
506
+ }
412
507
 
413
- &-container_xxl {
414
- width: var(--icon-container-xxl);
415
- height: var(--icon-container-xxl);
416
- }
508
+ .vc-icon-container_m {
509
+ min-width: calc(var(--icon-size-m) * 1.33);
510
+ min-height: calc(var(--icon-size-m) * 1.33);
511
+ font-size: var(--icon-size-m); /* Set font-size for the container */
512
+ }
417
513
 
418
- &-container_xxxl {
419
- width: var(--icon-container-xxxl);
420
- height: var(--icon-container-xxxl);
421
- }
514
+ .vc-icon-container_l {
515
+ min-width: calc(var(--icon-size-l) * 1.33);
516
+ min-height: calc(var(--icon-size-l) * 1.33);
517
+ font-size: var(--icon-size-l); /* Set font-size for the container */
422
518
  }
423
519
 
424
- /* Variants */
425
- :deep(.vc-icon_warning) {
426
- color: var(--icon-color-warning);
520
+ .vc-icon-container_xl {
521
+ min-width: calc(var(--icon-size-xl) * 1.33);
522
+ min-height: calc(var(--icon-size-xl) * 1.33);
523
+ font-size: var(--icon-size-xl); /* Set font-size for the container */
427
524
  }
428
525
 
429
- :deep(.vc-icon_danger) {
430
- color: var(--icon-color-danger);
526
+ .vc-icon-container_xxl {
527
+ min-width: calc(var(--icon-size-xxl) * 1.33);
528
+ min-height: calc(var(--icon-size-xxl) * 1.33);
529
+ font-size: var(--icon-size-xxl); /* Set font-size for the container */
431
530
  }
432
531
 
433
- :deep(.vc-icon_success) {
434
- color: var(--icon-color-success);
532
+ .vc-icon-container_xxxl {
533
+ min-width: calc(var(--icon-size-xxxl) * 1.33);
534
+ min-height: calc(var(--icon-size-xxxl) * 1.33);
535
+ font-size: var(--icon-size-xxxl); /* Set font-size for the container */
435
536
  }
436
537
 
437
538
  /* Material Icons specific styles */
438
- :deep(.material-symbols-outlined),
439
- :deep(.material-symbols-rounded),
440
- :deep(.material-symbols-sharp) {
441
- font-family: "Material Symbols Outlined", "Material Symbols Rounded", "Material Symbols Sharp";
539
+ .material-symbols-outlined,
540
+ .material-symbols-rounded,
541
+ .material-symbols-sharp {
542
+ font-family: "Material Symbols Outlined";
442
543
  font-weight: normal;
443
544
  font-style: normal;
444
545
  line-height: 1;
@@ -450,12 +551,11 @@ const iconSize = computed(() => props.customSize || sizeMap[props.size]);
450
551
  font-feature-settings: "liga";
451
552
  -webkit-font-feature-settings: "liga";
452
553
  -webkit-font-smoothing: antialiased;
453
- transform: scale(var(--material-icons-scale)); /* Optical adjustment */
454
554
  }
455
555
 
456
556
  /* Bootstrap Icons specific styles */
457
- :deep([class^="bi-"]),
458
- :deep([class*=" bi-"]) {
557
+ [class^="bi-"],
558
+ [class*=" bi-"] {
459
559
  font-family: bootstrap-icons !important;
460
560
  font-style: normal;
461
561
  font-weight: normal !important;
@@ -464,22 +564,21 @@ const iconSize = computed(() => props.customSize || sizeMap[props.size]);
464
564
  line-height: 1;
465
565
  -webkit-font-smoothing: antialiased;
466
566
  -moz-osx-font-smoothing: grayscale;
467
- transform: scale(var(--bootstrap-icons-scale)); /* Optical adjustment */
468
567
  }
469
568
 
470
569
  /* Font Awesome Icons */
471
- :deep([class^="fa-"]),
472
- :deep([class*=" fa-"]),
473
- :deep([class^="fas"]),
474
- :deep([class*=" fas"]),
475
- :deep([class^="far"]),
476
- :deep([class*=" far"]),
477
- :deep([class^="fal"]),
478
- :deep([class*=" fal"]),
479
- :deep([class^="fab"]),
480
- :deep([class*=" fab"]),
481
- :deep([class^="fad"]),
482
- :deep([class*=" fad"]) {
570
+ [class^="fa-"],
571
+ [class*=" fa-"],
572
+ [class^="fas"],
573
+ [class*=" fas"],
574
+ [class^="far"],
575
+ [class*=" far"],
576
+ [class^="fal"],
577
+ [class*=" fal"],
578
+ [class^="fab"],
579
+ [class*=" fab"],
580
+ [class^="fad"],
581
+ [class*=" fad"] {
483
582
  font-family: "Font Awesome 6 Free", "Font Awesome 6 Brands", "Font Awesome 6 Duotone", "Font Awesome 6 Pro";
484
583
  font-style: normal;
485
584
  font-weight: normal;
@@ -488,40 +587,26 @@ const iconSize = computed(() => props.customSize || sizeMap[props.size]);
488
587
  line-height: 1;
489
588
  -webkit-font-smoothing: antialiased;
490
589
  -moz-osx-font-smoothing: grayscale;
491
- transform: scale(var(--fontawesome-icons-scale)); /* Optical adjustment */
492
590
  }
493
591
 
494
592
  /* Font weight adjustments for Font Awesome */
495
- :deep(.fas),
496
- :deep(.fa-solid) {
593
+ .fas,
594
+ .fa-solid {
497
595
  font-weight: 900;
498
596
  }
499
597
 
500
- :deep(.far),
501
- :deep(.fa-regular) {
598
+ .far,
599
+ .fa-regular {
502
600
  font-weight: 400;
503
601
  }
504
602
 
505
- :deep(.fal),
506
- :deep(.fa-light) {
603
+ .fal,
604
+ .fa-light {
507
605
  font-weight: 300;
508
606
  }
509
607
 
510
- :deep(.fab),
511
- :deep(.fa-brands) {
608
+ .fab,
609
+ .fa-brands {
512
610
  font-family: "Font Awesome 6 Brands";
513
611
  }
514
-
515
- /* Lucide Icons specific styles */
516
- :deep(svg.vc-icon) {
517
- transform: scale(var(--lucide-icons-scale)); /* Optical adjustment */
518
- }
519
-
520
- .vc-icon {
521
- &-container {
522
- display: flex;
523
- align-items: center;
524
- justify-content: center;
525
- }
526
- }
527
612
  </style>