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
@@ -11,9 +11,8 @@ import {
11
11
  computed,
12
12
  } from "vue";
13
13
 
14
- import { cx, cva, setColor, getColor, vuelessConfig, mergeConfigs } from "../utils/utilUI.js";
15
-
16
- import { cloneDeep, isCSR } from "../utils/utilHelper.js";
14
+ import { cx, cva, setColor, getColor, vuelessConfig, mergeConfigs } from "../utils/ui.ts";
15
+ import { cloneDeep, isCSR } from "../utils/helper.ts";
17
16
  import {
18
17
  STRATEGY_TYPE,
19
18
  CVA_CONFIG_KEY,
@@ -21,6 +20,27 @@ import {
21
20
  NESTED_COMPONENT_REG_EXP,
22
21
  } from "../constants.js";
23
22
 
23
+ import type { ComponentInternalInstance, Slot, VNode, ComputedRef } from "vue";
24
+ import type {
25
+ BrandColors,
26
+ Strategies,
27
+ UnknownObject,
28
+ VueAttrs,
29
+ Component,
30
+ NestedComponent,
31
+ ComponentNames,
32
+ CVA,
33
+ KeyAttrs,
34
+ KeysToExtend,
35
+ } from "../types.ts";
36
+
37
+ interface MergedConfigOptions {
38
+ defaultConfig: Component;
39
+ globalConfig: Component;
40
+ propsConfig?: Component;
41
+ vuelessStrategy?: Strategies;
42
+ }
43
+
24
44
  /**
25
45
  * Merging component configs in a given sequence (bigger number = bigger priority):
26
46
  * 1. Default component config
@@ -28,21 +48,28 @@ import {
28
48
  * 3. Component config (:config="{...}" props)
29
49
  * 4. Component classes (class="...")
30
50
  */
31
- export default function useUI(defaultConfig = {}, propsConfigGetter = null, topLevelClassKey) {
32
- const { type, props } = getCurrentInstance();
33
- const componentName = type.__name;
34
- const globalConfig = vuelessConfig.component ? vuelessConfig.component[componentName] : {};
51
+ export default function useUI<T>(
52
+ defaultConfig: T & Component,
53
+ propsConfigGetter?: () => (T & Component) | undefined,
54
+ topLevelClassKey?: string,
55
+ ) {
56
+ const { type, props } = getCurrentInstance() as ComponentInternalInstance;
57
+ const componentName = type.__name as ComponentNames;
58
+ const globalConfig = vuelessConfig?.component?.[componentName] || {};
35
59
 
36
60
  const isStrategyValid =
37
61
  vuelessConfig.strategy && Object.values(STRATEGY_TYPE).includes(vuelessConfig.strategy);
38
- const vuelessStrategy = isStrategyValid ? vuelessConfig.strategy : STRATEGY_TYPE.merge;
39
62
 
40
- const [firstClassKey] = Object.keys(defaultConfig);
41
- const config = ref({});
63
+ const vuelessStrategy = isStrategyValid
64
+ ? (vuelessConfig.strategy as Strategies)
65
+ : (STRATEGY_TYPE.merge as Strategies);
66
+
67
+ const firstClassKey = defaultConfig ? Object.keys(defaultConfig)[0] : "";
68
+ const config = ref({} as T);
42
69
  const attrs = useAttrs();
43
70
 
44
71
  watchEffect(() => {
45
- const propsConfig = propsConfigGetter && propsConfigGetter();
72
+ const propsConfig = propsConfigGetter ? propsConfigGetter() : {};
46
73
 
47
74
  const mergedConfig = getMergedConfig({
48
75
  defaultConfig,
@@ -56,29 +83,27 @@ export default function useUI(defaultConfig = {}, propsConfigGetter = null, topL
56
83
 
57
84
  /**
58
85
  * Get classes by given key (including CVA if config set).
59
- * @param {string} key
60
- * @param {Object} mutatedProps
61
- * @returns {ComputedRef | String}
62
86
  */
63
- function getClasses(key, mutatedProps = {}) {
87
+ function getClasses(key: string, mutatedProps: UnknownObject): ComputedRef<string> {
64
88
  return computed(() => {
65
- const color = toValue(mutatedProps)?.color || props.color;
89
+ const color = (toValue(mutatedProps)?.color as BrandColors) || props?.color;
90
+ const value = config.value[key] as (CVA & NestedComponent) | string;
66
91
 
67
- let value = config.value[key];
92
+ let classes = "";
68
93
 
69
- if (isCVA(value)) {
70
- value = cva(value)({
94
+ if (typeof value === "object" && isCVA(value)) {
95
+ classes = cva(value)({
71
96
  ...props,
72
97
  ...toValue(mutatedProps),
73
- color: color ? getColor(color) : null,
98
+ ...(color ? { color: getColor(color) } : {}),
74
99
  });
75
- } else if (value.component) {
76
- // If the value of the key contains keys related to the nested component, it should be skipped.
77
- // Probably this should be fixed later to be possible to extend key with nested component keys.
78
- return "";
79
100
  }
80
101
 
81
- return color ? setColor(value, color) : value;
102
+ if (typeof value === "string") {
103
+ classes = value;
104
+ }
105
+
106
+ return color ? setColor(classes, color) : classes;
82
107
  });
83
108
  }
84
109
 
@@ -86,12 +111,9 @@ export default function useUI(defaultConfig = {}, propsConfigGetter = null, topL
86
111
  * Get an object where:
87
112
  * – key: extendingKey
88
113
  * – value: reactive string of extendingKey classes.
89
- * @param {Array} extendingKeys
90
- * @param {Object} mutatedProps
91
- * @returns {Object}
92
114
  */
93
- function getExtendingKeysClasses(extendingKeys, mutatedProps = {}) {
94
- const extendingClasses = {};
115
+ function getExtendingKeysClasses(extendingKeys: string[], mutatedProps = {}) {
116
+ const extendingClasses: UnknownObject = {};
95
117
 
96
118
  for (const key of extendingKeys) {
97
119
  extendingClasses[key] = getClasses(key, mutatedProps);
@@ -104,25 +126,23 @@ export default function useUI(defaultConfig = {}, propsConfigGetter = null, topL
104
126
  * Get an object where:
105
127
  * – key: elementKey
106
128
  * – value: reactive object of string element attributes (with classes).
107
- * @param mutatedProps
108
- * @param extendingKeys
109
- * @param keysToExtendConfig
110
- * @returns {Object}
111
129
  */
112
- function getKeysAttrs(mutatedProps = {}, extendingKeys = [], keysToExtendConfig = {}) {
130
+ function getKeysAttrs(
131
+ mutatedProps = {},
132
+ extendingKeys: string[] = [],
133
+ keysToExtendConfig: Record<string, KeysToExtend> = {},
134
+ ) {
113
135
  const keysToExtend = Object.keys(keysToExtendConfig);
114
- const keysAttrs = {};
136
+ const keysAttrs: UnknownObject = {};
115
137
 
116
138
  for (const key in defaultConfig) {
117
139
  if (isSystemKey(key) || extendingKeys.includes(key)) continue;
118
140
 
119
- keysAttrs[`${key}Attrs`] = getAttrs(key, {
120
- classes: getClasses(key, mutatedProps),
121
- });
141
+ keysAttrs[`${key}Attrs`] = getAttrs(key, getClasses(key, mutatedProps));
122
142
 
123
143
  if (keysToExtend.includes(key)) {
124
144
  const { base, extend } = keysToExtendConfig[key];
125
- const keyAttrs = keysAttrs[`${key}Attrs`];
145
+ const keyAttrs = keysAttrs[`${key}Attrs`] as ComputedRef<KeyAttrs>;
126
146
 
127
147
  keysAttrs[`${key}Attrs`] = computed(() => ({
128
148
  ...keyAttrs.value,
@@ -140,22 +160,19 @@ export default function useUI(defaultConfig = {}, propsConfigGetter = null, topL
140
160
 
141
161
  /**
142
162
  * Get an element attributes for a given key.
143
- * @param {String} configKey
144
- * @param {Object} options with classes
145
- * @returns {Object} element attributes
146
163
  */
147
- function getAttrs(configKey, options) {
148
- const nestedComponent = getNestedComponent(defaultConfig[configKey]);
164
+ function getAttrs(configKey: string, classes: ComputedRef) {
165
+ const nestedComponent = getNestedComponent(defaultConfig[configKey] || "");
149
166
 
150
167
  const attrs = useAttrs();
151
168
  const isDev = isCSR && import.meta.env?.DEV;
152
169
  const vuelessAttrs = ref({});
153
170
  const isTopLevelKey = (topLevelClassKey || firstClassKey) === configKey;
154
171
 
155
- const commonAttrs = {
172
+ const commonAttrs: KeyAttrs = {
156
173
  ...(isTopLevelKey ? attrs : {}),
157
- "vl-component": isDev ? attrs["vl-component"] || componentName || null : null,
158
- "vl-key": isDev ? attrs["vl-config-key"] || configKey || null : null,
174
+ "vl-component": isDev ? (attrs["vl-component"] as string) || componentName || null : null,
175
+ "vl-key": isDev ? (attrs["vl-config-key"] as string) || configKey || null : null,
159
176
  "vl-child-component":
160
177
  isDev && attrs["vl-component"] ? nestedComponent || componentName : null,
161
178
  "vl-child-key": isDev && attrs["vl-component"] ? configKey : null,
@@ -166,28 +183,26 @@ export default function useUI(defaultConfig = {}, propsConfigGetter = null, topL
166
183
 
167
184
  watch(config, updateVuelessAttrs, { immediate: true });
168
185
  watch(props, updateVuelessAttrs);
169
- options?.classes?.value && watch(options?.classes, updateVuelessAttrs);
186
+
187
+ if (classes?.value) {
188
+ watch(classes, updateVuelessAttrs);
189
+ }
170
190
 
171
191
  function updateVuelessAttrs() {
172
- const configKeyValue = config.value[configKey];
192
+ const configKeyValue = config.value[configKey] as Component | string;
173
193
  const isObject = typeof configKeyValue === "object";
174
194
 
175
195
  const configAttrs = {
176
196
  config: configKeyValue,
177
- ...configKeyValue?.defaults,
197
+ ...(isObject ? configKeyValue.defaults : {}),
178
198
  };
179
199
 
180
200
  const isTopLevelClassKey = configKey === (topLevelClassKey || firstClassKey);
181
201
  const attrClass = isTopLevelClassKey && !nestedComponent ? attrs.class : "";
182
202
 
183
- // TODO: remove `getBaseClasses(configKeyValue)` after migration of all composables to the new logic
184
203
  vuelessAttrs.value = {
185
204
  ...commonAttrs,
186
- class: cx([
187
- getBaseClasses(configKeyValue),
188
- getBaseClasses(toValue(options?.classes)),
189
- attrClass,
190
- ]),
205
+ class: cx([getBaseClasses(toValue(classes)), attrClass]),
191
206
  ...((isObject && configAttrs) || {}),
192
207
  };
193
208
  }
@@ -199,61 +214,59 @@ export default function useUI(defaultConfig = {}, propsConfigGetter = null, topL
199
214
  config,
200
215
  setColor,
201
216
  getColor,
202
- getAttrs,
203
217
  getKeysAttrs,
204
218
  getExtendingKeysClasses,
205
- isCVA,
206
- isSystemKey,
207
219
  hasSlotContent,
208
220
  };
209
221
  }
210
222
 
211
223
  /**
212
224
  * Get merged config based on config merging strategy.
213
- * @param {Object} defaultConfig
214
- * @param {Object} globalConfig
215
- * @param {Object} propsConfig
216
- * @param {string} vuelessStrategy - vueless top level merge strategy.
217
- *
218
- * @returns {Object}
219
225
  */
220
- function getMergedConfig({ defaultConfig, globalConfig, propsConfig, vuelessStrategy }) {
221
- defaultConfig = cloneDeep(defaultConfig);
222
-
226
+ function getMergedConfig({
227
+ defaultConfig,
228
+ globalConfig,
229
+ propsConfig,
230
+ vuelessStrategy,
231
+ }: MergedConfigOptions) {
232
+ defaultConfig = cloneDeep(defaultConfig) as Component;
233
+
234
+ let mergedConfig: Component = {};
223
235
  const strategy =
224
236
  !globalConfig && !propsConfig
225
237
  ? STRATEGY_TYPE.merge
226
238
  : propsConfig?.strategy || globalConfig?.strategy || vuelessStrategy;
227
239
 
228
240
  if (strategy === STRATEGY_TYPE.merge) {
229
- return mergeConfigs({ defaultConfig, globalConfig, propsConfig });
241
+ mergedConfig = mergeConfigs({ defaultConfig, globalConfig, propsConfig });
230
242
  }
231
243
 
232
244
  if (strategy === STRATEGY_TYPE.replace) {
233
- return mergeConfigs({ defaultConfig, globalConfig, propsConfig, isReplace: true });
245
+ mergedConfig = mergeConfigs({ defaultConfig, globalConfig, propsConfig, isReplace: true });
234
246
  }
235
247
 
236
248
  if (strategy === STRATEGY_TYPE.overwrite) {
237
249
  const isGlobalConfig = globalConfig && Object.keys(globalConfig).length;
238
250
  const isPropsConfig = propsConfig && Object.keys(propsConfig).length;
239
251
 
240
- return isPropsConfig ? propsConfig : isGlobalConfig ? globalConfig : defaultConfig;
252
+ mergedConfig = isPropsConfig ? propsConfig : isGlobalConfig ? globalConfig : defaultConfig;
241
253
  }
254
+
255
+ return mergedConfig;
242
256
  }
243
257
 
244
258
  /**
245
259
  * Merge component classes from "class" attribute into final config.
246
- * @param {Object} config
247
- * @param {Object} attrs
248
- * @param {string} topLevelClassKey
249
- *
250
- * @returns {Object}
251
260
  */
252
- function mergeClassesIntoConfig(config, topLevelClassKey, attrs) {
253
- if (typeof config[topLevelClassKey] === "object") {
254
- config[topLevelClassKey].base = cx([config[topLevelClassKey]?.base, attrs.class]);
261
+ function mergeClassesIntoConfig(config: Component, topLevelClassKey: string, attrs: VueAttrs) {
262
+ const configTopKey = config[topLevelClassKey];
263
+
264
+ if (typeof configTopKey === "object") {
265
+ (configTopKey as CVA).base = cx([(configTopKey as CVA)?.base, attrs.class]);
266
+
267
+ config[topLevelClassKey] = configTopKey;
255
268
  } else {
256
- config[topLevelClassKey] = cx([config[topLevelClassKey], attrs.class]);
269
+ config[topLevelClassKey] = cx([configTopKey, attrs.class]);
257
270
  }
258
271
 
259
272
  return config;
@@ -261,33 +274,28 @@ function mergeClassesIntoConfig(config, topLevelClassKey, attrs) {
261
274
 
262
275
  /**
263
276
  * Return base classes.
264
- * @param { String | Object } value
265
- * @returns { String }
266
277
  */
267
- function getBaseClasses(value) {
268
- return typeof value === "object" ? value.base || "" : value || "";
278
+ function getBaseClasses(value: string | CVA | NestedComponent) {
279
+ return typeof value === "object" ? (value.base as string) || "" : value || "";
269
280
  }
270
281
 
271
282
  /**
272
283
  * Check is config key contains component name and if contains return it.
273
- * @param { String | Object } value
274
- * @returns { String }
275
284
  */
276
- function getNestedComponent(value) {
285
+ function getNestedComponent(value: string | NestedComponent | CVA) {
277
286
  const classes = getBaseClasses(value);
278
- const component = value?.component || "";
287
+ const component = (value as NestedComponent)?.component as ComponentNames;
288
+
279
289
  const match =
280
- classes.match(NESTED_COMPONENT_REG_EXP) || component.match(NESTED_COMPONENT_REG_EXP);
290
+ classes.match(NESTED_COMPONENT_REG_EXP) || component?.match(NESTED_COMPONENT_REG_EXP);
281
291
 
282
292
  return match ? match[1] : "";
283
293
  }
284
294
 
285
295
  /**
286
296
  * Check is config key not contains classes or CVA config object.
287
- * @param { String } key
288
- * @returns { Boolean }
289
297
  */
290
- function isSystemKey(key) {
298
+ function isSystemKey(key: string): boolean {
291
299
  const isExactKey = Object.values(SYSTEM_CONFIG_KEY).some((value) => value === key);
292
300
 
293
301
  return isExactKey || key.toLowerCase().includes(SYSTEM_CONFIG_KEY.transition.toLowerCase());
@@ -295,12 +303,8 @@ function isSystemKey(key) {
295
303
 
296
304
  /**
297
305
  * Check is config contains default CVA keys.
298
- * @param { Object | String } config
299
- * @returns { Boolean }
300
306
  */
301
- function isCVA(config) {
302
- if (typeof config !== "object") return false;
303
-
307
+ function isCVA(config: UnknownObject): boolean {
304
308
  return Object.values(CVA_CONFIG_KEY).some((value) =>
305
309
  Object.keys(config).some((key) => key === value),
306
310
  );
@@ -308,15 +312,15 @@ function isCVA(config) {
308
312
 
309
313
  /**
310
314
  * Check if slot defined, and have a content.
311
- * @param slot
312
- * @param props
313
- *
314
- * @returns {boolean}
315
315
  */
316
- function hasSlotContent(slot, props = {}) {
317
- const asArray = (arg) => (Array.isArray(arg) ? arg : arg != null ? [arg] : []);
316
+ export function hasSlotContent(slot: Slot | undefined | null, props = {}): boolean {
317
+ type Args = VNode | VNode[] | undefined | null;
318
+
319
+ const asArray = (arg: Args) => {
320
+ return Array.isArray(arg) ? arg : arg != null ? [arg] : [];
321
+ };
318
322
 
319
- const isVNodeEmpty = (vnode) => {
323
+ const isVNodeEmpty = (vnode: Args) => {
320
324
  return (
321
325
  !vnode ||
322
326
  asArray(vnode).every(
package/constants.js CHANGED
@@ -1,3 +1,8 @@
1
+ /**
2
+ * The file has `.js` extension to support both node and browser scripts without a file transpilation.
3
+ * Please do not change the extension if you do not fully understand the consequences.
4
+ */
5
+
1
6
  /* Custom Vueless colors */
2
7
  export const BRAND_COLOR = "brand";
3
8
  export const GRAY_COLOR = "gray";
@@ -14,14 +19,13 @@ export const DEFAULT_GRAY_COLOR = COOL_COLOR;
14
19
  export const DEFAULT_RING = 4; /* pixels */
15
20
  export const DEFAULT_RING_OFFSET = 0; /* pixels */
16
21
  export const DEFAULT_RING_OFFSET_COLOR_LIGHT = "#ffffff"; // white
17
- export const DEFAULT_RING_OFFSET_COLOR_DARK = "#4b5563"; // gray-600
22
+ export const DEFAULT_RING_OFFSET_COLOR_DARK = "#1f2937"; // gray-800
18
23
  export const DEFAULT_ROUNDING = 8; /* pixels */
19
24
 
20
25
  /* Vueless supported colors and shades */
21
26
  export const COLOR_SHADES = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950];
22
27
  export const GRAY_COLORS = ["slate", COOL_COLOR, "zinc", "neutral", "stone"];
23
28
  export const BRAND_COLORS = [
24
- GRAYSCALE_COLOR,
25
29
  "red",
26
30
  "orange",
27
31
  "amber",
@@ -61,12 +65,130 @@ export const SYSTEM_CONFIG_KEY = {
61
65
  i18n: "i18n",
62
66
  defaults: "defaults",
63
67
  strategy: "strategy",
68
+ safelist: "safelist",
64
69
  component: "component",
65
70
  transition: "transition",
66
71
  safelistColors: "safelistColors",
67
72
  ...CVA_CONFIG_KEY,
68
73
  };
69
74
 
75
+ /* Component to folder mapping. */
76
+ export const COMPONENTS = {
77
+ /* Buttons & Links */
78
+ UButton: "ui.button",
79
+ ULink: "ui.button-link",
80
+ UToggle: "ui.button-toggle",
81
+ UToggleItem: "ui.button-toggle-item",
82
+
83
+ /* Dropdowns */
84
+ UDropdownButton: "ui.dropdown-button",
85
+ UDropdownBadge: "ui.dropdown-badge",
86
+ UDropdownLink: "ui.dropdown-link",
87
+ UDropdownList: "ui.dropdown-list",
88
+
89
+ /* Form Inputs & Controls */
90
+ UInput: "ui.form-input",
91
+ UInputFile: "ui.form-input-file",
92
+ UInputMoney: "ui.form-input-money",
93
+ UInputSearch: "ui.form-input-search",
94
+ UInputNumber: "ui.form-input-number",
95
+ UInputRating: "ui.form-input-rating",
96
+ UTextarea: "ui.form-textarea",
97
+ USelect: "ui.form-select",
98
+ UCheckbox: "ui.form-checkbox",
99
+ UCheckboxGroup: "ui.form-checkbox-group",
100
+ UCheckboxMultiState: "ui.form-checkbox-multi-state",
101
+ USwitch: "ui.form-switch",
102
+ URadio: "ui.form-radio",
103
+ URadioGroup: "ui.form-radio-group",
104
+ UCalendar: "ui.form-calendar",
105
+ UDatePicker: "ui.form-date-picker",
106
+ UDatePickerRange: "ui.form-date-picker-range",
107
+ ULabel: "ui.form-label",
108
+ UColorPicker: "ui.form-color-picker",
109
+
110
+ /* Text & Content */
111
+ UHeader: "ui.text-header",
112
+ UText: "ui.text-block",
113
+ UAlert: "ui.text-alert",
114
+ UNotify: "ui.text-notify",
115
+ UMoney: "ui.text-money",
116
+ UFile: "ui.text-file",
117
+ UFiles: "ui.text-files",
118
+ UEmpty: "ui.text-empty",
119
+ UBadge: "ui.text-badge",
120
+
121
+ /* Containers */
122
+ UDivider: "ui.container-divider",
123
+ UCol: "ui.container-col",
124
+ URow: "ui.container-row",
125
+ UGroup: "ui.container-group",
126
+ UAccordion: "ui.container-accordion",
127
+ UCard: "ui.container-card",
128
+ UModal: "ui.container-modal",
129
+ UModalConfirm: "ui.container-modal-confirm",
130
+ UPage: "ui.container-page",
131
+
132
+ /* Images and Icons */
133
+ UIcon: "ui.image-icon",
134
+ UAvatar: "ui.image-avatar",
135
+
136
+ /* Data */
137
+ UTable: "ui.data-table",
138
+ UDataList: "ui.data-list",
139
+
140
+ /* Navigation */
141
+ UTab: "ui.navigation-tab",
142
+ UTabs: "ui.navigation-tabs",
143
+ UProgress: "ui.navigation-progress",
144
+ UPagination: "ui.navigation-pagination",
145
+
146
+ /* Loaders and Skeletons */
147
+ ULoader: "ui.loader",
148
+ ULoaderProgress: "ui.loader-progress",
149
+ ULoaderOverlay: "ui.loader-overlay",
150
+
151
+ /* Other */
152
+ UDot: "ui.other-dot",
153
+ };
154
+
155
+ /* Extending Tailwind Merge by vueless custom tailwind classes. */
156
+ export const TAILWIND_MERGE_EXTENSION = {
157
+ extend: {
158
+ theme: {
159
+ spacing: ["safe-top", "safe-bottom", "safe-left", "safe-right"],
160
+ },
161
+ classGroups: {
162
+ "ring-w": [{ ring: ["dynamic"] }],
163
+ "ring-offset-w": [{ "ring-offset": ["dynamic"] }],
164
+ "ring-offset-color": [{ "ring-offset": ["color-dynamic"] }],
165
+ "font-size": [{ text: ["2xs"] }],
166
+ rounded: [{ rounded: ["dynamic"] }],
167
+ },
168
+ },
169
+ };
170
+
171
+ /* SVGO config for preparing SVG icons. */
172
+ export const DEFAULT_SVGO_CONFIG = {
173
+ plugins: [
174
+ {
175
+ name: "preset-default",
176
+ params: {
177
+ overrides: {
178
+ removeViewBox: false,
179
+ convertColors: {
180
+ currentColor: true,
181
+ },
182
+ },
183
+ },
184
+ },
185
+ ],
186
+ };
187
+
70
188
  /* Other */
71
189
  export const PX_IN_REM = 16;
72
190
  export const NESTED_COMPONENT_REG_EXP = /\{U[^}]*}/g;
191
+ export const DYNAMIC_COLOR_PATTERN = "{color}";
192
+ export const TAILWIND_CLASS_DELIMITER = ":";
193
+ export const CACHE_PATH = "node_modules/.cache/vueless";
194
+ export const VUELESS_CONFIG_FILE_NAME = "vueless.config";
@@ -1,6 +1,6 @@
1
1
  import { Meta, Title, Subtitle, Description, Primary, Controls, Stories, Source } from "@storybook/blocks";
2
2
 
3
- import * as stories from "./stories.js";
3
+ import * as stories from "./stories.ts";
4
4
 
5
5
  <Meta of={stories} />
6
6
  <Title of={stories} />
@@ -1,11 +1,12 @@
1
- import { getArgTypes } from "../../../utils/utilStorybook.js";
1
+ import type { Meta } from "@storybook/vue3";
2
+ import { getArgTypes } from "../../../utils/storybook.ts";
2
3
 
3
4
  import { ref, computed, onMounted, useTemplateRef } from "vue";
4
5
 
5
6
  import UAlert from "../../../ui.text-alert/UAlert.vue";
6
7
  import UButton from "../../../ui.button/UButton.vue";
7
8
  import UCalendar from "../../../ui.form-calendar/UCalendar.vue";
8
- import clickOutside from "../vClickOutside.js";
9
+ import clickOutside from "../vClickOutside.ts";
9
10
 
10
11
  /**
11
12
  * The `v-click-outside` directive. | [View on GitHub](https://github.com/vuelessjs/vueless/tree/main/src/directives/clickOutside)
@@ -17,10 +18,10 @@ export default {
17
18
  args: {},
18
19
  argTypes: {
19
20
  ...getArgTypes(UButton.__name),
20
- },
21
+ } as Meta,
21
22
  };
22
23
 
23
- const DefaultTemplate = (args) => ({
24
+ const DefaultTemplate = () => ({
24
25
  components: { UButton, UCalendar, UAlert },
25
26
  directives: { clickOutside },
26
27
  setup() {
@@ -39,7 +40,7 @@ const DefaultTemplate = (args) => ({
39
40
  isShownCalendar.value = false;
40
41
  }
41
42
 
42
- return { args, date, isShownCalendar, buttonLabel, toggleCalendar, closeCalendar };
43
+ return { date, isShownCalendar, buttonLabel, toggleCalendar, closeCalendar };
43
44
  },
44
45
  template: `
45
46
  <UButton :label="buttonLabel" @click="toggleCalendar" v-click-outside="closeCalendar" />
@@ -54,7 +55,7 @@ const DefaultTemplate = (args) => ({
54
55
  `,
55
56
  });
56
57
 
57
- const SettingsTemplate = (args) => ({
58
+ const SettingsTemplate = () => ({
58
59
  components: { UButton, UCalendar, UAlert },
59
60
  directives: { clickOutside },
60
61
  setup() {
@@ -80,7 +81,6 @@ const SettingsTemplate = (args) => ({
80
81
  }
81
82
 
82
83
  return {
83
- args,
84
84
  date,
85
85
  isShownCalendar,
86
86
  buttonLabel,
@@ -105,7 +105,5 @@ const SettingsTemplate = (args) => ({
105
105
  });
106
106
 
107
107
  export const Default = DefaultTemplate.bind({});
108
- Default.args = {};
109
108
 
110
109
  export const Settings = SettingsTemplate.bind({});
111
- Settings.args = {};
@@ -0,0 +1,22 @@
1
+ import type { DirectiveBinding } from "vue";
2
+ import type { TemplateRefElement } from "../../types.ts";
3
+
4
+ export type RemoveEvents = () => void;
5
+ export type ClickCallback = (event: MouseEvent) => void;
6
+
7
+ export interface ClickOutsideOptions {
8
+ capture?: boolean;
9
+ ignore?: TemplateRefElement[];
10
+ }
11
+
12
+ export interface DirectiveBindingCallback extends DirectiveBinding {
13
+ value: ClickCallback;
14
+ }
15
+
16
+ export interface DirectiveBindingOptions extends DirectiveBinding {
17
+ value: [ClickCallback, ClickOutsideOptions];
18
+ }
19
+
20
+ export interface ClickOutsideTargetElement extends HTMLElement {
21
+ _clickOutsideRemove: (...args: unknown[]) => unknown;
22
+ }