@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.
- package/README.md +3 -3
- package/auto-imports.d.ts +2 -0
- package/dist/components/VvAccordion/VvAccordion.es.js +15 -7
- package/dist/components/VvAccordionGroup/VvAccordionGroup.es.js +15 -7
- package/dist/components/VvAction/VvAction.es.js +17 -8
- package/dist/components/VvAction/VvAction.umd.js +1 -1
- package/dist/components/VvAction/VvAction.vue.d.ts +9 -0
- package/dist/components/VvAction/index.d.ts +4 -0
- package/dist/components/VvAlert/VvAlert.es.js +22 -13
- package/dist/components/VvAlert/VvAlert.umd.js +1 -1
- package/dist/components/VvAlert/VvAlert.vue.d.ts +6 -6
- package/dist/components/VvAlert/index.d.ts +3 -3
- package/dist/components/VvAlertGroup/VvAlertGroup.es.js +22 -13
- package/dist/components/VvAlertGroup/VvAlertGroup.umd.js +1 -1
- package/dist/components/VvAlertGroup/VvAlertGroup.vue.d.ts +6 -6
- package/dist/components/VvAlertGroup/index.d.ts +2 -2
- package/dist/components/VvAvatar/VvAvatar.es.js +15 -7
- package/dist/components/VvAvatarGroup/VvAvatarGroup.es.js +15 -7
- package/dist/components/VvBadge/VvBadge.es.js +15 -7
- package/dist/components/VvBreadcrumb/VvBreadcrumb.es.js +15 -7
- package/dist/components/VvButton/VvButton.es.js +19 -9
- package/dist/components/VvButton/VvButton.umd.js +1 -1
- package/dist/components/VvButton/VvButton.vue.d.ts +9 -0
- package/dist/components/VvButton/index.d.ts +4 -0
- package/dist/components/VvButtonGroup/VvButtonGroup.es.js +15 -7
- package/dist/components/VvCard/VvCard.es.js +15 -7
- package/dist/components/VvCheckbox/VvCheckbox.es.js +99 -21
- package/dist/components/VvCheckbox/VvCheckbox.umd.js +1 -1
- package/dist/components/VvCheckbox/VvCheckbox.vue.d.ts +4 -4
- package/dist/components/VvCheckboxGroup/VvCheckboxGroup.es.js +105 -22
- package/dist/components/VvCheckboxGroup/VvCheckboxGroup.umd.js +1 -1
- package/dist/components/VvCheckboxGroup/VvCheckboxGroup.vue.d.ts +4 -4
- package/dist/components/VvCombobox/VvCombobox.es.js +256 -191
- package/dist/components/VvCombobox/VvCombobox.umd.js +1 -1
- package/dist/components/VvCombobox/VvCombobox.vue.d.ts +329 -101
- package/dist/components/VvCombobox/index.d.ts +123 -37
- package/dist/components/VvDialog/VvDialog.es.js +50 -37
- package/dist/components/VvDialog/VvDialog.umd.js +1 -1
- package/dist/components/VvDropdown/VvDropdown.es.js +32 -18
- package/dist/components/VvDropdown/VvDropdown.umd.js +1 -1
- package/dist/components/VvDropdown/VvDropdown.vue.d.ts +300 -92
- package/dist/components/VvDropdown/VvDropdownAction.vue.d.ts +9 -0
- package/dist/components/VvDropdown/index.d.ts +99 -30
- package/dist/components/VvDropdownAction/VvDropdownAction.es.js +17 -8
- package/dist/components/VvDropdownAction/VvDropdownAction.umd.js +1 -1
- package/dist/components/VvDropdownOptgroup/VvDropdownOptgroup.es.js +15 -7
- package/dist/components/VvDropdownOption/VvDropdownOption.es.js +15 -7
- package/dist/components/VvInputText/VvInputText.es.js +279 -116
- package/dist/components/VvInputText/VvInputText.umd.js +1 -1
- package/dist/components/VvInputText/VvInputText.vue.d.ts +23 -41
- package/dist/components/VvInputText/index.d.ts +15 -33
- package/dist/components/VvNav/VvNav.es.js +18 -9
- package/dist/components/VvNav/VvNav.umd.js +1 -1
- package/dist/components/VvNav/index.d.ts +1 -1
- package/dist/components/VvProgress/VvProgress.es.js +15 -7
- package/dist/components/VvRadio/VvRadio.es.js +99 -21
- package/dist/components/VvRadio/VvRadio.umd.js +1 -1
- package/dist/components/VvRadio/VvRadio.vue.d.ts +4 -4
- package/dist/components/VvRadioGroup/VvRadioGroup.es.js +105 -22
- package/dist/components/VvRadioGroup/VvRadioGroup.umd.js +1 -1
- package/dist/components/VvRadioGroup/VvRadioGroup.vue.d.ts +4 -4
- package/dist/components/VvSelect/VvSelect.es.js +95 -21
- package/dist/components/VvSelect/VvSelect.umd.js +1 -1
- package/dist/components/VvSelect/VvSelect.vue.d.ts +5 -5
- package/dist/components/VvTab/VvTab.es.js +18 -9
- package/dist/components/VvTab/VvTab.umd.js +1 -1
- package/dist/components/VvTextarea/VvTextarea.es.js +103 -26
- package/dist/components/VvTextarea/VvTextarea.umd.js +1 -1
- package/dist/components/VvTextarea/VvTextarea.vue.d.ts +4 -4
- package/dist/components/VvTooltip/VvTooltip.es.js +15 -7
- package/dist/components/common/HintSlot.d.ts +4 -3
- package/dist/components/index.d.ts +5 -0
- package/dist/components/index.es.js +1212 -626
- package/dist/components/index.umd.js +1 -1
- package/dist/composables/alert/useAlert.d.ts +27 -0
- package/dist/composables/index.d.ts +1 -0
- package/dist/composables/index.es.js +81 -0
- package/dist/composables/index.umd.js +1 -0
- package/dist/constants.d.ts +14 -0
- package/dist/directives/index.es.js +15 -7
- package/dist/directives/v-tooltip.es.js +15 -7
- package/dist/icons.es.js +3 -3
- package/dist/icons.umd.js +1 -1
- package/dist/props/index.d.ts +107 -31
- package/dist/resolvers/unplugin.es.js +3 -0
- package/dist/resolvers/unplugin.umd.js +1 -1
- package/dist/stories/AccordionGroup/AccordionGroup.stories.d.ts +2 -2
- package/dist/stories/AccordionGroup/AccordionGroupSlots.stories.d.ts +54 -269
- package/dist/stories/Alert/Alert.settings.d.ts +3 -7
- package/dist/stories/AlertGroup/AlertGroupSlots.stories.d.ts +2 -2
- package/dist/stories/AlertGroup/AlertGroupWithComposable.stories.d.ts +6 -0
- package/dist/stories/Button/Button.settings.d.ts +3 -13
- package/dist/stories/Combobox/Combobox.settings.d.ts +117 -19
- package/dist/stories/InputText/InputText.settings.d.ts +31 -9
- package/dist/stories/InputText/InputText.stories.d.ts +0 -1
- package/dist/stories/InputText/InputTextMask.stories.d.ts +12 -0
- package/dist/stories/Nav/Nav.settings.d.ts +3 -21
- package/package.json +75 -66
- package/src/assets/icons/detailed.json +1 -1
- package/src/assets/icons/normal.json +1 -1
- package/src/assets/icons/simple.json +1 -1
- package/src/components/VvAction/VvAction.vue +2 -1
- package/src/components/VvAlert/VvAlert.vue +5 -1
- package/src/components/VvAlert/index.ts +3 -3
- package/src/components/VvAlertGroup/VvAlertGroup.vue +2 -0
- package/src/components/VvButton/VvButton.vue +1 -0
- package/src/components/VvCheckbox/VvCheckbox.vue +8 -1
- package/src/components/VvCheckboxGroup/VvCheckboxGroup.vue +8 -1
- package/src/components/VvCombobox/VvCombobox.vue +43 -23
- package/src/components/VvCombobox/index.ts +24 -0
- package/src/components/VvDialog/VvDialog.vue +22 -19
- package/src/components/VvDropdown/VvDropdown.vue +24 -18
- package/src/components/VvInputText/VvInputText.vue +177 -55
- package/src/components/VvInputText/index.ts +32 -34
- package/src/components/VvNav/VvNav.vue +1 -1
- package/src/components/VvNav/index.ts +1 -1
- package/src/components/VvRadio/VvRadio.vue +8 -1
- package/src/components/VvRadioGroup/VvRadioGroup.vue +8 -1
- package/src/components/VvSelect/VvSelect.vue +8 -1
- package/src/components/VvTextarea/VvTextarea.vue +16 -6
- package/src/components/common/HintSlot.ts +26 -13
- package/src/components/index.ts +5 -0
- package/src/composables/alert/useAlert.ts +103 -0
- package/src/composables/index.ts +1 -0
- package/src/constants.ts +26 -0
- package/src/props/index.ts +14 -11
- package/src/resolvers/unplugin.ts +3 -0
- package/src/stories/Alert/Alert.settings.ts +3 -1
- package/src/stories/AlertGroup/AlertGroup.test.ts +13 -0
- package/src/stories/AlertGroup/AlertGroupSlots.stories.ts +3 -3
- package/src/stories/AlertGroup/AlertGroupWithComposable.stories.ts +118 -0
- package/src/stories/Button/Button.settings.ts +5 -3
- package/src/stories/Combobox/Combobox.settings.ts +119 -2
- package/src/stories/Combobox/Combobox.test.ts +1 -1
- package/src/stories/InputText/InputText.settings.ts +36 -15
- package/src/stories/InputText/InputText.stories.ts +4 -12
- package/src/stories/InputText/InputText.test.ts +31 -15
- package/src/stories/InputText/InputTextMask.stories.ts +122 -0
- package/src/stories/Nav/Nav.settings.ts +3 -1
- package/src/stories/Tab/Tab.stories.ts +3 -3
- package/src/stories/Textarea/TextareaLength.stories.ts +1 -1
- package/src/types/alert.d.ts +20 -0
- /package/dist/components/{VvNavItemTitle → VvNav}/VvNavItemTitle.vue.d.ts +0 -0
- /package/dist/components/{VvNavSeparator → VvNav}/VvNavSeparator.d.ts +0 -0
- /package/src/components/{VvNavItemTitle → VvNav}/VvNavItemTitle.vue +0 -0
- /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 {
|
|
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
|
-
//
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
//
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
67
|
+
emit,
|
|
68
|
+
onAccept: () => {
|
|
69
|
+
if (!maskReady.value) {
|
|
70
|
+
return
|
|
59
71
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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 (
|
|
67
|
-
|
|
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
|
-
|
|
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 =
|
|
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:
|
|
150
|
-
upperLimit: Number(
|
|
151
|
-
lowerLimit: Number(
|
|
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(
|
|
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 {
|
|
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 = [
|
|
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
|
-
*
|
|
141
|
-
* @see https://
|
|
156
|
+
* iMask options
|
|
157
|
+
* @see https://imask.js.org/guide.html
|
|
142
158
|
*/
|
|
143
|
-
|
|
144
|
-
type:
|
|
159
|
+
iMask: {
|
|
160
|
+
type: Object as PropType<FactoryOpts>,
|
|
145
161
|
default: undefined,
|
|
146
162
|
},
|
|
147
163
|
/**
|
|
148
|
-
*
|
|
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
|
-
|
|
168
|
-
type:
|
|
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>
|
|
@@ -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(
|
|
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(
|
|
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(
|
|
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,
|
|
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:
|
|
64
|
-
upperLimit: Number(
|
|
65
|
-
lowerLimit: Number(
|
|
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(
|
|
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:
|
|
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(
|
|
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(
|
|
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({
|
package/src/components/index.ts
CHANGED
|
@@ -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'
|