vueless 0.0.382 → 0.0.384

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.
@@ -22,11 +22,11 @@ import {
22
22
  } from "../constants.js";
23
23
 
24
24
  /**
25
- Merging component configs in a given sequence (bigger number = bigger priority):
26
- 1. Default component config
27
- 2. Custom global component config (/vueless.config.js)
28
- 3. Component config (:config="{...}" props)
29
- 4. Component classes (class="...")
25
+ * Merging component configs in a given sequence (bigger number = bigger priority):
26
+ * 1. Default component config
27
+ * 2. Custom global component config (/vueless.config.js)
28
+ * 3. Component config (:config="{...}" props)
29
+ * 4. Component classes (class="...")
30
30
  */
31
31
  export default function useUI(defaultConfig = {}, propsConfigGetter = null, topLevelClassKey) {
32
32
  const { type, props } = getCurrentInstance();
@@ -109,7 +109,7 @@ export default function useUI(defaultConfig = {}, propsConfigGetter = null, topL
109
109
  * @param keysToExtendConfig
110
110
  * @returns {Object}
111
111
  */
112
- function getKeysAttrs(mutatedProps, extendingKeys = [], keysToExtendConfig = {}) {
112
+ function getKeysAttrs(mutatedProps = {}, extendingKeys = [], keysToExtendConfig = {}) {
113
113
  const keysToExtend = Object.keys(keysToExtendConfig);
114
114
  const keysAttrs = {};
115
115
 
@@ -124,7 +124,6 @@ export default function useUI(defaultConfig = {}, propsConfigGetter = null, topL
124
124
  const { base, extend } = keysToExtendConfig[key];
125
125
  const keyAttrs = keysAttrs[`${key}Attrs`];
126
126
 
127
- // TODO: if value of the key contains keys related to the nested nested component it should be skipped
128
127
  keysAttrs[`${key}Attrs`] = computed(() => ({
129
128
  ...keyAttrs.value,
130
129
  class: cx([
@@ -210,13 +209,13 @@ export default function useUI(defaultConfig = {}, propsConfigGetter = null, topL
210
209
  }
211
210
 
212
211
  /**
213
- Get merged config based on config merging strategy.
214
- @param {Object} defaultConfig
215
- @param {Object} globalConfig
216
- @param {Object} propsConfig
217
- @param {string} vuelessStrategy - vueless top level merge strategy.
218
-
219
- @returns {Object}
212
+ * 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}
220
219
  */
221
220
  function getMergedConfig({ defaultConfig, globalConfig, propsConfig, vuelessStrategy }) {
222
221
  defaultConfig = cloneDeep(defaultConfig);
@@ -243,15 +242,15 @@ function getMergedConfig({ defaultConfig, globalConfig, propsConfig, vuelessStra
243
242
  }
244
243
 
245
244
  /**
246
- Recursively merge config objects with removing tailwind classes duplicates.
247
- @param {Object} defaultConfig
248
- @param {Object} globalConfig
249
- @param {Object} propsConfig
250
- @param {Object} config - final merged config.
251
- @param {boolean} isReplace - enables class replacement instead of merge.
252
- @param {boolean} isVarinants - if true, prevents adding a "base" key into nested objects.
253
-
254
- @returns {Object}
245
+ * Recursively merge config objects with removing tailwind classes duplicates.
246
+ * @param {Object} defaultConfig
247
+ * @param {Object} globalConfig
248
+ * @param {Object} propsConfig
249
+ * @param {Object} config - final merged config.
250
+ * @param {boolean} isReplace - enables class replacement instead of merge.
251
+ * @param {boolean} isVarinants - if true, prevents adding a "base" key into nested objects.
252
+ *
253
+ * @returns {Object}
255
254
  */
256
255
  function mergeConfigs({
257
256
  defaultConfig,
@@ -369,14 +368,14 @@ function stringToObject(value, { addBase = false }) {
369
368
  }
370
369
 
371
370
  /**
372
- Merge CVA compound variants arrays.
373
- @param {Object} defaultConfig
374
- @param {Object} globalConfig
375
- @param {Object} propsConfig
376
- @param {string} key
377
- @param {boolean} isReplace - enables class replacement instead of merge.
378
-
379
- @returns {Array}
371
+ * Merge CVA compound variants arrays.
372
+ * @param {Object} defaultConfig
373
+ * @param {Object} globalConfig
374
+ * @param {Object} propsConfig
375
+ * @param {string} key
376
+ * @param {boolean} isReplace - enables class replacement instead of merge.
377
+ *
378
+ * @returns {Array}
380
379
  */
381
380
  function mergeCompoundVariants({ defaultConfig, globalConfig, propsConfig, key, isReplace }) {
382
381
  if (
@@ -393,9 +392,9 @@ function mergeCompoundVariants({ defaultConfig, globalConfig, propsConfig, key,
393
392
 
394
393
  const config = defaultConfig[key].map((defaultConfigItem) => {
395
394
  /**
396
- Compare two objects by keys for match.
397
- @param {Object} configItem
398
- @returns {Boolean}
395
+ * Compare two objects by keys for match.
396
+ * @param {Object} configItem
397
+ * @returns {Boolean}
399
398
  */
400
399
  function isSameItem(configItem) {
401
400
  const hasConfigItemKeys = Object.keys(defaultConfigItem)
@@ -410,9 +409,9 @@ function mergeCompoundVariants({ defaultConfig, globalConfig, propsConfig, key,
410
409
  }
411
410
 
412
411
  /**
413
- Find the same compound variant item in custom config if exist.
414
- @param {Object} config
415
- @returns {Object|undefined}
412
+ * Find the same compound variant item in custom config if exist.
413
+ * @param {Object} config
414
+ * @returns {Object|undefined}
416
415
  */
417
416
  function findItem(config = []) {
418
417
  const globalConfigUniqueItemIndex = globalConfigUniqueItems.findIndex(isSameItem);
@@ -446,12 +445,12 @@ function mergeCompoundVariants({ defaultConfig, globalConfig, propsConfig, key,
446
445
  }
447
446
 
448
447
  /**
449
- Merge component classes from "class" attribute into final config.
450
- @param {Object} config
451
- @param {Object} attrs
452
- @param {string} topLevelClassKey
453
-
454
- @returns {Object}
448
+ * Merge component classes from "class" attribute into final config.
449
+ * @param {Object} config
450
+ * @param {Object} attrs
451
+ * @param {string} topLevelClassKey
452
+ *
453
+ * @returns {Object}
455
454
  */
456
455
  function mergeClassesIntoConfig(config, topLevelClassKey, attrs) {
457
456
  if (typeof config[topLevelClassKey] === "object") {
@@ -464,18 +463,18 @@ function mergeClassesIntoConfig(config, topLevelClassKey, attrs) {
464
463
  }
465
464
 
466
465
  /**
467
- Return base classes.
468
- @param { String | Object } value
469
- @returns { String }
466
+ * Return base classes.
467
+ * @param { String | Object } value
468
+ * @returns { String }
470
469
  */
471
470
  function getBaseClasses(value) {
472
471
  return typeof value === "object" ? value.base || "" : value || "";
473
472
  }
474
473
 
475
474
  /**
476
- Check is config key contains component name and if contains return it.
477
- @param { String | Object } value
478
- @returns { String }
475
+ * Check is config key contains component name and if contains return it.
476
+ * @param { String | Object } value
477
+ * @returns { String }
479
478
  */
480
479
  function getNestedComponent(value) {
481
480
  const classes = getBaseClasses(value);
@@ -487,9 +486,9 @@ function getNestedComponent(value) {
487
486
  }
488
487
 
489
488
  /**
490
- Check is config key not contains classes or CVA config object.
491
- @param { String } key
492
- @returns { Boolean }
489
+ * Check is config key not contains classes or CVA config object.
490
+ * @param { String } key
491
+ * @returns { Boolean }
493
492
  */
494
493
  function isSystemKey(key) {
495
494
  const isExactKey = Object.values(SYSTEM_CONFIG_KEY).some((value) => value === key);
@@ -498,9 +497,9 @@ function isSystemKey(key) {
498
497
  }
499
498
 
500
499
  /**
501
- Check is config contains default CVA keys.
502
- @param { Object | String } config
503
- @returns { Boolean }
500
+ * Check is config contains default CVA keys.
501
+ * @param { Object | String } config
502
+ * @returns { Boolean }
504
503
  */
505
504
  function isCVA(config) {
506
505
  if (typeof config !== "object") return false;
@@ -511,11 +510,11 @@ function isCVA(config) {
511
510
  }
512
511
 
513
512
  /**
514
- Check if slot defined, and have a content.
515
- @param slot
516
- @param props
517
-
518
- @returns {boolean}
513
+ * Check if slot defined, and have a content.
514
+ * @param slot
515
+ * @param props
516
+ *
517
+ * @returns {boolean}
519
518
  */
520
519
  function hasSlotContent(slot, props = {}) {
521
520
  const asArray = (arg) => (Array.isArray(arg) ? arg : arg != null ? [arg] : []);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vueless",
3
- "version": "0.0.382",
3
+ "version": "0.0.384",
4
4
  "license": "MIT",
5
5
  "description": "Vue Styleless Component Framework.",
6
6
  "homepage": "https://vueless.com",
@@ -1,66 +1,44 @@
1
- import useUI from "../composables/useUI.js";
2
- import { cva } from "../utils/utilUI.js";
3
1
  import { computed, watchEffect } from "vue";
4
2
  import { merge } from "lodash-es";
3
+ import useUI from "../composables/useUI.js";
5
4
 
6
5
  import defaultConfig from "./config.js";
7
6
  import { POSITION } from "../composables/useAutoPosition.js";
8
7
 
9
8
  export default function useAttrs(props, { isShownCalendar, isTop, isRight }) {
10
- const { config, getAttrs, isSystemKey, hasSlotContent, isCVA } = useUI(
9
+ const { config, getKeysAttrs, hasSlotContent, getExtendingKeysClasses } = useUI(
11
10
  defaultConfig,
12
11
  () => props.config,
13
12
  );
14
- const attrs = {};
15
-
16
- for (const key in defaultConfig) {
17
- if (isSystemKey(key)) continue;
18
-
19
- const classes = computed(() => {
20
- let value = config.value[key];
21
13
 
22
- if (isCVA(value)) {
23
- value = cva(value)({
24
- ...props,
25
- openDirectionY: isTop.value ? POSITION.top : POSITION.bottom,
26
- openDirectionX: isRight.value ? POSITION.right : POSITION.left,
27
- error: Boolean(props.error),
28
- description: Boolean(props.description),
29
- });
30
- }
14
+ const mutatedProps = computed(() => ({
15
+ openDirectionY: isTop.value ? POSITION.top : POSITION.bottom,
16
+ openDirectionX: isRight.value ? POSITION.right : POSITION.left,
17
+ error: Boolean(props.error),
18
+ description: Boolean(props.description),
19
+ }));
31
20
 
32
- return value;
33
- });
21
+ const extendingKeys = ["inputFocused"];
22
+ const extendingKeysClasses = getExtendingKeysClasses(extendingKeys, mutatedProps);
34
23
 
35
- attrs[`${key}Attrs`] = getAttrs(key, { classes });
36
-
37
- if (key === "input") {
38
- const inputAttrs = attrs[`${key}Attrs`];
39
-
40
- attrs[`${key}Attrs`] = computed(() => ({
41
- ...inputAttrs.value,
42
- config: {
43
- ...inputAttrs.value.config,
44
- ...(isShownCalendar.value ? config.value.inputFocused : {}),
45
- },
46
- }));
47
- }
24
+ const keysAttrs = getKeysAttrs(mutatedProps, extendingKeys, {
25
+ input: {
26
+ extend: computed(() => [isShownCalendar.value && extendingKeysClasses.inputFocused.value]),
27
+ },
28
+ });
48
29
 
49
- if (key === "calendar") {
50
- /* Merging DatePicker's i18n translations into Calendar's i18n translations. */
51
- watchEffect(() => {
52
- const calendarConfig = attrs[`${key}Attrs`].value.config || {};
30
+ /* Merging DatePicker's i18n translations into Calendar's i18n translations. */
31
+ watchEffect(() => {
32
+ const calendarConfig = keysAttrs.calendarAttrs.value.config || {};
53
33
 
54
- if (!calendarConfig.i18n || props.config.i18n) {
55
- attrs[`${key}Attrs`].value.config.i18n = merge(calendarConfig.i18n, config.value.i18n);
56
- }
57
- });
34
+ if (!calendarConfig.i18n || props.config.i18n) {
35
+ keysAttrs.calendarAttrs.value.config.i18n = merge(calendarConfig.i18n, config.value.i18n);
58
36
  }
59
- }
37
+ });
60
38
 
61
39
  return {
62
- ...attrs,
63
40
  config,
41
+ ...keysAttrs,
64
42
  hasSlotContent,
65
43
  };
66
44
  }
@@ -98,7 +98,7 @@
98
98
  :is-period="isPeriod"
99
99
  :custom-range-button="customRangeButton"
100
100
  :locale="locale"
101
- :attrs="periodDatesMenuAttrs"
101
+ :attrs="keysAttrs"
102
102
  :date-format="dateFormat"
103
103
  :min-date="minDate"
104
104
  :max-date="maxDate"
@@ -120,7 +120,7 @@
120
120
  :locale="locale"
121
121
  :date-format="dateFormat"
122
122
  :config="config"
123
- :attrs="rangeInputsAttrs"
123
+ :attrs="keysAttrs"
124
124
  />
125
125
 
126
126
  <div v-if="inputRangeToError || inputRangeFromError" v-bind="inputRangeErrorAttrs">
@@ -403,6 +403,7 @@ const elementId = props.id || useId();
403
403
 
404
404
  const {
405
405
  config,
406
+ keysAttrs,
406
407
  wrapperAttrs,
407
408
  calendarAttrs,
408
409
  inputAttrs,
@@ -412,8 +413,6 @@ const {
412
413
  shiftRangeButtonAttrs,
413
414
  rangeInputWrapperAttrs,
414
415
  inputRangeErrorAttrs,
415
- periodDatesMenuAttrs,
416
- rangeInputsAttrs,
417
416
  } = useAttrs(props, { isShownMenu, isTop, isRight, isPeriod });
418
417
 
419
418
  const calendarValue = ref(props.modelValue);
@@ -5,7 +5,7 @@
5
5
  v-model="rangeStart"
6
6
  :error="inputRangeFromError"
7
7
  size="md"
8
- v-bind="attrs.rangeInputFirstAttrs"
8
+ v-bind="rangeInputFirstAttrs"
9
9
  :name="rangeInputName"
10
10
  @input="onInputRangeInput($event, INPUT_RANGE_TYPE.start)"
11
11
  />
@@ -15,7 +15,7 @@
15
15
  v-model="rangeEnd"
16
16
  :error="inputRangeToError"
17
17
  size="md"
18
- v-bind="attrs.rangeInputLastAttrs"
18
+ v-bind="rangeInputLastAttrs"
19
19
  :name="rangeInputName"
20
20
  @input="onInputRangeInput($event, INPUT_RANGE_TYPE.end)"
21
21
  />
@@ -58,6 +58,8 @@ const props = defineProps({
58
58
  },
59
59
  });
60
60
 
61
+ const { rangeInputFirstAttrs, rangeInputLastAttrs } = props.attrs;
62
+
61
63
  const localValue = defineModel("localValue", { required: true, type: Object });
62
64
  const inputRangeFromError = defineModel("inputRangeFromError", { required: true, type: String });
63
65
  const inputRangeToError = defineModel("inputRangeToError", { required: true, type: String });
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div v-bind="attrs.periodsRowAttrs">
2
+ <div v-bind="periodsRowAttrs">
3
3
  <template v-for="periodButton in periods" :key="periodButton.name">
4
4
  <UButton
5
5
  v-if="periodButton.name !== period"
@@ -9,7 +9,7 @@
9
9
  size="xs"
10
10
  variant="thirdary"
11
11
  :label="periodButton.title"
12
- v-bind="attrs.periodButtonAttrs"
12
+ v-bind="periodButtonAttrs"
13
13
  @click="onClickPeriodButton(periodButton.name)"
14
14
  />
15
15
 
@@ -21,13 +21,13 @@
21
21
  size="xs"
22
22
  variant="thirdary"
23
23
  :label="periodButton.title"
24
- v-bind="attrs.periodButtonActiveAttrs"
24
+ v-bind="periodButtonActiveAttrs"
25
25
  @click="onClickPeriodButton(periodButton.name)"
26
26
  />
27
27
  </template>
28
28
  </div>
29
29
 
30
- <div v-bind="attrs.periodsRowAttrs">
30
+ <div v-bind="periodsRowAttrs">
31
31
  <UButton
32
32
  v-if="customRangeButton.range.to && customRangeButton.range.from && PERIOD.custom !== period"
33
33
  square
@@ -35,13 +35,13 @@
35
35
  no-ring
36
36
  size="xs"
37
37
  variant="thirdary"
38
- v-bind="attrs.periodButtonAttrs"
38
+ v-bind="periodButtonAttrs"
39
39
  @click="onClickCustomRangeButton"
40
40
  >
41
41
  {{ customRangeButton.label }}
42
42
  <span
43
43
  v-if="customRangeButton.description"
44
- v-bind="attrs.customRangeDescription"
44
+ v-bind="customRangeDescription"
45
45
  v-text="customRangeButton.description"
46
46
  />
47
47
  </UButton>
@@ -53,13 +53,13 @@
53
53
  no-ring
54
54
  size="xs"
55
55
  variant="thirdary"
56
- v-bind="attrs.periodButtonActiveAttrs"
56
+ v-bind="periodButtonActiveAttrs"
57
57
  @click="onClickCustomRangeButton"
58
58
  >
59
59
  {{ customRangeButton.label }}
60
60
  <span
61
61
  v-if="customRangeButton.description"
62
- v-bind="attrs.customRangeDescription"
62
+ v-bind="customRangeDescription"
63
63
  v-text="customRangeButton.description"
64
64
  />
65
65
  </UButton>
@@ -73,7 +73,7 @@
73
73
  variant="thirdary"
74
74
  :label="locale.ownRange"
75
75
  :left-icon="config.defaults.ownRangeIcon"
76
- v-bind="attrs.periodButtonAttrs"
76
+ v-bind="periodButtonAttrs"
77
77
  @click="onClickOwnRange"
78
78
  />
79
79
 
@@ -86,13 +86,13 @@
86
86
  variant="thirdary"
87
87
  :label="locale.ownRange"
88
88
  :left-icon="config.defaults.ownRangeIcon"
89
- v-bind="attrs.periodButtonActiveAttrs"
89
+ v-bind="periodButtonActiveAttrs"
90
90
  @click="onClickOwnRange"
91
91
  />
92
92
  </div>
93
93
 
94
94
  <template v-if="!isPeriod.ownRange && !isPeriod.custom">
95
- <div v-bind="attrs.rangeSwitchWrapperAttrs">
95
+ <div v-bind="rangeSwitchWrapperAttrs">
96
96
  <UButton
97
97
  square
98
98
  no-ring
@@ -100,11 +100,11 @@
100
100
  color="gray"
101
101
  variant="thirdary"
102
102
  :left-icon="config.defaults.prevIcon"
103
- v-bind="attrs.rangeSwitchButtonAttrs"
103
+ v-bind="rangeSwitchButtonAttrs"
104
104
  @click="emit('clickPrev')"
105
105
  />
106
106
 
107
- <div v-bind="attrs.rangeSwitchTitleAttrs">
107
+ <div v-bind="rangeSwitchTitleAttrs">
108
108
  {{ rangeSwitchTitle }}
109
109
  </div>
110
110
 
@@ -115,12 +115,12 @@
115
115
  color="gray"
116
116
  variant="thirdary"
117
117
  :left-icon="config.defaults.nextIcon"
118
- v-bind="attrs.rangeSwitchButtonAttrs"
118
+ v-bind="rangeSwitchButtonAttrs"
119
119
  @click="emit('clickNext')"
120
120
  />
121
121
  </div>
122
122
 
123
- <div v-if="isDatePeriodOutOfRange" v-bind="attrs.periodDateListAttrs">
123
+ <div v-if="isDatePeriodOutOfRange" v-bind="periodDateListAttrs">
124
124
  <template v-for="(date, index) in periodDateList" :key="date.title">
125
125
  <UButton
126
126
  v-if="getDatePeriodState(date, index).isActive"
@@ -128,7 +128,7 @@
128
128
  size="sm"
129
129
  variant="thirdary"
130
130
  :disabled="isDatePeriodOutOfRange(date)"
131
- v-bind="attrs.periodDateActiveAttrs"
131
+ v-bind="periodDateActiveAttrs"
132
132
  :label="String(date.title)"
133
133
  :class="{ 'rounded-dynamic': getDatePeriodState(date, index).isSingleItem }"
134
134
  @click="selectDate(date), toggleMenu()"
@@ -140,7 +140,7 @@
140
140
  size="sm"
141
141
  variant="thirdary"
142
142
  :disabled="isDatePeriodOutOfRange(date)"
143
- v-bind="attrs.firstPeriodGridDateAttrs"
143
+ v-bind="firstPeriodGridDateAttrs"
144
144
  :label="String(date.title)"
145
145
  :class="{ 'rounded-dynamic': getDatePeriodState(date, index).isSingleItem }"
146
146
  @click="selectDate(date), toggleMenu()"
@@ -152,7 +152,7 @@
152
152
  size="sm"
153
153
  variant="thirdary"
154
154
  :disabled="isDatePeriodOutOfRange(date)"
155
- v-bind="attrs.firstPeriodListDateAttrs"
155
+ v-bind="firstPeriodListDateAttrs"
156
156
  :label="String(date.title)"
157
157
  :class="{ 'rounded-dynamic': getDatePeriodState(date, index).isSingleItem }"
158
158
  @click="selectDate(date), toggleMenu()"
@@ -164,7 +164,7 @@
164
164
  size="sm"
165
165
  variant="thirdary"
166
166
  :disabled="isDatePeriodOutOfRange(date)"
167
- v-bind="attrs.lastPeriodGridDateAttrs"
167
+ v-bind="lastPeriodGridDateAttrs"
168
168
  :label="String(date.title)"
169
169
  :class="{ 'rounded-dynamic': getDatePeriodState(date, index).isSingleItem }"
170
170
  @click="selectDate(date), toggleMenu()"
@@ -176,7 +176,7 @@
176
176
  size="sm"
177
177
  variant="thirdary"
178
178
  :disabled="isDatePeriodOutOfRange(date)"
179
- v-bind="attrs.lastPeriodListDateAttrs"
179
+ v-bind="lastPeriodListDateAttrs"
180
180
  :label="String(date.title)"
181
181
  :class="{ 'rounded-dynamic': getDatePeriodState(date, index).isSingleItem }"
182
182
  @click="selectDate(date), toggleMenu()"
@@ -188,7 +188,7 @@
188
188
  size="sm"
189
189
  variant="thirdary"
190
190
  :disabled="isDatePeriodOutOfRange(date)"
191
- v-bind="attrs.periodDateInRangeAttrs"
191
+ v-bind="periodDateInRangeAttrs"
192
192
  :label="String(date.title)"
193
193
  :class="{ 'rounded-dynamic': getDatePeriodState(date, index).isSingleItem }"
194
194
  @click="selectDate(date), toggleMenu()"
@@ -200,7 +200,7 @@
200
200
  size="sm"
201
201
  variant="thirdary"
202
202
  :disabled="isDatePeriodOutOfRange(date)"
203
- v-bind="attrs.periodDateAttrs"
203
+ v-bind="periodDateAttrs"
204
204
  :label="String(date.title)"
205
205
  @click="selectDate(date), toggleMenu()"
206
206
  />
@@ -274,6 +274,24 @@ const period = defineModel("period", { required: true, type: String });
274
274
 
275
275
  const isDatePeriodOutOfRange = inject("isDatePeriodOutOfRange", null);
276
276
 
277
+ const {
278
+ periodButtonAttrs,
279
+ periodsRowAttrs,
280
+ periodButtonActiveAttrs,
281
+ customRangeDescription,
282
+ rangeSwitchWrapperAttrs,
283
+ rangeSwitchButtonAttrs,
284
+ rangeSwitchTitleAttrs,
285
+ periodDateListAttrs,
286
+ periodDateActiveAttrs,
287
+ firstPeriodGridDateAttrs,
288
+ firstPeriodListDateAttrs,
289
+ lastPeriodGridDateAttrs,
290
+ lastPeriodListDateAttrs,
291
+ periodDateInRangeAttrs,
292
+ periodDateAttrs,
293
+ } = props.attrs;
294
+
277
295
  const periods = computed(() => [
278
296
  { name: PERIOD.week, title: props.locale.week },
279
297
  { name: PERIOD.month, title: props.locale.month },
@@ -64,20 +64,25 @@ export default /*tw*/ {
64
64
  periodDateActive: "bg-gray-100",
65
65
  customRangeDescription: "",
66
66
  rangeInputWrapper: "flex mt-4 -space-x-px group/range-input-wrapper",
67
- rangeInputFirst: "group/range-input-first",
68
- rangeInputLast: "group/range-input-last",
69
- rangeInput: {
67
+ rangeInputFirst: {
70
68
  component: "{UInput}",
71
69
  label: {
72
70
  component: "{ULabel}",
73
71
  wrapper: "w-full hover:z-10 focus:z-10",
74
72
  description: "hidden",
75
73
  },
76
- block: `
77
- focus-within:z-10 focus-within:ring-0
78
- group-[]/range-input-first:rounded-r-none group-[]/range-input-last:rounded-l-none
79
- `,
80
- input: "group-[]/range-input-first:rounded-r-none group-[]/range-input-last:rounded-l-none",
74
+ block: "focus-within:z-10 focus-within:ring-0 rounded-r-none",
75
+ input: "rounded-r-none",
76
+ },
77
+ rangeInputLast: {
78
+ component: "{UInput}",
79
+ label: {
80
+ component: "{ULabel}",
81
+ wrapper: "w-full hover:z-10 focus:z-10",
82
+ description: "hidden",
83
+ },
84
+ block: "focus-within:z-10 focus-within:ring-0 rounded-l-none",
85
+ input: "rounded-l-none",
81
86
  },
82
87
  inputRangeError: "text-xs font-normal leading-none mt-2 text-center text-red-500",
83
88
  calendar: {
@@ -1,223 +1,115 @@
1
- import useUI from "../composables/useUI.js";
2
- import { cx, cva } from "../utils/utilUI.js";
3
-
4
1
  import { computed, watchEffect } from "vue";
5
2
  import { merge } from "lodash-es";
6
3
 
4
+ import useUI from "../composables/useUI.js";
5
+
7
6
  import defaultConfig from "./config.js";
8
7
  import { POSITION } from "../composables/useAutoPosition.js";
9
8
 
10
9
  export default function useAttrs(props, { isShownMenu, isTop, isRight, isPeriod }) {
11
- const { config, getAttrs, isSystemKey, hasSlotContent, isCVA } = useUI(
10
+ const { config, getKeysAttrs, hasSlotContent, getExtendingKeysClasses } = useUI(
12
11
  defaultConfig,
13
12
  () => props.config,
14
13
  );
15
- const attrs = {};
16
14
 
17
- const variantKeys = [
18
- "rangeInputFirst",
19
- "rangeInputLast",
20
- "periodButtonActive",
21
- "periodDateWeekList",
15
+ const mutatedProps = computed(() => ({
16
+ openDirectionY: isTop.value ? POSITION.top : POSITION.bottom,
17
+ openDirectionX: isRight.value ? POSITION.right : POSITION.left,
18
+ error: Boolean(props.error),
19
+ description: Boolean(props.description),
20
+ }));
21
+
22
+ const extendingKeys = [
23
+ "buttonWrapperActive",
24
+ "buttonActive",
25
+ "edgePeriodDate",
22
26
  "periodDateMonthList",
23
- "periodDateQuarterList",
24
- "periodDateYearList",
25
- "firstPeriodGridDate",
26
- "firstPeriodListDate",
27
- "lastPeriodGridDate",
28
- "lastPeriodListDate",
29
- "periodDateActive",
30
- "periodDateInRange",
31
27
  ];
28
+ const extendingKeysClasses = getExtendingKeysClasses(
29
+ [
30
+ ...extendingKeys,
31
+ "periodButton",
32
+ "periodDateList",
33
+ "periodDate",
34
+ "periodDateWeekList",
35
+ "periodDateQuarterList",
36
+ "periodDateYearList",
37
+ ],
38
+ mutatedProps,
39
+ );
32
40
 
33
- for (const key in defaultConfig) {
34
- if (isSystemKey(key) && variantKeys.includes(key)) continue;
35
-
36
- const classes = computed(() => {
37
- let value = config.value[key];
38
-
39
- if (isCVA(value)) {
40
- value = cva(value)({
41
- ...props,
42
- error: Boolean(props.error),
43
- description: Boolean(props.description),
44
- });
45
- }
46
-
47
- return value;
48
- });
49
-
50
- attrs[`${key}Attrs`] = getAttrs(key, { classes });
51
-
52
- if (key === "menu") {
53
- const menuAttrs = attrs[`${key}Attrs`];
54
-
55
- attrs[`${key}Attrs`] = computed(() => ({
56
- ...menuAttrs.value,
57
- class: cx([
58
- cva(config.value.menu)({
59
- openDirectionY: isTop.value ? POSITION.top : POSITION.bottom,
60
- openDirectionX: isRight.value ? POSITION.right : POSITION.left,
61
- }),
62
- menuAttrs.value.class,
63
- ]),
64
- }));
65
- }
66
-
67
- if (key === "buttonWrapper") {
68
- const buttonWrapperAttrs = attrs[`${key}Attrs`];
69
-
70
- attrs[`${key}Attrs`] = computed(() => ({
71
- ...buttonWrapperAttrs.value,
72
- class: cx([
73
- buttonWrapperAttrs.value.class,
74
- isShownMenu.value && config.value.buttonWrapperActive,
75
- ]),
76
- }));
77
- }
78
-
79
- if (key === "button") {
80
- const buttonAttrs = attrs[`${key}Attrs`];
81
-
82
- attrs[`${key}Attrs`] = computed(() => ({
83
- ...buttonAttrs.value,
84
- class: cx([buttonAttrs.value.class, isShownMenu.value && config.value.buttonActive]),
85
- }));
86
- }
87
-
88
- if (key === "calendar") {
89
- /* Merging DatePickerRange's i18n translations into Calendar's i18n translations. */
90
- watchEffect(() => {
91
- const calendarConfig = attrs[`${key}Attrs`].value.config || {};
92
-
93
- if (!calendarConfig.i18n || props.config.i18n) {
94
- attrs[`${key}Attrs`].value.config.i18n = merge(calendarConfig.i18n, config.value.i18n);
95
- }
96
- });
97
- }
98
- }
99
-
100
- for (const key of variantKeys) {
101
- if (key === "rangeInputFirst") {
102
- attrs[`${key}Attrs`] = computed(() => ({
103
- ...attrs.rangeInputAttrs.value,
104
- class: cx([attrs.rangeInputAttrs.value.class, config.value.rangeInputFirst]),
105
- }));
106
- }
107
-
108
- if (key === "rangeInputLast") {
109
- attrs[`${key}Attrs`] = computed(() => ({
110
- ...attrs.rangeInputAttrs.value,
111
- class: cx([attrs.rangeInputAttrs.value.class, config.value.rangeInputLast]),
112
- }));
113
- }
114
-
115
- if (key === "periodButtonActive") {
116
- attrs[`${key}Attrs`] = computed(() => ({
117
- ...attrs.periodButtonAttrs.value,
118
- class: cx([attrs.periodButtonAttrs.value.class, config.value.periodButtonActive]),
119
- }));
120
- }
121
-
122
- if (key === "periodDateWeekList") {
123
- attrs[`${key}Attrs`] = computed(() => ({
124
- ...attrs.periodDateListAttrs.value,
125
- class: cx([attrs.periodDateListAttrs.value.class, config.value.periodDateWeekList]),
126
- }));
127
- }
128
-
129
- if (key === "periodDateMonthList") {
130
- attrs[`${key}Attrs`] = computed(() => ({
131
- ...attrs.periodDateListAttrs.value,
132
- class: cx([attrs.periodDateListAttrs.value.class, config.value.periodDateMonthList]),
133
- }));
134
- }
135
-
136
- if (key === "periodDateQuarterList") {
137
- attrs[`${key}Attrs`] = computed(() => ({
138
- ...attrs.periodDateListAttrs.value,
139
- class: cx([attrs.periodDateListAttrs.value.class, config.value.periodDateQuarterList]),
140
- }));
141
- }
142
-
143
- if (key === "periodDateYearList") {
144
- attrs[`${key}Attrs`] = computed(() => ({
145
- ...attrs.periodDateListAttrs.value,
146
- class: cx([attrs.periodDateListAttrs.value.class, config.value.periodDateYearList]),
147
- }));
148
- }
149
-
150
- if (key === "periodDateActive") {
151
- attrs[`${key}Attrs`] = computed(() => ({
152
- ...attrs.periodDateAttrs.value,
153
- class: cx([attrs.periodDateAttrs.value.class, config.value.periodDateActive]),
154
- }));
155
- }
41
+ const keysAttrs = getKeysAttrs(mutatedProps, extendingKeys, {
42
+ buttonWrapper: {
43
+ extend: computed(() => [isShownMenu.value && extendingKeysClasses.buttonWrapperActive.value]),
44
+ },
45
+ button: {
46
+ extend: computed(() => [isShownMenu.value && extendingKeysClasses.buttonActive.value]),
47
+ },
48
+ periodDateList: {
49
+ extend: computed(() => [
50
+ isPeriod.value.week && extendingKeysClasses.periodDateWeekList.value,
51
+ isPeriod.value.month && extendingKeysClasses.periodDateMonthList.value,
52
+ isPeriod.value.quarter && extendingKeysClasses.periodDateQuarterList.value,
53
+ isPeriod.value.year && extendingKeysClasses.periodDateYearList.value,
54
+ ]),
55
+ },
56
+ periodButtonActive: {
57
+ base: computed(() => [extendingKeysClasses.periodButton.value]),
58
+ },
59
+ periodDateWeekList: {
60
+ base: computed(() => [extendingKeysClasses.periodDateList.value]),
61
+ },
62
+ periodDateQuarterList: {
63
+ base: computed(() => [extendingKeysClasses.periodDateList.value]),
64
+ },
65
+ periodDateYearList: {
66
+ base: computed(() => [extendingKeysClasses.periodDateList.value]),
67
+ },
68
+ periodDateActive: {
69
+ base: computed(() => [extendingKeysClasses.periodDate.value]),
70
+ },
71
+ periodDateInRange: {
72
+ base: computed(() => [extendingKeysClasses.periodDate.value]),
73
+ },
74
+ firstPeriodGridDate: {
75
+ base: computed(() => [
76
+ extendingKeysClasses.periodDate.value,
77
+ extendingKeysClasses.edgePeriodDate.value,
78
+ ]),
79
+ },
80
+ firstPeriodListDate: {
81
+ base: computed(() => [
82
+ extendingKeysClasses.periodDate.value,
83
+ extendingKeysClasses.edgePeriodDate.value,
84
+ ]),
85
+ },
86
+ lastPeriodGridDate: {
87
+ base: computed(() => [
88
+ extendingKeysClasses.periodDate.value,
89
+ extendingKeysClasses.edgePeriodDate.value,
90
+ ]),
91
+ },
92
+ lastPeriodListDate: {
93
+ base: computed(() => [
94
+ extendingKeysClasses.periodDate.value,
95
+ extendingKeysClasses.edgePeriodDate.value,
96
+ ]),
97
+ },
98
+ });
156
99
 
157
- if (key === "periodDateInRange") {
158
- attrs[`${key}Attrs`] = computed(() => ({
159
- ...attrs.periodDateAttrs.value,
160
- class: cx([attrs.periodDateAttrs.value.class, config.value.periodDateInRange]),
161
- }));
162
- }
100
+ /* Merging DatePickerRange's i18n translations into Calendar's i18n translations. */
101
+ watchEffect(() => {
102
+ const calendarConfig = keysAttrs.calendarAttrs.value.config || {};
163
103
 
164
- if (
165
- [
166
- "firstPeriodGridDate",
167
- "firstPeriodListDate",
168
- "lastPeriodGridDate",
169
- "lastPeriodListDate",
170
- ].includes(key)
171
- ) {
172
- attrs[`${key}Attrs`] = computed(() => ({
173
- ...attrs.periodDateAttrs.value,
174
- class: cx([
175
- attrs.periodDateAttrs.value.class,
176
- config.value.edgePeriodDate,
177
- config.value[key],
178
- ]),
179
- }));
104
+ if (!calendarConfig.i18n || props.config.i18n) {
105
+ keysAttrs.calendarAttrs.value.config.i18n = merge(calendarConfig.i18n, config.value.i18n);
180
106
  }
181
- }
182
-
183
- const periodDateListAttrs = computed(() => {
184
- if (isPeriod.value.week) return attrs.periodDateWeekListAttrs.value;
185
- if (isPeriod.value.month) return attrs.periodDateMonthListAttrs.value;
186
- if (isPeriod.value.quarter) return attrs.periodDateQuarterListAttrs.value;
187
- if (isPeriod.value.year) return attrs.periodDateYearListAttrs.value;
188
-
189
- return attrs.periodDateListAttrs.value;
190
107
  });
191
108
 
192
- const periodDatesMenuAttrs = computed(() => ({
193
- periodsRowAttrs: attrs.periodsRowAttrs.value,
194
- periodButtonAttrs: attrs.periodButtonAttrs.value,
195
- periodButtonActiveAttrs: attrs.periodButtonActiveAttrs.value,
196
- periodDateAttrs: attrs.periodDateAttrs.value,
197
- periodDateActiveAttrs: attrs.periodDateActiveAttrs.value,
198
- periodDateInRangeAttrs: attrs.periodDateInRangeAttrs.value,
199
- periodDateListAttrs: periodDateListAttrs.value,
200
- rangeSwitchWrapperAttrs: attrs.rangeSwitchWrapperAttrs.value,
201
- rangeSwitchButtonAttrs: attrs.rangeSwitchButtonAttrs.value,
202
- rangeSwitchTitleAttrs: attrs.rangeSwitchTitleAttrs.value,
203
- lastPeriodGridDateAttrs: attrs.lastPeriodGridDateAttrs.value,
204
- firstPeriodGridDateAttrs: attrs.firstPeriodGridDateAttrs.value,
205
- lastPeriodListDateAttrs: attrs.lastPeriodListDateAttrs.value,
206
- firstPeriodListDateAttrs: attrs.firstPeriodListDateAttrs.value,
207
- customRangeDescription: attrs.customRangeDescriptionAttrs.value,
208
- }));
209
-
210
- const rangeInputsAttrs = computed(() => ({
211
- rangeInputFirstAttrs: attrs.rangeInputFirstAttrs.value,
212
- rangeInputLastAttrs: attrs.rangeInputLastAttrs.value,
213
- }));
214
-
215
109
  return {
216
- ...attrs,
217
- periodDatesMenuAttrs,
218
- rangeInputsAttrs,
219
- periodDateListAttrs,
220
110
  config,
111
+ keysAttrs,
112
+ ...keysAttrs,
221
113
  hasSlotContent,
222
114
  };
223
115
  }
@@ -1,9 +1,9 @@
1
1
  /**
2
- Deeply clone given object (same as lodash.cloneDeep).
3
- @param {Object} entity
4
- @param cache
5
-
6
- @returns {Object}
2
+ * Deeply clone given object (same as lodash.cloneDeep).
3
+ * @param {Object} entity
4
+ * @param cache
5
+ *
6
+ * @returns {Object}
7
7
  */
8
8
  export function cloneDeep(entity, cache = new WeakMap()) {
9
9
  // primitives
@@ -38,11 +38,11 @@ export function cloneDeep(entity, cache = new WeakMap()) {
38
38
  }
39
39
 
40
40
  /**
41
- Creates a debounced function with delay (same as lodash.debounce).
42
- @param {Function} func
43
- @param {Number} ms
44
-
45
- @returns {Function}
41
+ * Creates a debounced function with delay (same as lodash.debounce).
42
+ * @param {Function} func
43
+ * @param {Number} ms
44
+ *
45
+ * @returns {Function}
46
46
  */
47
47
  export function createDebounce(func, ms) {
48
48
  let timeout;
@@ -54,13 +54,13 @@ export function createDebounce(func, ms) {
54
54
  }
55
55
 
56
56
  /**
57
- Change page title in runtime by provided config.
58
- @param {Object} config
59
- @param {string} config.title
60
- @param {string} config.separator
61
- @param {string} config.suffix
62
-
63
- @returns {VoidFunction}
57
+ * Change page title in runtime by provided config.
58
+ * @param {Object} config
59
+ * @param {string} config.title
60
+ * @param {string} config.separator
61
+ * @param {string} config.suffix
62
+ *
63
+ * @returns {VoidFunction}
64
64
  */
65
65
  export function setTitle({ title, separator = " / ", suffix = "" }) {
66
66
  if (isCSR) {
@@ -69,13 +69,13 @@ export function setTitle({ title, separator = " / ", suffix = "" }) {
69
69
  }
70
70
 
71
71
  /**
72
- Check is code rendering on the server side.
73
- @returns {boolean}
72
+ * Check is code rendering on the server side.
73
+ * @returns {boolean}
74
74
  */
75
75
  export const isSSR = typeof window === "undefined";
76
76
 
77
77
  /**
78
- Check is code rendering on the client side.
79
- @returns {boolean}
78
+ * Check is code rendering on the client side.
79
+ * @returns {boolean}
80
80
  */
81
81
  export const isCSR = typeof window !== "undefined";
@@ -144,13 +144,6 @@ export function getSource(defaultConfig) {
144
144
  return defaultConfig.replace("export default /*tw*/ ", "").replace(";", "");
145
145
  }
146
146
 
147
- // TODO: remove it when allSlotsFragment will be replaced to getSlotsFragment
148
- export const allSlotsFragment = `
149
- <template v-for="(slot, index) of slots" :key="index" v-slot:[slot]>
150
- <template v-if="args[slot + 'Slot']">{{ args[slot + 'Slot'] }}</template>
151
- </template>
152
- `;
153
-
154
147
  export function getSlotsFragment(defaultTemplate) {
155
148
  return `
156
149
  <template v-for="(slot, index) of slots" :key="index" v-slot:[slot]>
package/utils/utilUI.js CHANGED
@@ -10,9 +10,9 @@ import {
10
10
  } from "../constants.js";
11
11
 
12
12
  /**
13
- Load Vueless config from the project root.
14
- Both for server and client side renderings.
15
- IIFE for SSR is used to prevent top level await issue.
13
+ * Load Vueless config from the project root.
14
+ * Both for server and client side renderings.
15
+ * IIFE for SSR is used to prevent top level await issue.
16
16
  */
17
17
  export let vuelessConfig = {};
18
18
 
@@ -35,9 +35,9 @@ if (isCSR) {
35
35
  }
36
36
 
37
37
  /**
38
- Extend twMerge (tailwind merge) by vueless and user config:
39
- All list of rules available here:
40
- https://github.com/dcastil/tailwind-merge/blob/v2.3.0/src/lib/default-config.ts
38
+ * Extend twMerge (tailwind merge) by vueless and user config:
39
+ * All list of rules available here:
40
+ * https://github.com/dcastil/tailwind-merge/blob/v2.3.0/src/lib/default-config.ts
41
41
  */
42
42
  const twMerge = extendTailwindMerge(
43
43
  merge(
@@ -59,11 +59,11 @@ const twMerge = extendTailwindMerge(
59
59
  );
60
60
 
61
61
  /**
62
- Export cva (class variance authority) methods:
63
- * extended with tailwind-merge
64
- * remove all Vueless nested component names ({U...} strings) from class list string.
65
- Learn more here: https://beta.cva.style
66
- */
62
+ * Export cva (class variance authority) methods:
63
+ * extended with tailwind-merge
64
+ * remove all Vueless nested component names ({U...} strings) from class list string.
65
+ * Learn more here: https://beta.cva.style
66
+ */
67
67
  export const {
68
68
  cx,
69
69
  compose,
@@ -84,11 +84,11 @@ export const cva = ({ base = "", variants = {}, compoundVariants = [], defaultVa
84
84
  });
85
85
 
86
86
  /**
87
- Return default values for component props, icons, etc..
88
- @param { Object } defaultConfig
89
- @param { String } name
90
-
91
- @returns { Object }
87
+ * Return default values for component props, icons, etc..
88
+ * @param { Object } defaultConfig
89
+ * @param { String } name
90
+ *
91
+ * @returns { Object }
92
92
  */
93
93
  export function getDefault(defaultConfig, name) {
94
94
  const defaults = merge(
@@ -102,10 +102,11 @@ export function getDefault(defaultConfig, name) {
102
102
  }
103
103
 
104
104
  /**
105
- Return `grayscale` color if in component config it `brand` but in vueless config it `grayscale`
106
- Otherwise return given color.
107
- @param { String } color
108
- @returns { String }
105
+ * Return `grayscale` color if in component config it `brand` but in vueless config it `grayscale`
106
+ * Otherwise return given color.
107
+ * @param { String } color
108
+ *
109
+ * @returns { String }
109
110
  */
110
111
  export function getColor(color) {
111
112
  return (vuelessConfig.brand ?? DEFAULT_BRAND_COLOR) === GRAYSCALE_COLOR && color === BRAND_COLOR
@@ -114,11 +115,11 @@ export function getColor(color) {
114
115
  }
115
116
 
116
117
  /**
117
- Replace in tailwind classes `{color}` variable into given color.
118
- @param { String } classes
119
- @param { String } color
120
-
121
- @returns { String }
118
+ * Replace in tailwind classes `{color}` variable into given color.
119
+ * @param { String } classes
120
+ * @param { String } color
121
+ *
122
+ * @returns { String }
122
123
  */
123
124
  export function setColor(classes, color) {
124
125
  if (typeof classes !== "string") {
@@ -129,9 +130,10 @@ export function setColor(classes, color) {
129
130
  }
130
131
 
131
132
  /**
132
- Generates simple unique identifier.
133
- @param { Number } length
134
- @returns { String }
133
+ * Generates simple unique identifier.
134
+ * @param { Number } length
135
+ *
136
+ * @returns { String }
135
137
  */
136
138
  export function getRandomId(length = 15) {
137
139
  const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
package/web-types.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "framework": "vue",
3
3
  "name": "vueless",
4
- "version": "0.0.382",
4
+ "version": "0.0.384",
5
5
  "contributions": {
6
6
  "html": {
7
7
  "description-markup": "markdown",