@volverjs/ui-vue 0.0.9-beta.2 → 0.0.9-beta.21

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 (146) hide show
  1. package/README.md +3 -3
  2. package/auto-imports.d.ts +2 -0
  3. package/dist/components/VvAccordion/VvAccordion.es.js +15 -7
  4. package/dist/components/VvAccordionGroup/VvAccordionGroup.es.js +15 -7
  5. package/dist/components/VvAction/VvAction.es.js +17 -8
  6. package/dist/components/VvAction/VvAction.umd.js +1 -1
  7. package/dist/components/VvAction/VvAction.vue.d.ts +9 -0
  8. package/dist/components/VvAction/index.d.ts +4 -0
  9. package/dist/components/VvAlert/VvAlert.es.js +22 -13
  10. package/dist/components/VvAlert/VvAlert.umd.js +1 -1
  11. package/dist/components/VvAlert/VvAlert.vue.d.ts +6 -6
  12. package/dist/components/VvAlert/index.d.ts +3 -3
  13. package/dist/components/VvAlertGroup/VvAlertGroup.es.js +22 -13
  14. package/dist/components/VvAlertGroup/VvAlertGroup.umd.js +1 -1
  15. package/dist/components/VvAlertGroup/VvAlertGroup.vue.d.ts +6 -6
  16. package/dist/components/VvAlertGroup/index.d.ts +2 -2
  17. package/dist/components/VvAvatar/VvAvatar.es.js +15 -7
  18. package/dist/components/VvAvatarGroup/VvAvatarGroup.es.js +15 -7
  19. package/dist/components/VvBadge/VvBadge.es.js +15 -7
  20. package/dist/components/VvBreadcrumb/VvBreadcrumb.es.js +15 -7
  21. package/dist/components/VvButton/VvButton.es.js +19 -9
  22. package/dist/components/VvButton/VvButton.umd.js +1 -1
  23. package/dist/components/VvButton/VvButton.vue.d.ts +9 -0
  24. package/dist/components/VvButton/index.d.ts +4 -0
  25. package/dist/components/VvButtonGroup/VvButtonGroup.es.js +15 -7
  26. package/dist/components/VvCard/VvCard.es.js +15 -7
  27. package/dist/components/VvCheckbox/VvCheckbox.es.js +99 -21
  28. package/dist/components/VvCheckbox/VvCheckbox.umd.js +1 -1
  29. package/dist/components/VvCheckbox/VvCheckbox.vue.d.ts +4 -4
  30. package/dist/components/VvCheckboxGroup/VvCheckboxGroup.es.js +105 -22
  31. package/dist/components/VvCheckboxGroup/VvCheckboxGroup.umd.js +1 -1
  32. package/dist/components/VvCheckboxGroup/VvCheckboxGroup.vue.d.ts +4 -4
  33. package/dist/components/VvCombobox/VvCombobox.es.js +256 -191
  34. package/dist/components/VvCombobox/VvCombobox.umd.js +1 -1
  35. package/dist/components/VvCombobox/VvCombobox.vue.d.ts +329 -101
  36. package/dist/components/VvCombobox/index.d.ts +123 -37
  37. package/dist/components/VvDialog/VvDialog.es.js +50 -37
  38. package/dist/components/VvDialog/VvDialog.umd.js +1 -1
  39. package/dist/components/VvDropdown/VvDropdown.es.js +32 -18
  40. package/dist/components/VvDropdown/VvDropdown.umd.js +1 -1
  41. package/dist/components/VvDropdown/VvDropdown.vue.d.ts +300 -92
  42. package/dist/components/VvDropdown/VvDropdownAction.vue.d.ts +9 -0
  43. package/dist/components/VvDropdown/index.d.ts +99 -30
  44. package/dist/components/VvDropdownAction/VvDropdownAction.es.js +17 -8
  45. package/dist/components/VvDropdownAction/VvDropdownAction.umd.js +1 -1
  46. package/dist/components/VvDropdownOptgroup/VvDropdownOptgroup.es.js +15 -7
  47. package/dist/components/VvDropdownOption/VvDropdownOption.es.js +15 -7
  48. package/dist/components/VvInputText/VvInputText.es.js +279 -116
  49. package/dist/components/VvInputText/VvInputText.umd.js +1 -1
  50. package/dist/components/VvInputText/VvInputText.vue.d.ts +23 -41
  51. package/dist/components/VvInputText/index.d.ts +15 -33
  52. package/dist/components/VvNav/VvNav.es.js +18 -9
  53. package/dist/components/VvNav/VvNav.umd.js +1 -1
  54. package/dist/components/VvNav/index.d.ts +1 -1
  55. package/dist/components/VvProgress/VvProgress.es.js +15 -7
  56. package/dist/components/VvRadio/VvRadio.es.js +99 -21
  57. package/dist/components/VvRadio/VvRadio.umd.js +1 -1
  58. package/dist/components/VvRadio/VvRadio.vue.d.ts +4 -4
  59. package/dist/components/VvRadioGroup/VvRadioGroup.es.js +105 -22
  60. package/dist/components/VvRadioGroup/VvRadioGroup.umd.js +1 -1
  61. package/dist/components/VvRadioGroup/VvRadioGroup.vue.d.ts +4 -4
  62. package/dist/components/VvSelect/VvSelect.es.js +95 -21
  63. package/dist/components/VvSelect/VvSelect.umd.js +1 -1
  64. package/dist/components/VvSelect/VvSelect.vue.d.ts +5 -5
  65. package/dist/components/VvTab/VvTab.es.js +18 -9
  66. package/dist/components/VvTab/VvTab.umd.js +1 -1
  67. package/dist/components/VvTextarea/VvTextarea.es.js +103 -26
  68. package/dist/components/VvTextarea/VvTextarea.umd.js +1 -1
  69. package/dist/components/VvTextarea/VvTextarea.vue.d.ts +4 -4
  70. package/dist/components/VvTooltip/VvTooltip.es.js +15 -7
  71. package/dist/components/common/HintSlot.d.ts +4 -3
  72. package/dist/components/index.d.ts +5 -0
  73. package/dist/components/index.es.js +1212 -626
  74. package/dist/components/index.umd.js +1 -1
  75. package/dist/composables/alert/useAlert.d.ts +27 -0
  76. package/dist/composables/index.d.ts +1 -0
  77. package/dist/composables/index.es.js +81 -0
  78. package/dist/composables/index.umd.js +1 -0
  79. package/dist/constants.d.ts +14 -0
  80. package/dist/directives/index.es.js +15 -7
  81. package/dist/directives/v-tooltip.es.js +15 -7
  82. package/dist/icons.es.js +3 -3
  83. package/dist/icons.umd.js +1 -1
  84. package/dist/props/index.d.ts +107 -31
  85. package/dist/resolvers/unplugin.es.js +3 -0
  86. package/dist/resolvers/unplugin.umd.js +1 -1
  87. package/dist/stories/AccordionGroup/AccordionGroup.stories.d.ts +2 -2
  88. package/dist/stories/AccordionGroup/AccordionGroupSlots.stories.d.ts +54 -269
  89. package/dist/stories/Alert/Alert.settings.d.ts +3 -7
  90. package/dist/stories/AlertGroup/AlertGroupSlots.stories.d.ts +2 -2
  91. package/dist/stories/AlertGroup/AlertGroupWithComposable.stories.d.ts +6 -0
  92. package/dist/stories/Button/Button.settings.d.ts +3 -13
  93. package/dist/stories/Combobox/Combobox.settings.d.ts +117 -19
  94. package/dist/stories/InputText/InputText.settings.d.ts +31 -9
  95. package/dist/stories/InputText/InputText.stories.d.ts +0 -1
  96. package/dist/stories/InputText/InputTextMask.stories.d.ts +12 -0
  97. package/dist/stories/Nav/Nav.settings.d.ts +3 -21
  98. package/package.json +75 -66
  99. package/src/assets/icons/detailed.json +1 -1
  100. package/src/assets/icons/normal.json +1 -1
  101. package/src/assets/icons/simple.json +1 -1
  102. package/src/components/VvAction/VvAction.vue +2 -1
  103. package/src/components/VvAlert/VvAlert.vue +5 -1
  104. package/src/components/VvAlert/index.ts +3 -3
  105. package/src/components/VvAlertGroup/VvAlertGroup.vue +2 -0
  106. package/src/components/VvButton/VvButton.vue +1 -0
  107. package/src/components/VvCheckbox/VvCheckbox.vue +8 -1
  108. package/src/components/VvCheckboxGroup/VvCheckboxGroup.vue +8 -1
  109. package/src/components/VvCombobox/VvCombobox.vue +43 -23
  110. package/src/components/VvCombobox/index.ts +24 -0
  111. package/src/components/VvDialog/VvDialog.vue +22 -19
  112. package/src/components/VvDropdown/VvDropdown.vue +24 -18
  113. package/src/components/VvInputText/VvInputText.vue +177 -55
  114. package/src/components/VvInputText/index.ts +32 -34
  115. package/src/components/VvNav/VvNav.vue +1 -1
  116. package/src/components/VvNav/index.ts +1 -1
  117. package/src/components/VvRadio/VvRadio.vue +8 -1
  118. package/src/components/VvRadioGroup/VvRadioGroup.vue +8 -1
  119. package/src/components/VvSelect/VvSelect.vue +8 -1
  120. package/src/components/VvTextarea/VvTextarea.vue +16 -6
  121. package/src/components/common/HintSlot.ts +26 -13
  122. package/src/components/index.ts +5 -0
  123. package/src/composables/alert/useAlert.ts +103 -0
  124. package/src/composables/index.ts +1 -0
  125. package/src/constants.ts +26 -0
  126. package/src/props/index.ts +14 -11
  127. package/src/resolvers/unplugin.ts +3 -0
  128. package/src/stories/Alert/Alert.settings.ts +3 -1
  129. package/src/stories/AlertGroup/AlertGroup.test.ts +13 -0
  130. package/src/stories/AlertGroup/AlertGroupSlots.stories.ts +3 -3
  131. package/src/stories/AlertGroup/AlertGroupWithComposable.stories.ts +118 -0
  132. package/src/stories/Button/Button.settings.ts +5 -3
  133. package/src/stories/Combobox/Combobox.settings.ts +119 -2
  134. package/src/stories/Combobox/Combobox.test.ts +1 -1
  135. package/src/stories/InputText/InputText.settings.ts +36 -15
  136. package/src/stories/InputText/InputText.stories.ts +4 -12
  137. package/src/stories/InputText/InputText.test.ts +31 -15
  138. package/src/stories/InputText/InputTextMask.stories.ts +122 -0
  139. package/src/stories/Nav/Nav.settings.ts +3 -1
  140. package/src/stories/Tab/Tab.stories.ts +3 -3
  141. package/src/stories/Textarea/TextareaLength.stories.ts +1 -1
  142. package/src/types/alert.d.ts +20 -0
  143. /package/dist/components/{VvNavItemTitle → VvNav}/VvNavItemTitle.vue.d.ts +0 -0
  144. /package/dist/components/{VvNavSeparator → VvNav}/VvNavSeparator.d.ts +0 -0
  145. /package/src/components/{VvNavItemTitle → VvNav}/VvNavItemTitle.vue +0 -0
  146. /package/src/components/{VvNavSeparator → VvNav}/VvNavSeparator.ts +0 -0
