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,366 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { merge } from "lodash-es";
|
|
3
|
+
import { existsSync } from "node:fs";
|
|
4
|
+
import { readFile } from "node:fs/promises";
|
|
5
|
+
import { extendTailwindMerge } from "tailwind-merge";
|
|
6
|
+
import { isEqual, omit } from "lodash-es";
|
|
7
|
+
import { defineConfig } from "cva";
|
|
8
|
+
|
|
9
|
+
import { vuelessConfig } from "./vuelessConfig.js";
|
|
10
|
+
import { createMergeConfigsFunction } from "./mergeConfigs.js";
|
|
11
|
+
import { getDefaultConfigJson, getDirFiles } from "./helper.js";
|
|
12
|
+
import {
|
|
13
|
+
COMPONENTS,
|
|
14
|
+
BRAND_COLORS,
|
|
15
|
+
BRAND_COLOR,
|
|
16
|
+
GRAY_COLOR,
|
|
17
|
+
DYNAMIC_COLOR_PATTERN,
|
|
18
|
+
TAILWIND_CLASS_DELIMITER,
|
|
19
|
+
TAILWIND_MERGE_EXTENSION,
|
|
20
|
+
NESTED_COMPONENT_REG_EXP,
|
|
21
|
+
} from "../../constants.js";
|
|
22
|
+
|
|
23
|
+
const twMerge = extendTailwindMerge(merge(TAILWIND_MERGE_EXTENSION, vuelessConfig.tailwindMerge));
|
|
24
|
+
|
|
25
|
+
export const { cx } = defineConfig({
|
|
26
|
+
hooks: {
|
|
27
|
+
onComplete: (classNames) => twMerge(classNames).replace(NESTED_COMPONENT_REG_EXP, ""),
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const mergeConfigs = createMergeConfigsFunction(cx);
|
|
32
|
+
|
|
33
|
+
export function clearTailwindSafelist() {
|
|
34
|
+
process.env.VUELESS_SAFELIST = "";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export async function createTailwindSafelist({ mode, env, debug, targetFiles = [] } = {}) {
|
|
38
|
+
const isStorybookMode = mode === "storybook";
|
|
39
|
+
const isVuelessEnv = env === "vueless";
|
|
40
|
+
const vuelessFilePath = isVuelessEnv ? "src" : "node_modules/vueless";
|
|
41
|
+
|
|
42
|
+
const vuelessVueFiles = await getDirFiles(vuelessFilePath, ".vue");
|
|
43
|
+
const vuelessConfigJsFiles = await getDirFiles(vuelessFilePath, "/config.ts");
|
|
44
|
+
const vuelessConfigTsFiles = await getDirFiles(vuelessFilePath, "/config.js");
|
|
45
|
+
const vuelessConfigFiles = [...vuelessConfigJsFiles, ...vuelessConfigTsFiles].flat();
|
|
46
|
+
|
|
47
|
+
let srcVueFiles = [];
|
|
48
|
+
|
|
49
|
+
if (!isVuelessEnv) {
|
|
50
|
+
srcVueFiles = await Promise.all(
|
|
51
|
+
targetFiles.map((componentPath) => getDirFiles(componentPath, ".vue")),
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
srcVueFiles = srcVueFiles.flat();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const vuelessFiles = [...srcVueFiles, ...vuelessVueFiles, ...vuelessConfigFiles];
|
|
58
|
+
|
|
59
|
+
const storybookColors = {
|
|
60
|
+
colors: [...BRAND_COLORS, BRAND_COLOR, GRAY_COLOR],
|
|
61
|
+
isComponentExists: true,
|
|
62
|
+
};
|
|
63
|
+
const safelist = [];
|
|
64
|
+
|
|
65
|
+
const componentNames = Object.keys(COMPONENTS);
|
|
66
|
+
|
|
67
|
+
for await (const component of componentNames) {
|
|
68
|
+
const defaultConfigPath = vuelessConfigFiles.find((file) =>
|
|
69
|
+
isDefaultComponentConfig(file, component),
|
|
70
|
+
);
|
|
71
|
+
const defaultConfig = await readFile(path.join(process.cwd(), defaultConfigPath), {
|
|
72
|
+
encoding: "utf-8",
|
|
73
|
+
});
|
|
74
|
+
const nestedComponents = (defaultConfig.match(/\{U\w+\}/g) || []).map(
|
|
75
|
+
(nestedComponentPattern) => nestedComponentPattern.replaceAll(/[{}]/g, ""),
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
const { colors, isComponentExists } = isStorybookMode
|
|
79
|
+
? storybookColors
|
|
80
|
+
: await findComponentColors(vuelessFiles, component);
|
|
81
|
+
|
|
82
|
+
if (isComponentExists && colors.length) {
|
|
83
|
+
const componentSafelist = await getComponentSafelist(component, {
|
|
84
|
+
colors,
|
|
85
|
+
vuelessConfigFiles,
|
|
86
|
+
isVuelessEnv,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
safelist.push(...componentSafelist);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (isComponentExists && colors.length && nestedComponents.length) {
|
|
93
|
+
for await (const nestedComponent of nestedComponents) {
|
|
94
|
+
const nestedComponentSafelist = await getComponentSafelist(nestedComponent, {
|
|
95
|
+
colors,
|
|
96
|
+
vuelessConfigFiles,
|
|
97
|
+
isVuelessEnv,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
safelist.push(...nestedComponentSafelist);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const mergedSafelist = mergeSafelistPatterns(safelist);
|
|
106
|
+
|
|
107
|
+
if (debug) {
|
|
108
|
+
// eslint-disable-next-line no-console
|
|
109
|
+
console.log("VUELESS_SAFELIST", mergedSafelist);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
process.env.VUELESS_SAFELIST = JSON.stringify(mergedSafelist);
|
|
113
|
+
process.env.VUELESS_STRATEGY = vuelessConfig.strategy || "";
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function getSafelistClasses(config) {
|
|
117
|
+
const safelistItems = [];
|
|
118
|
+
|
|
119
|
+
for (const key in config) {
|
|
120
|
+
if (Object.prototype.hasOwnProperty.call(config, key)) {
|
|
121
|
+
const classes = config[key];
|
|
122
|
+
|
|
123
|
+
if (typeof classes === "object" && Array.isArray(classes)) {
|
|
124
|
+
safelistItems.push(...classes.map(getSafelistClasses));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (typeof classes === "object" && !Array.isArray(classes)) {
|
|
128
|
+
safelistItems.push(...getSafelistClasses(classes));
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (typeof classes === "string") {
|
|
132
|
+
safelistItems.push(
|
|
133
|
+
...classes.split(" ").filter((classItem) => classItem.includes(DYNAMIC_COLOR_PATTERN)),
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return safelistItems.flat().map((item) => item.replaceAll("\\n", "").trim());
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function getSafelistItem(safelistClass, colorString) {
|
|
143
|
+
const classes = safelistClass.split(TAILWIND_CLASS_DELIMITER);
|
|
144
|
+
const mainClass = classes.at(-1);
|
|
145
|
+
const variantClasses = classes.slice(0, classes.length - 1);
|
|
146
|
+
|
|
147
|
+
const pattern = mainClass.replace(DYNAMIC_COLOR_PATTERN, colorString);
|
|
148
|
+
const variants = variantClasses
|
|
149
|
+
.map((variantItem) => (variantItem ? variantItem : TAILWIND_CLASS_DELIMITER))
|
|
150
|
+
.join("");
|
|
151
|
+
|
|
152
|
+
return classes.length === 1 ? { pattern } : { pattern, variants: [variants].flat() };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async function getComponentSafelist(componentName, { colors, vuelessConfigFiles }) {
|
|
156
|
+
let defaultConfigPath = vuelessConfigFiles.find((file) =>
|
|
157
|
+
isDefaultComponentConfig(file, componentName),
|
|
158
|
+
);
|
|
159
|
+
const customConfig = vuelessConfig.component?.[componentName] || {};
|
|
160
|
+
let defaultConfig = {};
|
|
161
|
+
|
|
162
|
+
if (defaultConfigPath) {
|
|
163
|
+
const configPath = path.join(process.cwd(), defaultConfigPath);
|
|
164
|
+
const defaultConfigContent = await readFile(configPath, { encoding: "utf-8" });
|
|
165
|
+
|
|
166
|
+
defaultConfig = getDefaultConfigJson(defaultConfigContent);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const mergedConfig = omit(mergeConfigs({ defaultConfig, globalConfig: customConfig }), [
|
|
170
|
+
"defaults",
|
|
171
|
+
]);
|
|
172
|
+
|
|
173
|
+
const colorString = `(${colors.join("|")})`;
|
|
174
|
+
|
|
175
|
+
return getSafelistClasses(mergedConfig).map((safelistClass) =>
|
|
176
|
+
getSafelistItem(safelistClass, colorString),
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async function findComponentColors(files, componentName) {
|
|
181
|
+
const objectColorRegExp = new RegExp(/\bcolor\s*:\s*["']([^"'\s]+)["']/, "g");
|
|
182
|
+
const singleColorRegExp = new RegExp(/\bcolor\s*=\s*["']([^"'\s]+)["']/);
|
|
183
|
+
const ternaryColorRegExp = new RegExp(/\bcolor="[^']*'([^']*)'\s*:\s*'([^']*)'/);
|
|
184
|
+
|
|
185
|
+
const brandColor = getComponentBrandColor(componentName);
|
|
186
|
+
const colors = new Set();
|
|
187
|
+
|
|
188
|
+
if (brandColor && brandColor !== "grayscale") {
|
|
189
|
+
colors.add(brandColor);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
getSafelistColorsFromConfig().forEach((color) => colors.add(color));
|
|
193
|
+
|
|
194
|
+
let isComponentExists = false;
|
|
195
|
+
|
|
196
|
+
for await (const file of files) {
|
|
197
|
+
if (!existsSync(file)) continue;
|
|
198
|
+
|
|
199
|
+
const fileContent = await readFile(file, "utf-8");
|
|
200
|
+
const isDefaultConfig = isDefaultComponentConfig(file, componentName);
|
|
201
|
+
const componentRegExp = new RegExp(`<${componentName}[^>]+>`, "g");
|
|
202
|
+
const matchedComponent = fileContent.match(componentRegExp);
|
|
203
|
+
|
|
204
|
+
if (!isComponentExists) {
|
|
205
|
+
isComponentExists = Boolean(matchedComponent);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (isDefaultConfig) {
|
|
209
|
+
fileContent.match(objectColorRegExp)?.forEach((colorMatch) => {
|
|
210
|
+
const [, color] = objectColorRegExp.exec(colorMatch) || [];
|
|
211
|
+
|
|
212
|
+
colors.add(color);
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/* Collect color from U[Component] */
|
|
217
|
+
matchedComponent?.forEach((match) => {
|
|
218
|
+
const [, singleColor] = singleColorRegExp.exec(match) || [];
|
|
219
|
+
const [, ternaryColorOne, ternaryColorTwo] = ternaryColorRegExp.exec(match) || [];
|
|
220
|
+
|
|
221
|
+
// Match color in script variables.
|
|
222
|
+
const objectColors = objectColorRegExp.exec(fileContent) || [];
|
|
223
|
+
|
|
224
|
+
[singleColor, ternaryColorOne, ternaryColorTwo, ...objectColors].forEach((color) => {
|
|
225
|
+
if (color) colors.add(color);
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return {
|
|
231
|
+
colors: Array.from(colors).filter(
|
|
232
|
+
(color) => color && [...BRAND_COLORS, BRAND_COLOR, GRAY_COLOR].includes(color),
|
|
233
|
+
),
|
|
234
|
+
isComponentExists,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function getComponentBrandColor(componentName) {
|
|
239
|
+
const globalBrandColor = vuelessConfig.brand || "";
|
|
240
|
+
const globalComponentConfig = vuelessConfig.component?.[componentName] || {};
|
|
241
|
+
|
|
242
|
+
return vuelessConfig.component ? globalComponentConfig.defaults?.color : globalBrandColor;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function isDefaultComponentConfig(filePath, componentName) {
|
|
246
|
+
const componentDirName = filePath.split(path.sep).at(-2);
|
|
247
|
+
|
|
248
|
+
return (
|
|
249
|
+
componentDirName === COMPONENTS[componentName] &&
|
|
250
|
+
(filePath.endsWith("/config.js") || filePath.endsWith("/config.ts"))
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function getSafelistColorsFromConfig(componentName) {
|
|
255
|
+
const globalSafelistColors = vuelessConfig.safelistColors || [];
|
|
256
|
+
const componentSafelistColors =
|
|
257
|
+
(vuelessConfig.component && vuelessConfig.component[componentName]?.safelistColors) || [];
|
|
258
|
+
|
|
259
|
+
return [...globalSafelistColors, ...componentSafelistColors];
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
Combine collected tailwind patterns from different components into groups.
|
|
264
|
+
*/
|
|
265
|
+
function mergeSafelistPatterns(safelist) {
|
|
266
|
+
const safelistData = getSafelistData(safelist);
|
|
267
|
+
const mergedColorsSafelist = mergeSafelistColors(safelistData);
|
|
268
|
+
|
|
269
|
+
return mergeSafelistVariants(mergedColorsSafelist).map((item) => {
|
|
270
|
+
const pattern = `${item.property}(${item.colorPattern})-(${Array.from(item.shades).join("|")})`;
|
|
271
|
+
const safelistItem = { pattern };
|
|
272
|
+
|
|
273
|
+
if (item.variants) {
|
|
274
|
+
safelistItem.variants = item.variants;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return safelistItem;
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function getSafelistData(safelist) {
|
|
282
|
+
return safelist.map((safelistItem) => {
|
|
283
|
+
const matchGroupStart = 1;
|
|
284
|
+
const matchGroupEnd = 4;
|
|
285
|
+
const safelistItemRegExp = new RegExp(/^(.*-)\((.*)\)-(\d+(?:\/\d+)?)$/);
|
|
286
|
+
|
|
287
|
+
const [property, colorPattern, colorShade] = safelistItem.pattern
|
|
288
|
+
.match(safelistItemRegExp)
|
|
289
|
+
.slice(matchGroupStart, matchGroupEnd);
|
|
290
|
+
|
|
291
|
+
return {
|
|
292
|
+
property,
|
|
293
|
+
colorPattern,
|
|
294
|
+
variants: safelistItem.variants,
|
|
295
|
+
shades: new Set([colorShade]),
|
|
296
|
+
};
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
function mergeSafelistColors(safelistData) {
|
|
301
|
+
const mergedSafelist = [];
|
|
302
|
+
|
|
303
|
+
safelistData.forEach((currentSafelistItem, currentIndex) => {
|
|
304
|
+
const duplicateIndex = mergedSafelist.findIndex((safelistItem, index) => {
|
|
305
|
+
const isSameItem = index === currentIndex;
|
|
306
|
+
const isSameProperty = safelistItem.property === currentSafelistItem.property;
|
|
307
|
+
const isSameVariants = isEqual(safelistItem.variants, currentSafelistItem.variants);
|
|
308
|
+
|
|
309
|
+
const currentItemColors = currentSafelistItem.colorPattern.split("|");
|
|
310
|
+
const safelistColors = safelistItem.colorPattern.split("|");
|
|
311
|
+
|
|
312
|
+
const isIncludesColors =
|
|
313
|
+
safelistItem.colorPattern === currentSafelistItem.colorPattern ||
|
|
314
|
+
currentItemColors.some((color) => safelistColors.includes(color)) ||
|
|
315
|
+
safelistColors.some((color) => currentItemColors.includes(color));
|
|
316
|
+
|
|
317
|
+
return !isSameItem && isSameProperty && isSameVariants && isIncludesColors;
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
if (duplicateIndex === -1) {
|
|
321
|
+
mergedSafelist.push(currentSafelistItem);
|
|
322
|
+
} else {
|
|
323
|
+
const mergedColors = [
|
|
324
|
+
...new Set([
|
|
325
|
+
...currentSafelistItem.colorPattern.split("|"),
|
|
326
|
+
...mergedSafelist[duplicateIndex].colorPattern.split("|"),
|
|
327
|
+
]),
|
|
328
|
+
];
|
|
329
|
+
|
|
330
|
+
mergedSafelist[duplicateIndex].colorPattern = mergedColors.join("|");
|
|
331
|
+
mergedSafelist[duplicateIndex].shades.add(
|
|
332
|
+
...currentSafelistItem.shades,
|
|
333
|
+
...mergedSafelist[duplicateIndex].shades,
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
return mergedSafelist;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
function mergeSafelistVariants(safelistData) {
|
|
342
|
+
safelistData.forEach((currentItem, currentIndex) => {
|
|
343
|
+
if (!currentItem.variants) return;
|
|
344
|
+
|
|
345
|
+
const duplicateIndex = safelistData.findIndex((item, index) => {
|
|
346
|
+
const isSameItem = index === currentIndex;
|
|
347
|
+
const isSameProperty = item.property === currentItem.property;
|
|
348
|
+
const isSameColors = item.colorPattern === currentItem.colorPattern;
|
|
349
|
+
const isSameShades = isEqual(item.shades, currentItem.shades);
|
|
350
|
+
|
|
351
|
+
return !isSameItem && isSameProperty && isSameColors && isSameShades;
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
if (~duplicateIndex) {
|
|
355
|
+
const currentItemVariants = currentItem.variants;
|
|
356
|
+
const foundItemVariants = safelistData[duplicateIndex].variants || [];
|
|
357
|
+
|
|
358
|
+
safelistData[duplicateIndex].variants = [
|
|
359
|
+
...new Set([...currentItemVariants, ...foundItemVariants]),
|
|
360
|
+
];
|
|
361
|
+
safelistData.splice(currentIndex, 1);
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
return safelistData;
|
|
366
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import esbuild from "esbuild";
|
|
4
|
+
|
|
5
|
+
import { CACHE_PATH, VUELESS_CONFIG_FILE_NAME } from "../../constants.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Load Vueless config from the project root.
|
|
9
|
+
* IIFE is used to prevent top level await issue.
|
|
10
|
+
*/
|
|
11
|
+
export let vuelessConfig = {};
|
|
12
|
+
|
|
13
|
+
(async () => {
|
|
14
|
+
const configPathJs = path.join(process.cwd(), `${VUELESS_CONFIG_FILE_NAME}.js`);
|
|
15
|
+
const configPathTs = path.join(process.cwd(), `${VUELESS_CONFIG_FILE_NAME}.ts`);
|
|
16
|
+
const configOutPath = path.join(process.cwd(), `${CACHE_PATH}/${VUELESS_CONFIG_FILE_NAME}.mjs`);
|
|
17
|
+
|
|
18
|
+
if (!fs.existsSync(configPathJs) && !fs.existsSync(configPathTs)) {
|
|
19
|
+
vuelessConfig = {};
|
|
20
|
+
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
fs.existsSync(configPathJs) && (await buildConfig(configPathJs, configOutPath));
|
|
25
|
+
fs.existsSync(configPathTs) && (await buildConfig(configPathTs, configOutPath));
|
|
26
|
+
|
|
27
|
+
if (fs.existsSync(configOutPath)) {
|
|
28
|
+
vuelessConfig = (await import(configOutPath)).default;
|
|
29
|
+
}
|
|
30
|
+
})();
|
|
31
|
+
|
|
32
|
+
async function buildConfig(entryPath, configOutFile) {
|
|
33
|
+
await esbuild.build({
|
|
34
|
+
entryPoints: [entryPath],
|
|
35
|
+
outfile: configOutFile,
|
|
36
|
+
bundle: true,
|
|
37
|
+
platform: "node",
|
|
38
|
+
format: "esm",
|
|
39
|
+
target: "ESNext",
|
|
40
|
+
loader: { ".ts": "ts" },
|
|
41
|
+
});
|
|
42
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Custom vueless UI library resolver for "unplugin-vue-components" Vite plugin.
|
|
3
|
+
|
|
4
|
+
When new components are added, please add related to them data into an `COMPONENTS` object with a format:
|
|
5
|
+
- key = component name;
|
|
6
|
+
- value = component folder;
|
|
7
|
+
|
|
8
|
+
Docs: https://github.com/unplugin/unplugin-vue-components?tab=readme-ov-file#importing-from-ui-libraries
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { COMPONENTS } from "../../constants.js";
|
|
12
|
+
|
|
13
|
+
export function componentResolver(componentName) {
|
|
14
|
+
const folder = COMPONENTS[componentName];
|
|
15
|
+
|
|
16
|
+
if (folder) {
|
|
17
|
+
return { from: `vueless/${folder}/${componentName}.vue` };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const directiveResolver = {
|
|
22
|
+
type: "directive",
|
|
23
|
+
resolve(name) {
|
|
24
|
+
return {
|
|
25
|
+
from: `vueless/directives/v${name}.js`,
|
|
26
|
+
};
|
|
27
|
+
},
|
|
28
|
+
};
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import { isCSR } from "./
|
|
1
|
+
import { isCSR } from "./helper.ts";
|
|
2
|
+
|
|
3
|
+
interface ModernNavigator extends Navigator {
|
|
4
|
+
standalone: string;
|
|
5
|
+
userAgentData: {
|
|
6
|
+
platform: string;
|
|
7
|
+
};
|
|
8
|
+
}
|
|
2
9
|
|
|
3
10
|
const isWindows = isCSR && checkIsWindows();
|
|
4
11
|
const isMac = isCSR && checkIsMac();
|
|
@@ -16,7 +23,7 @@ function checkIsMac() {
|
|
|
16
23
|
}
|
|
17
24
|
|
|
18
25
|
function checkIsPWA() {
|
|
19
|
-
return !!navigator.standalone;
|
|
26
|
+
return !!(navigator as ModernNavigator).standalone;
|
|
20
27
|
}
|
|
21
28
|
|
|
22
29
|
function checkIsIOS() {
|
|
@@ -40,7 +47,7 @@ function checkIsAndroid() {
|
|
|
40
47
|
}
|
|
41
48
|
|
|
42
49
|
function getPlatform() {
|
|
43
|
-
return navigator.userAgentData?.platform || navigator.platform || "unknown";
|
|
50
|
+
return (navigator as ModernNavigator).userAgentData?.platform || navigator.platform || "unknown";
|
|
44
51
|
}
|
|
45
52
|
|
|
46
53
|
export { isMac, isPWA, isIOS, isAndroid, isMobileApp, isWindows };
|
|
@@ -1,29 +1,96 @@
|
|
|
1
|
+
import { COMPONENTS } from "../constants.js";
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
WebTypes,
|
|
5
|
+
Tag,
|
|
6
|
+
Attribute,
|
|
7
|
+
EventProperty,
|
|
8
|
+
SlotBinding,
|
|
9
|
+
ExposeProperty,
|
|
10
|
+
} from "../types.ts";
|
|
11
|
+
|
|
12
|
+
interface Types {
|
|
13
|
+
[key: string]: ArgType | undefined;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface ArgType {
|
|
17
|
+
control?: "text" | "number" | "boolean" | "array" | "select" | false;
|
|
18
|
+
options?: string[];
|
|
19
|
+
table?: TableConfig;
|
|
20
|
+
name?: string;
|
|
21
|
+
description?: string;
|
|
22
|
+
type?: string | null;
|
|
23
|
+
action?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface TableConfig {
|
|
27
|
+
disable?: boolean;
|
|
28
|
+
defaultValue?: { summary: unknown };
|
|
29
|
+
category?: "slots" | "expose" | "Storybook Events";
|
|
30
|
+
type?: Record<string, string | string[]>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
type ComponentNames = keyof typeof COMPONENTS;
|
|
34
|
+
|
|
1
35
|
/* Load Web-Types from the project root. */
|
|
2
|
-
const [webTypes] = Object.values(
|
|
3
|
-
import.meta.glob("/web-types.json", {
|
|
36
|
+
const [webTypes]: WebTypes[] = Object.values(
|
|
37
|
+
import.meta.glob("/node_modules/.cache/vueless/web-types.json", {
|
|
38
|
+
eager: true,
|
|
39
|
+
import: "default",
|
|
40
|
+
}),
|
|
4
41
|
);
|
|
5
42
|
|
|
6
|
-
const getComponentData = (componentName) => {
|
|
7
|
-
|
|
43
|
+
const getComponentData = (componentName: ComponentNames) => {
|
|
44
|
+
const component = webTypes?.contributions?.html?.tags?.find(
|
|
45
|
+
(item: Tag) => item.name === componentName,
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
if (!component) {
|
|
49
|
+
// eslint-disable-next-line no-console
|
|
50
|
+
console.warn(
|
|
51
|
+
"The component docs data is missing. Probably the `web-types.json` file is missing or have incorrect format.",
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return component;
|
|
8
56
|
};
|
|
9
57
|
|
|
10
|
-
export function getSlotNames(componentName) {
|
|
11
|
-
|
|
58
|
+
export function getSlotNames(componentName: string | undefined) {
|
|
59
|
+
if (!componentName) return;
|
|
60
|
+
|
|
61
|
+
return getComponentData(componentName as ComponentNames)?.slots?.map((item) => item.name);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Create story param config to show component description with a link on GitHub.
|
|
66
|
+
*/
|
|
67
|
+
export function getDocsDescription(componentName: string | undefined) {
|
|
68
|
+
if (!componentName) return;
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
docs: {
|
|
72
|
+
description: {
|
|
73
|
+
component: `The \`${componentName}\` component. | [View on GitHub](https://github.com/vuelessjs/vueless/tree/main/src/${COMPONENTS[componentName as ComponentNames]})`,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
};
|
|
12
77
|
}
|
|
13
78
|
|
|
14
|
-
export function getArgTypes(componentName) {
|
|
15
|
-
|
|
79
|
+
export function getArgTypes(componentName: string | undefined) {
|
|
80
|
+
if (!componentName) return;
|
|
81
|
+
|
|
82
|
+
const component = getComponentData(componentName as ComponentNames);
|
|
16
83
|
|
|
17
84
|
if (!component) return;
|
|
18
85
|
|
|
19
|
-
const types = {
|
|
86
|
+
const types: Partial<Types> = {
|
|
20
87
|
// Hide default template arg in docs.
|
|
21
88
|
defaultTemplate: { table: { disable: true } },
|
|
22
89
|
// Hide slot template arg in docs.
|
|
23
90
|
slotTemplate: { table: { disable: true } },
|
|
24
91
|
};
|
|
25
92
|
|
|
26
|
-
component.attributes?.forEach((attribute) => {
|
|
93
|
+
component.attributes?.forEach((attribute: Attribute) => {
|
|
27
94
|
const type = attribute.value.type;
|
|
28
95
|
|
|
29
96
|
if (type === "string" || type.includes("string")) {
|
|
@@ -63,24 +130,23 @@ export function getArgTypes(componentName) {
|
|
|
63
130
|
}
|
|
64
131
|
|
|
65
132
|
if (type.includes("|")) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
133
|
+
types[attribute.name] = {
|
|
134
|
+
control: type.split("|")[0] as ArgType["control"],
|
|
135
|
+
table: {
|
|
136
|
+
defaultValue: { summary: attribute.default || "" },
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (attribute.enum) {
|
|
142
|
+
types[attribute.name] = {
|
|
143
|
+
options: attribute.enum,
|
|
144
|
+
control: "select",
|
|
145
|
+
table: {
|
|
146
|
+
defaultValue: { summary: attribute.default || "" },
|
|
147
|
+
type: { summary: attribute.enum.join(" | ") },
|
|
148
|
+
},
|
|
149
|
+
};
|
|
84
150
|
}
|
|
85
151
|
|
|
86
152
|
if (attribute.description?.includes("@ignore")) {
|
|
@@ -93,9 +159,9 @@ export function getArgTypes(componentName) {
|
|
|
93
159
|
});
|
|
94
160
|
|
|
95
161
|
component.slots?.forEach((slot) => {
|
|
96
|
-
const bindings = [];
|
|
162
|
+
const bindings: string[] = [];
|
|
97
163
|
|
|
98
|
-
slot.bindings?.forEach((binding) => {
|
|
164
|
+
slot.bindings?.forEach((binding: SlotBinding) => {
|
|
99
165
|
if (binding.name === "name") return;
|
|
100
166
|
|
|
101
167
|
const description = binding.description ? ` (${binding.description})` : "";
|
|
@@ -122,9 +188,9 @@ export function getArgTypes(componentName) {
|
|
|
122
188
|
});
|
|
123
189
|
|
|
124
190
|
component.exposes?.forEach((expose) => {
|
|
125
|
-
const properties = [];
|
|
191
|
+
const properties: string[] = [];
|
|
126
192
|
|
|
127
|
-
expose.properties?.forEach((property) => {
|
|
193
|
+
expose.properties?.forEach((property: ExposeProperty) => {
|
|
128
194
|
const description = property.description ? ` (${property.description})` : "";
|
|
129
195
|
|
|
130
196
|
properties.push(`${property.type}${description}`);
|
|
@@ -149,9 +215,9 @@ export function getArgTypes(componentName) {
|
|
|
149
215
|
});
|
|
150
216
|
|
|
151
217
|
component.events?.forEach((event) => {
|
|
152
|
-
const properties = [];
|
|
218
|
+
const properties: string[] = [];
|
|
153
219
|
|
|
154
|
-
event.properties?.forEach((property) => {
|
|
220
|
+
event.properties?.forEach((property: EventProperty) => {
|
|
155
221
|
const description = property.description ? ` (${property.description})` : "";
|
|
156
222
|
|
|
157
223
|
properties.push(`${property.name}: ${property.type}${description}`);
|
|
@@ -176,11 +242,11 @@ export function getArgTypes(componentName) {
|
|
|
176
242
|
return types;
|
|
177
243
|
}
|
|
178
244
|
|
|
179
|
-
export function getSource(defaultConfig) {
|
|
245
|
+
export function getSource(defaultConfig: string) {
|
|
180
246
|
return defaultConfig.replace("export default /*tw*/ ", "").replace(";", "");
|
|
181
247
|
}
|
|
182
248
|
|
|
183
|
-
export function getSlotsFragment(defaultTemplate) {
|
|
249
|
+
export function getSlotsFragment(defaultTemplate: string) {
|
|
184
250
|
return `
|
|
185
251
|
<template v-for="(slot, index) of slots" :key="index" v-slot:[slot]>
|
|
186
252
|
<template v-if="slot === 'default' && !args['defaultSlot']">${defaultTemplate || ""}</template>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { isSSR, isCSR } from "./helper.ts";
|
|
2
|
+
|
|
3
|
+
import type { Config } from "tailwindcss";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Load Tailwind config from the project root.
|
|
7
|
+
* Both for server and client side renderings.
|
|
8
|
+
* IIFE for SSR is used to prevent top level await issue.
|
|
9
|
+
*/
|
|
10
|
+
export let tailwindConfig: Config;
|
|
11
|
+
|
|
12
|
+
if (isSSR) {
|
|
13
|
+
/* Load Tailwind config from the project root in IIFE (no top-level await). */
|
|
14
|
+
(async () => {
|
|
15
|
+
try {
|
|
16
|
+
const filePath = `${process.cwd()}/tailwind.config`;
|
|
17
|
+
|
|
18
|
+
tailwindConfig = (await import(/* @vite-ignore */ `${filePath}.js`)).default;
|
|
19
|
+
|
|
20
|
+
if (!tailwindConfig) {
|
|
21
|
+
tailwindConfig = (await import(/* @vite-ignore */ `${filePath}.ts`)).default;
|
|
22
|
+
}
|
|
23
|
+
} catch {
|
|
24
|
+
tailwindConfig = {} as Config;
|
|
25
|
+
}
|
|
26
|
+
})();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (isCSR) {
|
|
30
|
+
tailwindConfig = Object.values(
|
|
31
|
+
import.meta.glob("/tailwind.config.{js,ts}", { eager: true, import: "default" }),
|
|
32
|
+
)[0] as Config;
|
|
33
|
+
}
|