vueless 0.0.555 → 0.0.556

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 (103) hide show
  1. package/composables/useUI.ts +11 -78
  2. package/constants.js +19 -1
  3. package/index.d.ts +8 -1
  4. package/index.ts +1 -1
  5. package/package.json +1 -1
  6. package/types.ts +4 -10
  7. package/ui.button/UButton.vue +21 -7
  8. package/ui.button-link/ULink.vue +14 -2
  9. package/ui.button-link/config.ts +6 -1
  10. package/ui.button-link/useAttrs.ts +8 -39
  11. package/ui.button-toggle/useAttrs.ts +2 -8
  12. package/ui.button-toggle-item/config.ts +9 -11
  13. package/ui.button-toggle-item/useAttrs.ts +4 -18
  14. package/ui.container-accordion/config.ts +3 -1
  15. package/ui.container-accordion/useAttrs.ts +6 -17
  16. package/ui.container-card/UCard.vue +2 -1
  17. package/ui.container-card/useAttrs.ts +2 -8
  18. package/ui.container-col/useAttrs.ts +2 -8
  19. package/ui.container-divider/useAttrs.ts +2 -8
  20. package/ui.container-group/useAttrs.ts +2 -8
  21. package/ui.container-groups/useAttrs.ts +2 -8
  22. package/ui.container-modal/UModal.vue +1 -1
  23. package/ui.container-modal/useAttrs.ts +2 -12
  24. package/ui.container-modal-confirm/UModalConfirm.vue +3 -7
  25. package/ui.container-modal-confirm/useAttrs.ts +2 -8
  26. package/ui.container-page/UPage.vue +4 -5
  27. package/ui.container-page/useAttrs.ts +3 -32
  28. package/ui.container-row/useAttrs.ts +2 -8
  29. package/ui.data-list/UDataList.vue +3 -2
  30. package/ui.data-list/config.js +1 -1
  31. package/ui.data-list/useAttrs.js +2 -18
  32. package/ui.data-table/UTable.vue +6 -6
  33. package/ui.data-table/UTableRow.vue +1 -5
  34. package/ui.data-table/config.ts +28 -13
  35. package/ui.data-table/useAttrs.ts +10 -75
  36. package/ui.dropdown-badge/config.ts +10 -2
  37. package/ui.dropdown-badge/useAttrs.ts +8 -21
  38. package/ui.dropdown-button/config.ts +6 -6
  39. package/ui.dropdown-button/useAttrs.ts +6 -19
  40. package/ui.dropdown-link/config.ts +8 -2
  41. package/ui.dropdown-link/useAttrs.ts +10 -20
  42. package/ui.dropdown-list/config.ts +3 -2
  43. package/ui.dropdown-list/useAttrs.ts +2 -25
  44. package/ui.form-calendar/useAttrs.ts +2 -8
  45. package/ui.form-checkbox/useAttrs.ts +2 -8
  46. package/ui.form-checkbox-group/useAttrs.ts +2 -8
  47. package/ui.form-checkbox-multi-state/useAttrs.ts +2 -6
  48. package/ui.form-color-picker/useAttrs.js +2 -8
  49. package/ui.form-date-picker/useAttrs.ts +2 -6
  50. package/ui.form-date-picker-range/UDatePickerRange.vue +28 -28
  51. package/ui.form-date-picker-range/config.ts +30 -16
  52. package/ui.form-date-picker-range/useAttrs.ts +9 -70
  53. package/ui.form-input/UInput.vue +1 -1
  54. package/ui.form-input/useAttrs.js +2 -8
  55. package/ui.form-input-file/UInputFile.vue +3 -4
  56. package/ui.form-input-file/useAttrs.js +2 -8
  57. package/ui.form-input-money/useAttrs.js +2 -8
  58. package/ui.form-input-number/useAttrs.js +2 -8
  59. package/ui.form-input-rating/UInputRating.vue +5 -11
  60. package/ui.form-input-rating/useAttrs.js +2 -8
  61. package/ui.form-input-search/useAttrs.js +2 -8
  62. package/ui.form-label/useAttrs.js +2 -8
  63. package/ui.form-radio/useAttrs.ts +2 -8
  64. package/ui.form-radio-group/useAttrs.ts +2 -8
  65. package/ui.form-select/USelect.vue +37 -38
  66. package/ui.form-select/config.js +30 -11
  67. package/ui.form-select/useAttrs.js +6 -50
  68. package/ui.form-switch/useAttrs.js +2 -8
  69. package/ui.form-textarea/UTextarea.vue +5 -9
  70. package/ui.form-textarea/useAttrs.js +2 -8
  71. package/ui.image-avatar/useAttrs.ts +2 -8
  72. package/ui.image-icon/useAttrs.ts +2 -8
  73. package/ui.loader/config.ts +4 -1
  74. package/ui.loader/useAttrs.ts +2 -17
  75. package/ui.loader-overlay/useAttrs.ts +2 -12
  76. package/ui.loader-progress/ULoaderProgress.vue +2 -2
  77. package/ui.loader-progress/config.ts +8 -2
  78. package/ui.loader-progress/types.ts +5 -0
  79. package/ui.loader-progress/useAttrs.ts +3 -27
  80. package/ui.navigation-pagination/config.ts +6 -6
  81. package/ui.navigation-pagination/useAttrs.ts +2 -34
  82. package/ui.navigation-progress/config.ts +3 -1
  83. package/ui.navigation-progress/useAttrs.ts +5 -17
  84. package/ui.navigation-tab/config.ts +3 -1
  85. package/ui.navigation-tab/useAttrs.ts +4 -18
  86. package/ui.navigation-tabs/useAttrs.ts +2 -8
  87. package/ui.other-dot/useAttrs.ts +2 -8
  88. package/ui.text-alert/UAlert.vue +2 -1
  89. package/ui.text-alert/useAttrs.ts +2 -8
  90. package/ui.text-badge/useAttrs.ts +3 -8
  91. package/ui.text-block/UText.vue +2 -1
  92. package/ui.text-block/useAttrs.ts +2 -8
  93. package/ui.text-empty/useAttrs.ts +2 -8
  94. package/ui.text-file/useAttrs.ts +2 -8
  95. package/ui.text-files/useAttrs.ts +2 -8
  96. package/ui.text-header/useAttrs.ts +2 -8
  97. package/ui.text-money/UMoney.vue +1 -1
  98. package/ui.text-money/useAttrs.ts +2 -8
  99. package/ui.text-notify/useAttrs.ts +2 -8
  100. package/utils/helper.ts +29 -0
  101. package/utils/ui.ts +0 -2
  102. package/web-types.json +17 -1
  103. package/ui.button/useAttrs.ts +0 -26