@@ -6,7 +6,7 @@
6
6
 
7
7
  <script setup lang="ts">
8
8
  import type { InputHTMLAttributes } from 'vue'
9
- import { Mask } from 'maska'
9
+ import { useIMask } from 'vue-imask'
10
10
  import HintSlotFactory from '../common/HintSlot'
11
11
  import VvIcon from '../VvIcon/VvIcon.vue'
12
12
  import VvInputTextActionsFactory from '../VvInputText/VvInputTextActions'
@@ -22,11 +22,12 @@
22
22
  const emit = defineEmits(VvInputTextEvents)
23
23
  const slots = useSlots()
24
24
 
25
- // template refs
26
- const inputEl = ref()
27
- const innerEl = ref()
28
-
29
- defineExpose({ $inner: innerEl })
25
+ // props merged with volver defaults (now only for labels)
26
+ const propsDefaults = useDefaults<typeof VvInputTextProps>(
27
+ 'VvInputText',
28
+ VvInputTextProps,
29
+ props,
30
+ )
30
31
 
31
32
  // data
32
33
  const {
@@ -39,6 +40,12 @@
39
40
  valid,
40
41
  invalid,
41
42
  loading,
43
+ debounce,
44
+ maxlength,
45
+ minlength,
46
+ type,
47
+ iMask,
48
+ step,
42
49
  } = toRefs(props)
