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.
Files changed (298) hide show
  1. package/README.md +3 -3
  2. package/adatper.locale/vue-i18n.ts +14 -0
  3. package/adatper.locale/{vueless.js → vueless.ts} +67 -19
  4. package/composables/useAutoPosition.ts +113 -0
  5. package/composables/useBreakpoint.ts +109 -0
  6. package/composables/useLocale.ts +22 -0
  7. package/composables/useMutationObserver.ts +53 -0
  8. package/composables/{useUI.js → useUI.ts} +109 -105
  9. package/constants.js +124 -2
  10. package/directives/clickOutside/storybook/Docs.mdx +1 -1
  11. package/directives/clickOutside/storybook/{stories.js → stories.ts} +7 -9
  12. package/directives/clickOutside/types.ts +22 -0
  13. package/directives/clickOutside/vClickOutside.ts +96 -0
  14. package/directives/index.js +7 -2
  15. package/directives/tooltip/storybook/Docs.mdx +1 -1
  16. package/directives/tooltip/storybook/{stories.js → stories.ts} +22 -10
  17. package/directives/tooltip/types.ts +14 -0
  18. package/directives/tooltip/vTooltip.ts +82 -0
  19. package/{index.js → index.ts} +12 -9
  20. package/package.json +38 -25
  21. package/plugin-vite.d.ts +10 -0
  22. package/plugin-vite.js +97 -0
  23. package/{preset.tailwind.js → preset-tailwind.js} +21 -7
  24. package/types.ts +322 -0
  25. package/ui.button/UButton.vue +1 -1
  26. package/ui.button/storybook/Docs.mdx +1 -1
  27. package/ui.button/storybook/stories.js +11 -6
  28. package/ui.button/useAttrs.js +1 -1
  29. package/ui.button-link/ULink.vue +2 -2
  30. package/ui.button-link/storybook/Docs.mdx +1 -1
  31. package/ui.button-link/storybook/stories.js +2 -2
  32. package/ui.button-link/useAttrs.js +1 -1
  33. package/ui.button-toggle/UToggle.vue +1 -1
  34. package/ui.button-toggle/storybook/Docs.mdx +1 -1
  35. package/ui.button-toggle/storybook/stories.js +2 -2
  36. package/ui.button-toggle/useAttrs.js +1 -1
  37. package/ui.button-toggle-item/UToggleItem.vue +1 -1
  38. package/ui.button-toggle-item/storybook/Docs.mdx +1 -1
  39. package/ui.button-toggle-item/storybook/stories.js +1 -1
  40. package/ui.button-toggle-item/useAttrs.js +1 -1
  41. package/ui.container-accordion/UAccordion.vue +1 -1
  42. package/ui.container-accordion/storybook/Docs.mdx +1 -1
  43. package/ui.container-accordion/storybook/stories.js +1 -1
  44. package/ui.container-accordion/useAttrs.js +1 -1
  45. package/ui.container-card/storybook/Docs.mdx +1 -1
  46. package/ui.container-card/storybook/stories.js +1 -1
  47. package/ui.container-card/useAttrs.js +1 -1
  48. package/ui.container-col/UCol.vue +1 -1
  49. package/ui.container-col/storybook/Docs.mdx +1 -1
  50. package/ui.container-col/storybook/stories.js +1 -1
  51. package/ui.container-col/useAttrs.js +1 -1
  52. package/ui.container-divider/UDivider.vue +1 -1
  53. package/ui.container-divider/storybook/Docs.mdx +1 -1
  54. package/ui.container-divider/storybook/stories.js +2 -2
  55. package/ui.container-divider/useAttrs.js +1 -1
  56. package/ui.container-group/UGroup.vue +1 -1
  57. package/ui.container-group/storybook/Docs.mdx +1 -1
  58. package/ui.container-group/storybook/stories.js +1 -1
  59. package/ui.container-group/useAttrs.js +1 -1
  60. package/ui.container-modal/UModal.vue +1 -1
  61. package/ui.container-modal/storybook/Docs.mdx +1 -1
  62. package/ui.container-modal/storybook/stories.js +2 -2
  63. package/ui.container-modal/useAttrs.js +1 -1
  64. package/ui.container-modal-confirm/UModalConfirm.vue +2 -2
  65. package/ui.container-modal-confirm/storybook/Docs.mdx +1 -1
  66. package/ui.container-modal-confirm/storybook/stories.js +2 -2
  67. package/ui.container-modal-confirm/useAttrs.js +1 -1
  68. package/ui.container-page/UPage.vue +2 -2
  69. package/ui.container-page/storybook/Docs.mdx +1 -1
  70. package/ui.container-page/storybook/stories.js +1 -1
  71. package/ui.container-page/useAttrs.js +2 -2
  72. package/ui.container-row/URow.vue +1 -1
  73. package/ui.container-row/storybook/Docs.mdx +1 -1
  74. package/ui.container-row/storybook/stories.js +2 -2
  75. package/ui.container-row/useAttrs.js +1 -1
  76. package/ui.data-list/UDataList.vue +6 -6
  77. package/ui.data-list/storybook/Docs.mdx +1 -1
  78. package/ui.data-list/storybook/stories.js +1 -1
  79. package/ui.data-list/useAttrs.js +1 -1
  80. package/ui.data-table/UTable.vue +3 -3
  81. package/ui.data-table/UTableRow.vue +7 -6
  82. package/ui.data-table/config.js +10 -3
  83. package/ui.data-table/storybook/Docs.mdx +1 -1
  84. package/ui.data-table/storybook/stories.js +5 -3
  85. package/ui.data-table/useAttrs.js +1 -1
  86. package/ui.data-table/utilTable.js +1 -1
  87. package/ui.dropdown-badge/UDropdownBadge.vue +1 -1
  88. package/ui.dropdown-badge/storybook/Docs.mdx +1 -1
  89. package/ui.dropdown-badge/storybook/stories.js +2 -2
  90. package/ui.dropdown-badge/useAttrs.js +1 -1
  91. package/ui.dropdown-button/UDropdownButton.vue +1 -1
  92. package/ui.dropdown-button/storybook/Docs.mdx +1 -1
  93. package/ui.dropdown-button/storybook/stories.js +3 -3
  94. package/ui.dropdown-button/useAttrs.js +1 -1
  95. package/ui.dropdown-link/UDropdownLink.vue +1 -1
  96. package/ui.dropdown-link/config.js +1 -1
  97. package/ui.dropdown-link/storybook/Docs.mdx +1 -1
  98. package/ui.dropdown-link/storybook/stories.js +2 -2
  99. package/ui.dropdown-link/useAttrs.js +4 -6
  100. package/ui.dropdown-list/UDropdownList.vue +3 -3
  101. package/ui.dropdown-list/storybook/Docs.mdx +1 -1
  102. package/ui.dropdown-list/storybook/stories.js +2 -2
  103. package/ui.dropdown-list/useAttrs.js +1 -1
  104. package/ui.form-calendar/UCalendar.vue +2 -2
  105. package/ui.form-calendar/storybook/Docs.mdx +1 -1
  106. package/ui.form-calendar/storybook/stories.js +1 -1
  107. package/ui.form-calendar/useAttrs.js +1 -1
  108. package/ui.form-checkbox/UCheckbox.vue +1 -1
  109. package/ui.form-checkbox/storybook/Docs.mdx +1 -1
  110. package/ui.form-checkbox/storybook/stories.js +2 -2
  111. package/ui.form-checkbox/useAttrs.js +1 -1
  112. package/ui.form-checkbox-group/UCheckboxGroup.vue +1 -1
  113. package/ui.form-checkbox-group/storybook/Docs.mdx +1 -1
  114. package/ui.form-checkbox-group/storybook/stories.js +2 -2
  115. package/ui.form-checkbox-group/useAttrs.js +1 -1
  116. package/ui.form-checkbox-multi-state/UCheckboxMultiState.vue +1 -1
  117. package/ui.form-checkbox-multi-state/storybook/Docs.mdx +1 -1
  118. package/ui.form-checkbox-multi-state/storybook/stories.js +2 -2
  119. package/ui.form-checkbox-multi-state/useAttrs.js +1 -1
  120. package/ui.form-color-picker/UColorPicker.vue +1 -1
  121. package/ui.form-color-picker/storybook/Docs.mdx +1 -1
  122. package/ui.form-color-picker/storybook/stories.js +2 -2
  123. package/ui.form-color-picker/useAttrs.js +1 -1
  124. package/ui.form-date-picker/UDatePicker.vue +4 -7
  125. package/ui.form-date-picker/storybook/Docs.mdx +1 -1
  126. package/ui.form-date-picker/storybook/stories.js +3 -3
  127. package/ui.form-date-picker/useAttrs.js +2 -2
  128. package/ui.form-date-picker-range/UDatePickerRange.vue +2 -2
  129. package/ui.form-date-picker-range/storybook/Docs.mdx +1 -1
  130. package/ui.form-date-picker-range/storybook/stories.js +2 -2
  131. package/ui.form-date-picker-range/useAttrs.js +2 -2
  132. package/ui.form-date-picker-range/useLocale.js +1 -1
  133. package/ui.form-input/UInput.vue +3 -3
  134. package/ui.form-input/storybook/Docs.mdx +1 -1
  135. package/ui.form-input/storybook/stories.js +2 -2
  136. package/ui.form-input/useAttrs.js +1 -1
  137. package/ui.form-input-file/UInputFile.vue +2 -2
  138. package/ui.form-input-file/storybook/Docs.mdx +1 -1
  139. package/ui.form-input-file/storybook/stories.js +2 -2
  140. package/ui.form-input-file/useAttrs.js +1 -1
  141. package/ui.form-input-money/UInputMoney.vue +1 -1
  142. package/ui.form-input-money/storybook/Docs.mdx +1 -1
  143. package/ui.form-input-money/storybook/stories.js +2 -2
  144. package/ui.form-input-money/useAttrs.js +1 -1
  145. package/ui.form-input-money/useFormatCurrency.js +1 -1
  146. package/ui.form-input-number/UInputNumber.vue +5 -4
  147. package/ui.form-input-number/storybook/Docs.mdx +1 -1
  148. package/ui.form-input-number/storybook/stories.js +2 -2
  149. package/ui.form-input-number/useAttrs.js +1 -1
  150. package/ui.form-input-rating/UInputRating.vue +1 -1
  151. package/ui.form-input-rating/storybook/Docs.mdx +1 -1
  152. package/ui.form-input-rating/storybook/stories.js +2 -2
  153. package/ui.form-input-rating/useAttrs.js +1 -1
  154. package/ui.form-input-search/UInputSearch.vue +2 -2
  155. package/ui.form-input-search/storybook/Docs.mdx +1 -1
  156. package/ui.form-input-search/storybook/stories.js +2 -2
  157. package/ui.form-input-search/useAttrs.js +1 -1
  158. package/ui.form-label/ULabel.vue +1 -1
  159. package/ui.form-label/config.js +2 -2
  160. package/ui.form-label/storybook/Docs.mdx +1 -1
  161. package/ui.form-label/storybook/stories.js +2 -2
  162. package/ui.form-label/useAttrs.js +1 -1
  163. package/ui.form-radio/URadio.vue +1 -1
  164. package/ui.form-radio/storybook/Docs.mdx +1 -1
  165. package/ui.form-radio/storybook/stories.js +1 -1
  166. package/ui.form-radio/useAttrs.js +1 -1
  167. package/ui.form-radio-group/URadioGroup.vue +1 -1
  168. package/ui.form-radio-group/storybook/Docs.mdx +1 -1
  169. package/ui.form-radio-group/storybook/stories.js +2 -2
  170. package/ui.form-radio-group/useAttrs.js +1 -1
  171. package/ui.form-select/USelect.vue +4 -4
  172. package/ui.form-select/storybook/Docs.mdx +1 -1
  173. package/ui.form-select/storybook/stories.js +2 -2
  174. package/ui.form-select/useAttrs.js +1 -1
  175. package/ui.form-switch/USwitch.vue +2 -2
  176. package/ui.form-switch/storybook/Docs.mdx +1 -1
  177. package/ui.form-switch/storybook/stories.js +2 -2
  178. package/ui.form-switch/useAttrs.js +1 -1
  179. package/ui.form-switch/utilVariant.js +1 -1
  180. package/ui.form-textarea/UTextarea.vue +1 -1
  181. package/ui.form-textarea/storybook/Docs.mdx +1 -1
  182. package/ui.form-textarea/storybook/stories.js +2 -2
  183. package/ui.form-textarea/useAttrs.js +1 -1
  184. package/ui.image-avatar/UAvatar.vue +1 -1
  185. package/ui.image-avatar/storybook/Docs.mdx +1 -1
  186. package/ui.image-avatar/storybook/stories.js +2 -2
  187. package/ui.image-avatar/useAttrs.js +1 -1
  188. package/ui.image-icon/UIcon.vue +14 -8
  189. package/ui.image-icon/storybook/Docs.mdx +2 -2
  190. package/ui.image-icon/storybook/stories.js +2 -2
  191. package/ui.image-icon/useAttrs.js +2 -2
  192. package/ui.loader/ULoader.vue +1 -1
  193. package/ui.loader/storybook/Docs.mdx +1 -1
  194. package/ui.loader/storybook/stories.js +2 -2
  195. package/ui.loader/useAttrs.js +1 -1
  196. package/ui.loader-overlay/ULoaderOverlay.vue +1 -1
  197. package/ui.loader-overlay/storybook/Docs.mdx +1 -1
  198. package/ui.loader-overlay/storybook/stories.js +1 -1
  199. package/ui.loader-overlay/useAttrs.js +1 -1
  200. package/ui.loader-progress/ULoaderProgress.vue +33 -48
  201. package/ui.loader-progress/constants.js +1 -0
  202. package/ui.loader-progress/storybook/Docs.mdx +1 -1
  203. package/ui.loader-progress/storybook/stories.js +3 -4
  204. package/ui.loader-progress/useAttrs.js +1 -1
  205. package/ui.loader-progress/useLoaderProgress.js +13 -8
  206. package/ui.loader-progress/utilLoaderProgress.js +1 -1
  207. package/ui.navigation-pagination/UPagination.vue +1 -1
  208. package/ui.navigation-pagination/storybook/Docs.mdx +1 -1
  209. package/ui.navigation-pagination/storybook/stories.js +1 -1
  210. package/ui.navigation-pagination/useAttrs.js +1 -1
  211. package/ui.navigation-progress/UProgress.vue +1 -1
  212. package/ui.navigation-progress/storybook/Docs.mdx +1 -1
  213. package/ui.navigation-progress/storybook/stories.js +2 -2
  214. package/ui.navigation-progress/useAttrs.js +1 -1
  215. package/ui.navigation-tab/UTab.vue +1 -1
  216. package/ui.navigation-tab/storybook/Docs.mdx +1 -1
  217. package/ui.navigation-tab/storybook/stories.js +1 -1
  218. package/ui.navigation-tab/useAttrs.js +1 -1
  219. package/ui.navigation-tabs/UTabs.vue +1 -1
  220. package/ui.navigation-tabs/storybook/Docs.mdx +1 -1
  221. package/ui.navigation-tabs/storybook/stories.js +2 -2
  222. package/ui.navigation-tabs/useAttrs.js +1 -1
  223. package/ui.other-dot/UDot.vue +1 -1
  224. package/ui.other-dot/storybook/Docs.mdx +1 -1
  225. package/ui.other-dot/storybook/stories.js +2 -2
  226. package/ui.other-dot/useAttrs.js +1 -1
  227. package/ui.text-alert/UAlert.vue +1 -1
  228. package/ui.text-alert/storybook/Docs.mdx +1 -1
  229. package/ui.text-alert/storybook/stories.js +2 -2
  230. package/ui.text-alert/useAttrs.js +1 -1
  231. package/ui.text-badge/UBadge.vue +89 -179
  232. package/ui.text-badge/storybook/Docs.mdx +3 -3
  233. package/ui.text-badge/storybook/{stories.js → stories.ts} +33 -37
  234. package/ui.text-badge/types.ts +84 -0
  235. package/ui.text-badge/useAttrs.ts +28 -0
  236. package/ui.text-block/UText.vue +18 -62
  237. package/ui.text-block/storybook/Docs.mdx +3 -3
  238. package/ui.text-block/storybook/{stories.js → stories.ts} +13 -8
  239. package/ui.text-block/types.ts +33 -0
  240. package/ui.text-block/useAttrs.ts +20 -0
  241. package/ui.text-empty/UEmpty.vue +1 -1
  242. package/ui.text-empty/storybook/Docs.mdx +1 -1
  243. package/ui.text-empty/storybook/stories.js +2 -2
  244. package/ui.text-empty/useAttrs.js +1 -1
  245. package/ui.text-file/UFile.vue +13 -16
  246. package/ui.text-file/config.js +12 -2
  247. package/ui.text-file/storybook/Docs.mdx +1 -1
  248. package/ui.text-file/storybook/stories.js +1 -1
  249. package/ui.text-file/useAttrs.js +1 -1
  250. package/ui.text-files/UFiles.vue +1 -1
  251. package/ui.text-files/config.js +1 -1
  252. package/ui.text-files/storybook/Docs.mdx +1 -1
  253. package/ui.text-files/storybook/stories.js +1 -1
  254. package/ui.text-files/useAttrs.js +1 -1
  255. package/ui.text-header/UHeader.vue +1 -1
  256. package/ui.text-header/storybook/Docs.mdx +1 -1
  257. package/ui.text-header/storybook/stories.js +2 -2
  258. package/ui.text-header/useAttrs.js +1 -1
  259. package/ui.text-money/UMoney.vue +1 -1
  260. package/ui.text-money/storybook/Docs.mdx +1 -1
  261. package/ui.text-money/storybook/stories.js +2 -2
  262. package/ui.text-money/useAttrs.js +1 -1
  263. package/ui.text-money/utilMoney.js +2 -2
  264. package/ui.text-notify/UNotify.vue +2 -2
  265. package/ui.text-notify/storybook/Docs.mdx +1 -1
  266. package/ui.text-notify/storybook/stories.js +1 -1
  267. package/ui.text-notify/useAttrs.js +1 -1
  268. package/ui.text-notify/utilNotify.js +1 -1
  269. package/utils/{utilHelper.js → helper.ts} +14 -27
  270. package/utils/node/helper.js +78 -0
  271. package/utils/node/loaderIcon.js +232 -0
  272. package/utils/node/loaderSvg.js +71 -0
  273. package/utils/node/mergeConfigs.js +199 -0
  274. package/utils/node/tailwindSafelist.js +366 -0
  275. package/utils/node/vuelessConfig.js +42 -0
  276. package/utils/node/vuelessResolver.js +28 -0
  277. package/utils/{utilPlatform.js → platform.ts} +10 -3
  278. package/utils/{utilStorybook.js → storybook.ts} +102 -36
  279. package/utils/tailwindConfig.ts +33 -0
  280. package/utils/{utilTheme.js → theme.ts} +65 -30
  281. package/utils/ui.ts +129 -0
  282. package/web-types.json +1362 -157
  283. package/adatper.locale/vue-i18n.js +0 -11
  284. package/composables/useAutoPosition.js +0 -94
  285. package/composables/useBreakpoint.js +0 -104
  286. package/composables/useLocale.js +0 -25
  287. package/composables/useMutationObserver.js +0 -48
  288. package/directives/clickOutside/vClickOutside.js +0 -64
  289. package/directives/tooltip/vTooltip.js +0 -56
  290. package/ui.text-badge/useAttrs.js +0 -23
  291. package/ui.text-block/useAttrs.js +0 -15
  292. package/utils/utilUI.js +0 -360
  293. /package/adatper.locale/locales/{en.js → en.ts} +0 -0
  294. /package/ui.image-icon/{config.js → config.ts} +0 -0
  295. /package/ui.text-badge/{config.js → config.ts} +0 -0
  296. /package/ui.text-badge/{constants.js → constants.ts} +0 -0
  297. /package/ui.text-block/{config.js → config.ts} +0 -0
  298. /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
+ }