@@ -1,15 +1,4 @@
1
- import {
2
- ref,
3
- watch,
4
- watchEffect,
5
- getCurrentInstance,
6
- toValue,
7
- useAttrs,
8
- Comment,
9
- Text,
10
- Fragment,
11
- computed,
12
- } from "vue";
1
+ import { ref, watch, watchEffect, getCurrentInstance, toValue, useAttrs, computed } from "vue";
13
2
 
14
3
  import { cx, cva, setColor, getColor, vuelessConfig, getMergedConfig } from "../utils/ui.ts";
15
4
  import { isCSR } from "../utils/helper.ts";
@@ -21,7 +10,7 @@ import {
21
10
  EXTENDS_PATTERN_REG_EXP,
22
11
  } from "../constants.js";
23
12
 
24
- import type { ComponentInternalInstance, Slot, VNode, ComputedRef } from "vue";
13
+ import type { ComponentInternalInstance, ComputedRef } from "vue";
25
14
  import type {
26
15
  BrandColors,
27
16
  Strategies,
@@ -31,8 +20,8 @@ import type {
31
20
  ComponentNames,
32
21
  CVA,
33
22
  KeyAttrs,
34
- KeysToExtend,
35
23
  ExtendedKeyClasses,
24
+ KeysAttrs,
36
25
  } from "../types.ts";
37
26
 
38
27
  /**
@@ -78,6 +67,7 @@ export default function useUI<T>(
78
67
  */
79
68
  function getClasses(key: string, mutatedProps: UnknownObject): ComputedRef<string> {
80
69
  return computed(() => {
70
+ const mutatedPropsValue = toValue(mutatedProps);
81
71
  const color = (toValue(mutatedProps)?.color as BrandColors) || props?.color;
82
72
  const value = config.value[key] as (CVA & NestedComponent) | string;
83
73
 
@@ -86,7 +76,7 @@ export default function useUI<T>(
86
76
  if (typeof value === "object" && isCVA(value)) {
87
77
  classes = cva(value)({
88
78
  ...props,
89
- ...toValue(mutatedProps),
79
+ ...mutatedPropsValue,
90
80
  ...(color ? { color: getColor(color) } : {}),
91
81
  });
92
82
  }
@@ -119,49 +109,22 @@ export default function useUI<T>(
119
109
  }
120
110
 
121
111
  /**
122
- * Get an object where:
112
+ * Returns an object where:
123
113
  * – key: elementKey
124
114
  * – value: reactive object of string element attributes (with classes).
125
115
  */
126
- function getKeysAttrs(
127
- mutatedProps = {},
128
- extendingKeys: string[] = [],
129
- keysToExtendConfig: Record<string, KeysToExtend> = {},
130
- ) {
131
- const keysAttrs: UnknownObject = {};
132
-
133
- // TODO: should be removed after migration of all components to the new api.
134
- for (const key in config.value) {
135
- if (isSystemKey(key) || extendingKeys.includes(key)) continue;
136
-
137
- keysAttrs[`${key}Attrs`] = getAttrs(key, getClasses(key, mutatedProps));
138
-
139
- const keysToExtend = Object.keys(keysToExtendConfig);
140
-
141
- if (keysToExtend.includes(key)) {
142
- const { base, extend } = keysToExtendConfig[key];
143
- const keyAttrs = keysAttrs[`${key}Attrs`] as ComputedRef<KeyAttrs>;
144
-
145
- keysAttrs[`${key}Attrs`] = computed(() => ({
146
- ...keyAttrs.value,
147
- class: cx([
148
- ...(Array.isArray(base) ? toValue(base) : [toValue(base)]),
149
- keyAttrs.value.class,
150
- ...(Array.isArray(extend) ? toValue(extend) : [toValue(extend)]),
151
- ]),
152
- }));
153
- }
154
- }
116
+ function getKeysAttrs(mutatedProps = {}): KeysAttrs {
117
+ const keysAttrs: KeysAttrs = {};
155
118
 
156
119
  for (const key in config.value) {
157
120
  if (isSystemKey(key)) continue;
158
121
 
122
+ keysAttrs[`${key}Attrs`] = getAttrs(key, getClasses(key, mutatedProps));
123
+
159
124
  const baseClasses = getBaseClasses(config.value[key]);
160
125
  const extendsMatches = baseClasses.match(EXTENDS_PATTERN_REG_EXP);
161
126
 
162
127
  if (extendsMatches) {
163
- keysAttrs[`${key}Attrs`] = getAttrs(key, getClasses(key, mutatedProps));
164
-
165
128
  // retrieves extends keys from patterns:
166
129
  // Example: `{>someKey} {>someOtherKey}` >>> `["someKey", "someOtherKey"]`.
167
130
  const extendsKeys = extendsMatches.map((pattern) => pattern.slice(2, -1));
@@ -228,12 +191,7 @@ export default function useUI<T>(
228
191
  return vuelessAttrs;
229
192
  }
230
193
 
231
- return {
232
- config,
233
- getKeysAttrs,
234
- getExtendingKeysClasses,
235
- hasSlotContent,
236
- };
194
+ return { config, getKeysAttrs };
237
195
  }
238
196
 
239
197
  /**
@@ -274,28 +232,3 @@ function isCVA(config: UnknownObject): boolean {
274
232
  Object.keys(config).some((key) => key === value),
275
233
  );
276
234
  }
277
-
278
- /**
279
- * Check if slot defined, and have a content.
280
- */
281
- export function hasSlotContent(slot: Slot | undefined | null, props = {}): boolean {
282
- type Args = VNode | VNode[] | undefined | null;
283
-
284
- const asArray = (arg: Args) => {
285
- return Array.isArray(arg) ? arg : arg != null ? [arg] : [];
286
- };
287
-
288
- const isVNodeEmpty = (vnode: Args) => {
289
- return (
290
- !vnode ||
291
- asArray(vnode).every(
292
- (vnode) =>
293
- vnode.type === Comment ||
294
- (vnode.type === Text && !vnode.children?.length) ||
295
- (vnode.type === Fragment && !vnode.children?.length),
296
- )
297
- );
298
- };
299
-
300
- return !isVNodeEmpty(slot?.(props));
301
- }
package/constants.js CHANGED
@@ -154,7 +154,11 @@ export const COMPONENTS = {
154
154
  UDot: "ui.other-dot",
155
155
  };
156
156
 
157
- /* Extending Tailwind Merge by vueless custom tailwind classes. */
157
+ /**
158
+ * Extending Tailwind Merge by vueless custom tailwind classes.
159
+ * All lists of rules available here:
160
+ * https://github.com/dcastil/tailwind-merge/blob/v2.3.0/src/lib/default-config.ts
161
+ */
158
162
  export const TAILWIND_MERGE_EXTENSION = {
159
163
  extend: {
160
164
  theme: {
@@ -166,6 +170,20 @@ export const TAILWIND_MERGE_EXTENSION = {
166
170
  "ring-offset-color": [{ "ring-offset": ["color-dynamic"] }],
167
171
  "font-size": [{ text: ["2xs"] }],
168
172
  rounded: [{ rounded: ["dynamic"] }],
173
+ "rounded-s": [{ "rounded-s": ["dynamic"] }],
174
+ "rounded-e": [{ "rounded-e": ["dynamic"] }],
175
+ "rounded-t": [{ "rounded-t": ["dynamic"] }],
176
+ "rounded-r": [{ "rounded-r": ["dynamic"] }],
177
+ "rounded-b": [{ "rounded-b": ["dynamic"] }],
178
+ "rounded-l": [{ "rounded-l": ["dynamic"] }],
179
+ "rounded-ss": [{ "rounded-ss": ["dynamic"] }],
180
+ "rounded-se": [{ "rounded-se": ["dynamic"] }],
181
+ "rounded-ee": [{ "rounded-ee": ["dynamic"] }],
182
+ "rounded-es": [{ "rounded-es": ["dynamic"] }],
183
+ "rounded-tl": [{ "rounded-tl": ["dynamic"] }],
184
+ "rounded-tr": [{ "rounded-tr": ["dynamic"] }],
185
+ "rounded-br": [{ "rounded-br": ["dynamic"] }],
186
+ "rounded-bl": [{ "rounded-bl": ["dynamic"] }],
169
187
  },
170
188
  },
171
189
  };
package/index.d.ts CHANGED
@@ -2,7 +2,14 @@ import type { App } from "vue";
2
2
  import type { CreateVuelessOptions } from "./types.ts";
3
3
  export { setTheme } from "./utils/theme.ts";
4
4
  export { cx, cva, compose } from "./utils/ui.ts";
5
- export { isSSR, isCSR, getRandomId, setTitle, createDebounce } from "./utils/helper.ts";
5
+ export {
6
+ isSSR,
7
+ isCSR,
8
+ getRandomId,
9
+ setTitle,
10
+ createDebounce,
11
+ hasSlotContent,
12
+ } from "./utils/helper.ts";
6
13
  export { isMac, isPWA, isIOS, isAndroid, isMobileApp, isWindows } from "./utils/platform.ts";
7
14
  export { default as createVueI18nAdapter } from "./adatper.locale/vue-i18n.js";
8
15
  export { default as defaultEnLocale } from "./adatper.locale/locales/en.js";
package/index.ts CHANGED
@@ -9,7 +9,7 @@ import type { CreateVuelessOptions } from './types.ts'
9
9
 
10
10
  export { setTheme } from "./utils/theme.ts";
11
11
  export { cx, cva, compose } from "./utils/ui.ts";
12
- export { isSSR, isCSR, getRandomId, setTitle, createDebounce } from "./utils/helper.ts";
12
+ export { isSSR, isCSR, getRandomId, setTitle, createDebounce, hasSlotContent } from "./utils/helper.ts";
13
13
  export { isMac, isPWA, isIOS, isAndroid, isMobileApp, isWindows } from "./utils/platform.ts";
14
14
  export { default as createVueI18nAdapter } from "./adatper.locale/vue-i18n.js";
15
15
  export { default as defaultEnLocale } from "./adatper.locale/locales/en.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vueless",
3
- "version": "0.0.555",
3
+ "version": "0.0.556",
4
4
  "license": "MIT",
5
5
  "description": "Vue Styleless UI Component Library, powered by Tailwind CSS.",
6
6
  "keywords": [
package/types.ts CHANGED
@@ -1,5 +1,3 @@
1
- import { hasSlotContent } from "./composables/useUI.ts";
2
-
3
1
  import UTextDefaultConfig from "./ui.text-block/config.ts";
4
2
  import UAlertDefaultConfig from "./ui.text-alert/config.ts";
5
3
  import UEmptyDefaultConfig from "./ui.text-empty/config.ts";
@@ -46,7 +44,7 @@ import UCheckboxMultiStateConfig from "./ui.form-checkbox-multi-state/config.ts"
46
44
  import URadioConfig from "./ui.form-radio/config.ts";
47
45
  import URadioGroupConfig from "./ui.form-radio-group/config.ts";
48
46
 
49
- import type { ComputedRef, MaybeRef, Ref } from "vue";
47
+ import type { MaybeRef, Ref } from "vue";
50
48
  import type { Props } from "tippy.js";
51
49
  import type { LocaleOptions } from "./adatper.locale/vueless.ts";
52
50
 
@@ -256,10 +254,11 @@ export interface VueAttrs {
256
254
  value?: string;
257
255
  }
258
256
 
257
+ export type KeysAttrs = Record<string, Ref<UnknownObject | undefined>>;
258
+
259
259
  export interface UseAttrs<TConfig> {
260
- hasSlotContent: typeof hasSlotContent;
261
260
  config: Ref<TConfig | undefined>;
262
- [key: string]: Ref<TConfig | undefined> | typeof hasSlotContent;
261
+ [key: string]: Ref<TConfig | undefined>;
263
262
  }
264
263
 
265
264
  export interface KeyAttrs extends VueAttrs {
@@ -271,11 +270,6 @@ export interface KeyAttrs extends VueAttrs {
271
270
  [key: string]: string | UnknownObject | undefined | null;
272
271
  }
273
272
 
274
- export interface KeysToExtend {
275
- base?: ComputedRef;
276
- extend?: ComputedRef;
277
- }
278
-
279
273
  export interface CreateVuelessOptions {
280
274
  i18n?: LocaleOptions;
281
275
  }
@@ -1,16 +1,18 @@
1
1
  <script setup lang="ts">
2
- import { computed, ref, watchEffect, useId, watch } from "vue";
2
+ import { computed, ref, watchEffect, useId, watch, useSlots } from "vue";
3
3
 
4
+ import useUI from "../composables/useUI.ts";
4
5
  import { useDarkMode } from "../composables/useDarkMode.ts";
6
+ import { hasSlotContent } from "../utils/helper.ts";
5
7
  import { getDefault } from "../utils/ui.ts";
8
+
6
9
  import ULoader from "../ui.loader/ULoader.vue";
7
10
  import UIcon from "../ui.image-icon/UIcon.vue";
8
11
 
9
12
  import defaultConfig from "./config.ts";
10
- import useAttrs from "./useAttrs.ts";
11
13
  import { UButton } from "./constants.ts";
12
14
 
13
- import type { UButtonProps, LoaderSize, IconSize } from "./types.ts";
15
+ import type { UButtonProps, LoaderSize, IconSize, Config } from "./types.ts";
14
16
 
15
17
  defineOptions({ inheritAttrs: false });
16
18
 
@@ -30,13 +32,10 @@ const props = withDefaults(defineProps<UButtonProps>(), {
30
32
  dataTest: "",
31
33
  });
32
34
 
35
+ const slots = useSlots();
33
36
  const elementId = props.id || useId();
34
-
35
37
  const { isDarkMode } = useDarkMode();
36
38
 
37
- const { buttonAttrs, loaderAttrs, leftIconAttrs, rightIconAttrs, centerIconAttrs } =
38
- useAttrs(props);
39
-
40
39
  const buttonRef = ref<HTMLElement | null>(null);
41
40
  const buttonStyle = ref({});
42
41
  const buttonWidth = ref(0);
@@ -102,6 +101,21 @@ defineExpose({
102
101
  */
103
102
  buttonRef,
104
103
  });
104
+
105
+ /**
106
+ * Get element / nested component attributes for each config token ✨
107
+ * Applies: `class`, `config`, redefined default `props` and dev `vl-...` attributes.
108
+ */
109
+ const { getKeysAttrs } = useUI<Config>(defaultConfig, () => props.config);
110
+
111
+ const mutatedProps = computed(() => ({
112
+ leftIcon: Boolean(props.leftIcon) || hasSlotContent(slots["left"]),
113
+ rightIcon: Boolean(props.rightIcon) || hasSlotContent(slots["right"]),
114
+ label: Boolean(props.label),
115
+ }));
116
+
117
+ const { buttonAttrs, loaderAttrs, leftIconAttrs, rightIconAttrs, centerIconAttrs } =
118
+ getKeysAttrs(mutatedProps);
105
119
  </script>
106
120
 
107
121
  <template>
@@ -83,7 +83,17 @@ const { route, isActive, isExactActive } = useLink(useLinkOptions);
83
83
 
84
84
  const wrapperRef = ref(null);
85
85
 
86
- const { wrapperAttrs, linkAttrs } = useAttrs(props, { isActive, isExactActive });
86
+ const { wrapperAttrs, linkAttrs } = useAttrs(props);
87
+
88
+ const wrapperActiveClasses = computed(() => [
89
+ isActive.value && props.wrapperActiveClass,
90
+ isExactActive.value && props.wrapperExactActiveClass,
91
+ ]);
92
+
93
+ const linkActiveClasses = computed(() => [
94
+ isActive.value && props.activeClass,
95
+ isExactActive.value && props.exactActiveClass,
96
+ ]);
87
97
 
88
98
  const targetValue = computed(() => {
89
99
  return props.targetBlank ? "_blank" : "_self";
@@ -129,7 +139,7 @@ defineExpose({
129
139
  </script>
130
140
 
131
141
  <template>
132
- <div v-bind="wrapperAttrs" ref="wrapperRef" tabindex="-1">
142
+ <div v-bind="wrapperAttrs" ref="wrapperRef" :class="wrapperActiveClasses" tabindex="-1">
133
143
  <!-- @slot Use it to add something before the label. -->
134
144
  <slot name="left" />
135
145
 
@@ -138,6 +148,7 @@ defineExpose({
138
148
  :to="route"
139
149
  :target="targetValue"
140
150
  v-bind="linkAttrs"
151
+ :class="linkActiveClasses"
141
152
  :data-test="dataTest"
142
153
  tabindex="0"
143
154
  @blur="onBlur"
@@ -157,6 +168,7 @@ defineExpose({
157
168
  :href="prefixedHref"
158
169
  :target="targetValue"
159
170
  v-bind="linkAttrs"
171
+ :class="linkActiveClasses"
160
172
  :data-test="dataTest"
161
173
  tabindex="0"
162
174
  @blur="onBlur"
@@ -17,6 +17,9 @@ export default /*tw*/ {
17
17
  disabled: {
18
18
  true: "!ring-0 !ring-offset-0 cursor-not-allowed",
19
19
  },
20
+ defaultSlot: {
21
+ true: "flex items-center focus-within:ring-0 focus-within:ring-offset-0",
22
+ },
20
23
  noRing: {
21
24
  true: "!ring-0 !ring-offset-0",
22
25
  },
@@ -59,9 +62,11 @@ export default /*tw*/ {
59
62
  disabled: {
60
63
  true: "text-gray-400 pointer-events-none",
61
64
  },
65
+ defaultSlot: {
66
+ true: "flex items-center no-underline hover:no-underline",
67
+ },
62
68
  },
63
69
  },
64
- linkWithChild: "flex items-center no-underline hover:no-underline focus-within:ring-0 focus-within:ring-offset-0",
65
70
  defaults: {
66
71
  color: "brand",
67
72
  type: "link",
@@ -1,51 +1,20 @@
1
1
  import { computed, useSlots } from "vue";
2
2
  import useUI from "../composables/useUI.ts";
3
+ import { hasSlotContent } from "../utils/helper.ts";
3
4
 
4
5
  import defaultConfig from "./config.ts";
5
6
 
6
- import type { Ref } from "vue";
7
7
  import type { UseAttrs } from "../types.ts";
8
8
  import type { ULinkProps, Config } from "./types.ts";
9
9
 
10
- type ComponentState = {
11
- isActive: Ref<boolean>;
12
- isExactActive: Ref<boolean>;
13
- };
14
-
15
- export default function useAttrs(
16
- props: ULinkProps,
17
- { isActive, isExactActive }: ComponentState,
18
- ): UseAttrs<Config> {
19
- const { config, getKeysAttrs, hasSlotContent, getExtendingKeysClasses } = useUI<Config>(
20
- defaultConfig,
21
- () => props.config,
22
- "link",
23
- );
10
+ export default function useAttrs(props: ULinkProps): UseAttrs<Config> {
11
+ const { config, getKeysAttrs } = useUI<Config>(defaultConfig, () => props.config, "link");
24
12
  const slots = useSlots();
25
13
 
26
- const extendingKeys = ["linkWithChild"];
27
- const extendingKeysClasses = getExtendingKeysClasses(extendingKeys);
28
-
29
- const keysAttrs = getKeysAttrs({}, extendingKeys, {
30
- wrapper: {
31
- extend: computed(() => [
32
- hasSlotContent(slots["default"]) && extendingKeysClasses.linkWithChild.value,
33
- isActive.value && props.wrapperActiveClass,
34
- isExactActive.value && props.wrapperExactActiveClass,
35
- ]),
36
- },
37
- link: {
38
- extend: computed(() => [
39
- hasSlotContent(slots["default"]) && extendingKeysClasses.linkWithChild.value,
40
- isActive.value && props.activeClass,
41
- isExactActive.value && props.exactActiveClass,
42
- ]),
43
- },
44
- });
14
+ const mutatedProps = computed(() => ({
15
+ /* component state, not a props */
16
+ defaultSlot: hasSlotContent(slots["default"]),
17
+ }));
45
18
 
46
- return {
47
- config,
48
- ...keysAttrs,
49
- hasSlotContent,
50
- };
19
+ return { config, ...getKeysAttrs(mutatedProps) };
51
20
  }
@@ -6,13 +6,7 @@ import type { UseAttrs } from "../types.ts";
6
6
  import type { UToggleProps, Config } from "./types.ts";
7
7
 
8
8
  export default function useAttrs(props: UToggleProps): UseAttrs<Config> {
9
- const { config, getKeysAttrs, hasSlotContent } = useUI<Config>(defaultConfig, () => props.config);
9
+ const { config, getKeysAttrs } = useUI<Config>(defaultConfig, () => props.config);
10
10
 
11
- const keysAttrs = getKeysAttrs();
12
-
13
- return {
14
- config,
15
- ...keysAttrs,
16
- hasSlotContent,
17
- };
11
+ return { config, ...getKeysAttrs() };
18
12
  }
@@ -10,7 +10,10 @@ export default /*tw*/ {
10
10
  `,
11
11
  variants: {
12
12
  separated: {
13
- false: "rounded-none",
13
+ false: "rounded-none focus:ring-0",
14
+ },
15
+ selected: {
16
+ false: "relative disabled:z-10",
14
17
  },
15
18
  variant: {
16
19
  thirdary: `
@@ -19,16 +22,11 @@ export default /*tw*/ {
19
22
  `,
20
23
  },
21
24
  },
22
- },
23
- toggleButtonActive: {
24
- base: "relative disabled:z-10",
25
- variants: {
26
- variant: {
27
- primary: "!text-white bg-brand-600 border-brand-600",
28
- secondary: "text-brand-600 border-brand-600 bg-brand-600/10",
29
- thirdary: "!bg-brand-600/20",
30
- },
31
- },
25
+ compoundVariants: [
26
+ { selected: true, variant: "primary", class: "!text-white bg-brand-600 !border-brand-600" },
27
+ { selected: true, variant: "secondary", class: "text-brand-600 border-brand-600 bg-brand-600/10" },
28
+ { selected: true, variant: "thirdary", class: "!bg-brand-600/20" },
29
+ ],
32
30
  },
33
31
  toggleInput: "p-0 m-0 size-0 invisible absolute",
34
32
  defaults: {
@@ -16,28 +16,14 @@ export default function useAttrs(
16
16
  props: UToggleItemProps,
17
17
  { isSelected, separated, variant }: itemState,
18
18
  ): UseAttrs<Config> {
19
- const { config, getKeysAttrs, hasSlotContent, getExtendingKeysClasses } = useUI<Config>(
20
- defaultConfig,
21
- () => props.config,
22
- );
19
+ const { config, getKeysAttrs } = useUI<Config>(defaultConfig, () => props.config);
23
20
 
24
21
  const mutatedProps = computed(() => ({
25
22
  variant: toValue(variant),
26
23
  separated: toValue(separated),
24
+ /* component state, not a props */
25
+ selected: isSelected.value,
27
26
  }));
28
27
 
29
- const extendingKeys = ["toggleButtonActive"];
30
- const extendingKeysClasses = getExtendingKeysClasses(extendingKeys, mutatedProps);
31
-
32
- const keysAttrs = getKeysAttrs(mutatedProps, extendingKeys, {
33
- toggleButton: {
34
- extend: computed(() => [isSelected.value && extendingKeysClasses.toggleButtonActive.value]),
35
- },
36
- });
37
-
38
- return {
39
- config,
40
- ...keysAttrs,
41
- hasSlotContent,
42
- };
28
+ return { config, ...getKeysAttrs(mutatedProps) };
43
29
  }
@@ -19,9 +19,11 @@ export default /*tw*/ {
19
19
  md: "text-sm",
20
20
  lg: "text-base",
21
21
  },
22
+ opened: {
23
+ true: "pt-2 h-fit opacity-100",
24
+ },
22
25
  },
23
26
  },
24
- descriptionShown: "pt-2 h-fit opacity-100",
25
27
  toggleIcon: "{UIcon}",
26
28
  divider: "{UDivider} group-last:hidden",
27
29
  defaults: {
@@ -15,23 +15,12 @@ export default function useAttrs(
15
15
  props: UAccordionProps,
16
16
  { isOpened }: ComponentState,
17
17
  ): UseAttrs<Config> {
18
- const { config, getKeysAttrs, hasSlotContent, getExtendingKeysClasses } = useUI<Config>(
19
- defaultConfig,
20
- () => props.config,
21
- );
18
+ const { config, getKeysAttrs } = useUI<Config>(defaultConfig, () => props.config);
22
19
 
23
- const extendingKeys = ["descriptionShown"];
24
- const extendingKeysClasses = getExtendingKeysClasses(extendingKeys);
20
+ const mutatedProps = computed(() => ({
21
+ /* component state, not a props */
22
+ opened: isOpened.value,
23
+ }));
25
24
 
26
- const keysAttrs = getKeysAttrs({}, extendingKeys, {
27
- description: {
28
- extend: computed(() => [isOpened.value && extendingKeysClasses.descriptionShown.value]),
29
- },
30
- });
31
-
32
- return {
33
- config,
34
- ...keysAttrs,
35
- hasSlotContent,
36
- };
25
+ return { config, ...getKeysAttrs(mutatedProps) };
37
26
  }
@@ -1,6 +1,8 @@
1
1
  <script setup lang="ts">
2
2
  import { computed, useSlots } from "vue";
3
3
 
4
+ import { hasSlotContent } from "../utils/helper.ts";
5
+
4
6
  import UHeader from "../ui.text-header/UHeader.vue";
5
7
  import UDivider from "../ui.container-divider/UDivider.vue";
6
8
 
@@ -28,7 +30,6 @@ const isShownFooter = computed(() => {
28
30
  });
29
31
 
30
32
  const {
31
- hasSlotContent,
32
33
  wrapperAttrs,
33
34
  titleAttrs,
34
35
  dividerAttrs,
@@ -6,13 +6,7 @@ import type { UseAttrs } from "../types.ts";
6
6
  import type { UCardProps, Config } from "./types.ts";
7
7
 
8
8
  export default function useAttrs(props: UCardProps): UseAttrs<Config> {
9
- const { config, getKeysAttrs, hasSlotContent } = useUI<Config>(defaultConfig, () => props.config);
9
+ const { config, getKeysAttrs } = useUI<Config>(defaultConfig, () => props.config);
10
10
 
11
- const keysAttrs = getKeysAttrs();
12
-
13
- return {
14
- config,
15
- ...keysAttrs,
16
- hasSlotContent,
17
- };
11
+ return { config, ...getKeysAttrs() };
18
12
  }
@@ -6,13 +6,7 @@ import type { UseAttrs } from "../types.ts";
6
6
  import type { UColProps, Config } from "./types.ts";
7
7
 
8
8
  export default function useAttrs(props: UColProps): UseAttrs<Config> {
9
- const { config, getKeysAttrs, hasSlotContent } = useUI<Config>(defaultConfig, () => props.config);
9
+ const { config, getKeysAttrs } = useUI<Config>(defaultConfig, () => props.config);
10
10
 
11
- const keysAttrs = getKeysAttrs();
12
-
13
- return {
14
- config,
15
- ...keysAttrs,
16
- hasSlotContent,
17
- };
11
+ return { config, ...getKeysAttrs() };
18
12
  }
@@ -7,17 +7,11 @@ import type { UseAttrs } from "../types.ts";
7
7
  import type { UDividerProps, Config } from "./types.ts";
8
8
 
9
9
  export default function useAttrs(props: UDividerProps): UseAttrs<Config> {
10
- const { config, getKeysAttrs, hasSlotContent } = useUI<Config>(defaultConfig, () => props.config);
10
+ const { config, getKeysAttrs } = useUI<Config>(defaultConfig, () => props.config);
11
11
 
12
12
  const mutatedProps = computed(() => ({
13
13
  label: Boolean(props.label),
14
14
  }));
15
15
 
16
- const keysAttrs = getKeysAttrs(mutatedProps);
17
-
18
- return {
19
- config,
20
- ...keysAttrs,
21
- hasSlotContent,
22
- };
16
+ return { config, ...getKeysAttrs(mutatedProps) };
23
17
  }
@@ -6,13 +6,7 @@ import type { UseAttrs } from "../types.ts";
6
6
  import type { UGroupProps, Config } from "./types.ts";
7
7
 
8
8
  export default function useAttrs(props: UGroupProps): UseAttrs<Config> {
9
- const { config, getKeysAttrs, hasSlotContent } = useUI<Config>(defaultConfig, () => props.config);
9
+ const { config, getKeysAttrs } = useUI<Config>(defaultConfig, () => props.config);
10
10
 
11
- const keysAttrs = getKeysAttrs();
12
-
13
- return {
14
- config,
15
- ...keysAttrs,
16
- hasSlotContent,
17
- };
11
+ return { config, ...getKeysAttrs() };
18
12
  }