Skip to content

Commit

Permalink
[epicmaxco#2228] autocomplete functional for va-select
Browse files Browse the repository at this point in the history
  • Loading branch information
aluarius committed Feb 1, 2023
1 parent faadfb3 commit 0e66e08
Show file tree
Hide file tree
Showing 11 changed files with 399 additions and 16 deletions.
9 changes: 8 additions & 1 deletion packages/docs/src/locales/en/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -853,7 +853,10 @@
"maxVisibleOptions": "Max selected options amount, that will be shown inside of input wrapper.",
"preventOverflow": "If true, dropdown will be teleported to target ignoring `overflow: hidden` on relative position elements.",
"selectedTopShown": "Selected options will be shown at the top of the options list.",
"stickToEdges": "Dropdown will not be rendered outside of viewport. It will be moved in opposite direction."
"stickToEdges": "Dropdown will not be rendered outside of viewport. It will be moved in opposite direction.",
"autocomplete": "Enables the autocomplete behaviour.",
"highlightSearch": "Highlight chars in options that are match the input value (search or autocomplete).",
"minSearchChars": "Minimal amount of chars in input value to initiate search or autocomplete."
},
"events": {
"clear": "Emitted if select value has been cleared",
Expand Down Expand Up @@ -3235,6 +3238,10 @@
"title": "State",
"text": "Includes error, success, disabled or loading state"
},
"autocomplete": {
"title": "Autocomplete",
"text": "The `autocomplete` prop enables autocomplete behaviour for the `va-select`."
},
"searchable": {
"title": "Searchable",
"text": "Supports ability to filter option list by typing"
Expand Down
9 changes: 8 additions & 1 deletion packages/docs/src/locales/ru/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,10 @@
"stickToEdges": "Если контент не помещается в экран, он будет перенесен на его противоположную сторону по оси X или Y.",
"selectedTopShown": "Выбранные опции будут отображаться вверху списка опций.",
"hiddenOptionsBadge": "Заменяет стандартный бейдж со счетчиком скрытых опций (за дополнительной информацией обращайтесь к секции по свойству `maxVisibleOptions`).",
"hideOptionsButton": "Заменяет стандартную кнопку для сокрытия отображаемых выбранных опций сверх установленного лимита (за дополнительной информацией обращайтесь к секции по свойству `maxVisibleOptions`)."
"hideOptionsButton": "Заменяет стандартную кнопку для сокрытия отображаемых выбранных опций сверх установленного лимита (за дополнительной информацией обращайтесь к секции по свойству `maxVisibleOptions`).",
"autocomplete": "Включает поведение автокомплита.",
"highlightSearch": "Подсвечивает совпадения знаков в опциях при поиске или вводе через автокомплит.",
"minSearchChars": "Минимальное количество введенных символов, после которого активируется сценарий поиска или автокомплита."
},
"events": {
"clear": "Событие вызывается при сбросе значения компонента",
Expand Down Expand Up @@ -3097,6 +3100,10 @@
"title": "Выбор опций с одинаковыми значениями",
"text": "Свойство `track-by` можно использовать, если у вас есть несколько вариантов с одинаковым значением."
},
"autocomplete": {
"title": "Автокомплит",
"text": "Свойство `autocomplete` задает поведение автокомплита для компонента."
},
"slots": {
"title": "Слоты",
"text": "Поддерживаемые слоты: `option`, `content`, `prepend`, `prepend-inner`, `append` и `append-inner`."
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<template>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<va-select
v-model="singleSelect"
class="col-span-1"
label="Sigle select"
placeholder="Start to write..."
:options="options"
autocomplete
highlight-search
/>

<va-select
v-model="multiSelect"
class="col-span-1"
label="Multiple select"
placeholder="Start to write..."
:options="options"
multiple
autocomplete
highlight-search
/>

<va-select
v-model="multiSelect"
class="col-span-1"
label="Multiple select with content slot"
placeholder="Start to write..."
:options="options"
multiple
autocomplete
highlight-search
>
<template #content="{ value }">
<va-chip
v-for="chip in value"
:key="chip"
class="mr-1"
size="small"
>
{{ chip }}
</va-chip>
</template>
</va-select>
</div>
</template>

<script setup>
import { ref } from 'vue'
const options = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']
const singleSelect = ref('')
const multiSelect = ref([])
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
v-model="value"
multiple
searchable
highlight-search
/>
</div>
</template>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ const config: ApiDocsBlock[] = [
'select.examples.selectedTopShown.text',
'SelectedTopShown',
),
...block.exampleBlock(
'select.examples.autocomplete.title',
'select.examples.autocomplete.text',
'Autocomplete',
),

block.headline('select.examples.keyboardNavigation.title'),
block.paragraph('select.examples.keyboardNavigation.moves'),
Expand Down
85 changes: 85 additions & 0 deletions packages/ui/src/components/va-select/VaSelect.demo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,91 @@
/>
<p>Value: {{ defaultSingleSelect.value }}</p>
</VbCard>
<VbCard
title="Autocomplete"
style="width: 400px;"
>
<va-select
v-model="defaultSingleSelect.value"
class="mb-6"
placeholder="Start to write..."
:options="defaultSingleSelect.options"
autocomplete
highlight-search
/>
<p>Value: {{ defaultSingleSelect.value }}</p>
</VbCard>
<VbCard
title="Multiple autocomplete"
style="width: 400px;"
>
<va-select
v-model="defaultMultiSelect.value"
class="mb-6"
placeholder="Start to write..."
:options="defaultMultiSelect.options"
multiple
autocomplete
highlight-search
/>
<p>Value: {{ defaultMultiSelect.value }}</p>
</VbCard>
<VbCard
title="Autocomplete with content slot"
style="width: 400px;"
>
<va-select
v-model="defaultMultiSelect.value"
class="mb-6"
placeholder="Start to write..."
:options="defaultMultiSelect.options"
multiple
autocomplete
highlight-search
>
<template #content="{ value }">
<va-chip
v-for="chip in value"
:key="chip"
class="mr-1"
size="small"
>
{{ chip }}
</va-chip>
</template>
</va-select>
<p>Value: {{ defaultMultiSelect.value }}</p>
</VbCard>
<VbCard
title="Min chars (2) to trigger autocomplete"
style="width: 400px;"
>
<va-select
v-model="defaultSingleSelect.value"
class="mb-6"
placeholder="Start to write..."
:options="defaultSingleSelect.options"
:min-search-chars="2"
autocomplete
highlight-search
/>
<p>Value: {{ defaultSingleSelect.value }}</p>
</VbCard>
<VbCard
title="Autocomplete with auto select first option"
style="width: 400px;"
>
<va-select
v-model="defaultSingleSelect.value"
class="mb-6"
placeholder="Start to write..."
:options="defaultSingleSelect.options"
autocomplete
highlight-search
auto-select-first-option
/>
<p>Value: {{ defaultSingleSelect.value }}</p>
</VbCard>
<VbCard
title="Selected options at the top"
style="width: 400px;"
Expand Down
51 changes: 48 additions & 3 deletions packages/ui/src/components/va-select/VaSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
v-bind="inputWrapperPropsComputed"
@focus="onInputFocus"
@blur="onInputBlur"
@click="focusAutocompleteInput"
>
<template
v-for="(_, name) in $slots"
Expand All @@ -41,13 +42,19 @@
<va-icon
:color="toggleIconColor"
:name="toggleIcon"
@click.stop="toggleDropdown"
/>
</template>

<template #default>
<va-select-content
v-bind="selectContentPropsComputed"
@toggle-hidden="toggleHiddenOptionsState"
@autocomplete-input="handleAutocompleteInput"
@focus-prev="focusPreviousOption"
@focus-next="focusNextOption"
@select-option="selectHoveredOption"
@delete-last-selected="deleteLastSelected"
>
<template
v-for="(_, name) in $slots"
Expand Down Expand Up @@ -205,6 +212,10 @@ export default defineComponent({
tabindex: { type: Number, default: 0 },
virtualScroller: { type: Boolean, default: false },
selectedTopShown: { type: Boolean, default: false },
autocomplete: { type: Boolean, default: false },
highlightSearch: { type: Boolean, default: false },
minSearchChars: { type: Number, default: 0 },
autoSelectFirstOption: { type: Boolean, default: false },
// Input style
outline: { type: Boolean, default: false },
Expand Down Expand Up @@ -553,8 +564,8 @@ export default defineComponent({
}))
const optionsListPropsComputed = computed(() => ({
...pick(props, ['textBy', 'trackBy', 'groupBy', 'disabledBy', 'color', 'virtualScroller']),
search: searchInput.value,
...pick(props, ['textBy', 'trackBy', 'groupBy', 'disabledBy', 'color', 'virtualScroller', 'highlightSearch', 'minSearchChars', 'autoSelectFirstOption']),
search: searchInput.value || autocompleteValue.value,
tabindex: tabIndexComputed.value,
selectedValue: valueComputed.value,
options: filteredOptions.value,
Expand All @@ -579,14 +590,24 @@ export default defineComponent({
// select content
const selectContentPropsComputed = computed(() => ({
...pick(props, ['placeholder']),
...pick(props, ['placeholder', 'autocomplete', 'multiple', 'disabled']),
tabindex: tabIndexComputed.value,
value: visibleSelectedOptions.value,
valueString: valueComputedString.value,
hiddenSelectedOptionsAmount: hiddenSelectedOptionsAmount.value,
isAllOptionsShown: isAllOptionsShown.value,
dropdownContentShown: showDropdownContent.value,
focused: isInputFocused.value,
getText,
}))
// autocomplete
const autocompleteValue = ref('')
const handleAutocompleteInput = (v: string) => {
autocompleteValue.value = v
showDropdownContent.value = true
}
// public methods
const focus = () => {
if (props.disabled) { return }
Expand All @@ -613,6 +634,26 @@ export default defineComponent({
resetValidation()
})
const focusAutocompleteInput = (e: Event) => {
if (props.autocomplete) {
e.stopImmediatePropagation()
onFocus()
}
}
const toggleDropdown = () => {
if (props.disabled || props.readonly) { return }
showDropdownContentComputed.value = !showDropdownContentComputed.value
}
const deleteLastSelected = () => {
if (!Array.isArray(valueComputed.value)) { return }
valueComputed.value = valueComputed.value.slice(0, -1)
}
const {
validate,
computedError,
Expand All @@ -629,6 +670,9 @@ export default defineComponent({
reset,
focus,
blur,
toggleDropdown,
deleteLastSelected,
focusAutocompleteInput,
tp,
t,
Expand Down Expand Up @@ -661,6 +705,7 @@ export default defineComponent({
visibleSelectedOptions,
optionsListPropsComputed,
toggleHiddenOptionsState,
handleAutocompleteInput,
inputWrapperPropsComputed,
inputWrapperClassComputed,
Expand Down
Loading

0 comments on commit 0e66e08

Please sign in to comment.