vueless 0.0.189 → 0.0.191

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.
@@ -8,15 +8,35 @@ import {
8
8
  Text,
9
9
  Fragment,
10
10
  } from "vue";
11
- import { cx, globalComponentConfig, strategy, getColor, setColor } from "../service.ui";
11
+
12
+ import {
13
+ cx,
14
+ setColor,
15
+ getColor,
16
+ strategy,
17
+ nestedComponentRegEx,
18
+ globalComponentConfig,
19
+ } from "../service.ui";
20
+
12
21
  import { cloneDeep } from "../service.helper";
13
22
 
14
- const strategyType = {
23
+ const STRATEGY_TYPE = {
15
24
  merge: "merge",
16
25
  replace: "replace",
17
26
  overwrite: "overwrite",
18
27
  };
19
28
 
29
+ const SYSTEM_CONFIG_KEY = {
30
+ i18n: "i18n",
31
+ strategy: "strategy",
32
+ safelist: "safelist",
33
+ safelistColors: "safelistColors",
34
+ defaultVariants: "defaultVariants",
35
+ compoundVariants: "compoundVariants",
36
+ iconNameCapitalize: "IconName",
37
+ iconName: "iconName",
38
+ };
39
+
20
40
  /**
21
41
  Merging component configs in a given sequence (bigger number = bigger priority):
22
42
  1. Default component config
@@ -28,8 +48,8 @@ export default function useUI(defaultConfig = {}, propsConfigGetter = null, topL
28
48
  const { name: componentName } = getCurrentInstance().type;
29
49
  const globalConfig = globalComponentConfig[componentName];
30
50
 
31
- const isStrategyValid = strategy && Object.values(strategyType).includes(strategy);
32
- const vuelessStrategy = isStrategyValid ? strategy : strategyType.merge;
51
+ const isStrategyValid = strategy && Object.values(STRATEGY_TYPE).includes(strategy);
52
+ const vuelessStrategy = isStrategyValid ? strategy : STRATEGY_TYPE.merge;
33
53
 
34
54
  const [firstClassKey] = Object.keys(defaultConfig);
35
55
  const config = ref({});
@@ -50,7 +70,7 @@ export default function useUI(defaultConfig = {}, propsConfigGetter = null, topL
50
70
 
51
71
  function getAttrs(configKey, options) {
52
72
  const cvaClasses = options?.classes || "";
53
- const isComponent = options?.isComponent;
73
+ const nestedComponent = options?.isComponent || getNestedComponent(defaultConfig[configKey]); // TODO: Remove `options?.isComponent` when all `attrs.composable.js` will be migranted
54
74
 
55
75
  const attrs = useAttrs();
56
76
  const isDev = import.meta.env.DEV;
@@ -60,7 +80,7 @@ export default function useUI(defaultConfig = {}, propsConfigGetter = null, topL
60
80
  ...attrs,
61
81
  component: isDev ? attrs.component || componentName || null : null,
62
82
  "config-key": isDev ? attrs["config-key"] || configKey || null : null,
63
- "child-component": isDev && attrs.component ? componentName : null,
83
+ "child-component": isDev && attrs.component ? nestedComponent || componentName : null,
64
84
  "child-config-key": isDev && attrs.component ? configKey : null,
65
85
  };
66
86
 
@@ -78,7 +98,7 @@ export default function useUI(defaultConfig = {}, propsConfigGetter = null, topL
78
98
 
79
99
  const isTopLevelClassKey = configKey === (topLevelClassKey || firstClassKey);
80
100
 
81
- const attrClass = isTopLevelClassKey && !isComponent ? attrs.class : "";
101
+ const attrClass = isTopLevelClassKey && !nestedComponent ? attrs.class : "";
82
102
  const configKeyClass = isObject ? configKeyValue.base : configKeyValue;
83
103
 
84
104
  vuelessAttrs.value = {
@@ -96,6 +116,7 @@ export default function useUI(defaultConfig = {}, propsConfigGetter = null, topL
96
116
  getAttrs,
97
117
  getColor,
98
118
  setColor,
119
+ isSystemKey,
99
120
  hasSlotContent,
100
121
  };
101
122
  }
@@ -114,18 +135,18 @@ function getMergedConfig({ defaultConfig, globalConfig, propsConfig, vuelessStra
114
135
 
115
136
  const strategy =
116
137
  !globalConfig && !propsConfig
117
- ? strategyType.merge
138
+ ? STRATEGY_TYPE.merge
118
139
  : propsConfig?.strategy || globalConfig?.strategy || vuelessStrategy;
119
140
 
120
- if (strategy === strategyType.merge) {
141
+ if (strategy === STRATEGY_TYPE.merge) {
121
142
  return mergeConfigs({ defaultConfig, globalConfig, propsConfig });
122
143
  }
123
144
 
124
- if (strategy === strategyType.replace) {
145
+ if (strategy === STRATEGY_TYPE.replace) {
125
146
  return mergeConfigs({ defaultConfig, globalConfig, propsConfig, isReplace: true });
126
147
  }
127
148
 
128
- if (strategy === strategyType.overwrite) {
149
+ if (strategy === STRATEGY_TYPE.overwrite) {
129
150
  const isGlobalConfig = globalConfig && Object.keys(globalConfig).length;
130
151
  const isPropsConfig = propsConfig && Object.keys(propsConfig).length;
131
152
 
@@ -173,18 +194,29 @@ function mergeConfigs({
173
194
  }
174
195
  }
175
196
 
197
+ const {
198
+ i18n,
199
+ strategy,
200
+ safelist,
201
+ safelistColors,
202
+ defaultVariants,
203
+ compoundVariants,
204
+ iconNameCapitalize,
205
+ iconName,
206
+ } = SYSTEM_CONFIG_KEY;
207
+
176
208
  for (let key in composedConfig) {
177
209
  if (isGlobalConfig || isPropsConfig) {
178
- if (key === "strategy") {
210
+ if (key === strategy) {
179
211
  config[key] = propsConfig[key] || globalConfig[key] || defaultConfig[key];
180
- } else if (key === "safelist" || key === "safelistColors") {
212
+ } else if (key === safelist || key === safelistColors) {
181
213
  if (propsConfig[key]) {
182
214
  // eslint-disable-next-line no-console
183
215
  console.warn(`Passing '${key}' key by 'config' prop is not allowed.`);
184
216
  }
185
- } else if (key === "defaultVariants") {
217
+ } else if (key === defaultVariants) {
186
218
  config[key] = { ...defaultConfig[key], ...globalConfig[key], ...propsConfig[key] };
187
- } else if (key === "compoundVariants") {
219
+ } else if (key === compoundVariants) {
188
220
  config[key] = mergeCompoundVariants({
189
221
  defaultConfig: composedConfig,
190
222
  globalConfig,
@@ -199,8 +231,8 @@ function mergeConfigs({
199
231
 
200
232
  const isObject = isObjectComposedConfig || isObjectGlobalConfig || isObjectPropsConfig;
201
233
  const isEmpty = composedConfig[key] === null;
202
- const isIconName = /^.*(iconName|IconName)$/.test(key);
203
- const isI18n = key === "i18n";
234
+ const isIconName = key.includes(iconName) || key.includes(iconNameCapitalize);
235
+ const isI18n = key === i18n;
204
236
 
205
237
  config[key] =
206
238
  isObject && !isEmpty && !isI18n
@@ -327,6 +359,27 @@ function mergeClassesIntoConfig(config, topLevelClassKey, attrs) {
327
359
  return config;
328
360
  }
329
361
 
362
+ /**
363
+ Check is config key contains component name and if contains return it.
364
+ @param { String | Object } value
365
+ @returns { String }
366
+ */
367
+ function getNestedComponent(value) {
368
+ const classes = typeof value === "object" ? value.base || "" : value || "";
369
+ const match = classes.match(nestedComponentRegEx);
370
+
371
+ return match ? match[1] : "";
372
+ }
373
+
374
+ /**
375
+ Check is config key not contains classes or CVA config object.
376
+ @param { String } key
377
+ @returns { Boolean }
378
+ */
379
+ function isSystemKey(key) {
380
+ return Object.values(SYSTEM_CONFIG_KEY).some((value) => value.includes(key));
381
+ }
382
+
330
383
  /**
331
384
  Check if slot defined, and have a content.
332
385
  @param slot
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vueless",
3
- "version": "0.0.189",
3
+ "version": "0.0.191",
4
4
  "license": "MIT",
5
5
  "description": "Vue Styleless Component Framework.",
6
6
  "homepage": "https://vueless.com",
@@ -16,8 +16,12 @@ const [vuelessConfig] = Object.values(
16
16
  import.meta.glob("/vueless.config.js", { eager: true, import: "default" }),
17
17
  );
18
18
 
19
+ export const nestedComponentRegEx = /\{U[^}]*}/g;
20
+
19
21
  /*
20
- Export cva (class variance authority) methods extended with tailwind-merge.
22
+ Export cva (class variance authority) methods:
23
+ * extended with tailwind-merge
24
+ * remove all Vueless nested component names ({U...} strings) from class list string.
21
25
  It helps to make class variation switchers and removes class duplications.
22
26
  https://beta.cva.style
23
27
  */
@@ -26,7 +30,7 @@ export const {
26
30
  cx,
27
31
  compose,
28
32
  } = defineConfig({
29
- hooks: { onComplete: (className) => twMerge(className) },
33
+ hooks: { onComplete: (className) => twMerge(className).replace(nestedComponentRegEx, "") },
30
34
  });
31
35
 
32
36
  export const cva = ({ base = "", variants = {}, compoundVariants = [], defaultVariants = {} }) =>
@@ -212,23 +216,6 @@ export default class UIService {
212
216
  setColor(classes, color) {
213
217
  return classes?.replaceAll("{color}", color);
214
218
  }
215
-
216
- /**
217
- Check is config key not contains classes or CVA config object.
218
- @param { String } key
219
- @returns { Boolean }
220
- */
221
- isSystemKey(key) {
222
- return (
223
- key === "i18n" ||
224
- key === "strategy" ||
225
- key === "safelist" ||
226
- key === "safelistColors" ||
227
- key === "defaultVariants" ||
228
- key.includes("iconName") ||
229
- key.includes("IconName")
230
- );
231
- }
232
219
  }
233
220
 
234
221
  export const {
@@ -1,15 +1,15 @@
1
1
  import { computed } from "vue";
2
2
  import useUI from "../../composable.ui";
3
- import { cva, isSystemKey } from "../../service.ui";
3
+ import { cva } from "../../service.ui";
4
4
  import defaultConfig from "../configs/default.config";
5
5
 
6
- const componentKeys = ["icon", "divider"];
7
-
8
6
  export function useAttrs(props, { isOpened }) {
9
- const { config, getAttrs } = useUI(defaultConfig, () => props.config);
7
+ const { config, getAttrs, hasSlotContent, isSystemKey } = useUI(
8
+ defaultConfig,
9
+ () => props.config,
10
+ );
10
11
  const attrs = {};
11
12
 
12
- // New approach of defining attrs dynamically (need to test).
13
13
  for (const key in defaultConfig) {
14
14
  if (isSystemKey(key)) continue;
15
15
 
@@ -27,11 +27,12 @@ export function useAttrs(props, { isOpened }) {
27
27
  );
28
28
  }
29
29
 
30
- attrs[`${key}Attrs`] = getAttrs(key, { classes, isComponent: componentKeys.includes(key) });
30
+ attrs[`${key}Attrs`] = getAttrs(key, { classes });
31
31
  }
32
32
 
33
33
  return {
34
34
  ...attrs,
35
35
  config,
36
+ hasSlotContent,
36
37
  };
37
38
  }
@@ -24,10 +24,10 @@ export default /*tw*/ {
24
24
  },
25
25
  },