43
50
  const hasId = useUniqueId(id)
44
51
  const hasHintId = computed(() => `${hasId.value}-hint`)
@@ -47,35 +54,144 @@
47
54
  props.floating && isEmpty(props.placeholder) ? ' ' : props.placeholder,
48
55
  )
49
56
 
50
- // debounce
51
- const localModelValue = useDebouncedInput(
52
- modelValue,
53
- emit,
54
- props.debounce,
57
+ // template refs
58
+ const maskReady = ref(false)
59
+ const { el, mask, typed, masked, unmasked } = useIMask(
60
+ computed(
61
+ () =>
62
+ iMask?.value ?? {
63
+ mask: /./,
64
+ },
65
+ ),
55
66
  {
56
- getter: (value) => {
57
- if (mask.value) {
58
- return mask.value.masked(value ?? '')
67
+ emit,
68
+ onAccept: () => {
69
+ if (!maskReady.value) {
70
+ return
59
71
  }
60
- return value
61
- },
62
- setter: (value) => {
63
- if (mask.value) {
64
- value = mask.value.unmasked(value)
72
+ emit('update:masked', masked.value)
73
+ if (type.value === INPUT_TYPES.NUMBER) {
74
+ if (masked.value === '') {
75
+ if (
76
+ localModelValue.value === null ||
77
+ localModelValue.value === undefined
78
+ ) {
79
+ return
80
+ }
81
+ localModelValue.value = undefined
82
+ return
83
+ }
84
+ if (typeof typed.value !== 'number') {
85
+ localModelValue.value = Number(typed.value)
86
+ return
87
+ }
88
+ localModelValue.value = typed.value
89
+ return
90
+ }
91
+ if (type.value === INPUT_TYPES.DATE) {
92
+ if (
93
+ el.value instanceof HTMLInputElement &&
94
+ el.value.type === 'date'
95
+ ) {
96
+ localModelValue.value = el.value.value
97
+ return
98
+ }
99
+ let date = typed.value
100
+ if (date === null || date === '') {
101
+ if (!localModelValue.value) {
102
+ return
103
+ }
104
+ localModelValue.value = ''
105
+ return
106
+ }
107
+ if (!(date instanceof Date)) {
108
+ date = new Date(date)
109
+ }
110
+ localModelValue.value = `${date.getFullYear()}-${(
111
+ '0' +
112
+ (date.getMonth() + 1)
113
+ ).slice(-2)}-${('0' + date.getDate()).slice(-2)}`
114
+ return
65
115
  }
66
- if (props.type === INPUT_TYPES.NUMBER) {
67
- return Number(value)
116
+ if (type.value === INPUT_TYPES.DATETIME_LOCAL) {
117
+ if (
118
+ el.value instanceof HTMLInputElement &&
119
+ el.value.type === 'datetime-local'
120
+ ) {
121
+ localModelValue.value = el.value.value
122
+ return
123
+ }
124
+ let date = typed.value
125
+ if (date === null || date === '') {
126
+ if (!localModelValue.value) {
127
+ return
128
+ }
129
+ localModelValue.value = ''
130
+ return
131
+ }
132
+ if (!(typed.value instanceof Date)) {
133
+ date = new Date(date)
134
+ }
135
+ localModelValue.value = `${date.getFullYear()}-${(
136
+ '0' +
137
+ (date.getMonth() + 1)
138
+ ).slice(-2)}-${('0' + date.getDate()).slice(-2)}T${(
139
+ '0' + date.getHours()
140
+ ).slice(-2)}:${('0' + date.getMinutes()).slice(-2)}`
141
+ return
68
142
  }
69
- return value
143
+ if (!localModelValue.value && !unmasked.value) {
144
+ return
145
+ }
146
+ localModelValue.value = unmasked.value
70
147
  },
71
148
  },
72
149
  )
150
+ onMounted(() => {
151
+ if (mask.value) {
152
+ maskReady.value = true
153
+ typed.value = localModelValue.value ?? ''
154
+ }
155
+ })
156
+ watch(
157
+ () => props.modelValue,
158
+ (newValue) => {
159
+ if (mask.value) {
160
+ typed.value =
161
+ newValue && iMask?.value?.mask === Date
162
+ ? new Date(newValue)
163
+ : newValue ?? ''
164
+ }
165
+ },
166
+ )
167
+ watch(
168
+ () => props.masked,
169
+ (newValue) => {
170
+ masked.value = newValue ?? ''
171
+ },
172
+ )
173
+ const inputEl = el as Ref<HTMLInputElement>
174
+ const innerEl = ref()
175
+
176
+ defineExpose({ $inner: innerEl })
177
+
178
+ // debounce
179
+ const localModelValue = useDebouncedInput(
180
+ modelValue,
181
+ emit,
182
+ debounce?.value ?? 0,
183
+ )
73
184
 
74
185
  // focus
75
186
  const { focused } = useComponentFocus(inputEl, emit)
76
187
  const isFocused = computed(
77
188
  () => focused.value && !props.disabled && !props.readonly,
78
189
  )
190
+ watch(isFocused, (newValue) => {
191
+ if (newValue && propsDefaults.value.selectOnFocus && inputEl.value) {
192
+ inputEl.value.select()
193
+ }
194
+ })
79
195
 
80
196
  // visibility
81
197
  const isVisible = useElementVisibility(inputEl)
@@ -106,12 +222,21 @@
106
222
  const isNumber = computed(() => props.type === INPUT_TYPES.NUMBER)
107
223
  const onStepUp = () => {
108
224
  if (isClickable.value) {
225
+ if (iMask?.value) {
226
+ typed.value = typed.value + Number(step?.value ?? 1)
227
+ return
228
+ }
109
229
  inputEl.value.stepUp()
110
230
  localModelValue.value = unref(inputEl).value
111
231
  }
112
232
  }
113
233
  const onStepDown = () => {
114
234
  if (isClickable.value) {
235
+ if (iMask?.value) {
236
+ typed.value = typed.value - Number(step?.value ?? 1)
237
+
238
+ return
239
+ }
115
240
  inputEl.value.stepDown()
116
241
  localModelValue.value = unref(inputEl).value
117
242
  }
@@ -120,7 +245,7 @@
120
245
  // search
121
246
  const isSearch = computed(() => props.type === INPUT_TYPES.SEARCH)
122
247
  const onClear = () => {
123
- localModelValue.value = undefined
248
+ localModelValue.value = ''
124
249
  }
125
250
 
126
251
  // icons
@@ -146,9 +271,9 @@
146
271
 
147
272
  // count
148
273
  const { formatted: countFormatted } = useTextCount(localModelValue, {
149
- mode: props.count,
150
- upperLimit: Number(props.maxlength),
151
- lowerLimit: Number(props.minlength),
274
+ mode: count.value,
275
+ upperLimit: Number(maxlength?.value),
276
+ lowerLimit: Number(minlength?.value),
152
277
  })
153
278
 
154
279
  // tabindex
@@ -200,6 +325,9 @@
200
325
  if (isDateTime.value && !isDirty.value && !focused.value) {
201
326
  return INPUT_TYPES.TEXT
202
327
  }
328
+ if (iMask?.value) {
329
+ return INPUT_TYPES.TEXT
330
+ }
203
331
  return props.type
204
332
  })()
205
333
  const toReturn: InputHTMLAttributes = {
@@ -278,7 +406,7 @@
278
406
  hasHintLabelOrSlot,
279
407
  hasInvalidLabelOrSlot,
280
408
  hintSlotScope,
281
- } = HintSlotFactory(props, slots)
409
+ } = HintSlotFactory(propsDefaults, slots)
282
410
  const PasswordInputActions = VvInputTextActionsFactory(
283
411
  INPUT_TYPES.PASSWORD,
284
412
  props,
@@ -292,33 +420,6 @@
292
420
  props,
293
421
  )
294
422
 
295
- // mask
296
- const mask = ref()
297
- watch(
298
- [
299
- () => props.mask,
300
- () => props.type,
301
- () => props.maskEager,
302
- () => props.maskReversed,
303
- () => props.maskTokens,
304
- () => props.maskTokensReplace,
305
- ],
306
- ([newMask, newType, eager, reversed, tokens, tokensReplace]) => {
307
- if (newMask && newType === INPUT_TYPES.TEXT) {
308
- mask.value = new Mask({
309
- mask: newMask,
310
- eager,
311
- reversed,
312
- tokens,
313
- tokensReplace,
314
- })
315
- return
316
- }
317
- mask.value = undefined
318
- },
319
- { immediate: true },
320
- )
321
-
322
423
  // auto-width
323
424
  const onClickInner = () => {
324
425
  if (isClickable.value) {
@@ -336,6 +437,26 @@
336
437
  : undefined,
337
438
  }
338
439
  })
440
+
441
+ // keydown
442
+ const onKeyDown = (event: KeyboardEvent) => {
443
+ switch (event.code) {
444
+ case 'ArrowUp':
445
+ if (isNumber.value) {
446
+ onStepUp()
447
+ event.preventDefault()
448
+ }
449
+ break
450
+
451
+ case 'ArrowDown':
452
+ if (isNumber.value) {
453
+ onStepDown()
454
+ event.preventDefault()
455
+ }
456
+ break
457
+ }
458
+ emit('keydown', event)
459
+ }
339
460
  </script>
340
461
 
341
462
  <template>
@@ -361,10 +482,11 @@
361
482
  <input
362
483
  :id="hasId"
363
484
  ref="inputEl"
364
- v-model="localModelValue"
365
485
  v-bind="hasAttrs"
366
486
  :style="hasStyle"
367
487
  @keyup="emit('keyup', $event)"
488
+ @keydown="onKeyDown"
489
+ @keypress="emit('keypress', $event)"
368
490
  />
369
491
  <div
370
492
  v-if="(unit || $slots.unit) && isDirty"
@@ -1,5 +1,5 @@
1
1
  import type { ExtractPropTypes, PropType } from 'vue'
2
- import type { MaskTokens } from 'maska'
2
+ import type { FactoryOpts } from 'imask'
3
3
  import { InputTextareaProps } from '../../props'
4
4
 
5
5
  export const INPUT_TYPES = {
@@ -28,7 +28,23 @@ export const TYPES_ICON = {
28
28
  SEARCH: 'close',
29
29
  } as const
30
30
 
31
- export const VvInputTextEvents = ['update:modelValue', 'focus', 'blur', 'keyup']
31
+ export const VvInputTextEvents = [
32
+ 'update:modelValue',
33
+ 'update:masked',
34
+ 'accept',
35
+ 'accept:typed',
36
+ 'accept:masked',
37
+ 'accept:unmasked',
38
+ 'complete',
39
+ 'complete:typed',
40
+ 'complete:masked',
41
+ 'complete:unmasked',
42
+ 'focus',
43
+ 'blur',
44
+ 'keyup',
45
+ 'keydown',
46
+ 'keypress',
47
+ ]
32
48
 
33
49
  export const VvInputTextProps = {
34
50
  ...InputTextareaProps,
@@ -137,45 +153,20 @@ export const VvInputTextProps = {
137
153
  default: 'Clear',
138
154
  },
139
155
  /**
140
- * Input mask, only for text type
141
- * @see https://beholdr.github.io/maska/
156
+ * iMask options
157
+ * @see https://imask.js.org/guide.html
142
158
  */
143
- mask: {
144
- type: String,
159
+ iMask: {
160
+ type: Object as PropType<FactoryOpts>,
145
161
  default: undefined,
146
162
  },
147
163
  /**
148
- * Show mask before typing
149
- * @see https://beholdr.github.io/maska/#/?id=maskinput-options
150
- */
151
- maskEager: {
152
- type: Boolean,
153
- default: false,
154
- },
155
- /**
156
- * Write values reverse (ex. for numbers)
157
- * @see https://beholdr.github.io/maska/#/?id=maskinput-options
158
- */
159
- maskReversed: {
160
- type: Boolean,
161
- default: false,
162
- },
163
- /**
164
- * Add mask custom tokens
165
- * @see https://beholdr.github.io/maska/#/?id=custom-tokens
164
+ * Masked value
166
165
  */
167
- maskTokens: {
168
- type: Object as PropType<MaskTokens>,
166
+ masked: {
167
+ type: String,
169
168
  default: undefined,
170
169
  },
171
- /**
172
- * Replace default tokens
173
- * @see https://beholdr.github.io/maska/#/?id=custom-tokens
174
- */
175
- maskTokensReplace: {
176
- type: Boolean,
177
- default: false,
178
- },
179
170
  /**
180
171
  * Adjust input width to content
181
172
  */
@@ -196,6 +187,13 @@ export const VvInputTextProps = {
196
187
  unit: {
197
188
  type: String,
198
189
  },
190
+ /**
191
+ * Select input text on focus
192
+ */
193
+ selectOnFocus: {
194
+ type: Boolean,
195
+ default: false,
196
+ },
199
197
  }
200
198
 
201
199
  export type VvInputTextPropsTypes = ExtractPropTypes<typeof VvInputTextProps>
@@ -55,7 +55,7 @@
55
55
  disabled: navItem.disabled,
56
56
  }"
57
57
  class="vv-nav__item-label"
58
- v-on="navItem.on || {}"
58
+ v-on="navItem.on"
59
59
  @click="onClick(navItem)"
60
60
  >
61
61
  {{ navItem.title }}
@@ -6,7 +6,7 @@ export type NavItem = {
6
6
  to?: string | { [key: string]: unknown }
7
7
  href?: string
8
8
  disabled?: boolean
9
- on: () => void
9
+ on?: Record<string, () => void>
10
10
  }
11
11
 
12
12
  export const VvNavProps = {
@@ -13,6 +13,13 @@
13
13
  const emit = defineEmits(VvRadioEvents)
14
14
  const slots = useSlots()
15
15
 
16
+ // props merged with volver defaults (now only for labels)
17
+ const propsDefaults = useDefaults<typeof VvRadioProps>(
18
+ 'VvRadio',
19
+ VvRadioProps,
20
+ props,
21
+ )
22
+
16
23
  // data
17
24
  const { id, disabled, readonly, modelValue, valid, invalid } =
18
25
  useGroupProps(props, emit)
@@ -77,7 +84,7 @@
77
84
  hasHintLabelOrSlot,
78
85
  hasInvalidLabelOrSlot,
79
86
  hintSlotScope,
80
- } = HintSlotFactory(props, slots)
87
+ } = HintSlotFactory(propsDefaults, slots)
81
88
  </script>
82
89
 
83
90
  <template>
@@ -17,6 +17,13 @@
17
17
  const emit = defineEmits(VvRadioGroupEvents)
18
18
  const slots = useSlots()
19
19
 
20
+ // props merged with volver defaults (now only for labels)
21
+ const propsDefaults = useDefaults<typeof VvRadioGroupProps>(
22
+ 'VvRadioGroup',
23
+ VvRadioGroupProps,
24
+ props,
25
+ )
26
+
20
27
  // data
21
28
  const modelValue = useVModel(props, 'modelValue', emit)
22
29
  const { disabled, readonly, vertical, valid, invalid, modifiers } =
@@ -58,7 +65,7 @@
58
65
  }
59
66
 
60
67
  // hint
61
- const { HintSlot, hintSlotScope } = HintSlotFactory(props, slots)
68
+ const { HintSlot, hintSlotScope } = HintSlotFactory(propsDefaults, slots)
62
69
  </script>
63
70
 
64
71
  <template>
@@ -16,6 +16,13 @@
16
16
  const emit = defineEmits(VvSelectEmits)
17
17
  const slots = useSlots()
18
18
 
19
+ // props merged with volver defaults (now only for labels)
20
+ const propsDefaults = useDefaults<typeof VvSelectProps>(
21
+ 'VvSelect',
22
+ VvSelectProps,
23
+ props,
24
+ )
25
+
19
26
  // template refs
20
27
  const select = ref()
21
28
 
@@ -25,7 +32,7 @@
25
32
  hasHintLabelOrSlot,
26
33
  hasInvalidLabelOrSlot,
27
34
  hintSlotScope,
28
- } = HintSlotFactory(props, slots)
35
+ } = HintSlotFactory(propsDefaults, slots)
29
36
 
30
37
  // data
31
38
  const {
@@ -15,6 +15,13 @@
15
15
  const emit = defineEmits(VvTextareaEvents)
16
16
  const slots = useSlots()
17
17
 
18
+ // props merged with volver defaults (now only for labels)
19
+ const propsDefaults = useDefaults<typeof VvTextareaProps>(
20
+ 'VvTextarea',
21
+ VvTextareaProps,
22
+ props,
23
+ )
24
+
18
25
  // template refs
19
26
  const textarea = ref()
20
27
 
@@ -30,6 +37,9 @@
30
37
  invalid,
31
38
  loading,
32
39
  modifiers,
40
+ debounce,
41
+ minlength,
42
+ maxlength,
33
43
  } = toRefs(props)
34
44
  const hasId = useUniqueId(id)
35
45
  const hasHintId = computed(() => `${hasId.value}-hint`)
@@ -39,7 +49,7 @@
39
49
  )
