@volverjs/ui-vue 0.0.1 → 0.0.2
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 +17 -0
- package/dist/components/VvButton/VvButton.es.js +159 -147
- package/dist/components/VvButton/VvButton.umd.js +1 -1
- package/dist/components/VvButton/VvButton.vue.d.ts +0 -8
- package/dist/components/VvButton/index.d.ts +4 -4
- package/dist/components/VvButtonGroup/VvButtonGroup.es.js +36 -37
- package/dist/components/VvButtonGroup/VvButtonGroup.umd.js +1 -1
- package/dist/components/VvButtonGroup/VvButtonGroup.vue.d.ts +10 -10
- package/dist/components/VvButtonGroup/index.d.ts +5 -5
- package/dist/components/VvCombobox/VvCombobox.es.js +526 -345
- package/dist/components/VvCombobox/VvCombobox.umd.js +1 -1
- package/dist/components/VvCombobox/VvCombobox.vue.d.ts +22 -0
- package/dist/components/VvCombobox/index.d.ts +13 -1
- package/dist/components/VvDropdown/VvDropdown.es.js +118 -109
- package/dist/components/VvDropdown/VvDropdown.umd.js +1 -1
- package/dist/components/VvDropdown/VvDropdown.vue.d.ts +19 -0
- package/dist/components/VvDropdown/index.d.ts +12 -0
- package/dist/components/VvInputText/VvInputText.es.js +221 -213
- package/dist/components/VvInputText/VvInputText.umd.js +1 -1
- package/dist/components/VvInputText/VvInputText.vue.d.ts +13 -13
- package/dist/components/VvInputText/index.d.ts +5 -5
- package/dist/components/VvSelect/VvSelect.es.js +186 -167
- package/dist/components/VvSelect/VvSelect.umd.js +1 -1
- package/dist/components/VvSelect/VvSelect.vue.d.ts +23 -11
- package/dist/components/VvSelect/index.d.ts +10 -17
- package/dist/components/VvTextarea/VvTextarea.es.js +112 -104
- package/dist/components/VvTextarea/VvTextarea.umd.js +1 -1
- package/dist/components/VvTextarea/VvTextarea.vue.d.ts +12 -12
- package/dist/components/VvTextarea/index.d.ts +5 -5
- package/dist/components/index.es.js +1045 -975
- package/dist/components/index.umd.js +1 -1
- package/dist/composables/group/types/IButtonGroupState.d.ts +1 -1
- package/dist/composables/group/types/IGroupState.d.ts +1 -1
- package/dist/composables/group/useInjectedGroupState.d.ts +1 -1
- package/dist/icons.es.js +3 -3
- package/dist/icons.umd.js +1 -1
- package/dist/index.es.js +1065 -995
- package/dist/index.umd.js +1 -1
- package/dist/props/index.d.ts +35 -4
- package/dist/resolvers/unplugin.es.js +26 -24
- package/dist/resolvers/unplugin.umd.js +1 -1
- package/dist/stories/Button/Button.settings.d.ts +9 -11
- package/dist/stories/ButtonGroup/ButtonGroup.settings.d.ts +9 -0
- package/dist/stories/Combobox/Combobox.settings.d.ts +19 -0
- package/dist/stories/Dropdown/Dropdown.settings.d.ts +10 -0
- package/dist/stories/InputText/InputText.settings.d.ts +23 -23
- package/dist/stories/Select/Select.settings.d.ts +42 -23
- package/dist/stories/Textarea/Textarea.settings.d.ts +23 -23
- package/dist/stories/argTypes.d.ts +50 -1
- package/package.json +5 -4
- 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/VvButton/index.ts +28 -10
- package/src/components/VvButtonGroup/VvButtonGroup.vue +1 -1
- package/src/components/VvButtonGroup/index.ts +3 -6
- package/src/components/VvCombobox/VvCombobox.vue +45 -11
- package/src/components/VvCombobox/index.ts +6 -0
- package/src/components/VvDropdown/VvDropdown.vue +9 -6
- package/src/components/VvDropdown/index.ts +11 -1
- package/src/components/VvInputText/VvInputText.vue +10 -8
- package/src/components/VvSelect/VvSelect.vue +23 -1
- package/src/components/VvSelect/index.ts +8 -11
- package/src/components/VvTextarea/VvTextarea.vue +10 -8
- package/src/composables/group/types/IButtonGroupState.ts +1 -1
- package/src/composables/group/types/IGroupState.ts +1 -1
- package/src/composables/group/useInjectedGroupState.ts +3 -3
- package/src/composables/useTextCount.ts +1 -1
- package/src/props/index.ts +33 -15
- package/src/resolvers/unplugin.ts +22 -13
- package/src/stories/Button/Button.settings.ts +2 -7
- package/src/stories/ButtonGroup/ButtonGroup.settings.ts +6 -1
- package/src/stories/ButtonGroup/ButtonGroupSlots.stories.mdx +37 -0
- package/src/stories/ButtonGroup/ButtonGroupToggle.stories.mdx +12 -1
- package/src/stories/Combobox/Combobox.settings.ts +5 -0
- package/src/stories/Combobox/Combobox.stories.mdx +51 -0
- package/src/stories/Combobox/Combobox.test.ts +7 -0
- package/src/stories/Dropdown/Dropdown.settings.ts +10 -1
- package/src/stories/Dropdown/Dropdown.stories.mdx +17 -0
- package/src/stories/Select/Select.settings.ts +9 -23
- package/src/stories/Select/Select.stories.mdx +60 -0
- package/src/stories/argTypes.ts +46 -22
|
@@ -4,8 +4,9 @@ import {
|
|
|
4
4
|
type ExtractPropTypes,
|
|
5
5
|
toRefs,
|
|
6
6
|
ref,
|
|
7
|
+
computed,
|
|
7
8
|
} from 'vue'
|
|
8
|
-
import { DisabledProps, ModifiersProps } from '@/props'
|
|
9
|
+
import { DisabledProps, ModifiersProps, UnselectableProps } from '@/props'
|
|
9
10
|
import type IButtonGroupState from '@/composables/group/types/IButtonGroupState'
|
|
10
11
|
import { useInjectedGroupState } from '@/composables/group/useInjectedGroupState'
|
|
11
12
|
import { VV_BUTTON_GROUP } from '@/constants'
|
|
@@ -42,6 +43,7 @@ export const VvButtonEvents = ['update:modelValue']
|
|
|
42
43
|
export const VvButtonProps = {
|
|
43
44
|
...ModifiersProps,
|
|
44
45
|
...DisabledProps,
|
|
46
|
+
...UnselectableProps,
|
|
45
47
|
/**
|
|
46
48
|
* Button icon
|
|
47
49
|
*/
|
|
@@ -119,7 +121,6 @@ export const VvButtonProps = {
|
|
|
119
121
|
default: false,
|
|
120
122
|
},
|
|
121
123
|
modelValue: String,
|
|
122
|
-
unselectable: { type: Boolean, default: true },
|
|
123
124
|
}
|
|
124
125
|
|
|
125
126
|
export type VvButtonPropsTypes = ExtractPropTypes<typeof VvButtonProps>
|
|
@@ -135,7 +136,13 @@ export function useGroupProps(
|
|
|
135
136
|
useInjectedGroupState<IButtonGroupState>(VV_BUTTON_GROUP)
|
|
136
137
|
|
|
137
138
|
// local props
|
|
138
|
-
const {
|
|
139
|
+
const {
|
|
140
|
+
iconPosition,
|
|
141
|
+
icon,
|
|
142
|
+
label,
|
|
143
|
+
pressed,
|
|
144
|
+
modifiers: localModifiers,
|
|
145
|
+
} = toRefs(props)
|
|
139
146
|
|
|
140
147
|
// group props
|
|
141
148
|
const modelValue = getGroupOrLocalRef('modelValue', props, emit) as Ref<
|
|
@@ -147,22 +154,33 @@ export function useGroupProps(
|
|
|
147
154
|
'unselectable',
|
|
148
155
|
props,
|
|
149
156
|
) as Ref<boolean>
|
|
150
|
-
const modifiers = getGroupOrLocalRef('modifiers', props) as Ref<
|
|
151
|
-
string[] | string
|
|
152
|
-
>
|
|
153
157
|
const multiple = group?.value?.multiple ?? ref(false)
|
|
154
158
|
|
|
159
|
+
const modifiers = computed(() => {
|
|
160
|
+
const localValue = localModifiers?.value
|
|
161
|
+
? Array.isArray(localModifiers.value)
|
|
162
|
+
? localModifiers.value
|
|
163
|
+
: [localModifiers.value]
|
|
164
|
+
: []
|
|
165
|
+
const groupValue = group?.value.itemModifiers?.value
|
|
166
|
+
? Array.isArray(group.value.itemModifiers.value)
|
|
167
|
+
? group.value.itemModifiers.value
|
|
168
|
+
: [group.value.itemModifiers.value]
|
|
169
|
+
: []
|
|
170
|
+
return [...localValue, ...groupValue]
|
|
171
|
+
})
|
|
172
|
+
|
|
155
173
|
return {
|
|
156
174
|
// group props
|
|
175
|
+
group,
|
|
176
|
+
isInGroup,
|
|
157
177
|
modelValue,
|
|
158
178
|
disabled,
|
|
159
179
|
toggle,
|
|
160
|
-
isInGroup,
|
|
161
|
-
group,
|
|
162
|
-
modifiers,
|
|
163
|
-
multiple,
|
|
164
180
|
unselectable,
|
|
181
|
+
multiple,
|
|
165
182
|
// local props
|
|
183
|
+
modifiers,
|
|
166
184
|
pressed,
|
|
167
185
|
iconPosition,
|
|
168
186
|
icon,
|
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
import { DisabledProps, ModifiersProps } from '@/props'
|
|
1
|
+
import { DisabledProps, ModifiersProps, UnselectableProps } from '@/props'
|
|
2
2
|
|
|
3
3
|
export const VvButtonGroupProps = {
|
|
4
4
|
...ModifiersProps,
|
|
5
5
|
...DisabledProps,
|
|
6
|
+
...UnselectableProps,
|
|
6
7
|
/**
|
|
7
8
|
* String or String[] of css classes (modifiers) that will be provided to each button'
|
|
8
9
|
*/
|
|
9
|
-
itemModifiers: {
|
|
10
|
-
type: [String, Array<string>],
|
|
11
|
-
default: '',
|
|
12
|
-
},
|
|
10
|
+
itemModifiers: { type: [String, Array<string>], default: undefined },
|
|
13
11
|
toggle: { type: Boolean, default: false },
|
|
14
12
|
multiple: { type: Boolean, default: false },
|
|
15
|
-
unselectable: { type: Boolean, default: true },
|
|
16
13
|
modelValue: { type: [String, Array<string>], default: undefined },
|
|
17
14
|
}
|
|
18
15
|
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
import { useComponentFocus } from '@/composables/useComponentFocus'
|
|
16
16
|
import VvDropdown from '@/components/VvDropdown/VvDropdown.vue'
|
|
17
17
|
import VvIcon from '@/components/VvIcon/VvIcon.vue'
|
|
18
|
+
import VvSelect from '@/components/VvSelect/VvSelect.vue'
|
|
18
19
|
import HintSlotFactory from '@/components/common/HintSlot'
|
|
19
20
|
import { VvComboboxProps, VvComboboxEvents } from '@/components/VvCombobox'
|
|
20
21
|
|
|
@@ -34,7 +35,7 @@
|
|
|
34
35
|
const { focused } = useComponentFocus(dropdown, emit)
|
|
35
36
|
|
|
36
37
|
// data
|
|
37
|
-
const
|
|
38
|
+
const hasId = computed(() => String(props.id || nanoid()))
|
|
38
39
|
const searchText = ref('')
|
|
39
40
|
const debouncedSearchText = refDebounced(
|
|
40
41
|
searchText,
|
|
@@ -50,6 +51,7 @@
|
|
|
50
51
|
loading,
|
|
51
52
|
valid,
|
|
52
53
|
invalid,
|
|
54
|
+
floating,
|
|
53
55
|
} = toRefs(props)
|
|
54
56
|
|
|
55
57
|
// emit on change search text
|
|
@@ -83,6 +85,7 @@
|
|
|
83
85
|
invalid,
|
|
84
86
|
dirty: isDirty,
|
|
85
87
|
focus: focused,
|
|
88
|
+
floating,
|
|
86
89
|
})
|
|
87
90
|
|
|
88
91
|
// current options, filtered or prop options
|
|
@@ -119,7 +122,7 @@
|
|
|
119
122
|
|
|
120
123
|
const hasLabel = computed(() => {
|
|
121
124
|
return selectedOptions.value
|
|
122
|
-
.map((option) =>
|
|
125
|
+
.map((option) => getOptionLabel(option))
|
|
123
126
|
.join(props.separator)
|
|
124
127
|
})
|
|
125
128
|
|
|
@@ -147,6 +150,7 @@
|
|
|
147
150
|
}
|
|
148
151
|
|
|
149
152
|
const dropdownProps = computed(() => ({
|
|
153
|
+
name: props.name,
|
|
150
154
|
options: hasOptions.value,
|
|
151
155
|
labelKey: props.labelKey,
|
|
152
156
|
valueKey: props.valueKey,
|
|
@@ -155,17 +159,46 @@
|
|
|
155
159
|
multiple: props.multiple,
|
|
156
160
|
maxValues: props.maxValues,
|
|
157
161
|
modelValue: props.modelValue,
|
|
162
|
+
unselectable: props.unselectable,
|
|
163
|
+
}))
|
|
164
|
+
|
|
165
|
+
const selectProps = computed(() => ({
|
|
166
|
+
id: hasId.value,
|
|
167
|
+
name: props.name,
|
|
168
|
+
tabindex: hasTabindex.value,
|
|
169
|
+
valid: valid.value,
|
|
170
|
+
validLabel: props.validLabel,
|
|
171
|
+
invalid: invalid.value,
|
|
172
|
+
invalidLabel: props.invalidLabel,
|
|
173
|
+
hintLabel: props.hintLabel,
|
|
174
|
+
loading: loading.value,
|
|
175
|
+
loadingLabel: props.loadingLabel,
|
|
176
|
+
disabled: disabled.value,
|
|
177
|
+
readonly: readonly.value,
|
|
178
|
+
modifiers: props.modifiers,
|
|
179
|
+
options: hasOptions.value,
|
|
180
|
+
labelKey: props.labelKey,
|
|
181
|
+
valueKey: props.valueKey,
|
|
182
|
+
icon: props.icon,
|
|
183
|
+
iconPosition: props.iconPosition,
|
|
184
|
+
floating: props.floating,
|
|
185
|
+
unselectable: props.unselectable,
|
|
186
|
+
multiple: props.multiple,
|
|
187
|
+
label: props.label,
|
|
188
|
+
placeholder: props.placeholder,
|
|
189
|
+
modelValue: props.modelValue,
|
|
158
190
|
}))
|
|
159
191
|
</script>
|
|
160
192
|
|
|
161
193
|
<template>
|
|
162
|
-
<div v-if="!native" :id="
|
|
194
|
+
<div v-if="!native" :id="hasId" :class="bemCssClasses">
|
|
163
195
|
<label
|
|
164
196
|
v-if="label"
|
|
165
|
-
:id="`${
|
|
166
|
-
:for="searchable && dropdownOpen ? `${
|
|
167
|
-
>{{ label }}</label
|
|
197
|
+
:id="`${hasId}-label`"
|
|
198
|
+
:for="searchable && dropdownOpen ? `${hasId}-input` : undefined"
|
|
168
199
|
>
|
|
200
|
+
{{ label }}
|
|
201
|
+
</label>
|
|
169
202
|
<details
|
|
170
203
|
ref="dropdown"
|
|
171
204
|
class="vv-select__wrapper"
|
|
@@ -189,7 +222,7 @@
|
|
|
189
222
|
<!-- #region search input -->
|
|
190
223
|
<template v-if="searchable && dropdownOpen">
|
|
191
224
|
<input
|
|
192
|
-
:id="`${
|
|
225
|
+
:id="`${hasId}-input`"
|
|
193
226
|
ref="inputSearch"
|
|
194
227
|
v-model="searchText"
|
|
195
228
|
role="combobox"
|
|
@@ -213,15 +246,16 @@
|
|
|
213
246
|
</summary>
|
|
214
247
|
<!-- @slot Slot to replace right icon -->
|
|
215
248
|
<VvDropdown
|
|
216
|
-
:id="`${
|
|
249
|
+
:id="`${hasId}-dropdown`"
|
|
217
250
|
v-bind="dropdownProps"
|
|
218
251
|
@update:model-value="onInput"
|
|
219
252
|
/>
|
|
220
253
|
</details>
|
|
221
254
|
<HintSlot class="vv-select__hint" />
|
|
222
255
|
</div>
|
|
223
|
-
|
|
256
|
+
<VvSelect
|
|
224
257
|
v-else
|
|
225
|
-
v-bind="
|
|
226
|
-
@update:model-value="emit('update:modelValue', $event)"
|
|
258
|
+
v-bind="selectProps"
|
|
259
|
+
@update:model-value="emit('update:modelValue', $event)"
|
|
260
|
+
/>
|
|
227
261
|
</template>
|
|
@@ -9,6 +9,9 @@ import {
|
|
|
9
9
|
OptionsProps,
|
|
10
10
|
IconProps,
|
|
11
11
|
TabindexProps,
|
|
12
|
+
FloatingProps,
|
|
13
|
+
UnselectableProps,
|
|
14
|
+
IdNameProps,
|
|
12
15
|
} from '@/props'
|
|
13
16
|
|
|
14
17
|
export const VvComboboxEvents = [
|
|
@@ -19,6 +22,7 @@ export const VvComboboxEvents = [
|
|
|
19
22
|
]
|
|
20
23
|
|
|
21
24
|
export const VvComboboxProps = {
|
|
25
|
+
...IdNameProps,
|
|
22
26
|
...TabindexProps,
|
|
23
27
|
...ValidProps,
|
|
24
28
|
...InvalidProps,
|
|
@@ -29,6 +33,8 @@ export const VvComboboxProps = {
|
|
|
29
33
|
...ModifiersProps,
|
|
30
34
|
...OptionsProps,
|
|
31
35
|
...IconProps,
|
|
36
|
+
...FloatingProps,
|
|
37
|
+
...UnselectableProps,
|
|
32
38
|
/**
|
|
33
39
|
* modelValue can be a string, number, boolean, object or array of string, number, boolean, object
|
|
34
40
|
*/
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
</script>
|
|
6
6
|
|
|
7
7
|
<script setup lang="ts">
|
|
8
|
-
import { toRefs } from 'vue'
|
|
8
|
+
import { computed, toRefs } from 'vue'
|
|
9
9
|
import { nanoid } from 'nanoid'
|
|
10
10
|
import { useBemModifiers } from '@/composables/useModifiers'
|
|
11
11
|
import { useOptions } from '@/composables/useOptions'
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
const emit = defineEmits(['update:modelValue'])
|
|
19
19
|
|
|
20
20
|
// data
|
|
21
|
-
const
|
|
21
|
+
const hasId = computed(() => String(props.id || nanoid()))
|
|
22
22
|
const { modifiers, disabled } = toRefs(props)
|
|
23
23
|
|
|
24
24
|
// options
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
return
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
let toReturn: string | string[] | Option | Option[] = value
|
|
72
|
+
let toReturn: string | string[] | Option | Option[] | undefined = value
|
|
73
73
|
// Check multiple prop, override value with array and remove or add the value
|
|
74
74
|
if (props.multiple) {
|
|
75
75
|
// check maxValues prop and block check new values
|
|
@@ -90,13 +90,15 @@
|
|
|
90
90
|
} else {
|
|
91
91
|
toReturn = [value as Option]
|
|
92
92
|
}
|
|
93
|
+
} else if (props.unselectable && value === props.modelValue) {
|
|
94
|
+
toReturn = undefined
|
|
93
95
|
}
|
|
94
96
|
emit('update:modelValue', toReturn)
|
|
95
97
|
}
|
|
96
98
|
</script>
|
|
97
99
|
|
|
98
100
|
<template>
|
|
99
|
-
<ul :class="dropdownClasses" role="listbox">
|
|
101
|
+
<ul :id="hasId" :class="dropdownClasses" role="listbox">
|
|
100
102
|
<li v-if="!options?.length" role="option">
|
|
101
103
|
<label>
|
|
102
104
|
{{ labelNoResults }}
|
|
@@ -109,15 +111,16 @@
|
|
|
109
111
|
:aria-selected="getChecked(option)"
|
|
110
112
|
>
|
|
111
113
|
<label
|
|
112
|
-
:for="`dropdown-${index}-${
|
|
114
|
+
:for="`dropdown-${index}-${hasId}`"
|
|
113
115
|
@click.prevent="onInput(getOptionValue(option))"
|
|
114
116
|
>
|
|
115
117
|
<input
|
|
116
|
-
:id="`dropdown-${index}-${
|
|
118
|
+
:id="`dropdown-${index}-${hasId}`"
|
|
117
119
|
:type="multiple ? 'checkbox' : 'radio'"
|
|
118
120
|
:value="getOptionValue(option)"
|
|
119
121
|
:checked="getChecked(option)"
|
|
120
122
|
:disabled="getDisabled(option)"
|
|
123
|
+
:name="name"
|
|
121
124
|
tabindex="-1"
|
|
122
125
|
aria-hidden="true"
|
|
123
126
|
/>
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
DisabledProps,
|
|
3
|
+
IdNameProps,
|
|
4
|
+
ModifiersProps,
|
|
5
|
+
OptionsProps,
|
|
6
|
+
} from '@/props'
|
|
2
7
|
|
|
3
8
|
export const VvDropdownProps = {
|
|
9
|
+
...IdNameProps,
|
|
4
10
|
...OptionsProps,
|
|
5
11
|
...DisabledProps,
|
|
6
12
|
...ModifiersProps,
|
|
@@ -22,4 +28,8 @@ export const VvDropdownProps = {
|
|
|
22
28
|
* The max number of selected values
|
|
23
29
|
*/
|
|
24
30
|
maxValues: [Number, String],
|
|
31
|
+
/**
|
|
32
|
+
* If true the input will be unselectable
|
|
33
|
+
*/
|
|
34
|
+
unselectable: { type: Boolean, default: true },
|
|
25
35
|
}
|
|
@@ -10,10 +10,11 @@
|
|
|
10
10
|
useSlots,
|
|
11
11
|
ref,
|
|
12
12
|
toRefs,
|
|
13
|
-
onMounted,
|
|
14
13
|
unref,
|
|
14
|
+
watch,
|
|
15
15
|
type InputHTMLAttributes,
|
|
16
16
|
} from 'vue'
|
|
17
|
+
import { useElementVisibility } from '@vueuse/core'
|
|
17
18
|
import { nanoid } from 'nanoid'
|
|
18
19
|
import { isEmpty } from '@/utils/ObjectUtilities'
|
|
19
20
|
import HintSlotFactory from '@/components/common/HintSlot'
|
|
@@ -63,6 +64,14 @@
|
|
|
63
64
|
// focus
|
|
64
65
|
const { focused } = useComponentFocus(input, emit)
|
|
65
66
|
|
|
67
|
+
// visibility
|
|
68
|
+
const isVisible = useElementVisibility(input)
|
|
69
|
+
watch(isVisible, (newValue) => {
|
|
70
|
+
if (newValue && props.autofocus) {
|
|
71
|
+
focused.value = true
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
|
|
66
75
|
// password
|
|
67
76
|
const showPassword = ref(false)
|
|
68
77
|
const isPassword = computed(() => props.type === INPUT_TYPES.PASSWORD)
|
|
@@ -258,13 +267,6 @@
|
|
|
258
267
|
INPUT_TYPES.SEARCH,
|
|
259
268
|
props,
|
|
260
269
|
)
|
|
261
|
-
|
|
262
|
-
// lifecycle
|
|
263
|
-
onMounted(() => {
|
|
264
|
-
if (props.autofocus) {
|
|
265
|
-
focused.value = true
|
|
266
|
-
}
|
|
267
|
-
})
|
|
268
270
|
</script>
|
|
269
271
|
|
|
270
272
|
<template>
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
toRefs,
|
|
12
12
|
useSlots,
|
|
13
13
|
ref,
|
|
14
|
+
watch,
|
|
14
15
|
type SelectHTMLAttributes,
|
|
15
16
|
} from 'vue'
|
|
16
17
|
import { nanoid } from 'nanoid'
|
|
@@ -22,6 +23,7 @@
|
|
|
22
23
|
import VvIcon from '@/components/VvIcon/VvIcon.vue'
|
|
23
24
|
import HintSlotFactory from '@/components/common/HintSlot'
|
|
24
25
|
import { VvSelectProps, VvSelectEmits } from '@/components/VvSelect'
|
|
26
|
+
import { useElementVisibility } from '@vueuse/core'
|
|
25
27
|
|
|
26
28
|
// props, emit and slots
|
|
27
29
|
const props = defineProps(VvSelectProps)
|
|
@@ -44,6 +46,8 @@
|
|
|
44
46
|
iconPosition,
|
|
45
47
|
invalid,
|
|
46
48
|
valid,
|
|
49
|
+
floating,
|
|
50
|
+
multiple,
|
|
47
51
|
} = toRefs(props)
|
|
48
52
|
|
|
49
53
|
// computed
|
|
@@ -53,6 +57,14 @@
|
|
|
53
57
|
// focus
|
|
54
58
|
const { focused } = useComponentFocus(select, emit)
|
|
55
59
|
|
|
60
|
+
// visibility
|
|
61
|
+
const isVisible = useElementVisibility(select)
|
|
62
|
+
watch(isVisible, (newValue) => {
|
|
63
|
+
if (newValue && props.autofocus) {
|
|
64
|
+
focused.value = true
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
|
|
56
68
|
// icons
|
|
57
69
|
const { hasIcon, hasIconLeft, hasIconRight } = useComponentIcon(
|
|
58
70
|
icon,
|
|
@@ -91,6 +103,8 @@
|
|
|
91
103
|
iconRight: hasIconRight,
|
|
92
104
|
dirty: isDirty,
|
|
93
105
|
focus: focused,
|
|
106
|
+
floating,
|
|
107
|
+
multiple,
|
|
94
108
|
})
|
|
95
109
|
|
|
96
110
|
// attrs
|
|
@@ -132,6 +146,9 @@
|
|
|
132
146
|
return props.modelValue
|
|
133
147
|
},
|
|
134
148
|
set: (newValue) => {
|
|
149
|
+
if (Array.isArray(newValue)) {
|
|
150
|
+
newValue = newValue.filter((item) => item !== undefined)
|
|
151
|
+
}
|
|
135
152
|
emit('update:modelValue', newValue)
|
|
136
153
|
},
|
|
137
154
|
})
|
|
@@ -151,7 +168,12 @@
|
|
|
151
168
|
v-model="localModelValue"
|
|
152
169
|
v-bind="hasAttrs"
|
|
153
170
|
>
|
|
154
|
-
<option
|
|
171
|
+
<option
|
|
172
|
+
v-if="placeholder"
|
|
173
|
+
:value="undefined"
|
|
174
|
+
:disabled="!unselectable"
|
|
175
|
+
:hidden="!unselectable"
|
|
176
|
+
>
|
|
155
177
|
{{ placeholder }}
|
|
156
178
|
</option>
|
|
157
179
|
<option
|
|
@@ -10,10 +10,16 @@ import {
|
|
|
10
10
|
OptionsProps,
|
|
11
11
|
IconProps,
|
|
12
12
|
IdNameProps,
|
|
13
|
+
FloatingProps,
|
|
14
|
+
UnselectableProps,
|
|
15
|
+
AutofocusProps,
|
|
16
|
+
AutocompleteProps,
|
|
13
17
|
} from '@/props'
|
|
14
18
|
|
|
15
19
|
export const VvSelectProps = {
|
|
16
20
|
...IdNameProps,
|
|
21
|
+
...AutofocusProps,
|
|
22
|
+
...AutocompleteProps,
|
|
17
23
|
...TabindexProps,
|
|
18
24
|
...ValidProps,
|
|
19
25
|
...InvalidProps,
|
|
@@ -24,17 +30,8 @@ export const VvSelectProps = {
|
|
|
24
30
|
...ModifiersProps,
|
|
25
31
|
...OptionsProps,
|
|
26
32
|
...IconProps,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select#attr-autocomplete
|
|
30
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete
|
|
31
|
-
*/
|
|
32
|
-
autocomplete: { type: String, default: 'off' },
|
|
33
|
-
/**
|
|
34
|
-
* Global attribute autofocus
|
|
35
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/autofocus
|
|
36
|
-
*/
|
|
37
|
-
autofocus: Boolean,
|
|
33
|
+
...FloatingProps,
|
|
34
|
+
...UnselectableProps,
|
|
38
35
|
/**
|
|
39
36
|
* This Boolean attribute indicates that multiple options can be selected in the list.
|
|
40
37
|
* If it is not specified, then only one option can be selected at a time.
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
useSlots,
|
|
11
11
|
ref,
|
|
12
12
|
toRefs,
|
|
13
|
-
|
|
13
|
+
watch,
|
|
14
14
|
type TextareaHTMLAttributes,
|
|
15
15
|
} from 'vue'
|
|
16
16
|
import { nanoid } from 'nanoid'
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
import { useBemModifiers } from '@/composables/useModifiers'
|
|
24
24
|
import VvIcon from '@/components/VvIcon/VvIcon.vue'
|
|
25
25
|
import { VvTextareaProps, VvTextareaEvents } from '@/components/VvTextarea'
|
|
26
|
+
import { useElementVisibility } from '@vueuse/core'
|
|
26
27
|
|
|
27
28
|
// props, emit and slots
|
|
28
29
|
const props = defineProps(VvTextareaProps)
|
|
@@ -62,6 +63,14 @@
|
|
|
62
63
|
// focus
|
|
63
64
|
const { focused } = useComponentFocus(textarea, emit)
|
|
64
65
|
|
|
66
|
+
// visibility
|
|
67
|
+
const isVisible = useElementVisibility(textarea)
|
|
68
|
+
watch(isVisible, (newValue) => {
|
|
69
|
+
if (newValue && props.autofocus) {
|
|
70
|
+
focused.value = true
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
|
|
65
74
|
// count
|
|
66
75
|
const { formatted: countFormatted } = useTextCount(localModelValue, {
|
|
67
76
|
mode: props.count,
|
|
@@ -151,13 +160,6 @@
|
|
|
151
160
|
const onClear = () => {
|
|
152
161
|
localModelValue.value = undefined
|
|
153
162
|
}
|
|
154
|
-
|
|
155
|
-
// lifecycle
|
|
156
|
-
onMounted(() => {
|
|
157
|
-
if (props.autofocus) {
|
|
158
|
-
focused.value = true
|
|
159
|
-
}
|
|
160
|
-
})
|
|
161
163
|
</script>
|
|
162
164
|
|
|
163
165
|
<template>
|
|
@@ -17,9 +17,9 @@ export function useInjectedGroupState<TGroup extends IGroupState>(
|
|
|
17
17
|
/**
|
|
18
18
|
* Get a group or local property
|
|
19
19
|
*/
|
|
20
|
-
function getGroupOrLocalRef<
|
|
20
|
+
function getGroupOrLocalRef<PropsType extends object>(
|
|
21
21
|
propName: keyof TGroup,
|
|
22
|
-
props:
|
|
22
|
+
props: PropsType,
|
|
23
23
|
emit?: (event: string, ...args: unknown[]) => void,
|
|
24
24
|
) {
|
|
25
25
|
if (group?.value) {
|
|
@@ -33,7 +33,7 @@ export function useInjectedGroupState<TGroup extends IGroupState>(
|
|
|
33
33
|
},
|
|
34
34
|
})
|
|
35
35
|
}
|
|
36
|
-
const propRef = toRef(props, propName as keyof
|
|
36
|
+
const propRef = toRef(props, propName as keyof PropsType)
|
|
37
37
|
return computed({
|
|
38
38
|
get() {
|
|
39
39
|
return propRef.value
|
package/src/props/index.ts
CHANGED
|
@@ -109,6 +109,20 @@ export const TabindexProps = {
|
|
|
109
109
|
tabindex: { type: [String, Number], default: 0 },
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
+
export const FloatingProps = {
|
|
113
|
+
/**
|
|
114
|
+
* If true the label will be floating
|
|
115
|
+
*/
|
|
116
|
+
floating: Boolean,
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export const UnselectableProps = {
|
|
120
|
+
/**
|
|
121
|
+
* If true the input will be unselectable
|
|
122
|
+
*/
|
|
123
|
+
unselectable: { type: Boolean, default: true },
|
|
124
|
+
}
|
|
125
|
+
|
|
112
126
|
export const IdNameProps = {
|
|
113
127
|
/**
|
|
114
128
|
* Global attribute id
|
|
@@ -123,8 +137,26 @@ export const IdNameProps = {
|
|
|
123
137
|
name: { type: String, required: true },
|
|
124
138
|
}
|
|
125
139
|
|
|
140
|
+
export const AutofocusProps = {
|
|
141
|
+
/**
|
|
142
|
+
* Global attribute autofocus
|
|
143
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/autofocus
|
|
144
|
+
*/
|
|
145
|
+
autofocus: Boolean,
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export const AutocompleteProps = {
|
|
149
|
+
/**
|
|
150
|
+
* Global attribute autocomplete
|
|
151
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete
|
|
152
|
+
*/
|
|
153
|
+
autocomplete: { type: String, default: 'off' },
|
|
154
|
+
}
|
|
155
|
+
|
|
126
156
|
export const InputTextareaProps = {
|
|
127
157
|
...IdNameProps,
|
|
158
|
+
...AutofocusProps,
|
|
159
|
+
...AutocompleteProps,
|
|
128
160
|
...TabindexProps,
|
|
129
161
|
...DisabledProps,
|
|
130
162
|
...ReadonlyProps,
|
|
@@ -136,17 +168,7 @@ export const InputTextareaProps = {
|
|
|
136
168
|
...CountProps,
|
|
137
169
|
...DebounceProps,
|
|
138
170
|
...IconProps,
|
|
139
|
-
|
|
140
|
-
* Global attribute autofocus
|
|
141
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/autofocus
|
|
142
|
-
*/
|
|
143
|
-
autofocus: Boolean,
|
|
144
|
-
/**
|
|
145
|
-
* Input / Textarea autocomplete
|
|
146
|
-
* Hint for for autofill feature
|
|
147
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#autocomplete
|
|
148
|
-
*/
|
|
149
|
-
autocomplete: { type: String, default: 'off' },
|
|
171
|
+
...FloatingProps,
|
|
150
172
|
/**
|
|
151
173
|
* Input / Textarea minlength
|
|
152
174
|
* Minimum length (number of characters) of value
|
|
@@ -179,10 +201,6 @@ export const InputTextareaProps = {
|
|
|
179
201
|
* <label> value for the Input / Textarea
|
|
180
202
|
*/
|
|
181
203
|
label: String,
|
|
182
|
-
/**
|
|
183
|
-
* If true the label will be floating
|
|
184
|
-
*/
|
|
185
|
-
floating: Boolean,
|
|
186
204
|
}
|
|
187
205
|
|
|
188
206
|
export const CheckboxRadioProps = {
|