vueless 0.0.479 → 0.0.481
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/README.md +3 -3
- package/adatper.locale/vue-i18n.ts +14 -0
- package/adatper.locale/{vueless.js → vueless.ts} +67 -19
- package/composables/useAutoPosition.ts +113 -0
- package/composables/useBreakpoint.ts +109 -0
- package/composables/useLocale.ts +22 -0
- package/composables/useMutationObserver.ts +53 -0
- package/composables/{useUI.js → useUI.ts} +109 -105
- package/constants.js +124 -2
- package/directives/clickOutside/storybook/Docs.mdx +1 -1
- package/directives/clickOutside/storybook/{stories.js → stories.ts} +7 -9
- package/directives/clickOutside/types.ts +22 -0
- package/directives/clickOutside/vClickOutside.ts +96 -0
- package/directives/index.js +7 -2
- package/directives/tooltip/storybook/Docs.mdx +1 -1
- package/directives/tooltip/storybook/{stories.js → stories.ts} +22 -10
- package/directives/tooltip/types.ts +14 -0
- package/directives/tooltip/vTooltip.ts +82 -0
- package/{index.js → index.ts} +12 -9
- package/package.json +38 -25
- package/plugin-vite.d.ts +10 -0
- package/plugin-vite.js +97 -0
- package/{preset.tailwind.js → preset-tailwind.js} +21 -7
- package/types.ts +322 -0
- package/ui.button/UButton.vue +1 -1
- package/ui.button/storybook/Docs.mdx +1 -1
- package/ui.button/storybook/stories.js +11 -6
- package/ui.button/useAttrs.js +1 -1
- package/ui.button-link/ULink.vue +2 -2
- package/ui.button-link/storybook/Docs.mdx +1 -1
- package/ui.button-link/storybook/stories.js +2 -2
- package/ui.button-link/useAttrs.js +1 -1
- package/ui.button-toggle/UToggle.vue +1 -1
- package/ui.button-toggle/storybook/Docs.mdx +1 -1
- package/ui.button-toggle/storybook/stories.js +2 -2
- package/ui.button-toggle/useAttrs.js +1 -1
- package/ui.button-toggle-item/UToggleItem.vue +1 -1
- package/ui.button-toggle-item/storybook/Docs.mdx +1 -1
- package/ui.button-toggle-item/storybook/stories.js +1 -1
- package/ui.button-toggle-item/useAttrs.js +1 -1
- package/ui.container-accordion/UAccordion.vue +1 -1
- package/ui.container-accordion/storybook/Docs.mdx +1 -1
- package/ui.container-accordion/storybook/stories.js +1 -1
- package/ui.container-accordion/useAttrs.js +1 -1
- package/ui.container-card/storybook/Docs.mdx +1 -1
- package/ui.container-card/storybook/stories.js +1 -1
- package/ui.container-card/useAttrs.js +1 -1
- package/ui.container-col/UCol.vue +1 -1
- package/ui.container-col/storybook/Docs.mdx +1 -1
- package/ui.container-col/storybook/stories.js +1 -1
- package/ui.container-col/useAttrs.js +1 -1
- package/ui.container-divider/UDivider.vue +1 -1
- package/ui.container-divider/storybook/Docs.mdx +1 -1
- package/ui.container-divider/storybook/stories.js +2 -2
- package/ui.container-divider/useAttrs.js +1 -1
- package/ui.container-group/UGroup.vue +1 -1
- package/ui.container-group/storybook/Docs.mdx +1 -1
- package/ui.container-group/storybook/stories.js +1 -1
- package/ui.container-group/useAttrs.js +1 -1
- package/ui.container-modal/UModal.vue +1 -1
- package/ui.container-modal/storybook/Docs.mdx +1 -1
- package/ui.container-modal/storybook/stories.js +2 -2
- package/ui.container-modal/useAttrs.js +1 -1
- package/ui.container-modal-confirm/UModalConfirm.vue +2 -2
- package/ui.container-modal-confirm/storybook/Docs.mdx +1 -1
- package/ui.container-modal-confirm/storybook/stories.js +2 -2
- package/ui.container-modal-confirm/useAttrs.js +1 -1
- package/ui.container-page/UPage.vue +2 -2
- package/ui.container-page/storybook/Docs.mdx +1 -1
- package/ui.container-page/storybook/stories.js +1 -1
- package/ui.container-page/useAttrs.js +2 -2
- package/ui.container-row/URow.vue +1 -1
- package/ui.container-row/storybook/Docs.mdx +1 -1
- package/ui.container-row/storybook/stories.js +2 -2
- package/ui.container-row/useAttrs.js +1 -1
- package/ui.data-list/UDataList.vue +6 -6
- package/ui.data-list/storybook/Docs.mdx +1 -1
- package/ui.data-list/storybook/stories.js +1 -1
- package/ui.data-list/useAttrs.js +1 -1
- package/ui.data-table/UTable.vue +3 -3
- package/ui.data-table/UTableRow.vue +7 -6
- package/ui.data-table/config.js +10 -3
- package/ui.data-table/storybook/Docs.mdx +1 -1
- package/ui.data-table/storybook/stories.js +5 -3
- package/ui.data-table/useAttrs.js +1 -1
- package/ui.data-table/utilTable.js +1 -1
- package/ui.dropdown-badge/UDropdownBadge.vue +1 -1
- package/ui.dropdown-badge/storybook/Docs.mdx +1 -1
- package/ui.dropdown-badge/storybook/stories.js +2 -2
- package/ui.dropdown-badge/useAttrs.js +1 -1
- package/ui.dropdown-button/UDropdownButton.vue +1 -1
- package/ui.dropdown-button/storybook/Docs.mdx +1 -1
- package/ui.dropdown-button/storybook/stories.js +3 -3
- package/ui.dropdown-button/useAttrs.js +1 -1
- package/ui.dropdown-link/UDropdownLink.vue +1 -1
- package/ui.dropdown-link/config.js +1 -1
- package/ui.dropdown-link/storybook/Docs.mdx +1 -1
- package/ui.dropdown-link/storybook/stories.js +2 -2
- package/ui.dropdown-link/useAttrs.js +4 -6
- package/ui.dropdown-list/UDropdownList.vue +3 -3
- package/ui.dropdown-list/storybook/Docs.mdx +1 -1
- package/ui.dropdown-list/storybook/stories.js +2 -2
- package/ui.dropdown-list/useAttrs.js +1 -1
- package/ui.form-calendar/UCalendar.vue +2 -2
- package/ui.form-calendar/storybook/Docs.mdx +1 -1
- package/ui.form-calendar/storybook/stories.js +1 -1
- package/ui.form-calendar/useAttrs.js +1 -1
- package/ui.form-checkbox/UCheckbox.vue +1 -1
- package/ui.form-checkbox/storybook/Docs.mdx +1 -1
- package/ui.form-checkbox/storybook/stories.js +2 -2
- package/ui.form-checkbox/useAttrs.js +1 -1
- package/ui.form-checkbox-group/UCheckboxGroup.vue +1 -1
- package/ui.form-checkbox-group/storybook/Docs.mdx +1 -1
- package/ui.form-checkbox-group/storybook/stories.js +2 -2
- package/ui.form-checkbox-group/useAttrs.js +1 -1
- package/ui.form-checkbox-multi-state/UCheckboxMultiState.vue +1 -1
- package/ui.form-checkbox-multi-state/storybook/Docs.mdx +1 -1
- package/ui.form-checkbox-multi-state/storybook/stories.js +2 -2
- package/ui.form-checkbox-multi-state/useAttrs.js +1 -1
- package/ui.form-color-picker/UColorPicker.vue +1 -1
- package/ui.form-color-picker/storybook/Docs.mdx +1 -1
- package/ui.form-color-picker/storybook/stories.js +2 -2
- package/ui.form-color-picker/useAttrs.js +1 -1
- package/ui.form-date-picker/UDatePicker.vue +4 -7
- package/ui.form-date-picker/storybook/Docs.mdx +1 -1
- package/ui.form-date-picker/storybook/stories.js +3 -3
- package/ui.form-date-picker/useAttrs.js +2 -2
- package/ui.form-date-picker-range/UDatePickerRange.vue +2 -2
- package/ui.form-date-picker-range/storybook/Docs.mdx +1 -1
- package/ui.form-date-picker-range/storybook/stories.js +2 -2
- package/ui.form-date-picker-range/useAttrs.js +2 -2
- package/ui.form-date-picker-range/useLocale.js +1 -1
- package/ui.form-input/UInput.vue +3 -3
- package/ui.form-input/storybook/Docs.mdx +1 -1
- package/ui.form-input/storybook/stories.js +2 -2
- package/ui.form-input/useAttrs.js +1 -1
- package/ui.form-input-file/UInputFile.vue +2 -2
- package/ui.form-input-file/storybook/Docs.mdx +1 -1
- package/ui.form-input-file/storybook/stories.js +2 -2
- package/ui.form-input-file/useAttrs.js +1 -1
- package/ui.form-input-money/UInputMoney.vue +1 -1
- package/ui.form-input-money/storybook/Docs.mdx +1 -1
- package/ui.form-input-money/storybook/stories.js +2 -2
- package/ui.form-input-money/useAttrs.js +1 -1
- package/ui.form-input-money/useFormatCurrency.js +1 -1
- package/ui.form-input-number/UInputNumber.vue +5 -4
- package/ui.form-input-number/storybook/Docs.mdx +1 -1
- package/ui.form-input-number/storybook/stories.js +2 -2
- package/ui.form-input-number/useAttrs.js +1 -1
- package/ui.form-input-rating/UInputRating.vue +1 -1
- package/ui.form-input-rating/storybook/Docs.mdx +1 -1
- package/ui.form-input-rating/storybook/stories.js +2 -2
- package/ui.form-input-rating/useAttrs.js +1 -1
- package/ui.form-input-search/UInputSearch.vue +2 -2
- package/ui.form-input-search/storybook/Docs.mdx +1 -1
- package/ui.form-input-search/storybook/stories.js +2 -2
- package/ui.form-input-search/useAttrs.js +1 -1
- package/ui.form-label/ULabel.vue +1 -1
- package/ui.form-label/config.js +2 -2
- package/ui.form-label/storybook/Docs.mdx +1 -1
- package/ui.form-label/storybook/stories.js +2 -2
- package/ui.form-label/useAttrs.js +1 -1
- package/ui.form-radio/URadio.vue +1 -1
- package/ui.form-radio/storybook/Docs.mdx +1 -1
- package/ui.form-radio/storybook/stories.js +1 -1
- package/ui.form-radio/useAttrs.js +1 -1
- package/ui.form-radio-group/URadioGroup.vue +1 -1
- package/ui.form-radio-group/storybook/Docs.mdx +1 -1
- package/ui.form-radio-group/storybook/stories.js +2 -2
- package/ui.form-radio-group/useAttrs.js +1 -1
- package/ui.form-select/USelect.vue +4 -4
- package/ui.form-select/storybook/Docs.mdx +1 -1
- package/ui.form-select/storybook/stories.js +2 -2
- package/ui.form-select/useAttrs.js +1 -1
- package/ui.form-switch/USwitch.vue +2 -2
- package/ui.form-switch/storybook/Docs.mdx +1 -1
- package/ui.form-switch/storybook/stories.js +2 -2
- package/ui.form-switch/useAttrs.js +1 -1
- package/ui.form-switch/utilVariant.js +1 -1
- package/ui.form-textarea/UTextarea.vue +1 -1
- package/ui.form-textarea/storybook/Docs.mdx +1 -1
- package/ui.form-textarea/storybook/stories.js +2 -2
- package/ui.form-textarea/useAttrs.js +1 -1
- package/ui.image-avatar/UAvatar.vue +1 -1
- package/ui.image-avatar/storybook/Docs.mdx +1 -1
- package/ui.image-avatar/storybook/stories.js +2 -2
- package/ui.image-avatar/useAttrs.js +1 -1
- package/ui.image-icon/UIcon.vue +14 -8
- package/ui.image-icon/storybook/Docs.mdx +2 -2
- package/ui.image-icon/storybook/stories.js +2 -2
- package/ui.image-icon/useAttrs.js +2 -2
- package/ui.loader/ULoader.vue +1 -1
- package/ui.loader/storybook/Docs.mdx +1 -1
- package/ui.loader/storybook/stories.js +2 -2
- package/ui.loader/useAttrs.js +1 -1
- package/ui.loader-overlay/ULoaderOverlay.vue +1 -1
- package/ui.loader-overlay/storybook/Docs.mdx +1 -1
- package/ui.loader-overlay/storybook/stories.js +1 -1
- package/ui.loader-overlay/useAttrs.js +1 -1
- package/ui.loader-progress/ULoaderProgress.vue +33 -48
- package/ui.loader-progress/constants.js +1 -0
- package/ui.loader-progress/storybook/Docs.mdx +1 -1
- package/ui.loader-progress/storybook/stories.js +3 -4
- package/ui.loader-progress/useAttrs.js +1 -1
- package/ui.loader-progress/useLoaderProgress.js +13 -8
- package/ui.loader-progress/utilLoaderProgress.js +1 -1
- package/ui.navigation-pagination/UPagination.vue +1 -1
- package/ui.navigation-pagination/storybook/Docs.mdx +1 -1
- package/ui.navigation-pagination/storybook/stories.js +1 -1
- package/ui.navigation-pagination/useAttrs.js +1 -1
- package/ui.navigation-progress/UProgress.vue +1 -1
- package/ui.navigation-progress/storybook/Docs.mdx +1 -1
- package/ui.navigation-progress/storybook/stories.js +2 -2
- package/ui.navigation-progress/useAttrs.js +1 -1
- package/ui.navigation-tab/UTab.vue +1 -1
- package/ui.navigation-tab/storybook/Docs.mdx +1 -1
- package/ui.navigation-tab/storybook/stories.js +1 -1
- package/ui.navigation-tab/useAttrs.js +1 -1
- package/ui.navigation-tabs/UTabs.vue +1 -1
- package/ui.navigation-tabs/storybook/Docs.mdx +1 -1
- package/ui.navigation-tabs/storybook/stories.js +2 -2
- package/ui.navigation-tabs/useAttrs.js +1 -1
- package/ui.other-dot/UDot.vue +1 -1
- package/ui.other-dot/storybook/Docs.mdx +1 -1
- package/ui.other-dot/storybook/stories.js +2 -2
- package/ui.other-dot/useAttrs.js +1 -1
- package/ui.text-alert/UAlert.vue +1 -1
- package/ui.text-alert/storybook/Docs.mdx +1 -1
- package/ui.text-alert/storybook/stories.js +2 -2
- package/ui.text-alert/useAttrs.js +1 -1
- package/ui.text-badge/UBadge.vue +89 -179
- package/ui.text-badge/storybook/Docs.mdx +3 -3
- package/ui.text-badge/storybook/{stories.js → stories.ts} +33 -37
- package/ui.text-badge/types.ts +84 -0
- package/ui.text-badge/useAttrs.ts +28 -0
- package/ui.text-block/UText.vue +18 -62
- package/ui.text-block/storybook/Docs.mdx +3 -3
- package/ui.text-block/storybook/{stories.js → stories.ts} +13 -8
- package/ui.text-block/types.ts +33 -0
- package/ui.text-block/useAttrs.ts +20 -0
- package/ui.text-empty/UEmpty.vue +1 -1
- package/ui.text-empty/storybook/Docs.mdx +1 -1
- package/ui.text-empty/storybook/stories.js +2 -2
- package/ui.text-empty/useAttrs.js +1 -1
- package/ui.text-file/UFile.vue +13 -16
- package/ui.text-file/config.js +12 -2
- package/ui.text-file/storybook/Docs.mdx +1 -1
- package/ui.text-file/storybook/stories.js +1 -1
- package/ui.text-file/useAttrs.js +1 -1
- package/ui.text-files/UFiles.vue +1 -1
- package/ui.text-files/config.js +1 -1
- package/ui.text-files/storybook/Docs.mdx +1 -1
- package/ui.text-files/storybook/stories.js +1 -1
- package/ui.text-files/useAttrs.js +1 -1
- package/ui.text-header/UHeader.vue +1 -1
- package/ui.text-header/storybook/Docs.mdx +1 -1
- package/ui.text-header/storybook/stories.js +2 -2
- package/ui.text-header/useAttrs.js +1 -1
- package/ui.text-money/UMoney.vue +1 -1
- package/ui.text-money/storybook/Docs.mdx +1 -1
- package/ui.text-money/storybook/stories.js +2 -2
- package/ui.text-money/useAttrs.js +1 -1
- package/ui.text-money/utilMoney.js +2 -2
- package/ui.text-notify/UNotify.vue +2 -2
- package/ui.text-notify/storybook/Docs.mdx +1 -1
- package/ui.text-notify/storybook/stories.js +1 -1
- package/ui.text-notify/useAttrs.js +1 -1
- package/ui.text-notify/utilNotify.js +1 -1
- package/utils/{utilHelper.js → helper.ts} +14 -27
- package/utils/node/helper.js +78 -0
- package/utils/node/loaderIcon.js +232 -0
- package/utils/node/loaderSvg.js +71 -0
- package/utils/node/mergeConfigs.js +199 -0
- package/utils/node/tailwindSafelist.js +366 -0
- package/utils/node/vuelessConfig.js +42 -0
- package/utils/node/vuelessResolver.js +28 -0
- package/utils/{utilPlatform.js → platform.ts} +10 -3
- package/utils/{utilStorybook.js → storybook.ts} +102 -36
- package/utils/tailwindConfig.ts +33 -0
- package/utils/{utilTheme.js → theme.ts} +65 -30
- package/utils/ui.ts +129 -0
- package/web-types.json +1362 -157
- package/adatper.locale/vue-i18n.js +0 -11
- package/composables/useAutoPosition.js +0 -94
- package/composables/useBreakpoint.js +0 -104
- package/composables/useLocale.js +0 -25
- package/composables/useMutationObserver.js +0 -48
- package/directives/clickOutside/vClickOutside.js +0 -64
- package/directives/tooltip/vTooltip.js +0 -56
- package/ui.text-badge/useAttrs.js +0 -23
- package/ui.text-block/useAttrs.js +0 -15
- package/utils/utilUI.js +0 -360
- /package/adatper.locale/locales/{en.js → en.ts} +0 -0
- /package/ui.image-icon/{config.js → config.ts} +0 -0
- /package/ui.text-badge/{config.js → config.ts} +0 -0
- /package/ui.text-badge/{constants.js → constants.ts} +0 -0
- /package/ui.text-block/{config.js → config.ts} +0 -0
- /package/ui.text-block/{constants.js → constants.ts} +0 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
This scrypt find icon names from the UIcon props and objects across the project
|
|
3
|
+
and copy SVG icons from the default icons library (@material-symbols or other from config)
|
|
4
|
+
to the ".../cache" folder.
|
|
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.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/* eslint-disable no-console */
|
|
11
|
+
import fs from "node:fs";
|
|
12
|
+
import path from "node:path";
|
|
13
|
+
import { createRequire } from "module";
|
|
14
|
+
import { rm, cp } from "node:fs/promises";
|
|
15
|
+
|
|
16
|
+
import { vuelessConfig } from "./vuelessConfig.js";
|
|
17
|
+
import { getDirFiles, getDefaultConfigJson, merge } from "./helper.js";
|
|
18
|
+
import { CACHE_PATH, VUELESS_CONFIG_FILE_NAME } from "../../constants.js";
|
|
19
|
+
|
|
20
|
+
const ICONS_DIR = "assets/icons";
|
|
21
|
+
const NUXT_ASSETS_DIR = path.join(process.cwd(), "assets/.vueless/icons");
|
|
22
|
+
const DEFAULT_ICONS_DIR = path.join(process.cwd(), `src/${ICONS_DIR}`);
|
|
23
|
+
const CACHED_ICONS_DIR = path.join(process.cwd(), `${CACHE_PATH}/${ICONS_DIR}`);
|
|
24
|
+
const ICON_CONFIG_PATH = "ui.image-icon/config.ts";
|
|
25
|
+
const ICON_COMPONENT_NAME = "UIcon";
|
|
26
|
+
const STORYBOOK_STORY_EXTENSIONS = ["/stories.js", "/stories.ts"];
|
|
27
|
+
|
|
28
|
+
let isDebug = false;
|
|
29
|
+
let isVuelessEnv = false;
|
|
30
|
+
let isDefaultMode = false;
|
|
31
|
+
let isStorybookMode = false;
|
|
32
|
+
let isVuelessIconsMode = false;
|
|
33
|
+
let cachedIconsDir = CACHED_ICONS_DIR;
|
|
34
|
+
|
|
35
|
+
// perform icons copy magick... ✨
|
|
36
|
+
export async function copyIcons({ mode = "", env, debug, targetFiles = [], isNuxt } = {}) {
|
|
37
|
+
isDebug = debug || false;
|
|
38
|
+
isVuelessEnv = env === "vueless";
|
|
39
|
+
isDefaultMode = mode === "";
|
|
40
|
+
isStorybookMode = mode === "storybook";
|
|
41
|
+
isVuelessIconsMode = mode === "vuelessIcons";
|
|
42
|
+
|
|
43
|
+
if (isVuelessIconsMode && isVuelessEnv) cachedIconsDir = DEFAULT_ICONS_DIR;
|
|
44
|
+
if (isStorybookMode && isVuelessEnv) cachedIconsDir = CACHED_ICONS_DIR;
|
|
45
|
+
|
|
46
|
+
if (isStorybookMode) {
|
|
47
|
+
const storybookStoriesJs = await getDirFiles("src", STORYBOOK_STORY_EXTENSIONS[0]);
|
|
48
|
+
const storybookStoriesTs = await getDirFiles("src", STORYBOOK_STORY_EXTENSIONS[1]);
|
|
49
|
+
|
|
50
|
+
findAndCopyIcons([...storybookStoriesJs.flat(), ...storybookStoriesTs.flat()]);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (isVuelessIconsMode || isDefaultMode || isStorybookMode) {
|
|
54
|
+
const vueFiles = targetFiles.map((componentPath) => getDirFiles(componentPath, ".vue"));
|
|
55
|
+
|
|
56
|
+
const jsFiles = targetFiles.map((jsFilePath) =>
|
|
57
|
+
getDirFiles(jsFilePath, ".js", { exclude: [STORYBOOK_STORY_EXTENSIONS[0]] }),
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
const tsFiles = targetFiles.map((tsFilePath) =>
|
|
61
|
+
getDirFiles(tsFilePath, ".ts", { exclude: [STORYBOOK_STORY_EXTENSIONS[1], ".d.ts"] }),
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
const iconFiles = await Promise.all([...vueFiles, ...jsFiles, ...tsFiles]);
|
|
65
|
+
|
|
66
|
+
findAndCopyIcons([
|
|
67
|
+
...iconFiles.flat(),
|
|
68
|
+
`${VUELESS_CONFIG_FILE_NAME}.js`,
|
|
69
|
+
`${VUELESS_CONFIG_FILE_NAME}.ts`,
|
|
70
|
+
]);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (isNuxt) {
|
|
74
|
+
await cp(CACHED_ICONS_DIR, NUXT_ASSETS_DIR, {
|
|
75
|
+
recursive: true,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export async function removeIcons({ debug, isNuxt }) {
|
|
81
|
+
if (!fs.existsSync(cachedIconsDir)) return;
|
|
82
|
+
|
|
83
|
+
await rm(cachedIconsDir, { recursive: true, force: true });
|
|
84
|
+
|
|
85
|
+
if (isNuxt) {
|
|
86
|
+
await rm(NUXT_ASSETS_DIR, { recursive: true, force: true });
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (debug) {
|
|
90
|
+
console.log("Dynamically copied icons was successfully removed.");
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function findAndCopyIcons(files) {
|
|
95
|
+
const defaults = getMergedConfig();
|
|
96
|
+
const safelistIcons = getSafelistIcons();
|
|
97
|
+
|
|
98
|
+
safelistIcons.forEach((iconName) => {
|
|
99
|
+
copyFile(iconName, false);
|
|
100
|
+
copyFile(iconName, true);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
files.forEach((file) => {
|
|
104
|
+
const fileContents = fs.existsSync(file) ? fs.readFileSync(file).toString() : "";
|
|
105
|
+
|
|
106
|
+
/* Objects across the project */
|
|
107
|
+
const iconNameRegex = /\w*(icon)\w*:\s*["']([^"'\s]+)["']/gi;
|
|
108
|
+
const objectMatchNameArray = fileContents.match(iconNameRegex);
|
|
109
|
+
|
|
110
|
+
if (objectMatchNameArray) {
|
|
111
|
+
for (const match of objectMatchNameArray) {
|
|
112
|
+
const iconNameMatch = iconNameRegex.exec(match);
|
|
113
|
+
const iconName = iconNameMatch && iconNameMatch[2];
|
|
114
|
+
|
|
115
|
+
try {
|
|
116
|
+
if (iconName) {
|
|
117
|
+
copyFile(iconName);
|
|
118
|
+
}
|
|
119
|
+
} catch (error) {
|
|
120
|
+
isDebug && console.log(error);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
iconNameRegex.lastIndex = 0;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/* Vueless components props */
|
|
128
|
+
const uComponentIconNamePattern = `\\b\\w*(name|icon)\\w*\\s*=\\s*(['"])(.*?)\\2`;
|
|
129
|
+
const uComponentIconNameArray = fileContents.match(new RegExp(uComponentIconNamePattern, "g"));
|
|
130
|
+
|
|
131
|
+
if (!uComponentIconNameArray) return;
|
|
132
|
+
|
|
133
|
+
for (const match of uComponentIconNameArray) {
|
|
134
|
+
const groupMatch = match.match(new RegExp(uComponentIconNamePattern));
|
|
135
|
+
const iconName = groupMatch ? groupMatch[3] : null;
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
if (!iconName) return;
|
|
139
|
+
|
|
140
|
+
if (iconName?.includes("?")) {
|
|
141
|
+
const [trueName, falseName] = getTernaryValues(iconName);
|
|
142
|
+
|
|
143
|
+
copyFile(trueName);
|
|
144
|
+
copyFile(falseName);
|
|
145
|
+
} else {
|
|
146
|
+
copyFile(iconName);
|
|
147
|
+
}
|
|
148
|
+
} catch (error) {
|
|
149
|
+
isDebug && console.log(error);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
function getTernaryValues(expression) {
|
|
155
|
+
const [, values] = expression
|
|
156
|
+
.replace(/\s/g, "") // newlines and spaces
|
|
157
|
+
.replace(/\?\./g, "") // conditional chaining `?.`
|
|
158
|
+
.replace(/['"]/g, "") // single and double quotes
|
|
159
|
+
.split("?");
|
|
160
|
+
|
|
161
|
+
const [trueValue, falseValue] = values.split(":");
|
|
162
|
+
|
|
163
|
+
return [trueValue, falseValue];
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function copyFile(name) {
|
|
167
|
+
name = name.toLowerCase();
|
|
168
|
+
|
|
169
|
+
const library = defaults.library;
|
|
170
|
+
const weight = defaults.weight;
|
|
171
|
+
const style = defaults.style;
|
|
172
|
+
|
|
173
|
+
const require = createRequire(import.meta.url);
|
|
174
|
+
|
|
175
|
+
/* eslint-disable vue/max-len, prettier/prettier */
|
|
176
|
+
const libraries = {
|
|
177
|
+
vueless: {
|
|
178
|
+
// @material-symbols icons which used across the components.
|
|
179
|
+
source: `${process.cwd()}/node_modules/${library}/svg-${weight}/${style}/${name}.svg`,
|
|
180
|
+
destination: `${cachedIconsDir}/${name}.svg`
|
|
181
|
+
},
|
|
182
|
+
"@material-symbols": {
|
|
183
|
+
source: `${process.cwd()}/node_modules/${library}/svg-${weight}/${style}/${name}.svg`,
|
|
184
|
+
destination: `${cachedIconsDir}/${library}/svg-${weight}/${style}/${name}.svg`
|
|
185
|
+
},
|
|
186
|
+
"bootstrap-icons": {
|
|
187
|
+
source: `${process.cwd()}/node_modules/${library}/icons/${name}.svg`,
|
|
188
|
+
destination: `${cachedIconsDir}/${library}/icons/${name}.svg`
|
|
189
|
+
},
|
|
190
|
+
heroicons: {
|
|
191
|
+
source: `${process.cwd()}/node_modules/${library}/24/${name.endsWith("-fill") ? "solid" : "outline"}/${name}.svg`,
|
|
192
|
+
destination: `${cachedIconsDir}/24/${style}/${name.endsWith("-fill") ? "solid" : "outline"}/${name}.svg`
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
/* eslint-enable vue/max-len, prettier/prettier */
|
|
196
|
+
|
|
197
|
+
const { source, destination } =
|
|
198
|
+
libraries[isVuelessIconsMode && isVuelessEnv ? "vueless" : library];
|
|
199
|
+
|
|
200
|
+
if (fs.existsSync(destination) || !fs.existsSync(source)) return;
|
|
201
|
+
|
|
202
|
+
const destDir = path.dirname(destination);
|
|
203
|
+
|
|
204
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
205
|
+
fs.copyFile(require.resolve(source), destination, (error) => {
|
|
206
|
+
if (isDebug) {
|
|
207
|
+
error
|
|
208
|
+
? console.error(`Error copying icon "${name}":`, error)
|
|
209
|
+
: console.log(`Icon "${name}" copied successfully!`);
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function getSafelistIcons() {
|
|
216
|
+
return vuelessConfig.component
|
|
217
|
+
? vuelessConfig.component[ICON_COMPONENT_NAME]?.safelistIcons || []
|
|
218
|
+
: [];
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function getMergedConfig() {
|
|
222
|
+
const defaultConfigPath = (isVuelessEnv ? "src/" : "node_modules/vueless/") + ICON_CONFIG_PATH;
|
|
223
|
+
|
|
224
|
+
if (fs.existsSync(defaultConfigPath)) {
|
|
225
|
+
const defaultConfigFile = fs.readFileSync(defaultConfigPath).toString();
|
|
226
|
+
|
|
227
|
+
const defaultConfig = getDefaultConfigJson(defaultConfigFile);
|
|
228
|
+
const globalConfig = vuelessConfig.component && vuelessConfig.component[ICON_COMPONENT_NAME];
|
|
229
|
+
|
|
230
|
+
return merge(globalConfig?.defaults || {}, defaultConfig.defaults);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import { compileTemplate } from "vue/compiler-sfc";
|
|
3
|
+
import { optimize as optimizeSvg } from "svgo";
|
|
4
|
+
|
|
5
|
+
import { DEFAULT_SVGO_CONFIG } from "../../constants.js";
|
|
6
|
+
|
|
7
|
+
export async function loadSvg(id, options) {
|
|
8
|
+
const {
|
|
9
|
+
defaultImport = "url",
|
|
10
|
+
svgo = true,
|
|
11
|
+
svgoConfig = DEFAULT_SVGO_CONFIG,
|
|
12
|
+
debug = false,
|
|
13
|
+
} = options;
|
|
14
|
+
const svgRegex = /\.svg(\?(raw|url|component|skipsvgo))?$/;
|
|
15
|
+
|
|
16
|
+
if (!id.match(svgRegex)) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
let svg;
|
|
21
|
+
let [svgPath, query] = id.split("?", 2);
|
|
22
|
+
const importType = query || defaultImport;
|
|
23
|
+
|
|
24
|
+
// clear svg path from prefix if exist
|
|
25
|
+
svgPath = svgPath.replace("/__skip_vite/", "");
|
|
26
|
+
|
|
27
|
+
// use default svg loader
|
|
28
|
+
if (importType === "url" && !svgPath.includes(".generated")) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (debug) {
|
|
33
|
+
// eslint-disable-next-line no-console
|
|
34
|
+
console.log("iconPath:", svgPath);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
svg = await fs.promises.readFile(svgPath, "utf-8");
|
|
39
|
+
} catch {
|
|
40
|
+
// define an empty svg to prevent a UI crash.
|
|
41
|
+
svg = `<svg xmlns="http://www.w3.org/2000/svg"></svg>`;
|
|
42
|
+
// eslint-disable-next-line no-console
|
|
43
|
+
console.warn("\n", `${id} couldn't be loaded by vueless vite plugin.`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (importType === "raw") {
|
|
47
|
+
return `export default ${JSON.stringify(svg)}`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (svgo !== false && query !== "skipsvgo") {
|
|
51
|
+
svg = optimizeSvg(svg, {
|
|
52
|
+
...svgoConfig,
|
|
53
|
+
svgPath,
|
|
54
|
+
}).data;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// prevent compileTemplate from removing the style tag
|
|
58
|
+
svg = svg.replace(/<style/g, '<component is="style"').replace(/<\/style/g, "</component");
|
|
59
|
+
|
|
60
|
+
const { code } = compileTemplate({
|
|
61
|
+
id: JSON.stringify(id),
|
|
62
|
+
source: svg,
|
|
63
|
+
filename: svgPath,
|
|
64
|
+
transformAssetUrls: false,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
return `
|
|
68
|
+
${code}
|
|
69
|
+
export default { render: render }
|
|
70
|
+
`;
|
|
71
|
+
}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { cloneDeep } from "lodash-es";
|
|
2
|
+
|
|
3
|
+
import { SYSTEM_CONFIG_KEY } from "../../constants.js";
|
|
4
|
+
|
|
5
|
+
export function createMergeConfigsFunction(cx) {
|
|
6
|
+
/**
|
|
7
|
+
* Recursively merge config objects with removing tailwind classes duplicates.
|
|
8
|
+
* config - final merged config.
|
|
9
|
+
* isReplace - enables class replacement instead of merge.
|
|
10
|
+
* isVariants - if true, prevents adding a "base" key into nested objects.
|
|
11
|
+
*/
|
|
12
|
+
function mergeConfigs({
|
|
13
|
+
defaultConfig,
|
|
14
|
+
globalConfig,
|
|
15
|
+
propsConfig,
|
|
16
|
+
config = {},
|
|
17
|
+
isReplace = false,
|
|
18
|
+
isVariants = false,
|
|
19
|
+
}) {
|
|
20
|
+
globalConfig = cloneDeep(globalConfig || {});
|
|
21
|
+
propsConfig = cloneDeep(propsConfig || {});
|
|
22
|
+
|
|
23
|
+
const isGlobalConfig = Object.keys(globalConfig).length;
|
|
24
|
+
const isPropsConfig = Object.keys(propsConfig).length;
|
|
25
|
+
|
|
26
|
+
// Add unique keys from defaultConfig to composedConfig
|
|
27
|
+
const composedConfig = cloneDeep(defaultConfig);
|
|
28
|
+
|
|
29
|
+
// Add unique keys from globalConfig to composedConfig
|
|
30
|
+
for (const key in globalConfig) {
|
|
31
|
+
if (!Object.keys(composedConfig).includes(key)) {
|
|
32
|
+
composedConfig[key] = globalConfig[key];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Add unique keys from propsConfig to composedConfig
|
|
37
|
+
for (const key in propsConfig) {
|
|
38
|
+
if (!Object.keys(composedConfig).includes(key)) {
|
|
39
|
+
composedConfig[key] = propsConfig[key];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const {
|
|
44
|
+
i18n,
|
|
45
|
+
defaults,
|
|
46
|
+
strategy,
|
|
47
|
+
safelist,
|
|
48
|
+
component,
|
|
49
|
+
safelistColors,
|
|
50
|
+
defaultVariants,
|
|
51
|
+
compoundVariants,
|
|
52
|
+
} = SYSTEM_CONFIG_KEY;
|
|
53
|
+
|
|
54
|
+
for (const key in composedConfig) {
|
|
55
|
+
if (isGlobalConfig || isPropsConfig) {
|
|
56
|
+
if (key === safelist || key === safelistColors) {
|
|
57
|
+
if (propsConfig[key]) {
|
|
58
|
+
// eslint-disable-next-line no-console
|
|
59
|
+
console.warn(`Passing '${key}' key in 'config' prop is not allowed.`);
|
|
60
|
+
}
|
|
61
|
+
} else if (key === component) {
|
|
62
|
+
config[key] = propsConfig[key] || defaultConfig[key];
|
|
63
|
+
|
|
64
|
+
if (globalConfig[key]) {
|
|
65
|
+
// eslint-disable-next-line no-console
|
|
66
|
+
console.warn(
|
|
67
|
+
`Passing '${key}' key in 'config' prop or by global config is not allowed.`,
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
} else if (key === strategy) {
|
|
71
|
+
config[key] = propsConfig[key] || globalConfig[key] || defaultConfig[key];
|
|
72
|
+
} else if (key === defaults || key === defaultVariants) {
|
|
73
|
+
config[key] = {
|
|
74
|
+
...defaultConfig[key],
|
|
75
|
+
...globalConfig[key],
|
|
76
|
+
...propsConfig[key],
|
|
77
|
+
};
|
|
78
|
+
} else if (key === compoundVariants) {
|
|
79
|
+
config[key] = mergeCompoundVariants({
|
|
80
|
+
defaultConfig,
|
|
81
|
+
globalConfig,
|
|
82
|
+
propsConfig,
|
|
83
|
+
isReplace,
|
|
84
|
+
});
|
|
85
|
+
} else {
|
|
86
|
+
const isObjectComposedConfig = typeof composedConfig[key] === "object";
|
|
87
|
+
const isObjectGlobalConfig = typeof globalConfig[key] === "object";
|
|
88
|
+
const isObjectPropsConfig = typeof propsConfig[key] === "object";
|
|
89
|
+
|
|
90
|
+
const isObject = isObjectComposedConfig || isObjectGlobalConfig || isObjectPropsConfig;
|
|
91
|
+
const isEmpty = composedConfig[key] === null;
|
|
92
|
+
const isI18n = key === i18n;
|
|
93
|
+
|
|
94
|
+
if (key === "variants" && !isVariants) {
|
|
95
|
+
isVariants = true;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
config[key] =
|
|
99
|
+
isObject && !isEmpty && !isI18n
|
|
100
|
+
? mergeConfigs({
|
|
101
|
+
defaultConfig: stringToObject(composedConfig[key], { addBase: !isVariants }),
|
|
102
|
+
globalConfig: stringToObject(globalConfig[key], { addBase: !isVariants }),
|
|
103
|
+
propsConfig: stringToObject(propsConfig[key], { addBase: !isVariants }),
|
|
104
|
+
config: stringToObject(composedConfig[key], { addBase: !isVariants }),
|
|
105
|
+
isReplace,
|
|
106
|
+
isVariants,
|
|
107
|
+
})
|
|
108
|
+
: isReplace || isI18n
|
|
109
|
+
? propsConfig[key] || globalConfig[key] || defaultConfig[key]
|
|
110
|
+
: cx([defaultConfig[key], globalConfig[key], propsConfig[key]]);
|
|
111
|
+
}
|
|
112
|
+
} else {
|
|
113
|
+
config[key] = composedConfig[key];
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return config;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Merge CVA compound variants arrays.
|
|
122
|
+
* isReplace - enables class replacement instead of merge.
|
|
123
|
+
*/
|
|
124
|
+
function mergeCompoundVariants({ defaultConfig, globalConfig, propsConfig, isReplace }) {
|
|
125
|
+
if (
|
|
126
|
+
(globalConfig.compoundVariants && !Array.isArray(globalConfig.compoundVariants)) ||
|
|
127
|
+
(propsConfig.compoundVariants && !Array.isArray(propsConfig.compoundVariants)) ||
|
|
128
|
+
(defaultConfig.compoundVariants && !Array.isArray(defaultConfig.compoundVariants))
|
|
129
|
+
) {
|
|
130
|
+
// eslint-disable-next-line no-console
|
|
131
|
+
console.error("CompoundVariants should be an array.");
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const globalConfigUniqueItems = cloneDeep(globalConfig.compoundVariants || []);
|
|
135
|
+
const propsConfigUniqueItems = cloneDeep(propsConfig.compoundVariants || []);
|
|
136
|
+
|
|
137
|
+
const config = defaultConfig.compoundVariants?.map((defaultConfigItem) => {
|
|
138
|
+
/**
|
|
139
|
+
* Compare two objects by keys for match.
|
|
140
|
+
*/
|
|
141
|
+
function isSameItem(configItem) {
|
|
142
|
+
const hasConfigItemKeys = Object.keys(defaultConfigItem)
|
|
143
|
+
.map((key) => defaultConfigItem[key] === configItem[key] || key === "class")
|
|
144
|
+
.every((item) => Boolean(item));
|
|
145
|
+
|
|
146
|
+
const hasDefaultConfigItemKeys = Object.keys(configItem)
|
|
147
|
+
.map((key) => defaultConfigItem[key] === configItem[key] || key === "class")
|
|
148
|
+
.every((item) => Boolean(item));
|
|
149
|
+
|
|
150
|
+
return hasConfigItemKeys && hasDefaultConfigItemKeys;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Find the same compound variant item in custom config if exist.
|
|
155
|
+
*/
|
|
156
|
+
function findItem(config = []) {
|
|
157
|
+
const globalConfigUniqueItemIndex = globalConfigUniqueItems.findIndex(isSameItem);
|
|
158
|
+
const propsConfigUniqueItemIndex = propsConfigUniqueItems.findIndex(isSameItem);
|
|
159
|
+
|
|
160
|
+
if (~globalConfigUniqueItemIndex) {
|
|
161
|
+
globalConfigUniqueItems.splice(globalConfigUniqueItemIndex, 1);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (~propsConfigUniqueItemIndex) {
|
|
165
|
+
propsConfigUniqueItems.splice(propsConfigUniqueItemIndex, 1);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return config.find(isSameItem);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const globalConfigItem = findItem(globalConfig.compoundVariants);
|
|
172
|
+
const propsConfigItem = findItem(propsConfig.compoundVariants);
|
|
173
|
+
|
|
174
|
+
return globalConfigItem || propsConfigItem
|
|
175
|
+
? {
|
|
176
|
+
...defaultConfigItem,
|
|
177
|
+
class: isReplace
|
|
178
|
+
? propsConfigItem?.class || globalConfigItem?.class || defaultConfigItem.class
|
|
179
|
+
: cx([defaultConfigItem.class, globalConfigItem?.class, propsConfigItem?.class]),
|
|
180
|
+
}
|
|
181
|
+
: defaultConfigItem;
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
return [...(config || []), ...globalConfigUniqueItems, ...propsConfigUniqueItems];
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return mergeConfigs;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
Turn simplified nested component config to regular config.
|
|
192
|
+
*/
|
|
193
|
+
function stringToObject(value, { addBase = false }) {
|
|
194
|
+
if (typeof value !== "object" && addBase) {
|
|
195
|
+
return { base: value || "" };
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return typeof value === "object" ? value : addBase ? { base: value || "" } : {};
|
|
199
|
+
}
|