40
50
 
41
51
  // debounce
42
- const localModelValue = useDebouncedInput(modelValue, emit, props.debounce)
52
+ const localModelValue = useDebouncedInput(modelValue, emit, debounce?.value)
43
53
 
44
54
  // icons
45
55
  const { hasIcon, hasIconBefore, hasIconAfter } = useComponentIcon(
@@ -60,9 +70,9 @@
60
70
 
61
71
  // count
62
72
  const { formatted: countFormatted } = useTextCount(localModelValue, {
63
- mode: props.count,
64
- upperLimit: Number(props.maxlength),
65
- lowerLimit: Number(props.minlength),
73
+ mode: count?.value,
74
+ upperLimit: Number(maxlength?.value),
75
+ lowerLimit: Number(minlength?.value),
66
76
  })
67
77
 
68
78
  // tabindex
@@ -91,7 +101,7 @@
91
101
  hasHintLabelOrSlot,
92
102
  hasInvalidLabelOrSlot,
93
103
  hintSlotScope,
94
- } = HintSlotFactory(props, slots)
104
+ } = HintSlotFactory(propsDefaults, slots)
95
105
 
96
106
  // styles
97
107
  const bemCssClasses = useModifiers(
@@ -136,7 +146,7 @@
136
146
  'aria-errormessage': hasInvalidLabelOrSlot.value
137
147
  ? hasHintId.value
138
148
  : undefined,
139
- } as TextareaHTMLAttributes),
149
+ }) as TextareaHTMLAttributes,
140
150
  )
