vueless 0.0.596 → 0.0.597

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.
@@ -1,4 +1,5 @@
1
1
  import { ref, watch, watchEffect, getCurrentInstance, toValue, useAttrs, computed } from "vue";
2
+ import { merge } from "lodash-es";
2
3
 
3
4
  import { cx, cva, setColor, getColor, vuelessConfig, getMergedConfig } from "../utils/ui.ts";
4
5
  import { isCSR } from "../utils/helper.ts";
@@ -14,6 +15,7 @@ import type { Ref, ComputedRef } from "vue";
14
15
  import type {
15
16
  CVA,
16
17
  UseUI,
18
+ Defaults,
17
19
  KeyAttrs,
18
20
  KeysAttrs,
19
21
  Strategies,
@@ -22,7 +24,7 @@ import type {
22
24
  UnknownObject,
23
25
  ComponentNames,
24
26
  ComponentConfig,
25
- KeyAttrsWithConfig,
27
+ NestedComponent,
26
28
  VuelessComponentInstance,
27
29
  } from "../types.ts";
28
30
 
@@ -44,7 +46,7 @@ export default function useUI<T>(
44
46
  ? (parent?.type.__name as ComponentNames)
45
47
  : (type.__name as ComponentNames);
46
48
 
47
- const globalConfig = vuelessConfig?.component?.[componentName] || {};
49
+ const globalConfig = (vuelessConfig?.component?.[componentName] || {}) as ComponentConfig<T>;
48
50
 
49
51
  const vuelessStrategy = Object.values(STRATEGY_TYPE).includes(vuelessConfig.strategy || "")
50
52
  ? (vuelessConfig.strategy as Strategies)
@@ -107,31 +109,6 @@ export default function useUI<T>(
107
109
  if (isSystemKey(key)) continue;
108
110
 
109
111
  keysAttrs[`${key}Attrs`] = getAttrs(key, getClasses(key, mutatedProps));
110
-
111
- const baseClasses = getBaseClasses(config.value[key]);
112
- const extendsKeys = getExtendsKeys(baseClasses);
113
-
114
- if (extendsKeys.length) {
115
- const keyAttrs = keysAttrs[`${key}Attrs`];
116
-
117
- keysAttrs[`${key}Attrs`] = computed(() => {
118
- const extendsClasses = extendsKeys.map((key) => toValue(getClasses(key, mutatedProps)));
119
-
120
- return {
121
- ...keyAttrs.value,
122
- class: cx([
123
- ...extendsClasses,
124
- keyAttrs.value.class?.replaceAll(EXTENDS_PATTERN_REG_EXP, ""),
125
- ]),
126
- // TODO: Add ability to merge array of keys
127
- config: getMergedConfig({
128
- defaultConfig: config.value[extendsKeys[0]],
129
- globalConfig: keyAttrs.value.config,
130
- propsConfig: propsConfig[extendsKeys[0]],
131
- }),
132
- };
133
- }) as ComputedRef<KeyAttrsWithConfig<T>>;
134
- }
135
112
  }
136
113
 
137
114
  return keysAttrs;
@@ -168,24 +145,65 @@ export default function useUI<T>(
168
145
  }
169
146
 
170
147
  function updateVuelessAttrs() {
171
- const configKeyValue = config.value[configKey];
148
+ let configAttr: NestedComponent = {};
149
+ let extendsConfigAttr: NestedComponent = {};
150
+ let extendsClasses: string[] = [];
172
151
 
173
- let configAttr = {};
174
- let defaultAttrs = {};
152
+ const baseClasses = getBaseClasses(config.value[configKey]);
153
+ const extendsKeys = getExtendsKeys(baseClasses);
175
154
 
176
- if (typeof configKeyValue === "object") {
177
- configAttr = configKeyValue;
178
- defaultAttrs = configKeyValue?.defaults;
155
+ if (typeof config.value[configKey] === "object") {
156
+ configAttr = config.value[configKey] as NestedComponent;
157
+ }
158
+
159
+ if (extendsKeys.length) {
160
+ extendsClasses = extendsKeys.map((key) => toValue(getClasses(key, mutatedProps)));
161
+ extendsConfigAttr = getExtendsConfig(extendsKeys);
179
162
  }
180
163
 
181
164
  vuelessAttrs.value = {
182
165
  ...commonAttrs,
183
- class: toValue(classes),
184
- config: configAttr,
185
- ...defaultAttrs,
166
+ class: cx([...extendsClasses, toValue(classes).replaceAll(EXTENDS_PATTERN_REG_EXP, "")]),
167
+ config: merge(configAttr, extendsConfigAttr),
168
+ ...getDefaults({
169
+ ...(configAttr.defaults || {}),
170
+ ...(extendsConfigAttr.defaults || {}),
171
+ }),
186
172
  };
187
173
  }
188
174
 
175
+ /**
176
+ * Merge extends nested component configs.
177
+ * TODO: Add ability to merge multiple keys in one (now works for merging only 1 first key).
178
+ */
179
+ function getExtendsConfig(extendsKeys: string[]) {
180
+ const [firstKey] = extendsKeys;
181
+
182
+ return getMergedConfig({
183
+ defaultConfig: config.value[firstKey],
184
+ globalConfig: globalConfig[firstKey],
185
+ propsConfig: propsConfig[firstKey],
186
+ }) as NestedComponent;
187
+ }
188
+
189
+ /**
190
+ * Conditionally set props default value for nested components based on parent component prop value.
191
+ * For example, set icon size for the nested component based on the size of the parent component.
192
+ * Use an object where key = parent component prop value, value = nested component prop value.
193
+ * */
194
+ function getDefaults(defaultAttrs: NestedComponent["defaults"]) {
195
+ const defaults: Defaults = {};
196
+
197
+ for (const key in defaultAttrs) {
198
+ defaults[key] =
199
+ typeof defaultAttrs[key] === "object"
200
+ ? defaultAttrs[key][String(props[key])]
201
+ : defaultAttrs[key];
202
+ }
203
+
204
+ return defaults;
205
+ }
206
+
189
207
  return vuelessAttrs;
190
208
  }
191
209
 
@@ -195,7 +213,7 @@ export default function useUI<T>(
195
213
  /**
196
214
  * Return base classes.
197
215
  */
198
- function getBaseClasses(value: string | CVA) {
216
+ function getBaseClasses(value: string | CVA | undefined) {
199
217
  return typeof value === "object" ? value.base || "" : value || "";
200
218
  }
201
219
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vueless",
3
- "version": "0.0.596",
3
+ "version": "0.0.597",
4
4
  "license": "MIT",
5
5
  "description": "Vue Styleless UI Component Library, powered by Tailwind CSS.",
6
6
  "keywords": [
package/types.ts CHANGED
@@ -241,12 +241,13 @@ export type ComponentConfig<T> = Partial<{
241
241
  NestedComponent;
242
242
 
243
243
  export interface NestedComponent {
244
- [key: string]: Record<string, string | UnknownObject> | string;
244
+ defaults?: Record<string, string | UnknownObject>;
245
+ [key: string]: Record<string, string | UnknownObject> | string | undefined;
245
246
  }
246
247
 
247
248
  export type Defaults = {
248
249
  color?: string;
249
- [key: string]: unknown;
250
+ [key: string]: unknown | UnknownObject;
250
251
  };
251
252
 
252
253
  export interface Transition {
@@ -11,7 +11,7 @@ import UIcon from "../ui.image-icon/UIcon.vue";
11
11
  import defaultConfig from "./config.ts";
12
12
  import { COMPONENT_NAME } from "./constants.ts";
13
13
 
14
- import type { Props, LoaderSize, IconSize, Config } from "./types.ts";
14
+ import type { Props, Config } from "./types.ts";
15
15
 
16
16
  defineOptions({ inheritAttrs: false });
17
17
 
@@ -27,32 +27,6 @@ const buttonRef = ref<HTMLElement | null>(null);
27
27
  const buttonStyle = ref({});
28
28
  const buttonWidth = ref(0);
29
29
 
30
- const loaderSize = computed(() => {
31
- const sizes = {
32
- "2xs": "sm",
33
- xs: "sm",
34
- sm: "md",
35
- md: "md",
36
- lg: "lg",
37
- xl: "lg",
38
- };
39
-
40
- return sizes[props.size] as LoaderSize;
41
- });
42
-
43
- const iconSize = computed(() => {
44
- const sizes = {
45
- "2xs": "2xs",
46
- xs: "xs",
47
- sm: "sm",
48
- md: "sm",
49
- lg: "sm",
50
- xl: "sm",
51
- };
52
-
53
- return sizes[props.size] as IconSize;
54
- });
55
-
56
30
  watch(
57
31
  () => props.loading,
58
32
  (newValue, oldValue) => {
@@ -111,7 +85,7 @@ const { buttonAttrs, loaderAttrs, leftIconAttrs, rightIconAttrs, centerIconAttrs
111
85
  :data-test="dataTest"
112
86
  >
113
87
  <template v-if="loading">
114
- <ULoader :loading="loading" :size="loaderSize" color="inherit" v-bind="loaderAttrs" />
88
+ <ULoader :loading="loading" color="inherit" v-bind="loaderAttrs" />
115
89
  </template>
116
90
 
117
91
  <template v-else>
@@ -120,15 +94,8 @@ const { buttonAttrs, loaderAttrs, leftIconAttrs, rightIconAttrs, centerIconAttrs
120
94
  @binding {string} icon-name
121
95
  @binding {string} icon-size
122
96
  -->
123
- <slot name="left" :icon-name="leftIcon" :icon-size="iconSize">
124
- <UIcon
125
- v-if="leftIcon"
126
- internal
127
- color="inherit"
128
- :name="leftIcon"
129
- :size="iconSize"
130
- v-bind="leftIconAttrs"
131
- />
97
+ <slot name="left" :icon-name="leftIcon">
98
+ <UIcon v-if="leftIcon" internal color="inherit" :name="leftIcon" v-bind="leftIconAttrs" />
132
99
  </slot>
133
100
 
134
101
  <!--
@@ -137,15 +104,8 @@ const { buttonAttrs, loaderAttrs, leftIconAttrs, rightIconAttrs, centerIconAttrs
137
104
  @binding {string} icon-name
138
105
  @binding {string} icon-size
139
106
  -->
140
- <slot name="default" :label="label" :icon-name="icon" :icon-size="iconSize">
141
- <UIcon
142
- v-if="icon"
143
- internal
144
- color="inherit"
145
- :name="icon"
146
- :size="iconSize"
147
- v-bind="centerIconAttrs"
148
- />
107
+ <slot name="default" :label="label" :icon-name="icon">
108
+ <UIcon v-if="icon" internal color="inherit" :name="icon" v-bind="centerIconAttrs" />
149
109
  <template v-else>
150
110
  {{ label }}
151
111
  </template>
@@ -156,13 +116,12 @@ const { buttonAttrs, loaderAttrs, leftIconAttrs, rightIconAttrs, centerIconAttrs
156
116
  @binding {string} icon-name
157
117
  @binding {string} icon-size
158
118
  -->
159
- <slot name="right" :icon-name="rightIcon" :icon-size="iconSize">
119
+ <slot name="right" :icon-name="rightIcon">
160
120
  <UIcon
161
121
  v-if="rightIcon"
162
122
  internal
163
123
  color="inherit"
164
124
  :name="rightIcon"
165
- :size="iconSize"
166
125
  v-bind="rightIconAttrs"
167
126
  />
168
127
  </slot>
@@ -149,10 +149,34 @@ export default /*tw*/ {
149
149
  { square: true, size: "xl", class: "p-3.5" },
150
150
  ],
151
151
  },
152
- loader: "{ULoader}",
153
- leftIcon: "{UIcon}",
154
- rightIcon: "{UIcon}",
155
- centerIcon: "{UIcon}",
152
+ loader: {
153
+ base: "{ULoader}",
154
+ defaults: {
155
+ size: {
156
+ "2xs": "sm",
157
+ xs: "sm",
158
+ sm: "md",
159
+ md: "md",
160
+ lg: "lg",
161
+ xl: "lg",
162
+ },
163
+ },
164
+ },
165
+ leftIcon: "{UIcon} {>centerIcon}",
166
+ rightIcon: "{UIcon} {>centerIcon}",
167
+ centerIcon: {
168
+ base: "{UIcon}",
169
+ defaults: {
170
+ size: {
171
+ "2xs": "2xs",
172
+ xs: "xs",
173
+ sm: "sm",
174
+ md: "sm",
175
+ lg: "sm",
176
+ xl: "sm",
177
+ },
178
+ },
179
+ },
156
180
  defaults: {
157
181
  color: "brand",
158
182
  variant: "primary",
@@ -172,10 +172,12 @@ export const IconProps: StoryFn<UButtonArgs> = (args) => ({
172
172
  template: `
173
173
  <URow no-mobile>
174
174
  <UButton
175
+ v-bind="args"
175
176
  left-icon="download"
176
177
  label="Download"
177
178
  />
178
179
  <UButton
180
+ v-bind="args"
179
181
  right-icon="menu"
180
182
  label="Menu"
181
183
  />
@@ -3,9 +3,6 @@ import type { ComponentConfig } from "../types.ts";
3
3
 
4
4
  export type Config = typeof defaultConfig;
5
5
 
6
- export type LoaderSize = "sm" | "md" | "lg";
7
- export type IconSize = "2xs" | "xs" | "sm" | "md";
8
-
9
6
  export interface Props {
10
7
  /**
11
8
  * Button variant.
package/web-types.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "framework": "vue",
3
3
  "name": "vueless",
4
- "version": "0.0.596",
4
+ "version": "0.0.597",
5
5
  "contributions": {
6
6
  "html": {
7
7
  "description-markup": "markdown",
@@ -980,10 +980,6 @@
980
980
  {
981
981
  "type": "string",
982
982
  "name": "icon-name"
983
- },
984
- {
985
- "type": "string",
986
- "name": "icon-size"
987
983
  }
988
984
  ]
989
985
  },
@@ -999,10 +995,6 @@
999
995
  {
1000
996
  "type": "string",
1001
997
  "name": "icon-name"
1002
- },
1003
- {
1004
- "type": "string",
1005
- "name": "icon-size"
1006
998
  }
1007
999
  ]
1008
1000
  },
@@ -1014,10 +1006,6 @@
1014
1006
  {
1015
1007
  "type": "string",
1016
1008
  "name": "icon-name"
1017
- },
1018
- {
1019
- "type": "string",
1020
- "name": "icon-size"
1021
1009
  }
1022
1010
  ]
1023
1011
  }