26
26
  },
27
- icon: "",
27
+ icon: "{UIcon}",
28
28
  expandIconName: "add",
29
29
  collapseIconName: "remove",
30
- divider: "group-last:hidden",
30
+ divider: "{UDivider} group-last:hidden",
31
31
  defaultVariants: {
32
32
  size: "md",
33
33
  },
@@ -1,184 +1,117 @@
1
+ import { computed } from "vue";
1
2
  import useUI from "../../composable.ui";
2
3
  import { cva, cx } from "../../service.ui";
3
-
4
4
  import defaultConfig from "../configs/default.config";
5
- import { computed } from "vue";
6
5
 
7
6
  export default function useAttrs(props, { isTop, isOpen, selectedLabel: selectedLabelValue }) {
8
- const { config, getAttrs, hasSlotContent } = useUI(defaultConfig, () => props.config);
9
- const { wrapper, innerWrapper, searchInput, selectedLabel, caret, caretClearText } = config.value;
10
-
11
- const cvaWrapper = cva({
12
- base: wrapper.base,
13
- variants: wrapper.variants,
14
- compoundVariants: wrapper.compoundVariants,
15
- });
16
-
17
- const cvaInnerWrapper = cva({
18
- base: innerWrapper.base,
19
- variants: innerWrapper.variants,
20
- compoundVariants: innerWrapper.compoundVariants,
21
- });
22
-
23
- const cvaSearchInput = cva({
24
- base: searchInput.base,
25
- variants: searchInput.variants,
26
- compoundVariants: searchInput.compoundVariants,
27
- });
28
-
29
- const cvaSelectedLabel = cva({
30
- base: selectedLabel.base,
31
- variants: selectedLabel.variants,
32
- compoundVariants: selectedLabel.compoundVariants,
33
- });
34
-
35
- const cvaCaret = cva({
36
- base: caret.base,
37
- variants: caret.variants,
38
- compoundVariants: caret.compoundVariants,
39
- });
40
-
41
- const cvaCaretClearText = cva({
42
- base: caretClearText.base,
43
- variants: caretClearText.variants,
44
- compoundVariants: caretClearText.compoundVariants,
45
- });
46
-
47
- const wrapperClasses = computed(() =>
48
- cvaWrapper({
49
- size: props.size,
50
- error: Boolean(props.error),
51
- disabled: props.disabled,
52
- labelAlign: props.labelAlign,
53
- label: Boolean(props.label),
54
- }),
55
- );
56
-
57
- const innerWrapperClasses = computed(() =>
58
- cvaInnerWrapper({
59
- multiple: props.multiple,
60
- size: props.size,
61
- }),
62
- );
63
-
64
- const searchInputClasses = computed(() =>
65
- cvaSearchInput({
66
- size: props.size,
67
- }),
68
- );
69
-
70
- const selectedLabelClasses = computed(() =>
71
- cvaSelectedLabel({
72
- size: props.size,
73
- disabled: props.disabled,
74
- multiple: props.multiple,
75
- }),
7
+ const { config, getAttrs, hasSlotContent, isSystemKey } = useUI(
8
+ defaultConfig,
9
+ () => props.config,
76
10
  );
11
+ const attrs = {};
77
12
 
78
13
  const caretClasses = computed(() =>
79
- cvaCaret({
80
- size: props.size,
81
- labelAlign: props.labelAlign,
14
+ cva(config.value.caret)({
15
+ ...props,
16
+ error: Boolean(props.error),
82
17
  label: Boolean(props.label),
83
18
  }),
84
19
  );
85
20
 
86
- const caretClearTextClasses = computed(() =>
87
- cvaCaretClearText({
88
- size: props.size,
89
- }),
90
- );
91
-
92
- const innerWrapperAttrs = getAttrs("innerWrapper", { classes: innerWrapperClasses });
93
- const wrapperTopAttrs = getAttrs("wrapperTop");
94
- const leftSlotAttrs = getAttrs("leftSlot");
95
- const searchInputAttrs = getAttrs("searchInput", { classes: searchInputClasses });
96
- const selectedLabelsAttrs = getAttrs("selectedLabels");
97
- const selectedLabelAttrs = getAttrs("selectedLabel", { classes: selectedLabelClasses });
98
- const dropdownListAttrs = getAttrs("dropdownList", { isComponent: true });
99
- const caretClearTextAttrs = getAttrs("caretClearText", { classes: caretClearTextClasses });
100
- const caretRemoveItemAttrs = getAttrs("caretRemoveItem");
101
- const toggleIconAttrs = getAttrs("toggleIcon", { isComponent: true });
102
- const clearIconAttrs = getAttrs("clearIcon", { isComponent: true });
103
- const removeItemIconAttrs = getAttrs("removeItemIcon", { isComponent: true });
104
-
105
- const wrapperAttrsRaw = getAttrs("wrapper", { classes: wrapperClasses });
106
-
107
- const wrapperAttrs = computed(() => ({
108
- ...wrapperAttrsRaw.value,
109
- class: cx([wrapperAttrsRaw.value.class, isOpen.value && config.value.wrapperActive]),
110
- }));
111
-
112
- const labelAttrsRaw = getAttrs("label", { isComponent: true });
113
-
114
- const labelAttrs = computed(() => ({
115
- ...labelAttrsRaw.value,
116
- class: cx([
117
- labelAttrsRaw.value.class,
118
- isOpen.value && config.value.labelWrapperActive,
119
- isTop.value && config.value.labelWrapperTop,
120
- ]),
121
- }));
122
-
123
- const caretToggleAttrsRaw = getAttrs("caretToggle");
124
-
125
- const caretToggleAttrs = computed(() => ({
126
- ...caretToggleAttrsRaw.value,
127
- class: cx([caretToggleAttrsRaw.value.class, caretClasses.value]),
128
- }));
129
-
130
- const caretClearAttrsRaw = getAttrs("caretClear");
131
-
132
- const caretClearAttrs = computed(() => ({
133
- ...caretClearAttrsRaw.value,
134
- class: cx([caretClearAttrsRaw.value.class, caretClasses.value]),
135
- }));
136
-
137
- const beforeCaretSlotAttrsRaw = getAttrs("beforeCaretSlot");
138
-
139
- const beforeCaretSlotAttrs = computed(() => ({
140
- ...beforeCaretSlotAttrsRaw.value,
141
- class: cx([beforeCaretSlotAttrsRaw.value.class, caretClasses.value]),
142
- }));
143
-
144
- const afterCaretSlotAttrsRaw = getAttrs("afterCaretSlot");
145
-
146
- const afterCaretSlotAttrs = computed(() => ({
147
- ...afterCaretSlotAttrsRaw.value,
148
- class: cx([afterCaretSlotAttrsRaw.value.class, caretClasses.value]),
149
- }));
150
-
151
- const searchAttrsRaw = getAttrs("search");
152
-
153
- const searchAttrs = computed(() => ({
154
- ...searchAttrsRaw.value,
155
- class: cx([
156
- searchAttrsRaw.value.class,
157
- Boolean(selectedLabelValue.value) && !isOpen.value && "w-0", // this is not configurable
158
- ]),
159
- }));
21
+ for (const key in defaultConfig) {
22
+ if (isSystemKey(key)) continue;
23
+
24
+ let classes = "";
25
+ let value = config.value[key];
26
+
27
+ if (value.variants || value.compoundVariants) {
28
+ const getCVA = cva(value);
29
+
30
+ classes = computed(() =>
31
+ getCVA({
32
+ ...props,
33
+ error: Boolean(props.error),
34
+ label: Boolean(props.label),
35
+ }),
36
+ );
37
+ }
38
+
39
+ attrs[`${key}Attrs`] = getAttrs(key, { classes });
40
+
41
+ if (key === "wrapper") {
42
+ const wrapperAttrs = attrs[`${key}Attrs`];
43
+
44
+ attrs[`${key}Attrs`] = computed(() => ({
45
+ ...wrapperAttrs.value,
46
+ class: cx([wrapperAttrs.value.class, isOpen.value && config.value.wrapperActive]),
47
+ }));
48
+ }
49
+
50
+ if (key === "label") {
51
+ const labelAttrs = attrs[`${key}Attrs`];
52
+
53
+ attrs[`${key}Attrs`] = computed(() => ({
54
+ ...labelAttrs.value,
55
+ class: cx([
56
+ labelAttrs.value.class,
57
+ isOpen.value && config.value.labelWrapperActive,
58
+ isTop.value && config.value.labelWrapperTop,
59
+ ]),
60
+ }));
61
+ }
62
+
63
+ if (key === "caretToggle") {
64
+ const caretToggleAttrs = attrs[`${key}Attrs`];
65
+
66
+ attrs[`${key}Attrs`] = computed(() => ({
67
+ ...caretToggleAttrs.value,
68
+ class: cx([caretToggleAttrs.value.class, caretClasses.value]),
69
+ }));
70
+ }
71
+
72
+ if (key === "caretClear") {
73
+ const caretClearAttrs = attrs[`${key}Attrs`];
74
+
75
+ attrs[`${key}Attrs`] = computed(() => ({
76
+ ...caretClearAttrs.value,
77
+ class: cx([caretClearAttrs.value.class, caretClasses.value]),
78
+ }));
79
+ }
80
+
81
+ if (key === "beforeCaretSlot") {
82
+ const beforeCaretSlotAttrs = attrs[`${key}Attrs`];
83
+
84
+ attrs[`${key}Attrs`] = computed(() => ({
85
+ ...beforeCaretSlotAttrs.value,
86
+ class: cx([beforeCaretSlotAttrs.value.class, caretClasses.value]),
87
+ }));
88
+ }
89
+
90
+ if (key === "afterCaretSlot") {
91
+ const afterCaretSlotAttrs = attrs[`${key}Attrs`];
92
+
93
+ attrs[`${key}Attrs`] = computed(() => ({
94
+ ...afterCaretSlotAttrs.value,
95
+ class: cx([afterCaretSlotAttrs.value.class, caretClasses.value]),
96
+ }));
97
+ }
98
+
99
+ if (key === "search") {
100
+ const searchAttrs = attrs[`${key}Attrs`];
101
+
102
+ attrs[`${key}Attrs`] = computed(() => ({
103
+ ...searchAttrs.value,
104
+ class: cx([
105
+ searchAttrs.value.class,
106
+ Boolean(selectedLabelValue.value) && !isOpen.value && "w-0", // this is not configurable
107
+ ]),
108
+ }));
109
+ }
110
+ }
160
111
 
161
112
  return {
113
+ ...attrs,
162
114
  config,
163
115
  hasSlotContent,
164
- labelAttrs,
165
- wrapperAttrs,
166
- innerWrapperAttrs,
167
- wrapperTopAttrs,
168
- leftSlotAttrs,
169
- beforeCaretSlotAttrs,
170
- afterCaretSlotAttrs,
171
- caretToggleAttrs,
172
- caretClearAttrs,
173
- caretClearTextAttrs,
174
- caretRemoveItemAttrs,
175
- searchAttrs,
176
- searchInputAttrs,
177
- selectedLabelsAttrs,
178
- selectedLabelAttrs,
179
- dropdownListAttrs,
180
- toggleIconAttrs,
181
- clearIconAttrs,
182
- removeItemIconAttrs,
183
116
  };
184
117
  }
@@ -1,5 +1,5 @@
1
1
  export default /*tw*/ {
2
- label: "w-full relative",
2
+ label: "{ULabel} w-full relative",
3
3
  wrapper: {
4
4
  base: `
5
5
  pb-2 pt-2 flex flex-row-reverse justify-between w-full min-h-full box-border relative
@@ -55,14 +55,16 @@ export default /*tw*/ {
55
55
  beforeCaretSlot: "",
56
56
  afterCaretSlot: "mr-3",
57
57
  caretToggle: "mr-3",
58
- toggleIcon: "transform transition duration-300 group-[]/active:rotate-180",
58
+ toggleIcon: "{UIcon} transform transition duration-300 group-[]/active:rotate-180",
59
59
  toggleIconName: "expand_more",
60
- clearIcon: "",
60
+ clearIcon: "{UIcon}",
61
61
  clearIconName: "close_small",
62
- removeItemIcon: "",
62
+ removeItemIcon: "{UIcon}",
63
63
  removeItemIconName: "close_small",
64
64
  caretRemoveItem: "flex items-center",
65
+ caretClear: "",
65
66
  caretClearText: {
67
+ // TODO: caretClearMultiple is better
66
68
  base: "cursor-pointer flex items-center text-sm font-normal text-gray-400 hover:text-gray-500 transition",
67
69
  compoundVariants: [
68
70
  { size: "sm", class: "text-sm" },
@@ -110,7 +112,7 @@ export default /*tw*/ {
110
112
  { size: "lg", multiple: true, class: "text-lg" },
111
113
  ],
112
114
  },
113
- dropdownList: "group-[]/top:bottom-full group-[]/top:top-auto top-full",
115
+ dropdownList: "{UDropdownList} group-[]/top:bottom-full group-[]/top:top-auto top-full",
114
116
  i18n: {
115
117
  listIsEmpty: "List is empty.",
116
118
  noDataToShow: "No data to show.",
package/web-types.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "framework": "vue",
3
3
  "name": "vueless",
4
- "version": "0.0.189",
4
+ "version": "0.0.191",
5
5
  "contributions": {
6
6
  "html": {
7
7
  "description-markup": "markdown",