141
151
 
142
152
  // slots props
@@ -1,4 +1,5 @@
1
1
  import type { ExtractPropTypes, Slots } from 'vue'
2
+ import type { Ref } from 'vue'
2
3
 
3
4
  /**
4
5
  * Merge array of string
@@ -19,7 +20,7 @@ export type HintSlotProps = Readonly<
19
20
  default: ''
20
21
  required: true
21
22
  }
22
- modelValue: null
23
+ modelValue: unknown
23
24
  valid: BooleanConstructor
24
25
  validLabel: (StringConstructor | ArrayConstructor)[]
25
26
  invalid: BooleanConstructor
@@ -35,27 +36,39 @@ export type HintSlotProps = Readonly<
35
36
  * @param {Slots} parentSlots vue slots
36
37
  * @returns {Component} vue component
37
38
  */
38
- export function HintSlotFactory(props: HintSlotProps, slots: Slots) {
39
+ export function HintSlotFactory(
40
+ propsOrRef: HintSlotProps | Ref<HintSlotProps>,
41
+ slots: Slots,
42
+ ) {
43
+ const props = computed(() => {
44
+ if (isRef(propsOrRef)) {
45
+ return propsOrRef.value
46
+ }
47
+ return propsOrRef
48
+ })
49
+
39
50
  // label
40
- const invalidLabel = computed(() => joinLines(props.invalidLabel))
41
- const validLabel = computed(() => joinLines(props.validLabel))
42
- const loadingLabel = computed(() => props.loadingLabel)
43
- const hintLabel = computed(() => props.hintLabel)
51
+ const invalidLabel = computed(() => joinLines(props.value.invalidLabel))
52
+ const validLabel = computed(() => joinLines(props.value.validLabel))
53
+ const loadingLabel = computed(() => props.value.loadingLabel)
54
+ const hintLabel = computed(() => props.value.hintLabel)
44
55
 
45
56
  // type
46
57
  const hasLoadingLabelOrSlot = computed(() =>
47
- Boolean(props.loading && (slots.loading || loadingLabel.value)),
58
+ Boolean(props.value.loading && (slots.loading || loadingLabel.value)),
48
59
  )
49
60
  const hasInvalidLabelOrSlot = computed(
50
61
  () =>
51
62
  !hasLoadingLabelOrSlot.value &&
52
- Boolean(props.invalid && (slots.invalid || invalidLabel.value)),
63
+ Boolean(
64
+ props.value.invalid && (slots.invalid || invalidLabel.value),
65
+ ),
53
66
  )
54
67
  const hasValidLabelOrSlot = computed(
55
68
  () =>
56
69
  !hasLoadingLabelOrSlot.value &&
57
70
  !hasInvalidLabelOrSlot.value &&
58
- Boolean(props.valid && (slots.valid || validLabel.value)),
71
+ Boolean(props.value.valid && (slots.valid || validLabel.value)),
59
72
  )
60
73
  const hasHintLabelOrSlot = computed(
61
74
  () =>
@@ -72,10 +85,10 @@ export function HintSlotFactory(props: HintSlotProps, slots: Slots) {
72
85
  hasHintLabelOrSlot.value,
73
86
  )
74
87
  const hintSlotScope = computed(() => ({
75
- modelValue: props.modelValue,
76
- valid: props.valid,
77
- invalid: props.invalid,
78
- loading: props.loading,
88
+ modelValue: props.value.modelValue,
89
+ valid: props.value.valid,
90
+ invalid: props.value.invalid,
91
+ loading: props.value.loading,
79
92
  }))
80
93
  // component
81
94
  const HintSlot = defineComponent({
@@ -1,5 +1,7 @@
1
1
  export { default as VvAccordion } from './VvAccordion/VvAccordion.vue'
2
2
  export { default as VvAccordionGroup } from './VvAccordionGroup/VvAccordionGroup.vue'
3
+ export { default as VvAction } from './VvAction/VvAction.vue'
4
+ export { default as VvAlert } from './VvAlert/VvAlert.vue'
3
5
  export { default as VvBadge } from './VvBadge/VvBadge.vue'
4
6
  export { default as VvBreadcrumb } from './VvBreadcrumb/VvBreadcrumb.vue'
5
7
  export { default as VvButton } from './VvButton/VvButton.vue'
@@ -12,8 +14,11 @@ export { default as VvDialog } from './VvDialog/VvDialog.vue'
12
14
  export { default as VvDropdown } from './VvDropdown/VvDropdown.vue'
13
15
  export { default as VvIcon } from './VvIcon/VvIcon.vue'
14
16
  export { default as VvInputText } from './VvInputText/VvInputText.vue'
17
+ export { default as VvNav } from './VvNav/VvNav.vue'
15
18
  export { default as VvProgress } from './VvProgress/VvProgress.vue'
16
19
  export { default as VvRadio } from './VvRadio/VvRadio.vue'
17
20
  export { default as VvRadioGroup } from './VvRadioGroup/VvRadioGroup.vue'
18
21
  export { default as VvSelect } from './VvSelect/VvSelect.vue'
22
+ export { default as VvTab } from './VvTab/VvTab.vue'
19
23
  export { default as VvTextarea } from './VvTextarea/VvTextarea.vue'
24
+ export { default as VvTooltip } from './VvTooltip/VvTooltip.vue'