refactor(select-menu): use vueuc

This commit is contained in:
07akioni 2020-10-09 18:56:59 +08:00
parent dffcc93d95
commit 502deff40b
5 changed files with 50 additions and 41 deletions

View File

@ -13,12 +13,35 @@
>
<n-scrollbar
v-if="!empty"
ref="scrollbar"
ref="scrollbarRef"
:theme="theme"
:scrollable="scrollable"
@scroll="handleMenuScroll"
>
<div class="n-base-select-menu-option-wrapper">
<virtual-list
v-if="virtualScroll"
ref="virtualListRef"
class="n-virtual-list"
:items="flattenedOptions"
:item-height="itemSize"
:show-scrollbar="false"
>
<template v-slot="{ item: option }">
<n-select-option
v-if="option.type === OPTION_TYPE.OPTION"
:key="option.key"
:index="option.index"
:wrapped-option="option"
:grouped="option.grouped"
/>
<n-select-group-header
v-else-if="option.type === OPTION_TYPE.GROUP_HEADER"
:key="option.key"
:data="option.data"
/>
</template>
</virtual-list>
<!-- <recycle-scroller
v-if="virtualScroll"
ref="virtualScroller"
@ -44,7 +67,6 @@
:index="option.index"
:wrapped-option="option"
:grouped="option.grouped"
:selected="isOptionSelected({ value: option.data.value })"
/>
<n-select-group-header
v-else-if="option.type === OPTION_TYPE.GROUP_HEADER"
@ -53,7 +75,7 @@
/>
</template>
</recycle-scroller> -->
<template v-for="option in flattenedOptions">
<template v-for="option in flattenedOptions" v-else>
<n-select-option
v-if="option.type === OPTION_TYPE.OPTION"
:key="option.key"
@ -89,6 +111,8 @@
</template>
<script>
import { ref } from 'vue'
import { VirtualList } from 'vueuc'
import NScrollbar from '../../../scrollbar'
import NSelectOption from './SelectOption.js'
import NSelectGroupHeader from './SelectGroupHeader.js'
@ -113,6 +137,7 @@ export default {
}
},
components: {
VirtualList,
NScrollbar,
NSelectOption,
NEmpty,
@ -164,7 +189,7 @@ export default {
},
virtualScroll: {
type: Boolean,
default: false
default: true
},
// deprecated
onMenuVisible: {
@ -185,6 +210,12 @@ export default {
default: false
}
},
setup () {
return {
virtualListRef: ref(null),
scrollbarRef: ref(null)
}
},
data () {
const flattenedOptions = flattenOptions(this.options)
const firstAvailableOptionIndex = this.autoPendingFirstOption
@ -327,27 +358,11 @@ export default {
setPendingWrappedOptionIndex (index, doScroll = false) {
if (index === null) {
this.pendingWrappedOption = null
return
}
const scrollbar = this.$refs.scrollbar
if (this.virtualScroll) {
// this.pendingWrappedOption = this.flattenedOptions[index]
// const size = this.itemSize
// const offsetTop = size * index
// this.updateTrackingRectTop({
// offsetTop
// })
// doScroll && scrollbar && scrollbar.scrollToElement({}, () => offsetTop, () => size)
} else {
this.pendingWrappedOption = this.flattenedOptions[index]
if (doScroll && scrollbar) {
const el = this.$el
const optionEl = el.querySelector(`[n-option-index="${index}"]`)
scrollbar.scrollToElement(optionEl, {
behavior: 'auto'
})
}
}
// TODO: fix scroll logic
// const scrollbar = this.scrollbarRef
this.pendingWrappedOption = this.flattenedOptions[index]
// scrollbar.scrollTo({ y: index * this.itemSize })
}
}
}

View File

@ -11,20 +11,7 @@ export default c([
const menuHeight = pxfy(depx(optionHeight) * 7.6)
return cTB('base-select-menu', [
cM(size + '-size', [
cB('virtual-scroller', {
raw: `
height: 100%;
max-height: ${menuHeight};
scrollbar-width: none;
-moz-scrollbar-width: none;
`
}, [
c('&::-webkit-scrollbar', {
width: 0,
height: 0
})
]),
cB('scrollbar-container', {
cB('virtual-list', {
maxHeight: menuHeight
}),
cB('base-select-option', {

View File

@ -205,7 +205,7 @@ export default {
(widthMode === 'trigger' || widthMode === 'activator')
) {
const body = this.__getBodyElement()
body.style.minWidth = triggerRect.width + 'px'
body.style.width = triggerRect.width + 'px'
}
let adjustedPlacement = this.placement
let contentBoundingClientRect = null

View File

@ -20,7 +20,10 @@
>
<div
ref="scrollContent"
:style="contentStyle"
:style="{
width: xScrollable ? 'fit-content' : null,
...contentStyle,
}"
class="n-scrollbar-content"
>
<slot />
@ -110,6 +113,10 @@ export default {
type: Boolean,
default: true
},
xScrollable: {
type: Boolean,
default: false
},
container: {
type: Function,
default: null

View File

@ -12,6 +12,7 @@ export default c([
} = props.$base
return cTB('scrollbar', {
raw: `
overflow: hidden;
position: relative;
z-index: auto;
height: 100%;
@ -36,7 +37,6 @@ export default c([
c('>', [
cB('scrollbar-content', {
raw: `
width: fit-content;
overflow: hidden;
min-width: 100%;
`