Skip to content

Commit

Permalink
fix(base-select): fix virtual list props
Browse files Browse the repository at this point in the history
  • Loading branch information
rudnovd committed Apr 11, 2024
1 parent 327d33a commit a5cb839
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 23 deletions.
14 changes: 7 additions & 7 deletions src/components/MagicCalculator.vue
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
:value="selectedSpell[sideName]"
:options="spells"
:placeholder="t('components.magicCalculator.selectSpell')"
use-virtual-scoll
virtual-scroll
@select="onSelectSpell(sideName, $event)"
@clear="selectedSpell[sideName] = null"
>
Expand Down Expand Up @@ -382,7 +382,7 @@ const getSpellTargets = (sideName: BattleSide) => {
.spell {
display: grid;
grid-template-areas: 'target select';
grid-template-columns: minmax(auto, 33.3%) 1fr;
grid-template-columns: minmax(auto, 40%) 1fr;
gap: 8px;
align-items: center;
Expand Down Expand Up @@ -411,18 +411,18 @@ const getSpellTargets = (sideName: BattleSide) => {
}
.title {
grid-template-columns: minmax(auto, 33.3%) 1fr;
grid-template-columns: minmax(auto, 40%) 1fr;
}
.main {
grid-template-columns: minmax(auto, 33.3%) 1fr;
grid-template-columns: minmax(auto, 40%) 1fr;
}
}
.defender {
.title {
grid-template-areas: 'button title';
grid-template-columns: 1fr minmax(auto, 33.3%);
grid-template-columns: 1fr minmax(auto, 40%);
}
.title > h2 {
grid-area: title;
Expand All @@ -431,7 +431,7 @@ const getSpellTargets = (sideName: BattleSide) => {
.main {
grid-template-areas: 'hero creature';
grid-template-columns: auto minmax(auto, 33.3%);
grid-template-columns: auto minmax(auto, 40%);
}
.creature {
Expand All @@ -440,7 +440,7 @@ const getSpellTargets = (sideName: BattleSide) => {
}
.spell {
grid-template-columns: 1fr minmax(auto, 33.3%);
grid-template-columns: 1fr minmax(auto, 40%);
div:nth-child(1) {
grid-area: select;
Expand Down
2 changes: 1 addition & 1 deletion src/components/SelectHero.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
:value="value"
:options="heroes"
:preload-options-count="20"
use-virtual-scoll
virtual-scroll
:placeholder="t('components.selectHero.placeholder')"
@select="$emit('select', $event)"
@clear="$emit('clear')"
Expand Down
45 changes: 30 additions & 15 deletions src/components/base/BaseSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,18 @@
<Transition name="fade">
<div
v-if="opened"
:ref="containerProps.ref"
v-bind="virtualScroll ? virtualScrollContainer : void 0"
class="items"
:class="dropdownPosition"
tabindex="-1"
@scroll="containerProps.onScroll"
>
<ul v-bind="wrapperProps">
<ul v-bind="virtualScroll ? wrapperProps : void 0">
<li
v-for="{ index, data } in optionsList"
:key="index"
:key="data[label]"
class="option-item"
:class="{ selected: selectedValue && selectedValue[label] === data[label] }"
@click="onSelect(data)"
@click="onSelect(data, index)"
>
<slot name="option" :option="data">{{ data[label] }}</slot>
</li>
Expand All @@ -60,7 +59,7 @@
import i18n from '@/i18n'
import { onClickOutside, useVirtualList } from '@vueuse/core'
import type { Ref } from 'vue'
import { computed, ref, watch } from 'vue'
import { computed, nextTick, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'
const props = withDefaults(
Expand All @@ -70,7 +69,7 @@ const props = withDefaults(
options: T[]
optionsMaxHeight?: string
preloadOptionsCount?: number
useVirtualScroll?: boolean
virtualScroll?: boolean
height?: string
dropdownPosition?: 'top' | 'bottom'
placeholder?: string
Expand All @@ -79,7 +78,7 @@ const props = withDefaults(
label: 'name',
optionsMaxHeight: '300px',
preloadOptionsCount: 5,
useVirtualScroll: false,
virtualScroll: false,
height: '42px',
dropdownPosition: 'bottom',
placeholder: () => {
Expand All @@ -98,24 +97,35 @@ const { t } = useI18n()
const opened = ref(false)
const selectedValue: Ref<T | null> = ref(null)
selectedValue.value = props.value
let selectedIndex = 0
const search = ref('')
const onSelect = (item: T) => {
const onSelect = (item: T, index: number) => {
selectedValue.value = item
opened.value = false
search.value = ''
selectedIndex = index
emit('select', item)
}
const onClear = () => {
selectedValue.value = null
search.value = ''
if (opened.value) opened.value = false
if (opened.value) {
opened.value = false
selectedIndex = 0
}
emit('clear')
}
const open = () => {
if (!opened.value) opened.value = true
if (!opened.value) {
opened.value = true
nextTick(() => {
const top = selectedIndex ? selectedIndex * parseInt(props.height) : 0
if (props.virtualScroll) virtualScrollContainer.ref.value?.scrollTo({ top })
})
}
}
const searchElement = (event: Event) => {
Expand All @@ -125,24 +135,29 @@ const searchElement = (event: Event) => {
const firstOptions = computed(() => {
if (search.value.length) {
const searchQuery = search.value.toLowerCase()
return props.options
.filter((option) => {
const optionString = option[props.label] as string
return optionString.toLowerCase().indexOf(search.value.toLowerCase()) > -1
return optionString.toLowerCase().includes(searchQuery)
})
.map((data, index) => ({ data, index }))
} else {
return props.options.map((data, index) => ({ data, index }))
}
})
const { list, containerProps, wrapperProps } = useVirtualList(firstOptions, {
const {
list,
containerProps: virtualScrollContainer,
wrapperProps,
} = useVirtualList(firstOptions, {
itemHeight: parseInt(props.height),
overscan: props.preloadOptionsCount,
})
const optionsList = computed(() => {
if (props.useVirtualScroll) {
if (props.virtualScroll) {
return list.value.map((item) => ({ ...item.data, index: item.index }))
} else {
return firstOptions.value
Expand All @@ -155,7 +170,7 @@ watch(search, () => {
}
})
onClickOutside(containerProps.ref, () => {
onClickOutside(virtualScrollContainer.ref, () => {
setTimeout(() => {
opened.value = false
}, 100)
Expand Down

0 comments on commit a5cb839

Please sign in to comment.