vueless 1.2.5-beta.0 → 1.2.5-beta.10
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/bin/commands/copy.js +93 -42
- package/bin/commands/create.js +62 -29
- package/bin/constants.d.ts +0 -2
- package/bin/constants.js +0 -3
- package/bin/utils/data.js +19 -15
- package/bin/utils/format.js +17 -2
- package/constants.d.ts +15 -7
- package/constants.js +12 -7
- package/index.d.ts +7 -3
- package/index.ts +7 -3
- package/package.json +2 -2
- package/plugin-vite.js +11 -3
- package/types.ts +11 -0
- package/ui.boilerplate/UBoilerplate.vue +1 -1
- package/ui.container-accordion/UAccordion.vue +12 -3
- package/ui.container-accordion/storybook/stories.ts +2 -1
- package/ui.container-accordion/tests/UAccordion.test.ts +27 -7
- package/ui.container-accordion-item/UAccordionItem.vue +7 -10
- package/ui.container-accordion-item/storybook/stories.ts +1 -0
- package/ui.container-accordion-item/tests/UAccordionItem.test.ts +8 -8
- package/ui.image-icon/config.ts +2 -2
- package/ui.image-icon/types.ts +1 -1
- package/ui.navigation-pagination/UPagination.vue +0 -7
- package/ui.navigation-pagination/tests/UPagination.test.ts +0 -24
- package/utils/helper.ts +32 -0
- package/utils/node/helper.d.ts +1 -1
- package/utils/node/helper.js +4 -3
- package/utils/node/loaderSvg.js +8 -2
- package/utils/node/vuelessConfig.js +0 -8
- package/utils/theme.ts +205 -53
- package/utils/ui.ts +6 -1
package/plugin-vite.js
CHANGED
|
@@ -28,17 +28,19 @@ import {
|
|
|
28
28
|
autoImportUserConfigs,
|
|
29
29
|
} from "./utils/node/helper.js";
|
|
30
30
|
import {
|
|
31
|
+
VUE_EXT,
|
|
32
|
+
JAVASCRIPT_EXT,
|
|
33
|
+
TYPESCRIPT_EXT,
|
|
31
34
|
INTERNAL_ENV,
|
|
32
35
|
STORYBOOK_ENV,
|
|
33
36
|
NUXT_MODULE_ENV,
|
|
34
37
|
VUELESS_LOCAL_DIR,
|
|
35
38
|
VUELESS_PACKAGE_DIR,
|
|
39
|
+
SRC_USER_COMPONENTS_DIR,
|
|
40
|
+
VUELESS_USER_COMPONENTS_DIR,
|
|
36
41
|
ICONS_VIRTUAL_MODULE_ID,
|
|
37
42
|
RESOLVED_ICONS_VIRTUAL_MODULE_ID,
|
|
38
43
|
DEFAULT_EXIT_CODE,
|
|
39
|
-
JAVASCRIPT_EXT,
|
|
40
|
-
TYPESCRIPT_EXT,
|
|
41
|
-
VUE_EXT,
|
|
42
44
|
} from "./constants.js";
|
|
43
45
|
|
|
44
46
|
/* TailwindCSS Vite plugins. */
|
|
@@ -49,6 +51,7 @@ export const TailwindCSS = (options) => {
|
|
|
49
51
|
/* Automatically importing Vueless components on demand */
|
|
50
52
|
export const UnpluginComponents = (options) =>
|
|
51
53
|
UnpluginVueComponents({
|
|
54
|
+
dirs: [VUELESS_USER_COMPONENTS_DIR, SRC_USER_COMPONENTS_DIR],
|
|
52
55
|
resolvers: [componentResolver, directiveResolver],
|
|
53
56
|
dts: true,
|
|
54
57
|
...options,
|
|
@@ -103,6 +106,11 @@ export const Vueless = function (options = {}) {
|
|
|
103
106
|
define: {
|
|
104
107
|
"process.env": {},
|
|
105
108
|
},
|
|
109
|
+
build: {
|
|
110
|
+
rollupOptions: {
|
|
111
|
+
external: ["node:fs/promises"],
|
|
112
|
+
},
|
|
113
|
+
},
|
|
106
114
|
optimizeDeps: {
|
|
107
115
|
include: isInternalEnv
|
|
108
116
|
? []
|
package/types.ts
CHANGED
|
@@ -129,6 +129,11 @@ export interface ThemeConfig {
|
|
|
129
129
|
*/
|
|
130
130
|
colorMode?: `${ColorMode}`;
|
|
131
131
|
|
|
132
|
+
/**
|
|
133
|
+
* Defines the color mode to auto.
|
|
134
|
+
*/
|
|
135
|
+
isColorModeAuto?: boolean;
|
|
136
|
+
|
|
132
137
|
/**
|
|
133
138
|
* Light theme design system CSS variables.
|
|
134
139
|
*/
|
|
@@ -185,6 +190,12 @@ export interface Config extends ThemeConfig {
|
|
|
185
190
|
tailwindMerge?: UnknownObject;
|
|
186
191
|
}
|
|
187
192
|
|
|
193
|
+
export type MergedThemeConfig = Omit<ThemeConfig, "text | outline | rounding"> & {
|
|
194
|
+
text: Partial<ThemeConfigText>;
|
|
195
|
+
outline: Partial<ThemeConfigOutline>;
|
|
196
|
+
rounding: Partial<ThemeConfigRounding>;
|
|
197
|
+
};
|
|
198
|
+
|
|
188
199
|
export type UnknownObject = Record<string, unknown>;
|
|
189
200
|
export type UnknownArray = unknown[];
|
|
190
201
|
export type UnknownType = string | number | boolean | UnknownObject | undefined | null;
|
|
@@ -35,5 +35,5 @@ const { getDataTest, wrapperAttrs } = useUI<Config>(defaultConfig, mutatedProps)
|
|
|
35
35
|
</script>
|
|
36
36
|
|
|
37
37
|
<template>
|
|
38
|
-
<div v-bind="wrapperAttrs" :data-test="getDataTest()">
|
|
38
|
+
<div v-bind="wrapperAttrs" :data-test="getDataTest()">UBoilerplate</div>
|
|
39
39
|
</template>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { computed, provide, useTemplateRef, ref, watch } from "vue";
|
|
2
|
+
import { computed, provide, useTemplateRef, ref, watch, onMounted } from "vue";
|
|
3
3
|
|
|
4
4
|
import useUI from "../composables/useUI";
|
|
5
5
|
import { getDefaults } from "../utils/ui";
|
|
@@ -15,7 +15,7 @@ defineOptions({ inheritAttrs: false });
|
|
|
15
15
|
|
|
16
16
|
const props = withDefaults(defineProps<Props>(), {
|
|
17
17
|
...getDefaults<Props, Config>(defaultConfig, COMPONENT_NAME),
|
|
18
|
-
modelValue:
|
|
18
|
+
modelValue: () => [],
|
|
19
19
|
options: () => [],
|
|
20
20
|
});
|
|
21
21
|
|
|
@@ -42,6 +42,16 @@ const selectedItem = computed({
|
|
|
42
42
|
},
|
|
43
43
|
});
|
|
44
44
|
|
|
45
|
+
onMounted(() => {
|
|
46
|
+
const initiallyOpened = props.options
|
|
47
|
+
.filter((option) => option.opened)
|
|
48
|
+
.map((option) => option.value);
|
|
49
|
+
|
|
50
|
+
if (initiallyOpened.length > 0) {
|
|
51
|
+
selectedItem.value = props.multiple ? initiallyOpened : initiallyOpened[0];
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
45
55
|
provide<SetAccordionSelectedItem>("setAccordionSelectedItem", (value, opened) => {
|
|
46
56
|
if (props.multiple) {
|
|
47
57
|
let current: string[] = [];
|
|
@@ -101,7 +111,6 @@ const { getDataTest, accordionItemAttrs, accordionAttrs } = useUI<Config>(defaul
|
|
|
101
111
|
:key="index"
|
|
102
112
|
:model-value="selectedItem"
|
|
103
113
|
:value="option.value"
|
|
104
|
-
:opened="option.opened"
|
|
105
114
|
:title="option.title"
|
|
106
115
|
:description="option.description"
|
|
107
116
|
:size="size"
|
|
@@ -28,7 +28,7 @@ export default {
|
|
|
28
28
|
title: "Containers / Accordion",
|
|
29
29
|
component: UAccordion,
|
|
30
30
|
args: {
|
|
31
|
-
modelValue:
|
|
31
|
+
modelValue: null,
|
|
32
32
|
options: [
|
|
33
33
|
{
|
|
34
34
|
value: "1",
|
|
@@ -40,6 +40,7 @@ export default {
|
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
42
|
value: "2",
|
|
43
|
+
opened: true,
|
|
43
44
|
title: "Pioneering Cutting-Edge Solutions",
|
|
44
45
|
description:
|
|
45
46
|
trimText(`Our team stays ahead of the curve, integrating the latest technologies
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ref } from "vue";
|
|
1
2
|
import { mount } from "@vue/test-utils";
|
|
2
3
|
import { describe, it, expect } from "vitest";
|
|
3
4
|
|
|
@@ -57,40 +58,59 @@ describe("UAccordion", () => {
|
|
|
57
58
|
// Events
|
|
58
59
|
describe("Events", () => {
|
|
59
60
|
it("emits update:modelValue when an item is toggled (single)", async () => {
|
|
61
|
+
const modelValue = ref<string | null>(null);
|
|
62
|
+
|
|
60
63
|
const component = mount(UAccordion, {
|
|
61
|
-
props: {
|
|
64
|
+
props: {
|
|
65
|
+
options,
|
|
66
|
+
modelValue: modelValue.value,
|
|
67
|
+
"onUpdate:modelValue": (value: string | null) => {
|
|
68
|
+
modelValue.value = value;
|
|
69
|
+
component.setProps({ modelValue: value });
|
|
70
|
+
},
|
|
71
|
+
},
|
|
62
72
|
});
|
|
63
73
|
|
|
64
74
|
const firstItem = component.findAllComponents(UAccordionItem)[0];
|
|
65
75
|
|
|
66
|
-
await firstItem.trigger("click");
|
|
76
|
+
await firstItem.find("[vl-child-key='title']").trigger("click");
|
|
67
77
|
|
|
68
78
|
const updates = component.emitted("update:modelValue");
|
|
69
79
|
|
|
70
80
|
expect(updates).toBeTruthy();
|
|
71
81
|
expect(updates?.[0]).toEqual(["a"]);
|
|
72
82
|
|
|
73
|
-
await firstItem.trigger("click");
|
|
83
|
+
await firstItem.find("[vl-child-key='title']").trigger("click");
|
|
74
84
|
const updates2 = component.emitted("update:modelValue");
|
|
75
85
|
|
|
76
86
|
expect(updates2?.[1]).toEqual([null]);
|
|
77
87
|
});
|
|
78
88
|
|
|
79
89
|
it("emits update:modelValue with arrays when multiple=true", async () => {
|
|
90
|
+
const modelValue = ref<string[]>([]);
|
|
91
|
+
|
|
80
92
|
const component = mount(UAccordion, {
|
|
81
|
-
props: {
|
|
93
|
+
props: {
|
|
94
|
+
options,
|
|
95
|
+
multiple: true,
|
|
96
|
+
modelValue: modelValue.value,
|
|
97
|
+
"onUpdate:modelValue": (value: string[]) => {
|
|
98
|
+
modelValue.value = value;
|
|
99
|
+
component.setProps({ modelValue: value });
|
|
100
|
+
},
|
|
101
|
+
},
|
|
82
102
|
});
|
|
83
103
|
|
|
84
104
|
const [firstItem, secondItem] = component.findAllComponents(UAccordionItem);
|
|
85
105
|
|
|
86
|
-
await firstItem.trigger("click");
|
|
87
|
-
await secondItem.trigger("click");
|
|
106
|
+
await firstItem.find("[vl-child-key='title']").trigger("click");
|
|
107
|
+
await secondItem.find("[vl-child-key='title']").trigger("click");
|
|
88
108
|
const updates = component.emitted("update:modelValue");
|
|
89
109
|
|
|
90
110
|
expect(updates?.[0]).toEqual([["a"]]);
|
|
91
111
|
expect(updates?.[1]).toEqual([["a", "b"]]);
|
|
92
112
|
|
|
93
|
-
await firstItem.trigger("click");
|
|
113
|
+
await firstItem.find("[vl-child-key='title']").trigger("click");
|
|
94
114
|
const updates2 = component.emitted("update:modelValue");
|
|
95
115
|
|
|
96
116
|
expect(updates2?.[2]).toEqual([["b"]]);
|
|
@@ -42,8 +42,7 @@ const emit = defineEmits([
|
|
|
42
42
|
]);
|
|
43
43
|
|
|
44
44
|
const wrapperRef = useTemplateRef<HTMLDivElement>("wrapper");
|
|
45
|
-
const
|
|
46
|
-
const contentRef = useTemplateRef<HTMLDivElement>("content");
|
|
45
|
+
const titleRef = useTemplateRef<HTMLDivElement>("title");
|
|
47
46
|
|
|
48
47
|
const accordionSize = ref(toValue(getAccordionSize) || props.size);
|
|
49
48
|
const accordionDisabled = ref(toValue(getAccordionDisabled) || props.disabled);
|
|
@@ -54,7 +53,7 @@ watchEffect(() => (accordionDisabled.value = toValue(getAccordionDisabled) || pr
|
|
|
54
53
|
const slots = useSlots();
|
|
55
54
|
const elementId = props.id || useId();
|
|
56
55
|
|
|
57
|
-
const internalOpened = ref(false);
|
|
56
|
+
const internalOpened = ref(props.opened || false);
|
|
58
57
|
|
|
59
58
|
const isOpened = computed(() => {
|
|
60
59
|
const selectedItem = toValue(getAccordionSelectedItem);
|
|
@@ -67,7 +66,7 @@ const isOpened = computed(() => {
|
|
|
67
66
|
return isEqual(selectedItem, props.value);
|
|
68
67
|
}
|
|
69
68
|
|
|
70
|
-
return
|
|
69
|
+
return internalOpened.value;
|
|
71
70
|
});
|
|
72
71
|
|
|
73
72
|
const toggleIconName = computed(() => {
|
|
@@ -79,10 +78,9 @@ const toggleIconName = computed(() => {
|
|
|
79
78
|
});
|
|
80
79
|
|
|
81
80
|
function onClickItem(event: MouseEvent) {
|
|
82
|
-
const
|
|
83
|
-
const clickedDescription = descriptionRef.value?.contains(event.target as Node);
|
|
81
|
+
const clickedOnTitle = titleRef.value?.contains(event.target as Node);
|
|
84
82
|
|
|
85
|
-
if (props.disabled
|
|
83
|
+
if (!clickedOnTitle || props.disabled) return;
|
|
86
84
|
|
|
87
85
|
emit("click", elementId, !isOpened.value);
|
|
88
86
|
|
|
@@ -123,7 +121,7 @@ const {
|
|
|
123
121
|
<template>
|
|
124
122
|
<div ref="wrapper" v-bind="wrapperAttrs" :data-test="getDataTest()" @click="onClickItem">
|
|
125
123
|
<div v-bind="bodyAttrs">
|
|
126
|
-
<div v-bind="titleAttrs">
|
|
124
|
+
<div v-bind="titleAttrs" ref="title">
|
|
127
125
|
{{ title }}
|
|
128
126
|
<!--
|
|
129
127
|
@slot Use it to add something instead of the toggle icon.
|
|
@@ -144,12 +142,11 @@ const {
|
|
|
144
142
|
<div
|
|
145
143
|
v-if="description"
|
|
146
144
|
:id="`description-${elementId}`"
|
|
147
|
-
ref="description"
|
|
148
145
|
v-bind="descriptionAttrs"
|
|
149
146
|
v-text="description"
|
|
150
147
|
/>
|
|
151
148
|
|
|
152
|
-
<div v-if="isOpened && hasSlotContent(slots['default'])"
|
|
149
|
+
<div v-if="isOpened && hasSlotContent(slots['default'])" v-bind="contentAttrs">
|
|
153
150
|
<!-- @slot Use it to add accordion content. -->
|
|
154
151
|
<slot />
|
|
155
152
|
</div>
|
|
@@ -27,6 +27,7 @@ export default {
|
|
|
27
27
|
title: "Containers / Accordion Item",
|
|
28
28
|
component: UAccordionItem,
|
|
29
29
|
args: {
|
|
30
|
+
opened: true,
|
|
30
31
|
title: "Committed to Quality and Performance",
|
|
31
32
|
description: trimText(
|
|
32
33
|
`We take pride in delivering high-quality solutions tailored to your needs.
|
|
@@ -171,7 +171,7 @@ describe("UAccordionItem", () => {
|
|
|
171
171
|
expect(toggleElement.attributes("data-opened")).toBe("false");
|
|
172
172
|
|
|
173
173
|
// Click to toggle
|
|
174
|
-
await component.trigger("click");
|
|
174
|
+
await component.find("[vl-key='title']").trigger("click");
|
|
175
175
|
|
|
176
176
|
expect(toggleElement.attributes("data-opened")).toBe("true");
|
|
177
177
|
});
|
|
@@ -190,12 +190,12 @@ describe("UAccordionItem", () => {
|
|
|
190
190
|
|
|
191
191
|
expect(component.find(`.${slotClass}`).exists()).toBe(false);
|
|
192
192
|
|
|
193
|
-
await component.trigger("click");
|
|
193
|
+
await component.find("[vl-key='title']").trigger("click");
|
|
194
194
|
|
|
195
195
|
expect(component.find(`.${slotClass}`).exists()).toBe(true);
|
|
196
196
|
expect(component.find(`.${slotClass}`).text()).toBe(slotContent);
|
|
197
197
|
|
|
198
|
-
await component.trigger("click");
|
|
198
|
+
await component.find("[vl-key='title']").trigger("click");
|
|
199
199
|
|
|
200
200
|
expect(component.find(`.${slotClass}`).exists()).toBe(false);
|
|
201
201
|
});
|
|
@@ -217,7 +217,7 @@ describe("UAccordionItem", () => {
|
|
|
217
217
|
it("does not render content wrapper when default slot is empty", async () => {
|
|
218
218
|
const component = mount(UAccordionItem, { props: { name: "test" } });
|
|
219
219
|
|
|
220
|
-
await component.trigger("click");
|
|
220
|
+
await component.find("[vl-key='title']").trigger("click");
|
|
221
221
|
|
|
222
222
|
expect(component.find("[vl-key='content']").exists()).toBe(false);
|
|
223
223
|
});
|
|
@@ -235,7 +235,7 @@ describe("UAccordionItem", () => {
|
|
|
235
235
|
},
|
|
236
236
|
});
|
|
237
237
|
|
|
238
|
-
await component.trigger("click");
|
|
238
|
+
await component.find("[vl-key='title']").trigger("click");
|
|
239
239
|
|
|
240
240
|
const emitted = component.emitted("click");
|
|
241
241
|
|
|
@@ -243,7 +243,7 @@ describe("UAccordionItem", () => {
|
|
|
243
243
|
expect(emitted?.[0]).toEqual([id, true]);
|
|
244
244
|
|
|
245
245
|
// Click again to toggle back
|
|
246
|
-
await component.trigger("click");
|
|
246
|
+
await component.find("[vl-key='title']").trigger("click");
|
|
247
247
|
|
|
248
248
|
const emittedAgain = component.emitted("click");
|
|
249
249
|
|
|
@@ -281,13 +281,13 @@ describe("UAccordionItem", () => {
|
|
|
281
281
|
expect(descriptionElement.classes()).not.toContain(openedClass);
|
|
282
282
|
|
|
283
283
|
// Click to open
|
|
284
|
-
await component.trigger("click");
|
|
284
|
+
await component.find("[vl-key='title']").trigger("click");
|
|
285
285
|
|
|
286
286
|
// Should be opened
|
|
287
287
|
expect(descriptionElement.classes()).toContain(openedClass);
|
|
288
288
|
|
|
289
289
|
// Click to close
|
|
290
|
-
await component.trigger("click");
|
|
290
|
+
await component.find("[vl-key='title']").trigger("click");
|
|
291
291
|
|
|
292
292
|
// Should be closed again
|
|
293
293
|
expect(descriptionElement.classes()).not.toContain(openedClass);
|
package/ui.image-icon/config.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export default /*tw*/ {
|
|
2
2
|
icon: {
|
|
3
|
-
base: "text-{color}
|
|
3
|
+
base: "text-{color} shrink-0 grow-0 focus:outline-0",
|
|
4
4
|
variants: {
|
|
5
5
|
variant: {
|
|
6
6
|
light: "brightness-125",
|
|
@@ -40,7 +40,7 @@ export default /*tw*/ {
|
|
|
40
40
|
interactive: false,
|
|
41
41
|
/* icon library */
|
|
42
42
|
library: "@material-symbols",
|
|
43
|
-
path: "", // set for `custom
|
|
43
|
+
path: "", // set for `custom` library only.
|
|
44
44
|
style: "outlined",
|
|
45
45
|
weight: 500,
|
|
46
46
|
},
|
package/ui.image-icon/types.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type { ComponentConfig } from "../types";
|
|
|
6
6
|
|
|
7
7
|
export type Config = typeof defaultConfig;
|
|
8
8
|
|
|
9
|
-
export type IconLibraries = "@material-symbols" | "bootstrap-icons" | "heroicons" | "custom
|
|
9
|
+
export type IconLibraries = "@material-symbols" | "bootstrap-icons" | "heroicons" | "custom";
|
|
10
10
|
|
|
11
11
|
export interface Props {
|
|
12
12
|
/**
|
|
@@ -25,12 +25,6 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
const emit = defineEmits([
|
|
28
|
-
/**
|
|
29
|
-
* Triggers when current page changes.
|
|
30
|
-
* @property {number} value
|
|
31
|
-
*/
|
|
32
|
-
"change",
|
|
33
|
-
|
|
34
28
|
/**
|
|
35
29
|
* Triggers when current page changes.
|
|
36
30
|
* @property {number} value
|
|
@@ -44,7 +38,6 @@ const currentPage = computed({
|
|
|
44
38
|
get: () => props.modelValue,
|
|
45
39
|
set: (value) => {
|
|
46
40
|
emit("update:modelValue", value);
|
|
47
|
-
emit("change", value);
|
|
48
41
|
},
|
|
49
42
|
});
|
|
50
43
|
|
|
@@ -346,30 +346,6 @@ describe("UPagination.vue", () => {
|
|
|
346
346
|
|
|
347
347
|
// Events tests
|
|
348
348
|
describe("Events", () => {
|
|
349
|
-
// Change event
|
|
350
|
-
it("emits change event when page is changed", async () => {
|
|
351
|
-
const component = mount(UPagination, {
|
|
352
|
-
props: {
|
|
353
|
-
modelValue: 1,
|
|
354
|
-
total: 100,
|
|
355
|
-
perPage: 10,
|
|
356
|
-
},
|
|
357
|
-
});
|
|
358
|
-
|
|
359
|
-
// Find the second page button and click it
|
|
360
|
-
const pageButtons = component.findAllComponents(UButton).filter((button) => {
|
|
361
|
-
const text = button.text();
|
|
362
|
-
|
|
363
|
-
return text && !isNaN(Number(text));
|
|
364
|
-
});
|
|
365
|
-
|
|
366
|
-
// Second button
|
|
367
|
-
await pageButtons[1].trigger("click");
|
|
368
|
-
|
|
369
|
-
expect(component.emitted("change")).toBeTruthy();
|
|
370
|
-
expect(component.emitted("change")?.[0]).toEqual([2]); // Second button value
|
|
371
|
-
});
|
|
372
|
-
|
|
373
349
|
// Update:modelValue event
|
|
374
350
|
it("emits update:modelValue event when page is changed", async () => {
|
|
375
351
|
const component = mount(UPagination, {
|
package/utils/helper.ts
CHANGED
|
@@ -184,3 +184,35 @@ export function isEmptyValue(value: object | null | undefined | string | unknown
|
|
|
184
184
|
(typeof value === "object" && !Object.keys(value).length)
|
|
185
185
|
);
|
|
186
186
|
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Converts the given value to a number if possible.
|
|
190
|
+
*
|
|
191
|
+
* @param {unknown} value - The value to be converted to a number. Can be of any data type.
|
|
192
|
+
* @return {number | undefined} The numeric representation of the value if conversion is successful; otherwise, undefined.
|
|
193
|
+
*/
|
|
194
|
+
export function toNumber(value: unknown): number | undefined {
|
|
195
|
+
if (typeof value === "number") {
|
|
196
|
+
return value;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
200
|
+
const number = Number(value);
|
|
201
|
+
|
|
202
|
+
if (!Number.isNaN(number)) {
|
|
203
|
+
return number;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Get a stored value from local storage.
|
|
212
|
+
* @return string | undefined
|
|
213
|
+
*/
|
|
214
|
+
export function getStored(key: string) {
|
|
215
|
+
if (isSSR) return;
|
|
216
|
+
|
|
217
|
+
return localStorage.getItem(key) ?? undefined;
|
|
218
|
+
}
|
package/utils/node/helper.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export function getVueDirs(): string[];
|
|
|
7
7
|
export function getVuelessConfigDirs(): string[];
|
|
8
8
|
export function getMergedComponentConfig(name: any): Promise<any>;
|
|
9
9
|
export function getDefaultComponentConfig(name: any, configDir: any): Promise<{}>;
|
|
10
|
-
export function cacheMergedConfigs(
|
|
10
|
+
export function cacheMergedConfigs(basePath: any): Promise<void>;
|
|
11
11
|
export function buildTSFile(entryPath: any, configOutFile: any): Promise<void>;
|
|
12
12
|
export function removeFolderIfEmpty(dirPath: any): Promise<void>;
|
|
13
13
|
export function detectTypeScript(): Promise<boolean>;
|
package/utils/node/helper.js
CHANGED
|
@@ -5,7 +5,7 @@ import { pathToFileURL } from "node:url";
|
|
|
5
5
|
import { existsSync, statSync } from "node:fs";
|
|
6
6
|
import { mkdir, readdir, rmdir, readFile, writeFile } from "node:fs/promises";
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { getMergedConfig, getVuelessConfig } from "./vuelessConfig.js";
|
|
9
9
|
|
|
10
10
|
import {
|
|
11
11
|
COMPONENTS,
|
|
@@ -117,11 +117,12 @@ export async function getDefaultComponentConfig(name, configDir) {
|
|
|
117
117
|
return config;
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
export async function cacheMergedConfigs(
|
|
120
|
+
export async function cacheMergedConfigs(basePath) {
|
|
121
|
+
const vuelessConfig = await getVuelessConfig(basePath);
|
|
121
122
|
const componentNames = Object.entries(COMPONENTS);
|
|
122
123
|
|
|
123
124
|
for await (const [componentName, componentDir] of componentNames) {
|
|
124
|
-
const defaultComponentConfigPath = path.join(
|
|
125
|
+
const defaultComponentConfigPath = path.join(basePath, componentDir, "config.ts");
|
|
125
126
|
|
|
126
127
|
const defaultConfig = await getDefaultComponentConfig(
|
|
127
128
|
componentName,
|
package/utils/node/loaderSvg.js
CHANGED
|
@@ -2,13 +2,15 @@ import fs from "node:fs";
|
|
|
2
2
|
import { compileTemplate } from "vue/compiler-sfc";
|
|
3
3
|
import { optimize as optimizeSvg } from "svgo";
|
|
4
4
|
|
|
5
|
+
import { getVuelessConfig } from "./vuelessConfig.js";
|
|
5
6
|
import { DEFAULT_SVGO_CONFIG } from "../../constants.js";
|
|
6
7
|
|
|
7
8
|
export async function loadSvg(id, options) {
|
|
8
|
-
|
|
9
|
+
let {
|
|
10
|
+
basePath = "",
|
|
9
11
|
defaultImport = "url",
|
|
12
|
+
svgoConfig = {},
|
|
10
13
|
svgo = true,
|
|
11
|
-
svgoConfig = DEFAULT_SVGO_CONFIG,
|
|
12
14
|
debug = false,
|
|
13
15
|
} = options;
|
|
14
16
|
const svgRegex = /\.svg(\?(raw|url|component|skipsvgo))?$/;
|
|
@@ -45,7 +47,11 @@ export async function loadSvg(id, options) {
|
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
if (svgo !== false && query !== "skipsvgo") {
|
|
50
|
+
const vuelessConfig = getVuelessConfig(basePath);
|
|
51
|
+
const isLucideLibrary = vuelessConfig.components?.UIcon?.defaults?.library === "lucide-static";
|
|
52
|
+
|
|
48
53
|
svg = optimizeSvg(svg, {
|
|
54
|
+
...(isLucideLibrary ? {} : DEFAULT_SVGO_CONFIG),
|
|
49
55
|
...svgoConfig,
|
|
50
56
|
svgPath,
|
|
51
57
|
}).data;
|
|
@@ -17,14 +17,6 @@ import {
|
|
|
17
17
|
|
|
18
18
|
export let vuelessConfig = {};
|
|
19
19
|
|
|
20
|
-
/**
|
|
21
|
-
* Load Vueless config from the project root.
|
|
22
|
-
* IIFE is used to prevent top level await issue.
|
|
23
|
-
*/
|
|
24
|
-
(async () => {
|
|
25
|
-
vuelessConfig = await getVuelessConfig();
|
|
26
|
-
})();
|
|
27
|
-
|
|
28
20
|
/**
|
|
29
21
|
* Retrieves the Vueless config from the project root.
|
|
30
22
|
*
|