vueless 0.0.490 → 0.0.492
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/constants.js +11 -2
- package/package.json +1 -1
- package/plugin-vite.d.ts +1 -0
- package/plugin-vite.js +25 -16
- package/ui.form-select/USelect.vue +0 -1
- package/ui.image-icon/UIcon.vue +9 -7
- package/utils/node/helper.js +20 -8
- package/utils/node/loaderIcon.js +198 -126
- package/utils/node/loaderSvg.js +3 -3
- package/utils/node/vuelessConfig.js +5 -2
- package/web-types.json +1 -1
- /package/assets/icons/{add.svg → vueless/add.svg} +0 -0
- /package/assets/icons/{apps.svg → vueless/apps.svg} +0 -0
- /package/assets/icons/{arrow_back.svg → vueless/arrow_back.svg} +0 -0
- /package/assets/icons/{attach_file.svg → vueless/attach_file.svg} +0 -0
- /package/assets/icons/{calendar_month-fill.svg → vueless/calendar_month-fill.svg} +0 -0
- /package/assets/icons/{check.svg → vueless/check.svg} +0 -0
- /package/assets/icons/{check_circle.svg → vueless/check_circle.svg} +0 -0
- /package/assets/icons/{chevron_left.svg → vueless/chevron_left.svg} +0 -0
- /package/assets/icons/{chevron_right.svg → vueless/chevron_right.svg} +0 -0
- /package/assets/icons/{close.svg → vueless/close.svg} +0 -0
- /package/assets/icons/{close_small.svg → vueless/close_small.svg} +0 -0
- /package/assets/icons/{delete.svg → vueless/delete.svg} +0 -0
- /package/assets/icons/{description.svg → vueless/description.svg} +0 -0
- /package/assets/icons/{drag_indicator.svg → vueless/drag_indicator.svg} +0 -0
- /package/assets/icons/{edit.svg → vueless/edit.svg} +0 -0
- /package/assets/icons/{edit_note.svg → vueless/edit_note.svg} +0 -0
- /package/assets/icons/{emoji_food_beverage.svg → vueless/emoji_food_beverage.svg} +0 -0
- /package/assets/icons/{error.svg → vueless/error.svg} +0 -0
- /package/assets/icons/{expand_more.svg → vueless/expand_more.svg} +0 -0
- /package/assets/icons/{first_page.svg → vueless/first_page.svg} +0 -0
- /package/assets/icons/{image.svg → vueless/image.svg} +0 -0
- /package/assets/icons/{keyboard_arrow_down.svg → vueless/keyboard_arrow_down.svg} +0 -0
- /package/assets/icons/{keyboard_arrow_left.svg → vueless/keyboard_arrow_left.svg} +0 -0
- /package/assets/icons/{keyboard_arrow_right.svg → vueless/keyboard_arrow_right.svg} +0 -0
- /package/assets/icons/{label.svg → vueless/label.svg} +0 -0
- /package/assets/icons/{last_page.svg → vueless/last_page.svg} +0 -0
- /package/assets/icons/{remove.svg → vueless/remove.svg} +0 -0
- /package/assets/icons/{search.svg → vueless/search.svg} +0 -0
- /package/assets/icons/{star-fill.svg → vueless/star-fill.svg} +0 -0
- /package/assets/icons/{star.svg → vueless/star.svg} +0 -0
- /package/assets/icons/{title.svg → vueless/title.svg} +0 -0
- /package/assets/icons/{visibility-fill.svg → vueless/visibility-fill.svg} +0 -0
- /package/assets/icons/{visibility_off-fill.svg → vueless/visibility_off-fill.svg} +0 -0
- /package/assets/icons/{warning.svg → vueless/warning.svg} +0 -0
package/constants.js
CHANGED
|
@@ -185,6 +185,17 @@ export const DEFAULT_SVGO_CONFIG = {
|
|
|
185
185
|
],
|
|
186
186
|
};
|
|
187
187
|
|
|
188
|
+
/* Vueless general */
|
|
189
|
+
export const ICONS_DIR = "assets/icons";
|
|
190
|
+
export const VUELESS_LIBRARY = "vueless";
|
|
191
|
+
export const VUELESS_CONFIG_FILE_NAME = "vueless.config";
|
|
192
|
+
export const VUELESS_CACHE_DIR = "node_modules/.cache/vueless";
|
|
193
|
+
export const VUELESS_DIR = `node_modules/${VUELESS_LIBRARY}`;
|
|
194
|
+
export const VUELESS_LOCAL_DIR = `src`;
|
|
195
|
+
export const VUELESS_ICONS_DIR = `${VUELESS_DIR}/${ICONS_DIR}`;
|
|
196
|
+
export const VUELESS_ICONS_LOCAL_DIR = `src/${ICONS_DIR}`;
|
|
197
|
+
export const VUELESS_ICONS_CACHED_DIR = `${VUELESS_CACHE_DIR}/${ICONS_DIR}`;
|
|
198
|
+
|
|
188
199
|
/* Other */
|
|
189
200
|
export const PX_IN_REM = 16;
|
|
190
201
|
export const NESTED_COMPONENT_REG_EXP = /\{U[^}]*}/g;
|
|
@@ -192,5 +203,3 @@ export const DYNAMIC_COLOR_PATTERN = "{color}";
|
|
|
192
203
|
export const TAILWIND_COLOR_OPACITY_DELIMITER = "/";
|
|
193
204
|
export const TAILWIND_VARIANT_DELIMITER = ":";
|
|
194
205
|
export const TAILWIND_VARIANT_DELIMITER_REG_EXP = /:(?![^[]*])/;
|
|
195
|
-
export const CACHE_PATH = "node_modules/.cache/vueless";
|
|
196
|
-
export const VUELESS_CONFIG_FILE_NAME = "vueless.config";
|
package/package.json
CHANGED
package/plugin-vite.d.ts
CHANGED
package/plugin-vite.js
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
import UnpluginVueComponents from "unplugin-vue-components/vite";
|
|
7
7
|
|
|
8
8
|
import { loadSvg } from "./utils/node/loaderSvg.js";
|
|
9
|
-
import {
|
|
9
|
+
import { cacheIcons, removeIconsCache, copyIconsCache } from "./utils/node/loaderIcon.js";
|
|
10
10
|
import { createTailwindSafelist, clearTailwindSafelist } from "./utils/node/tailwindSafelist.js";
|
|
11
|
-
import { getNuxtFiles,
|
|
11
|
+
import { getNuxtFiles, getVueFiles } from "./utils/node/helper.js";
|
|
12
12
|
import { componentResolver, directiveResolver } from "./utils/node/vuelessResolver.js";
|
|
13
13
|
|
|
14
14
|
/* Automatically importing Vueless components on demand */
|
|
@@ -25,21 +25,22 @@ export const VuelessUnpluginComponents = (options) =>
|
|
|
25
25
|
– Loads SVG images as a Vue components.
|
|
26
26
|
*/
|
|
27
27
|
export const Vueless = function (options = {}) {
|
|
28
|
-
const { mode, debug, env, include } = options;
|
|
28
|
+
const { mode, debug, env, include, mirrorCacheDir } = options;
|
|
29
29
|
|
|
30
30
|
const isVuelessEnv = env === "vueless";
|
|
31
31
|
const isNuxt = mode === "nuxt-module";
|
|
32
|
-
const srcDir = isNuxt ? process.cwd() : getVueSourceFile();
|
|
33
32
|
|
|
34
|
-
const targetFiles = [
|
|
33
|
+
const targetFiles = [...(include || []), ...(isNuxt ? getNuxtFiles() : getVueFiles())];
|
|
35
34
|
|
|
36
35
|
/* if server stopped by developer (Ctrl+C) */
|
|
37
36
|
process.on("SIGINT", async () => {
|
|
38
|
-
/* remove
|
|
39
|
-
await
|
|
37
|
+
/* remove cached icons */
|
|
38
|
+
await removeIconsCache(mirrorCacheDir, debug);
|
|
40
39
|
|
|
41
40
|
/* clear tailwind safelist */
|
|
42
41
|
clearTailwindSafelist(debug);
|
|
42
|
+
|
|
43
|
+
/* stop command line process */
|
|
43
44
|
process.exit(0);
|
|
44
45
|
});
|
|
45
46
|
|
|
@@ -57,28 +58,36 @@ export const Vueless = function (options = {}) {
|
|
|
57
58
|
}),
|
|
58
59
|
|
|
59
60
|
configResolved: async (config) => {
|
|
60
|
-
/* collect used in project colors for tailwind safelist */
|
|
61
61
|
if (!isNuxt) {
|
|
62
|
+
/* collect used in project colors for tailwind safelist */
|
|
62
63
|
await createTailwindSafelist({ mode, env, debug, targetFiles });
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
if (config.command === "build") {
|
|
66
|
-
|
|
67
|
+
/* remove cached icons */
|
|
68
|
+
await removeIconsCache(mirrorCacheDir, debug);
|
|
69
|
+
|
|
70
|
+
/* cache vueless built-in and project icons */
|
|
71
|
+
await cacheIcons({ mode: "vuelessIcons", env, debug, targetFiles });
|
|
72
|
+
await cacheIcons({ mode, env, debug, targetFiles });
|
|
67
73
|
|
|
68
|
-
/*
|
|
69
|
-
await
|
|
70
|
-
await copyIcons({ mode, env, debug, targetFiles });
|
|
74
|
+
/* copy vueless cache folder */
|
|
75
|
+
await copyIconsCache(mirrorCacheDir, debug);
|
|
71
76
|
}
|
|
72
77
|
|
|
73
78
|
if (config.command === "dev" || config.command === "serve") {
|
|
74
|
-
/* remove
|
|
75
|
-
await
|
|
79
|
+
/* remove cached icons */
|
|
80
|
+
await removeIconsCache(mirrorCacheDir, debug);
|
|
81
|
+
/* cache vueless built-in icons */
|
|
82
|
+
await cacheIcons({ mode: "vuelessIcons", env, debug, targetFiles });
|
|
83
|
+
/* copy vueless cache folder */
|
|
84
|
+
await copyIconsCache(mirrorCacheDir, debug);
|
|
76
85
|
}
|
|
77
86
|
},
|
|
78
87
|
|
|
79
|
-
/* remove dynamically copied icons after build */
|
|
80
88
|
buildEnd: async () => {
|
|
81
|
-
|
|
89
|
+
/* remove cached icons */
|
|
90
|
+
await removeIconsCache(mirrorCacheDir, debug);
|
|
82
91
|
},
|
|
83
92
|
|
|
84
93
|
/* load SVG images as a Vue components */
|
package/ui.image-icon/UIcon.vue
CHANGED
|
@@ -11,15 +11,15 @@
|
|
|
11
11
|
|
|
12
12
|
<script setup>
|
|
13
13
|
import { computed, defineAsyncComponent } from "vue";
|
|
14
|
+
import { vTooltip } from "../directives";
|
|
14
15
|
import { getDefault } from "../utils/ui.ts";
|
|
15
16
|
import { isSSR } from "../utils/helper.ts";
|
|
17
|
+
import { VUELESS_ICONS_CACHED_DIR, VUELESS_LIBRARY } from "../constants.js";
|
|
16
18
|
|
|
17
19
|
import { UIcon } from "./constants.js";
|
|
18
20
|
import defaultConfig from "./config.ts";
|
|
19
21
|
import useAttrs from "./useAttrs.js";
|
|
20
22
|
|
|
21
|
-
import { vTooltip } from "../directives";
|
|
22
|
-
|
|
23
23
|
defineOptions({ inheritAttrs: false });
|
|
24
24
|
|
|
25
25
|
const props = defineProps({
|
|
@@ -140,10 +140,12 @@ const generatedIcons = computed(() => {
|
|
|
140
140
|
const dynamicComponent = computed(() => {
|
|
141
141
|
const FILL_SUFFIX = "-fill";
|
|
142
142
|
|
|
143
|
-
const
|
|
144
|
-
|
|
143
|
+
const isInternalIcon = Boolean(
|
|
144
|
+
generatedIcons.value.find(([path]) => path.includes(VUELESS_LIBRARY + "/" + props.name)),
|
|
145
|
+
);
|
|
145
146
|
|
|
146
|
-
const
|
|
147
|
+
const userLibrary = config.value.defaults.library;
|
|
148
|
+
const library = props.internal && isInternalIcon ? VUELESS_LIBRARY : userLibrary;
|
|
147
149
|
const weight = config.value.defaults.weight;
|
|
148
150
|
const style = config.value.defaults.style;
|
|
149
151
|
const isFill = props.name.endsWith(FILL_SUFFIX);
|
|
@@ -176,8 +178,8 @@ const dynamicComponent = computed(() => {
|
|
|
176
178
|
return import.meta.env.PROD
|
|
177
179
|
? await getIcon([name])
|
|
178
180
|
: isSSR
|
|
179
|
-
? import(/* @vite-ignore */
|
|
180
|
-
: import(/* @vite-ignore */
|
|
181
|
+
? import(/* @vite-ignore */ `${VUELESS_ICONS_CACHED_DIR}/${VUELESS_LIBRARY}/${name}.svg?component`)
|
|
182
|
+
: import(/* @vite-ignore */ `/${VUELESS_ICONS_CACHED_DIR}/${VUELESS_LIBRARY}/${name}.svg?component`);
|
|
181
183
|
},
|
|
182
184
|
"@material-symbols": async () => {
|
|
183
185
|
return import.meta.env.PROD
|
package/utils/node/helper.js
CHANGED
|
@@ -5,15 +5,27 @@ import { readdir } from "node:fs/promises";
|
|
|
5
5
|
export async function getDirFiles(dirPath, ext, { recursive = true, exclude = [] } = {}) {
|
|
6
6
|
let fileNames = [];
|
|
7
7
|
|
|
8
|
+
const ERROR_CODE = {
|
|
9
|
+
dirIsFile: "ENOTDIR",
|
|
10
|
+
noEntry: "ENOENT",
|
|
11
|
+
};
|
|
12
|
+
|
|
8
13
|
try {
|
|
9
14
|
fileNames = await readdir(dirPath, { recursive });
|
|
10
15
|
} catch (error) {
|
|
11
|
-
if (error.code ===
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
16
|
+
if (error.code === ERROR_CODE.dirIsFile) {
|
|
17
|
+
const pathArray = dirPath.split(path.sep);
|
|
18
|
+
const fileName = pathArray.pop();
|
|
19
|
+
|
|
20
|
+
fileNames = [fileName];
|
|
21
|
+
dirPath = pathArray.join(path.sep);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (error.code === ERROR_CODE.noEntry) {
|
|
15
25
|
fileNames = [];
|
|
16
|
-
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (!Object.values(ERROR_CODE).includes(error.code)) {
|
|
17
29
|
// eslint-disable-next-line no-console
|
|
18
30
|
console.error(error);
|
|
19
31
|
}
|
|
@@ -52,8 +64,8 @@ export function getNuxtFiles() {
|
|
|
52
64
|
];
|
|
53
65
|
}
|
|
54
66
|
|
|
55
|
-
export function
|
|
56
|
-
return path.join(process.cwd(), "src");
|
|
67
|
+
export function getVueFiles() {
|
|
68
|
+
return [path.join(process.cwd(), "src")];
|
|
57
69
|
}
|
|
58
70
|
|
|
59
71
|
export function getDefaultConfigJson(fileContents) {
|
|
@@ -64,7 +76,7 @@ export function getDefaultConfigJson(fileContents) {
|
|
|
64
76
|
return (0, eval)("(" + objectString + ")"); // Converting into JS object
|
|
65
77
|
}
|
|
66
78
|
|
|
67
|
-
export function merge(source, target) {
|
|
79
|
+
export function merge(source = {}, target = {}) {
|
|
68
80
|
for (const [key, val] of Object.entries(source)) {
|
|
69
81
|
if (val !== null && typeof val === `object`) {
|
|
70
82
|
target[key] ??= new val.__proto__.constructor();
|
package/utils/node/loaderIcon.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
This scrypt find icon names from the UIcon props and objects across the project
|
|
3
3
|
and copy SVG icons from the default icons library (@material-symbols or other from config)
|
|
4
|
-
to the
|
|
5
|
-
|
|
6
|
-
Those icons will be used only in the build stage.
|
|
7
|
-
The script is needed to avoid all @material-symbols icons set in the project bundle.
|
|
4
|
+
to the `VUELESS_ICONS_CACHED_DIR` folder.
|
|
8
5
|
*/
|
|
9
6
|
|
|
10
7
|
/* eslint-disable no-console */
|
|
@@ -15,89 +12,140 @@ import { rm, cp } from "node:fs/promises";
|
|
|
15
12
|
|
|
16
13
|
import { vuelessConfig } from "./vuelessConfig.js";
|
|
17
14
|
import { getDirFiles, getDefaultConfigJson, merge } from "./helper.js";
|
|
18
|
-
import {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
15
|
+
import {
|
|
16
|
+
COMPONENTS,
|
|
17
|
+
VUELESS_DIR,
|
|
18
|
+
VUELESS_LOCAL_DIR,
|
|
19
|
+
VUELESS_LIBRARY,
|
|
20
|
+
VUELESS_ICONS_DIR,
|
|
21
|
+
VUELESS_ICONS_LOCAL_DIR,
|
|
22
|
+
VUELESS_ICONS_CACHED_DIR,
|
|
23
|
+
VUELESS_CONFIG_FILE_NAME,
|
|
24
|
+
ICONS_DIR,
|
|
25
|
+
} from "../../constants.js";
|
|
26
|
+
|
|
27
|
+
const cwd = process.cwd();
|
|
28
|
+
|
|
29
|
+
const DEFAULT_ICONS_DIR = path.join(cwd, VUELESS_ICONS_DIR);
|
|
30
|
+
const DEFAULT_ICONS_LOCAL_DIR = path.join(cwd, VUELESS_ICONS_LOCAL_DIR);
|
|
31
|
+
const CACHED_ICONS_DIR = path.join(cwd, VUELESS_ICONS_CACHED_DIR);
|
|
32
|
+
const U_ICON = "UIcon";
|
|
27
33
|
|
|
28
34
|
let isDebug = false;
|
|
29
35
|
let isVuelessEnv = false;
|
|
30
|
-
let isDefaultMode = false;
|
|
31
36
|
let isStorybookMode = false;
|
|
32
37
|
let isVuelessIconsMode = false;
|
|
33
|
-
let
|
|
38
|
+
let cacheIconsPath = CACHED_ICONS_DIR;
|
|
34
39
|
|
|
35
|
-
|
|
36
|
-
|
|
40
|
+
/**
|
|
41
|
+
* Dynamically find icons across the project and cache it.
|
|
42
|
+
* Icons cache magick happens here... ✨
|
|
43
|
+
* @param {string} mode
|
|
44
|
+
* @param {string} env
|
|
45
|
+
* @param {boolean} debug
|
|
46
|
+
* @param {Array} targetFiles
|
|
47
|
+
*/
|
|
48
|
+
export async function cacheIcons({ mode, env, debug, targetFiles = [] } = {}) {
|
|
37
49
|
isDebug = debug || false;
|
|
38
50
|
isVuelessEnv = env === "vueless";
|
|
39
|
-
isDefaultMode = mode === "";
|
|
40
51
|
isStorybookMode = mode === "storybook";
|
|
41
52
|
isVuelessIconsMode = mode === "vuelessIcons";
|
|
53
|
+
cacheIconsPath = CACHED_ICONS_DIR;
|
|
42
54
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
await cp(DEFAULT_ICONS_LOCAL_DIR, CACHED_ICONS_DIR, { recursive: true });
|
|
55
|
+
if (isVuelessIconsMode && isVuelessEnv) {
|
|
56
|
+
cacheIconsPath = DEFAULT_ICONS_LOCAL_DIR;
|
|
46
57
|
}
|
|
47
58
|
|
|
48
|
-
|
|
49
|
-
if (!isVuelessEnv && fs.existsSync(DEFAULT_ICONS_DIR)) {
|
|
50
|
-
await cp(DEFAULT_ICONS_DIR, CACHED_ICONS_DIR, { recursive: true });
|
|
51
|
-
}
|
|
59
|
+
const exclude = isStorybookMode ? [] : ["/stories.js", "/stories.ts", ".d.ts"];
|
|
52
60
|
|
|
53
|
-
|
|
54
|
-
|
|
61
|
+
const vueFiles = targetFiles.map((componentPath) => getDirFiles(componentPath, ".vue"));
|
|
62
|
+
const jsFiles = targetFiles.map((jsFilePath) => getDirFiles(jsFilePath, ".js", { exclude }));
|
|
63
|
+
const tsFiles = targetFiles.map((tsFilePath) => getDirFiles(tsFilePath, ".ts", { exclude }));
|
|
55
64
|
|
|
56
|
-
|
|
57
|
-
const storybookStoriesJs = await getDirFiles("src", STORYBOOK_STORY_EXTENSIONS[0]);
|
|
58
|
-
const storybookStoriesTs = await getDirFiles("src", STORYBOOK_STORY_EXTENSIONS[1]);
|
|
65
|
+
const iconFiles = await Promise.all([...vueFiles, ...jsFiles, ...tsFiles]);
|
|
59
66
|
|
|
60
|
-
|
|
61
|
-
|
|
67
|
+
findAndCopyIcons([
|
|
68
|
+
...iconFiles.flat(),
|
|
69
|
+
`${VUELESS_CONFIG_FILE_NAME}.js`,
|
|
70
|
+
`${VUELESS_CONFIG_FILE_NAME}.ts`,
|
|
71
|
+
]);
|
|
62
72
|
|
|
63
|
-
if (isVuelessIconsMode
|
|
64
|
-
|
|
73
|
+
if (isVuelessIconsMode) {
|
|
74
|
+
await copyVuelessIconsIntoCache(isVuelessEnv);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
65
77
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Remove cached icons.
|
|
80
|
+
* @param {string} mirrorCacheDir
|
|
81
|
+
* @param {boolean} debug
|
|
82
|
+
* @returns {Promise<void>}
|
|
83
|
+
*/
|
|
84
|
+
export async function removeIconsCache(mirrorCacheDir, debug) {
|
|
85
|
+
if (fs.existsSync(cacheIconsPath)) {
|
|
86
|
+
await rm(cacheIconsPath, { recursive: true, force: true });
|
|
87
|
+
}
|
|
69
88
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
);
|
|
89
|
+
if (mirrorCacheDir) {
|
|
90
|
+
const mirrorCacheIconsPath = path.join(cwd, mirrorCacheDir, ICONS_DIR);
|
|
73
91
|
|
|
74
|
-
|
|
92
|
+
if (fs.existsSync(mirrorCacheIconsPath)) {
|
|
93
|
+
await rm(mirrorCacheIconsPath, { recursive: true, force: true });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
75
96
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
`${VUELESS_CONFIG_FILE_NAME}.js`,
|
|
79
|
-
`${VUELESS_CONFIG_FILE_NAME}.ts`,
|
|
80
|
-
]);
|
|
97
|
+
if (debug) {
|
|
98
|
+
console.log("Icons cache was successfully removed.");
|
|
81
99
|
}
|
|
82
100
|
}
|
|
83
101
|
|
|
84
|
-
|
|
85
|
-
|
|
102
|
+
/**
|
|
103
|
+
* Copy cached icons in the provided folder by path.
|
|
104
|
+
* @param {string} mirrorCacheDir
|
|
105
|
+
* @param {boolean} debug
|
|
106
|
+
* @returns {Promise<void>}
|
|
107
|
+
*/
|
|
108
|
+
export async function copyIconsCache(mirrorCacheDir, debug) {
|
|
109
|
+
const cachePath = path.join(cwd, VUELESS_ICONS_CACHED_DIR);
|
|
86
110
|
|
|
87
|
-
|
|
111
|
+
if (mirrorCacheDir && fs.existsSync(cachePath)) {
|
|
112
|
+
await cp(cachePath, path.join(cwd, mirrorCacheDir, ICONS_DIR), { recursive: true });
|
|
113
|
+
}
|
|
88
114
|
|
|
89
115
|
if (debug) {
|
|
90
|
-
console.log(
|
|
116
|
+
console.log(`Vueless cached icons was successfully copied into: ${mirrorCacheDir}.`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Copy icons which using in vueless components to the cache.
|
|
122
|
+
* @param {boolean} isVuelessEnv
|
|
123
|
+
* @returns {Promise<void>}
|
|
124
|
+
*/
|
|
125
|
+
async function copyVuelessIconsIntoCache(isVuelessEnv) {
|
|
126
|
+
if (isVuelessEnv && fs.existsSync(DEFAULT_ICONS_LOCAL_DIR)) {
|
|
127
|
+
await cp(DEFAULT_ICONS_LOCAL_DIR, CACHED_ICONS_DIR, {
|
|
128
|
+
recursive: true,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (!isVuelessEnv && fs.existsSync(DEFAULT_ICONS_DIR)) {
|
|
133
|
+
await cp(DEFAULT_ICONS_DIR, CACHED_ICONS_DIR, {
|
|
134
|
+
recursive: true,
|
|
135
|
+
});
|
|
91
136
|
}
|
|
92
137
|
}
|
|
93
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Scan the project for icon names and copy found icons to the cache.
|
|
141
|
+
* @param {Array} files
|
|
142
|
+
*/
|
|
94
143
|
function findAndCopyIcons(files) {
|
|
95
|
-
const defaults =
|
|
96
|
-
const safelistIcons =
|
|
144
|
+
const defaults = getDefaults();
|
|
145
|
+
const safelistIcons = vuelessConfig.component?.[U_ICON]?.safelistIcons;
|
|
97
146
|
|
|
98
|
-
safelistIcons
|
|
99
|
-
|
|
100
|
-
copyFile(iconName, true);
|
|
147
|
+
safelistIcons?.forEach((iconName) => {
|
|
148
|
+
copyIcon(iconName, defaults);
|
|
101
149
|
});
|
|
102
150
|
|
|
103
151
|
files.forEach((file) => {
|
|
@@ -114,7 +162,7 @@ function findAndCopyIcons(files) {
|
|
|
114
162
|
|
|
115
163
|
try {
|
|
116
164
|
if (iconName) {
|
|
117
|
-
|
|
165
|
+
copyIcon(iconName, defaults);
|
|
118
166
|
}
|
|
119
167
|
} catch (error) {
|
|
120
168
|
isDebug && console.log(error);
|
|
@@ -137,103 +185,127 @@ function findAndCopyIcons(files) {
|
|
|
137
185
|
try {
|
|
138
186
|
if (!iconName) return;
|
|
139
187
|
|
|
140
|
-
if (iconName?.includes("?")) {
|
|
188
|
+
if (iconName?.includes("?") && iconName?.includes(":")) {
|
|
141
189
|
const [trueName, falseName] = getTernaryValues(iconName);
|
|
142
190
|
|
|
143
|
-
|
|
144
|
-
|
|
191
|
+
copyIcon(trueName, defaults);
|
|
192
|
+
copyIcon(falseName, defaults);
|
|
145
193
|
} else {
|
|
146
|
-
|
|
194
|
+
copyIcon(iconName, defaults);
|
|
147
195
|
}
|
|
148
196
|
} catch (error) {
|
|
149
197
|
isDebug && console.log(error);
|
|
150
198
|
}
|
|
151
199
|
}
|
|
152
200
|
});
|
|
201
|
+
}
|
|
153
202
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
203
|
+
/**
|
|
204
|
+
* Retrieve values from ternary of strings.
|
|
205
|
+
* @param {string} expression
|
|
206
|
+
* @returns {Array} of ternary values
|
|
207
|
+
*/
|
|
208
|
+
function getTernaryValues(expression) {
|
|
209
|
+
const [, values] = expression
|
|
210
|
+
.replace(/\s/g, "") // newlines and spaces
|
|
211
|
+
.replace(/\?\./g, "") // conditional chaining `?.`
|
|
212
|
+
.replace(/['"]/g, "") // single and double quotes
|
|
213
|
+
.split("?");
|
|
160
214
|
|
|
161
|
-
|
|
215
|
+
const [trueValue, falseValue] = values.split(":");
|
|
162
216
|
|
|
163
|
-
|
|
164
|
-
|
|
217
|
+
return [trueValue, falseValue];
|
|
218
|
+
}
|
|
165
219
|
|
|
166
|
-
|
|
167
|
-
|
|
220
|
+
/**
|
|
221
|
+
* Copy icon from icon package into cache folder.
|
|
222
|
+
* @param {string} name
|
|
223
|
+
* @param {object} defaults
|
|
224
|
+
*/
|
|
225
|
+
function copyIcon(name, defaults) {
|
|
226
|
+
name = name.toLowerCase();
|
|
168
227
|
|
|
169
|
-
|
|
228
|
+
const iconNameRegex = /^[a-z0-9_-]+$/;
|
|
170
229
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
230
|
+
/* Stop the scrypt if the icon name is irrelevant. */
|
|
231
|
+
if (!iconNameRegex.test(name)) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
175
234
|
|
|
176
|
-
|
|
177
|
-
const weight = defaults.weight;
|
|
178
|
-
const style = defaults.style;
|
|
179
|
-
|
|
180
|
-
const require = createRequire(import.meta.url);
|
|
181
|
-
|
|
182
|
-
/* eslint-disable vue/max-len, prettier/prettier */
|
|
183
|
-
const libraries = {
|
|
184
|
-
vueless: {
|
|
185
|
-
// @material-symbols icons which used across the components.
|
|
186
|
-
source: `${process.cwd()}/node_modules/${library}/svg-${weight}/${style}/${name}.svg`,
|
|
187
|
-
destination: `${cachedIconsDir}/${name}.svg`
|
|
188
|
-
},
|
|
189
|
-
"@material-symbols": {
|
|
190
|
-
source: `${process.cwd()}/node_modules/${library}/svg-${weight}/${style}/${name}.svg`,
|
|
191
|
-
destination: `${cachedIconsDir}/${library}/svg-${weight}/${style}/${name}.svg`
|
|
192
|
-
},
|
|
193
|
-
"bootstrap-icons": {
|
|
194
|
-
source: `${process.cwd()}/node_modules/${library}/icons/${name}.svg`,
|
|
195
|
-
destination: `${cachedIconsDir}/${library}/icons/${name}.svg`
|
|
196
|
-
},
|
|
197
|
-
heroicons: {
|
|
198
|
-
source: `${process.cwd()}/node_modules/${library}/24/${name.endsWith("-fill") ? "solid" : "outline"}/${name}.svg`,
|
|
199
|
-
destination: `${cachedIconsDir}/24/${style}/${name.endsWith("-fill") ? "solid" : "outline"}/${name}.svg`
|
|
200
|
-
}
|
|
201
|
-
};
|
|
202
|
-
/* eslint-enable vue/max-len, prettier/prettier */
|
|
235
|
+
const { source, destination } = getIconLibraryPaths(name, defaults);
|
|
203
236
|
|
|
204
|
-
|
|
205
|
-
|
|
237
|
+
if (!fs.existsSync(source) || fs.existsSync(destination)) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
206
240
|
|
|
207
|
-
|
|
241
|
+
const require = createRequire(import.meta.url);
|
|
242
|
+
const destDir = path.dirname(destination);
|
|
208
243
|
|
|
209
|
-
|
|
244
|
+
fs.mkdirSync(destDir, {
|
|
245
|
+
recursive: true,
|
|
246
|
+
});
|
|
210
247
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
error
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
});
|
|
219
|
-
}
|
|
248
|
+
fs.copyFile(require.resolve(source), destination, (error) => {
|
|
249
|
+
if (isDebug) {
|
|
250
|
+
error
|
|
251
|
+
? console.error(`Error copying icon "${name}":`, error)
|
|
252
|
+
: console.log(`Icon "${name}" copied successfully!`);
|
|
253
|
+
}
|
|
254
|
+
});
|
|
220
255
|
}
|
|
221
256
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
257
|
+
/**
|
|
258
|
+
* Build a path to the icon source in the selected icon library and cache destination path.
|
|
259
|
+
* @param {string} name
|
|
260
|
+
* @param {object} defaults
|
|
261
|
+
* @returns {source: string, destination: string}
|
|
262
|
+
*/
|
|
263
|
+
function getIconLibraryPaths(name, defaults) {
|
|
264
|
+
const library = defaults.library;
|
|
265
|
+
const weight = defaults.weight;
|
|
266
|
+
const style = defaults.style;
|
|
267
|
+
|
|
268
|
+
/* eslint-disable prettier/prettier, vue/max-len */
|
|
269
|
+
const libraries = {
|
|
270
|
+
[VUELESS_LIBRARY]: {
|
|
271
|
+
// @material-symbols icons which used across the components.
|
|
272
|
+
source: `${cwd}/node_modules/${library}/svg-${weight}/${style}/${name}.svg`,
|
|
273
|
+
destination: `${cacheIconsPath}/${VUELESS_LIBRARY}/${name}.svg`
|
|
274
|
+
},
|
|
275
|
+
"@material-symbols": {
|
|
276
|
+
source: `${cwd}/node_modules/${library}/svg-${weight}/${style}/${name}.svg`,
|
|
277
|
+
destination: `${cacheIconsPath}/${library}/svg-${weight}/${style}/${name}.svg`
|
|
278
|
+
},
|
|
279
|
+
"bootstrap-icons": {
|
|
280
|
+
source: `${cwd}/node_modules/${library}/icons/${name}.svg`,
|
|
281
|
+
destination: `${cacheIconsPath}/${library}/icons/${name}.svg`
|
|
282
|
+
},
|
|
283
|
+
"heroicons": {
|
|
284
|
+
source: `${cwd}/node_modules/${library}/24/${name.endsWith("-fill") ? "solid" : "outline"}/${name}.svg`,
|
|
285
|
+
destination: `${cacheIconsPath}/${library}/24/${style}/${name.endsWith("-fill") ? "solid" : "outline"}/${name}.svg`
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
/* eslint-enable prettier/prettier, vue/max-len */
|
|
289
|
+
|
|
290
|
+
const libraryName = isVuelessIconsMode && isVuelessEnv ? VUELESS_LIBRARY : library;
|
|
291
|
+
|
|
292
|
+
return libraries[libraryName];
|
|
226
293
|
}
|
|
227
294
|
|
|
228
|
-
|
|
229
|
-
|
|
295
|
+
/**
|
|
296
|
+
* Merge global and local defaults config for UIcon.
|
|
297
|
+
* @returns {Object}
|
|
298
|
+
*/
|
|
299
|
+
function getDefaults() {
|
|
300
|
+
const defaultIconsDir = isVuelessEnv ? VUELESS_LOCAL_DIR : VUELESS_DIR;
|
|
301
|
+
const defaultConfigPath = path.join(cwd, defaultIconsDir, COMPONENTS[U_ICON], "config.ts");
|
|
230
302
|
|
|
231
303
|
if (fs.existsSync(defaultConfigPath)) {
|
|
232
304
|
const defaultConfigFile = fs.readFileSync(defaultConfigPath).toString();
|
|
233
305
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
306
|
+
return merge(
|
|
307
|
+
getDefaultConfigJson(defaultConfigFile)?.defaults,
|
|
308
|
+
vuelessConfig?.component?.[U_ICON]?.defaults,
|
|
309
|
+
);
|
|
238
310
|
}
|
|
239
311
|
}
|
package/utils/node/loaderSvg.js
CHANGED
|
@@ -25,7 +25,7 @@ export async function loadSvg(id, options) {
|
|
|
25
25
|
svgPath = svgPath.replace("/__skip_vite/", "");
|
|
26
26
|
|
|
27
27
|
// use default svg loader
|
|
28
|
-
if (importType === "url"
|
|
28
|
+
if (importType === "url") {
|
|
29
29
|
return;
|
|
30
30
|
}
|
|
31
31
|
|
|
@@ -36,11 +36,11 @@ export async function loadSvg(id, options) {
|
|
|
36
36
|
|
|
37
37
|
try {
|
|
38
38
|
svg = await fs.promises.readFile(svgPath, "utf-8");
|
|
39
|
-
} catch {
|
|
39
|
+
} catch (error) {
|
|
40
40
|
// define an empty svg to prevent a UI crash.
|
|
41
41
|
svg = `<svg xmlns="http://www.w3.org/2000/svg"></svg>`;
|
|
42
42
|
// eslint-disable-next-line no-console
|
|
43
|
-
console.warn(
|
|
43
|
+
console.warn(`${svgPath} couldn't be loaded by vueless vite plugin.`, "\n", error);
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
if (importType === "raw") {
|
|
@@ -2,7 +2,7 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import esbuild from "esbuild";
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { VUELESS_CACHE_DIR, VUELESS_CONFIG_FILE_NAME } from "../../constants.js";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Load Vueless config from the project root.
|
|
@@ -13,7 +13,10 @@ export let vuelessConfig = {};
|
|
|
13
13
|
(async () => {
|
|
14
14
|
const configPathJs = path.join(process.cwd(), `${VUELESS_CONFIG_FILE_NAME}.js`);
|
|
15
15
|
const configPathTs = path.join(process.cwd(), `${VUELESS_CONFIG_FILE_NAME}.ts`);
|
|
16
|
-
const configOutPath = path.join(
|
|
16
|
+
const configOutPath = path.join(
|
|
17
|
+
process.cwd(),
|
|
18
|
+
`${VUELESS_CACHE_DIR}/${VUELESS_CONFIG_FILE_NAME}.mjs`,
|
|
19
|
+
);
|
|
17
20
|
|
|
18
21
|
if (!fs.existsSync(configPathJs) && !fs.existsSync(configPathTs)) {
|
|
19
22
|
vuelessConfig = {};
|
package/web-types.json
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|