@vc-shell/framework 1.1.4 → 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.
- package/CHANGELOG.md +10 -0
- package/core/directives/loading/styles.css +1 -1
- package/core/plugins/modularity/README.md +347 -17
- package/core/plugins/modularity/loader.ts +217 -3
- package/dist/core/plugins/modularity/loader.d.ts +4 -0
- package/dist/core/plugins/modularity/loader.d.ts.map +1 -1
- package/dist/framework.js +1 -1
- package/dist/{index-BdflTsg6.js → index-BBHl6nap.js} +1 -1
- package/dist/{index-DJOis7Nc.js → index-BG6N4UCY.js} +1 -1
- package/dist/{index-CIcET-ZI.js → index-Bv5as3SI.js} +1 -1
- package/dist/{index-wfv8ehcx.js → index-C4VyqVxv.js} +1 -1
- package/dist/{index-Cf2H7YZ1.js → index-CKLiFGZ-.js} +1 -1
- package/dist/{index-DuY7BIGm.js → index-CTmAMa_1.js} +1 -1
- package/dist/{index-D-fPN3yf.js → index-CtGZgIiV.js} +1 -1
- package/dist/{index-BpBTtmQ6.js → index-D13Jcezf.js} +1 -1
- package/dist/{index-DWTsz5bC.js → index-DbpKygJh.js} +1 -1
- package/dist/{index-Br0y2YMn.js → index-DgCtSr4P.js} +1 -1
- package/dist/{index-Ck055pN8.js → index-Dh1XjfgY.js} +1 -1
- package/dist/{index-CYAMpxnu.js → index-DpDbQQg6.js} +1 -1
- package/dist/{index-BDqUaIyQ.js → index-DwuQbDJG.js} +1 -1
- package/dist/{index-BBYKbiRX.js → index-Fhuqbkq2.js} +1 -1
- package/dist/{index-o6aSdNED.js → index-JTAZpxKF.js} +1 -1
- package/dist/{index-BDm0tcWn.js → index-MKD2CP5c.js} +49888 -48568
- package/dist/{index-DKtQMsy4.js → index-Q3k1PYzc.js} +1 -1
- package/dist/index.css +3 -3
- package/dist/shared/components/generic-dropdown/generic-dropdown.vue.d.ts.map +1 -1
- package/dist/shared/components/settings-menu-item/settings-menu-item.vue.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/ui/components/atoms/vc-icon/composables/index.d.ts +3 -0
- package/dist/ui/components/atoms/vc-icon/composables/index.d.ts.map +1 -0
- package/dist/ui/components/atoms/vc-icon/composables/use-icon-type.d.ts +22 -0
- package/dist/ui/components/atoms/vc-icon/composables/use-icon-type.d.ts.map +1 -0
- package/dist/ui/components/atoms/vc-icon/composables/use-icon.d.ts +30 -0
- package/dist/ui/components/atoms/vc-icon/composables/use-icon.d.ts.map +1 -0
- package/dist/ui/components/atoms/vc-icon/index.d.ts +1 -0
- package/dist/ui/components/atoms/vc-icon/index.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-icon/types.d.ts +31 -0
- package/dist/ui/components/atoms/vc-icon/types.d.ts.map +1 -0
- package/dist/ui/components/atoms/vc-icon/vc-bootstrap-icon.vue.d.ts +18 -4
- package/dist/ui/components/atoms/vc-icon/vc-bootstrap-icon.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-icon/vc-fontawesome-icon.vue.d.ts +15 -2
- package/dist/ui/components/atoms/vc-icon/vc-fontawesome-icon.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-icon/vc-icon-examples.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-icon/vc-icon-test.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-icon/vc-icon.vue.d.ts +11 -6
- package/dist/ui/components/atoms/vc-icon/vc-icon.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-icon/vc-lucide-icon.vue.d.ts +21 -4
- package/dist/ui/components/atoms/vc-icon/vc-lucide-icon.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-icon/vc-material-icon.vue.d.ts +30 -4
- package/dist/ui/components/atoms/vc-icon/vc-material-icon.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-icon/vc-svg-icon.vue.d.ts +33 -0
- package/dist/ui/components/atoms/vc-icon/vc-svg-icon.vue.d.ts.map +1 -0
- package/dist/ui/components/molecules/vc-pagination/vc-pagination.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-app/_internal/vc-app-bar/vc-app-bar.vue.d.ts.map +1 -1
- 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
- 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
- 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
- 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
- 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
- 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
- package/dist/ui/components/organisms/vc-table/_internal/vc-table-cell/vc-table-cell.vue.d.ts +1 -1
- package/dist/ui/components/organisms/vc-table/_internal/vc-table-cell/vc-table-cell.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-table/_internal/vc-table-column-switcher/vc-table-column-switcher.vue.d.ts +1 -1
- package/dist/ui/components/organisms/vc-table/_internal/vc-table-column-switcher/vc-table-column-switcher.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/_internal/vc-table-body/vc-table-body.vue.d.ts +1 -1
- 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
- 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
- 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
- package/dist/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/_internal/vc-table-row/vc-table-row.vue.d.ts +1 -1
- 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
- package/dist/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/vc-table-desktop-view.vue.d.ts +1 -1
- package/dist/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/vc-table-desktop-view.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-table/_internal/vc-table-mobile-view/vc-table-mobile-view.vue.d.ts +1 -1
- package/dist/ui/components/organisms/vc-table/_internal/vc-table-mobile-view/vc-table-mobile-view.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-table/composables/useTableActions.d.ts +1 -1
- package/dist/ui/components/organisms/vc-table/composables/useTableActions.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-table/composables/useTableColumnReorder.d.ts +1 -1
- package/dist/ui/components/organisms/vc-table/composables/useTableColumnReorder.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-table/composables/useTableColumnResize.d.ts +1 -1
- package/dist/ui/components/organisms/vc-table/composables/useTableColumnResize.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-table/composables/useTableRowReorder.d.ts +1 -1
- package/dist/ui/components/organisms/vc-table/composables/useTableRowReorder.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-table/composables/useTableSelection.d.ts +1 -1
- package/dist/ui/components/organisms/vc-table/composables/useTableSelection.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-table/composables/useTableState.d.ts +1 -1
- package/dist/ui/components/organisms/vc-table/composables/useTableState.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-table/types.d.ts +36 -0
- package/dist/ui/components/organisms/vc-table/types.d.ts.map +1 -0
- package/dist/ui/components/organisms/vc-table/vc-table.vue.d.ts +2 -34
- package/dist/ui/components/organisms/vc-table/vc-table.vue.d.ts.map +1 -1
- package/package.json +4 -4
- package/shared/components/generic-dropdown/generic-dropdown.vue +1 -1
- package/shared/components/settings-menu-item/settings-menu-item.vue +1 -6
- package/shared/components/user-dropdown-button/_internal/user-info.vue +3 -3
- package/ui/components/atoms/vc-icon/README.md +198 -220
- package/ui/components/atoms/vc-icon/composables/index.ts +2 -0
- package/ui/components/atoms/vc-icon/composables/use-icon-type.ts +83 -0
- package/ui/components/atoms/vc-icon/composables/use-icon.ts +129 -0
- package/ui/components/atoms/vc-icon/index.ts +1 -0
- package/ui/components/atoms/vc-icon/types.ts +36 -0
- package/ui/components/atoms/vc-icon/vc-bootstrap-icon.vue +111 -10
- package/ui/components/atoms/vc-icon/vc-fontawesome-icon.vue +119 -17
- package/ui/components/atoms/vc-icon/vc-icon-examples.vue +485 -124
- package/ui/components/atoms/vc-icon/vc-icon-test.vue +399 -209
- package/ui/components/atoms/vc-icon/vc-icon.stories.ts +502 -56
- package/ui/components/atoms/vc-icon/vc-icon.vue +240 -155
- package/ui/components/atoms/vc-icon/vc-lucide-icon.vue +163 -33
- package/ui/components/atoms/vc-icon/vc-material-icon.vue +136 -30
- package/ui/components/atoms/vc-icon/vc-svg-icon.vue +168 -0
- package/ui/components/atoms/vc-widget/vc-widget.stories.ts +13 -0
- package/ui/components/molecules/vc-multivalue/vc-multivalue.vue +1 -1
- package/ui/components/molecules/vc-pagination/vc-pagination.vue +23 -14
- package/ui/components/organisms/vc-app/_internal/vc-app-bar/_internal/AppBarHeader.vue +2 -2
- package/ui/components/organisms/vc-app/_internal/vc-app-bar/vc-app-bar.vue +2 -3
- package/ui/components/organisms/vc-blade/_internal/vc-blade-toolbar/_internal/vc-blade-toolbar-buttons/_internal/vc-blade-toolbar-button/props.ts +14 -0
- 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
- 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
- package/ui/components/organisms/vc-table/_internal/vc-table-cell/vc-table-cell.vue +1 -1
- package/ui/components/organisms/vc-table/_internal/vc-table-column-switcher/vc-table-column-switcher.vue +1 -1
- package/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/_internal/vc-table-body/vc-table-body.vue +1 -1
- package/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/_internal/vc-table-columns-header/vc-table-columns-header.vue +1 -1
- package/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/_internal/vc-table-row/vc-table-row.vue +1 -1
- package/ui/components/organisms/vc-table/_internal/vc-table-desktop-view/vc-table-desktop-view.vue +1 -1
- package/ui/components/organisms/vc-table/_internal/vc-table-mobile-view/vc-table-mobile-view.vue +1 -1
- package/ui/components/organisms/vc-table/composables/useTableActions.ts +1 -1
- package/ui/components/organisms/vc-table/composables/useTableColumnReorder.ts +1 -1
- package/ui/components/organisms/vc-table/composables/useTableColumnResize.ts +1 -1
- package/ui/components/organisms/vc-table/composables/useTableRowReorder.ts +1 -1
- package/ui/components/organisms/vc-table/composables/useTableSelection.ts +1 -1
- package/ui/components/organisms/vc-table/composables/useTableState.ts +1 -1
- package/ui/components/organisms/vc-table/types.ts +32 -0
- package/ui/components/organisms/vc-table/vc-table.vue +2 -30
|
@@ -1,66 +1,196 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<component
|
|
3
|
-
:is="
|
|
4
|
-
|
|
5
|
-
:
|
|
3
|
+
:is="resolvedIconComponent"
|
|
4
|
+
v-if="resolvedIconComponent"
|
|
5
|
+
:class="[
|
|
6
|
+
'vc-lucide-icon',
|
|
7
|
+
!hasCustomSize && `vc-lucide-icon--${size}`,
|
|
8
|
+
variant ? `vc-lucide-icon--${variant}` : '',
|
|
9
|
+
]"
|
|
10
|
+
:style="computedStyle"
|
|
11
|
+
aria-hidden="true"
|
|
6
12
|
/>
|
|
13
|
+
<span
|
|
14
|
+
v-else
|
|
15
|
+
:class="['vc-lucide-icon', !hasCustomSize && `vc-lucide-icon--${size}`]"
|
|
16
|
+
>
|
|
17
|
+
<i class="vc-lucide-icon__fallback">❓</i>
|
|
18
|
+
</span>
|
|
7
19
|
</template>
|
|
8
20
|
|
|
9
21
|
<script lang="ts" setup>
|
|
10
|
-
import { computed,
|
|
22
|
+
import { computed, markRaw, onMounted, ref } from "vue";
|
|
23
|
+
import type { IconSize, IconVariant } from "./types";
|
|
24
|
+
import type { Component } from "vue";
|
|
25
|
+
import { useIcon } from "./composables";
|
|
11
26
|
|
|
12
|
-
|
|
27
|
+
interface Props {
|
|
28
|
+
/**
|
|
29
|
+
* Lucide icon name or reference
|
|
30
|
+
*/
|
|
13
31
|
icon: string;
|
|
14
|
-
|
|
15
|
-
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Icon size
|
|
35
|
+
*/
|
|
36
|
+
size?: IconSize;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Icon color variant
|
|
40
|
+
*/
|
|
41
|
+
variant?: IconVariant;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Stroke width for SVG
|
|
45
|
+
*/
|
|
16
46
|
strokeWidth?: number;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Custom size in pixels
|
|
50
|
+
*/
|
|
51
|
+
customSize?: number;
|
|
17
52
|
}
|
|
18
53
|
|
|
19
54
|
const props = withDefaults(defineProps<Props>(), {
|
|
20
55
|
size: "m",
|
|
21
|
-
strokeWidth:
|
|
56
|
+
strokeWidth: 1.5,
|
|
22
57
|
});
|
|
23
58
|
|
|
24
|
-
//
|
|
59
|
+
// Check if using custom size to conditionally apply CSS class
|
|
60
|
+
const hasCustomSize = computed(() => typeof props.customSize === "number" && props.customSize > 0);
|
|
61
|
+
|
|
62
|
+
// Component reference for Lucide icon
|
|
63
|
+
const resolvedIconComponent = ref<Component | null>(null);
|
|
64
|
+
|
|
65
|
+
// Use the shared icon composable for consistent scaling
|
|
66
|
+
const { iconStyle } = useIcon({
|
|
67
|
+
type: "lucide",
|
|
68
|
+
size: props.size,
|
|
69
|
+
variant: props.variant,
|
|
70
|
+
customSize: props.customSize,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Normalize the icon name for Lucide
|
|
25
74
|
const normalizedIconName = computed(() => {
|
|
26
|
-
if (!props.icon) return "";
|
|
75
|
+
if (!props.icon) return "HelpCircleIcon";
|
|
27
76
|
|
|
28
|
-
//
|
|
29
|
-
let
|
|
30
|
-
if (
|
|
31
|
-
|
|
77
|
+
// Handle removal of lucide- prefix
|
|
78
|
+
let name = props.icon;
|
|
79
|
+
if (name.startsWith("lucide-")) {
|
|
80
|
+
name = name.substring(7);
|
|
32
81
|
}
|
|
33
82
|
|
|
34
|
-
//
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
83
|
+
// Ensure name ends with 'Icon'
|
|
84
|
+
if (!name.endsWith("Icon")) {
|
|
85
|
+
name = `${name}Icon`;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Convert to PascalCase if kebab-case
|
|
89
|
+
if (name.includes("-")) {
|
|
90
|
+
name = name
|
|
38
91
|
.split("-")
|
|
39
92
|
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
40
93
|
.join("");
|
|
41
|
-
} else {
|
|
42
|
-
baseName = baseName.charAt(0).toUpperCase() + baseName.slice(1);
|
|
43
94
|
}
|
|
44
95
|
|
|
45
|
-
//
|
|
46
|
-
|
|
47
|
-
|
|
96
|
+
// Ensure first letter is capitalized
|
|
97
|
+
return name.charAt(0).toUpperCase() + name.slice(1);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// Combine the shared icon styles with Lucide-specific settings
|
|
101
|
+
const computedStyle = computed(() => {
|
|
102
|
+
const styles = { ...iconStyle.value };
|
|
103
|
+
|
|
104
|
+
if (props.strokeWidth) {
|
|
105
|
+
styles.strokeWidth = props.strokeWidth.toString();
|
|
48
106
|
}
|
|
49
107
|
|
|
50
|
-
|
|
51
|
-
|
|
108
|
+
// If using custom size, make sure size is applied with !important
|
|
109
|
+
if (hasCustomSize.value) {
|
|
110
|
+
if (styles.width) styles.width = `${styles.width.replace("px", "")}px !important`;
|
|
111
|
+
if (styles.height) styles.height = `${styles.height.replace("px", "")}px !important`;
|
|
112
|
+
}
|
|
52
113
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
if (!props.icon) return null;
|
|
114
|
+
return styles;
|
|
115
|
+
});
|
|
56
116
|
|
|
117
|
+
// Dynamically import the Lucide icon
|
|
118
|
+
onMounted(async () => {
|
|
57
119
|
try {
|
|
120
|
+
// Import from lucide-vue-next
|
|
121
|
+
const module = await import("lucide-vue-next");
|
|
122
|
+
|
|
123
|
+
// Get the icon component safely with type checking
|
|
58
124
|
const iconName = normalizedIconName.value;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
125
|
+
if (module && typeof module === "object" && iconName in module) {
|
|
126
|
+
resolvedIconComponent.value = markRaw(module[iconName as keyof typeof module] as Component);
|
|
127
|
+
} else {
|
|
128
|
+
console.warn(`Lucide icon not found: ${iconName}`);
|
|
129
|
+
}
|
|
130
|
+
} catch (error) {
|
|
131
|
+
console.error(`Error loading Lucide icon: ${normalizedIconName.value}`, error);
|
|
64
132
|
}
|
|
65
133
|
});
|
|
66
134
|
</script>
|
|
135
|
+
|
|
136
|
+
<style lang="scss">
|
|
137
|
+
.vc-lucide-icon {
|
|
138
|
+
display: inline-flex;
|
|
139
|
+
align-items: center;
|
|
140
|
+
justify-content: center;
|
|
141
|
+
vertical-align: middle;
|
|
142
|
+
font-size: inherit;
|
|
143
|
+
|
|
144
|
+
&--xs {
|
|
145
|
+
width: var(--icon-size-xs);
|
|
146
|
+
height: var(--icon-size-xs);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
&--s {
|
|
150
|
+
width: var(--icon-size-s);
|
|
151
|
+
height: var(--icon-size-s);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
&--m {
|
|
155
|
+
width: var(--icon-size-m);
|
|
156
|
+
height: var(--icon-size-m);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
&--l {
|
|
160
|
+
width: var(--icon-size-l);
|
|
161
|
+
height: var(--icon-size-l);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
&--xl {
|
|
165
|
+
width: var(--icon-size-xl);
|
|
166
|
+
height: var(--icon-size-xl);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
&--xxl {
|
|
170
|
+
width: var(--icon-size-xxl);
|
|
171
|
+
height: var(--icon-size-xxl);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
&--xxxl {
|
|
175
|
+
width: var(--icon-size-xxxl);
|
|
176
|
+
height: var(--icon-size-xxxl);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
&--warning {
|
|
180
|
+
color: var(--icon-color-warning);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
&--danger {
|
|
184
|
+
color: var(--icon-color-danger);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
&--success {
|
|
188
|
+
color: var(--icon-color-success);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
&__fallback {
|
|
192
|
+
font-style: normal;
|
|
193
|
+
color: currentColor;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
</style>
|
|
@@ -1,61 +1,167 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<span
|
|
3
|
-
:class="[
|
|
3
|
+
:class="[
|
|
4
|
+
'vc-material-icon',
|
|
5
|
+
!hasCustomSize && `vc-material-icon--${size}`,
|
|
6
|
+
variant ? `vc-material-icon--${variant}` : '',
|
|
7
|
+
materialIconClass,
|
|
8
|
+
]"
|
|
4
9
|
:style="computedStyle"
|
|
5
|
-
|
|
10
|
+
aria-hidden="true"
|
|
6
11
|
>
|
|
12
|
+
{{ icon }}
|
|
13
|
+
</span>
|
|
7
14
|
</template>
|
|
8
15
|
|
|
9
16
|
<script lang="ts" setup>
|
|
10
17
|
import { computed } from "vue";
|
|
18
|
+
import type { IconSize, IconVariant } from "./types";
|
|
19
|
+
import { useIcon } from "./composables";
|
|
11
20
|
|
|
12
|
-
|
|
21
|
+
interface Props {
|
|
22
|
+
/**
|
|
23
|
+
* Material icon name
|
|
24
|
+
*/
|
|
13
25
|
icon: string;
|
|
14
|
-
|
|
15
|
-
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Icon size
|
|
29
|
+
*/
|
|
30
|
+
size?: IconSize;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Type of the Material icon (outlined, rounded, sharp)
|
|
34
|
+
*/
|
|
16
35
|
type?: "outlined" | "rounded" | "sharp";
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Icon color variant
|
|
39
|
+
*/
|
|
40
|
+
variant?: IconVariant;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Fill value (0-1)
|
|
44
|
+
*/
|
|
17
45
|
fill?: number;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Weight value (100-700)
|
|
49
|
+
*/
|
|
18
50
|
weight?: number;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Grade value (-25 to 200)
|
|
54
|
+
*/
|
|
19
55
|
grade?: number;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Custom size in pixels
|
|
59
|
+
*/
|
|
60
|
+
customSize?: number;
|
|
20
61
|
}
|
|
21
62
|
|
|
22
63
|
const props = withDefaults(defineProps<Props>(), {
|
|
23
64
|
size: "m",
|
|
24
65
|
type: "outlined",
|
|
25
66
|
fill: 0,
|
|
26
|
-
weight:
|
|
67
|
+
weight: 300,
|
|
27
68
|
grade: 0,
|
|
28
69
|
});
|
|
29
70
|
|
|
30
|
-
//
|
|
31
|
-
const
|
|
32
|
-
return {
|
|
33
|
-
fontVariationSettings: `'FILL' ${props.fill}, 'wght' ${props.weight}, 'GRAD' ${props.grade}`,
|
|
34
|
-
};
|
|
35
|
-
});
|
|
71
|
+
// Check if using custom size to conditionally apply CSS class
|
|
72
|
+
const hasCustomSize = computed(() => typeof props.customSize === "number" && props.customSize > 0);
|
|
36
73
|
|
|
37
|
-
//
|
|
38
|
-
const
|
|
39
|
-
|
|
74
|
+
// Use the shared icon composable for consistent scaling
|
|
75
|
+
const { iconStyle } = useIcon({
|
|
76
|
+
type: "material",
|
|
77
|
+
size: props.size,
|
|
78
|
+
variant: props.variant,
|
|
79
|
+
customSize: props.customSize,
|
|
80
|
+
});
|
|
40
81
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
82
|
+
// Compute the Google Material Symbols class based on type
|
|
83
|
+
const materialIconClass = computed(() => {
|
|
84
|
+
switch (props.type) {
|
|
85
|
+
case "rounded":
|
|
86
|
+
return "material-symbols-rounded";
|
|
87
|
+
case "sharp":
|
|
88
|
+
return "material-symbols-sharp";
|
|
89
|
+
case "outlined":
|
|
90
|
+
default:
|
|
91
|
+
return "material-symbols-outlined";
|
|
45
92
|
}
|
|
46
|
-
|
|
47
|
-
// Remove possible type suffixes if they still exist
|
|
48
|
-
return iconName.replace(/-outlined$|-rounded$|-sharp$/, "");
|
|
49
93
|
});
|
|
50
94
|
|
|
51
|
-
//
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
95
|
+
// Combine the shared icon styles with Material-specific settings
|
|
96
|
+
const computedStyle = computed(() => {
|
|
97
|
+
const styles = { ...iconStyle.value };
|
|
98
|
+
|
|
99
|
+
// Apply Material variation settings
|
|
100
|
+
styles.fontVariationSettings = `'FILL' ${props.fill}, 'wght' ${props.weight}, 'GRAD' ${props.grade}`;
|
|
101
|
+
|
|
102
|
+
// If using custom size, make sure fontSize is applied with !important
|
|
103
|
+
if (hasCustomSize.value && styles.fontSize) {
|
|
104
|
+
styles.fontSize = `${styles.fontSize.replace("px", "")}px !important`;
|
|
105
|
+
}
|
|
58
106
|
|
|
59
|
-
return
|
|
107
|
+
return styles;
|
|
60
108
|
});
|
|
61
109
|
</script>
|
|
110
|
+
|
|
111
|
+
<style lang="scss">
|
|
112
|
+
.vc-material-icon {
|
|
113
|
+
font-family: "Material Symbols Outlined";
|
|
114
|
+
font-weight: normal;
|
|
115
|
+
font-style: normal;
|
|
116
|
+
line-height: 1;
|
|
117
|
+
letter-spacing: normal;
|
|
118
|
+
text-transform: none;
|
|
119
|
+
display: inline-block;
|
|
120
|
+
white-space: nowrap;
|
|
121
|
+
word-wrap: normal;
|
|
122
|
+
direction: ltr;
|
|
123
|
+
-webkit-font-feature-settings: "liga";
|
|
124
|
+
-webkit-font-smoothing: antialiased;
|
|
125
|
+
font-size: inherit;
|
|
126
|
+
|
|
127
|
+
&--xs {
|
|
128
|
+
font-size: var(--icon-size-xs);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
&--s {
|
|
132
|
+
font-size: var(--icon-size-s);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
&--m {
|
|
136
|
+
font-size: var(--icon-size-m);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
&--l {
|
|
140
|
+
font-size: var(--icon-size-l);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
&--xl {
|
|
144
|
+
font-size: var(--icon-size-xl);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
&--xxl {
|
|
148
|
+
font-size: var(--icon-size-xxl);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
&--xxxl {
|
|
152
|
+
font-size: var(--icon-size-xxxl);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
&--warning {
|
|
156
|
+
color: var(--icon-color-warning);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
&--danger {
|
|
160
|
+
color: var(--icon-color-danger);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
&--success {
|
|
164
|
+
color: var(--icon-color-success);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
</style>
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg
|
|
3
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
4
|
+
:class="['vc-svg-icon', !hasCustomSize && `vc-svg-icon--${size}`, variant ? `vc-svg-icon--${variant}` : '']"
|
|
5
|
+
:style="computedStyle"
|
|
6
|
+
v-bind="$attrs"
|
|
7
|
+
>
|
|
8
|
+
<use
|
|
9
|
+
v-if="resolvedIconPath"
|
|
10
|
+
:xlink:href="resolvedIconPath"
|
|
11
|
+
/>
|
|
12
|
+
</svg>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script lang="ts" setup>
|
|
16
|
+
import { computed } from "vue";
|
|
17
|
+
import type { IconSize, IconVariant } from "./types";
|
|
18
|
+
import { useIcon } from "./composables";
|
|
19
|
+
|
|
20
|
+
defineOptions({
|
|
21
|
+
inheritAttrs: false,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
interface Props {
|
|
25
|
+
/**
|
|
26
|
+
* Path to SVG icon or sprite
|
|
27
|
+
*/
|
|
28
|
+
icon: string;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Icon size
|
|
32
|
+
*/
|
|
33
|
+
size?: IconSize;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Variant for special coloring
|
|
37
|
+
*/
|
|
38
|
+
variant?: IconVariant;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Base path prepended to icon path
|
|
42
|
+
*/
|
|
43
|
+
basePath?: string;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Custom size in pixels
|
|
47
|
+
*/
|
|
48
|
+
customSize?: number;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Stroke width for SVG icons
|
|
52
|
+
*/
|
|
53
|
+
strokeWidth?: number;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
57
|
+
size: "m",
|
|
58
|
+
basePath: "/assets/icons",
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Check if using custom size to conditionally apply CSS class
|
|
62
|
+
const hasCustomSize = computed(() => typeof props.customSize === "number" && props.customSize > 0);
|
|
63
|
+
|
|
64
|
+
// Use the shared icon composable for consistent scaling
|
|
65
|
+
const { iconStyle } = useIcon({
|
|
66
|
+
type: "svg",
|
|
67
|
+
size: props.size,
|
|
68
|
+
variant: props.variant,
|
|
69
|
+
customSize: props.customSize,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Compute the full path to the icon
|
|
73
|
+
const resolvedIconPath = computed(() => {
|
|
74
|
+
// Check if the icon is already a complete path
|
|
75
|
+
if (props.icon.startsWith("/") || props.icon.includes("://") || props.icon.startsWith("#")) {
|
|
76
|
+
return props.icon;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Check if the icon is a reference to a sprite (contains #)
|
|
80
|
+
const hashIndex = props.icon.indexOf("#");
|
|
81
|
+
if (hashIndex > -1) {
|
|
82
|
+
const spritePath = props.icon.substring(0, hashIndex);
|
|
83
|
+
const iconId = props.icon.substring(hashIndex);
|
|
84
|
+
return `${props.basePath}/${spritePath}${iconId}`;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Apply basePath for relative paths
|
|
88
|
+
return `${props.basePath}/${props.icon}`;
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// Combine the shared icon styles with SVG-specific settings
|
|
92
|
+
const computedStyle = computed(() => {
|
|
93
|
+
const styles = { ...iconStyle.value };
|
|
94
|
+
|
|
95
|
+
if (props.strokeWidth) {
|
|
96
|
+
styles.strokeWidth = `${props.strokeWidth}`;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// If using custom size, make sure size is applied with !important
|
|
100
|
+
if (hasCustomSize.value) {
|
|
101
|
+
if (styles.width) styles.width = `${styles.width.replace("px", "")}px !important`;
|
|
102
|
+
if (styles.height) styles.height = `${styles.height.replace("px", "")}px !important`;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return styles;
|
|
106
|
+
});
|
|
107
|
+
</script>
|
|
108
|
+
|
|
109
|
+
<style lang="scss">
|
|
110
|
+
.vc-svg-icon {
|
|
111
|
+
display: inline-block;
|
|
112
|
+
width: 1em;
|
|
113
|
+
height: 1em;
|
|
114
|
+
stroke-width: 0;
|
|
115
|
+
stroke: currentColor;
|
|
116
|
+
fill: currentColor;
|
|
117
|
+
vertical-align: middle;
|
|
118
|
+
flex-shrink: 0;
|
|
119
|
+
font-size: inherit;
|
|
120
|
+
|
|
121
|
+
&--xs {
|
|
122
|
+
width: var(--icon-size-xs);
|
|
123
|
+
height: var(--icon-size-xs);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
&--s {
|
|
127
|
+
width: var(--icon-size-s);
|
|
128
|
+
height: var(--icon-size-s);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
&--m {
|
|
132
|
+
width: var(--icon-size-m);
|
|
133
|
+
height: var(--icon-size-m);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
&--l {
|
|
137
|
+
width: var(--icon-size-l);
|
|
138
|
+
height: var(--icon-size-l);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
&--xl {
|
|
142
|
+
width: var(--icon-size-xl);
|
|
143
|
+
height: var(--icon-size-xl);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
&--xxl {
|
|
147
|
+
width: var(--icon-size-xxl);
|
|
148
|
+
height: var(--icon-size-xxl);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
&--xxxl {
|
|
152
|
+
width: var(--icon-size-xxxl);
|
|
153
|
+
height: var(--icon-size-xxxl);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
&--warning {
|
|
157
|
+
color: var(--icon-color-warning);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
&--danger {
|
|
161
|
+
color: var(--icon-color-danger);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
&--success {
|
|
165
|
+
color: var(--icon-color-success);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
</style>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ref } from "vue";
|
|
2
2
|
import type { Meta, StoryObj } from "@storybook/vue3";
|
|
3
3
|
import { VcWidget } from "./";
|
|
4
|
+
import { provideWidgetService } from "../../../../core/composables";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* `VcWidget` is a component that represents a clickable widget with an icon, title, and optional badge.
|
|
@@ -10,6 +11,18 @@ const meta = {
|
|
|
10
11
|
title: "Atoms/VcWidget",
|
|
11
12
|
component: VcWidget,
|
|
12
13
|
tags: ["autodocs"],
|
|
14
|
+
decorators: [
|
|
15
|
+
() => ({
|
|
16
|
+
setup() {
|
|
17
|
+
provideWidgetService();
|
|
18
|
+
},
|
|
19
|
+
template: `
|
|
20
|
+
<div>
|
|
21
|
+
<story />
|
|
22
|
+
</div>
|
|
23
|
+
`,
|
|
24
|
+
}),
|
|
25
|
+
],
|
|
13
26
|
argTypes: {
|
|
14
27
|
icon: {
|
|
15
28
|
description: "Icon to display in the widget (Font Awesome format or component name)",
|
|
@@ -539,7 +539,7 @@ function onSearch(event: Event) {
|
|
|
539
539
|
|
|
540
540
|
&__field {
|
|
541
541
|
@apply tw-border-none tw-outline-none tw-min-h-[var(--multivalue-height)] tw-bg-[color:var(--multivalue-background-color)]
|
|
542
|
-
tw-
|
|
542
|
+
tw-flex-grow tw-flex-shrink tw-w-auto tw-box-border placeholder:tw-text-[color:var(--multivalue-placeholder-color)] tw-text-sm tw-rounded-[var(--multivalue-border-radius)];
|
|
543
543
|
|
|
544
544
|
&::-webkit-input-placeholder {
|
|
545
545
|
@apply tw-text-[color:var(--multivalue-placeholder-color)];
|