Skip to content

Commit

Permalink
perf: Improved Menu performance and Flip bugs (#680)
Browse files Browse the repository at this point in the history
  • Loading branch information
wangKBweb authored and BeADre committed Sep 18, 2022
1 parent 4658805 commit f582c78
Show file tree
Hide file tree
Showing 12 changed files with 135 additions and 517 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -315,18 +315,18 @@ exports[`test form with select 1`] = `
<div class=\\"var-select var--box var-select--disabled\\">
<div class=\\"var-select__controller var-select--disabled\\">
<div class=\\"var-select__icon\\"></div>
<div class=\\"var-menu var-select__menu\\" var-select-cover=\\"\\">
<div class=\\"var-select__wrap\\">
<div class=\\"var-select__wrap\\">
<div class=\\"var-menu-v2 var-select__menu\\" var-select-cover=\\"\\">
<div class=\\"var-select__select var-select--disabled\\" style=\\"text-align: left;\\">
<div>
<div class=\\"var-select__chips\\">
<transition-stub><span class=\\"var-chip var--box var-chip--small var--inline-flex var-chip--default var-chip--round var-select__chip\\" var-select-cover=\\"\\"><span class=\\"var-chip__text-small\\">选项1</span><span class=\\"var-chip--close\\"><i class=\\"var-icon var-icon--set var-icon-close-circle\\" style=\\"transition: transform 0ms;\\"></i></span></span></transition-stub>
</div>
</div><i class=\\"var-icon var-icon--set var-icon-menu-down var-select__arrow\\" style=\\"transition: transform 300ms;\\" var-select-cover=\\"\\"></i>
</div><label class=\\"var-select__placeholder var--ellipsis var-select--disabled var-select--placeholder-hint\\"></label>
<!--teleport start-->
<!--teleport end-->
</div>
<!--teleport start-->
<!--teleport end-->
</div>
<div class=\\"var-select__icon\\"><i class=\\"var-icon var-icon--set var-icon-close-circle var-select__clear-icon\\" style=\\"transition: transform 0ms; font-size: 14px;\\"></i></div>
</div>
Expand All @@ -345,18 +345,18 @@ exports[`test form with select 2`] = `
<div class=\\"var-select var--box\\">
<div class=\\"var-select__controller\\">
<div class=\\"var-select__icon\\"></div>
<div class=\\"var-menu var-select__menu\\" var-select-cover=\\"\\">
<div class=\\"var-select__wrap\\">
<div class=\\"var-select__wrap\\">
<div class=\\"var-menu-v2 var-select__menu\\" var-select-cover=\\"\\">
<div class=\\"var-select__select\\" style=\\"text-align: left;\\">
<div>
<div class=\\"var-select__chips\\">
<transition-stub><span class=\\"var-chip var--box var-chip--small var--inline-flex var-chip--default var-chip--round var-select__chip\\" var-select-cover=\\"\\"><span class=\\"var-chip__text-small\\">选项1</span><span class=\\"var-chip--close\\"><i class=\\"var-icon var-icon--set var-icon-close-circle\\" style=\\"transition: transform 0ms;\\"></i></span></span></transition-stub>
</div>
</div><i class=\\"var-icon var-icon--set var-icon-menu-down var-select__arrow\\" style=\\"transition: transform 300ms;\\" var-select-cover=\\"\\"></i>
</div><label class=\\"var-select__placeholder var--ellipsis var-select--placeholder-hint\\"></label>
<!--teleport start-->
<!--teleport end-->
</div>
<!--teleport start-->
<!--teleport end-->
</div>
<div class=\\"var-select__icon\\"><i class=\\"var-icon var-icon--set var-icon-close-circle var-select__clear-icon\\" style=\\"transition: transform 0ms; font-size: 14px;\\"></i></div>
</div>
Expand All @@ -375,18 +375,18 @@ exports[`test form with select 3`] = `
<div class=\\"var-select var--box\\">
<div class=\\"var-select__controller var-select--error\\">
<div class=\\"var-select__icon\\"></div>
<div class=\\"var-menu var-select__menu\\" var-select-cover=\\"\\">
<div class=\\"var-select__wrap\\">
<div class=\\"var-select__wrap\\">
<div class=\\"var-menu-v2 var-select__menu\\" var-select-cover=\\"\\">
<div class=\\"var-select__select var-select--error\\" style=\\"text-align: left;\\">
<div>
<div class=\\"var-select__chips\\">
<transition-stub><span class=\\"var-chip var--box var-chip--small var--inline-flex var-chip--danger var-chip--round var-select__chip\\" var-select-cover=\\"\\"><span class=\\"var-chip__text-small\\">选项1</span><span class=\\"var-chip--close\\"><i class=\\"var-icon var-icon--set var-icon-close-circle\\" style=\\"transition: transform 0ms;\\"></i></span></span></transition-stub>
</div>
</div><i class=\\"var-icon var-icon--set var-icon-menu-down var-select__arrow\\" style=\\"transition: transform 300ms;\\" var-select-cover=\\"\\"></i>
</div><label class=\\"var-select__placeholder var--ellipsis var-select--error var-select--placeholder-hint\\"></label>
<!--teleport start-->
<!--teleport end-->
</div>
<!--teleport start-->
<!--teleport end-->
</div>
<div class=\\"var-select__icon\\"><i class=\\"var-icon var-icon--set var-icon-close-circle var-select__clear-icon\\" style=\\"transition: transform 0ms; font-size: 14px;\\"></i></div>
</div>
Expand All @@ -408,16 +408,16 @@ exports[`test form with select 4`] = `
<div class=\\"var-select var--box\\">
<div class=\\"var-select__controller\\">
<div class=\\"var-select__icon\\"></div>
<div class=\\"var-menu var-select__menu\\" var-select-cover=\\"\\">
<div class=\\"var-select__wrap\\">
<div class=\\"var-select__wrap\\">
<div class=\\"var-menu-v2 var-select__menu\\" var-select-cover=\\"\\">
<div class=\\"var-select__select\\" style=\\"text-align: left;\\">
<div>
<div class=\\"var-select__chips\\"></div>
</div><i class=\\"var-icon var-icon--set var-icon-menu-down var-select__arrow\\" style=\\"transition: transform 300ms;\\" var-select-cover=\\"\\"></i>
</div><label class=\\"var-select__placeholder var--ellipsis\\"></label>
<!--teleport start-->
<!--teleport end-->
</div>
<!--teleport start-->
<!--teleport end-->
</div>
<div class=\\"var-select__icon\\"><i class=\\"var-icon var-icon--set var-icon-close-circle var-select__clear-icon\\" style=\\"transition: transform 0ms; font-size: 14px;\\"></i></div>
</div>
Expand Down
16 changes: 15 additions & 1 deletion packages/varlet-ui/src/menu-v2/MenuV2.vue
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,10 @@ export default defineComponent({
return {
placement,
modifiers: [
flip,
{
...flip,
enabled: show.value,
},
{
...offset,
options: {
Expand All @@ -262,6 +265,12 @@ export default defineComponent({
// expose
const open = () => {
const { disabled } = props
if (disabled) {
return
}
show.value = true
call(props['onUpdate:show'], true)
}
Expand Down Expand Up @@ -307,6 +316,8 @@ export default defineComponent({
}
)
watch(() => props.disabled, close)
onMounted(() => {
popover = createPopper(host.value!, menu.value!, getPopperOptions())
Expand All @@ -316,6 +327,7 @@ export default defineComponent({
})
onUnmounted(() => {
document.removeEventListener('click', handleMenuClose)
popover!.destroy()
})
return {
Expand All @@ -342,4 +354,6 @@ export default defineComponent({

<style lang="less">
@import './menuV2';
@import '../styles/elevation.less';
@import '../styles/common.less';
</style>
4 changes: 4 additions & 0 deletions packages/varlet-ui/src/menu-v2/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ export const props = {
type: Boolean,
default: false,
},
disabled: {
type: Boolean,
default: false,
},
trigger: {
type: String as PropType<'click' | 'hover'>,
default: 'click',
Expand Down
60 changes: 21 additions & 39 deletions packages/varlet-ui/src/select/Select.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,15 @@
<slot name="prepend-icon" />
</div>

<var-menu :class="n('menu')" var-select-cover :offset-y="offsetY" v-model:show="isFocus" @close="handleBlur">
<div :class="classes(n('wrap'), [!hint, n('--non-hint')])" ref="wrapEl" @click="handleFocus">
<div :class="classes(n('wrap'), [!hint, n('--non-hint')])" ref="wrapEl" @click="handleFocus">
<var-menu
:class="n('menu')"
var-select-cover
:offset-y="offsetY"
:disabled="readonly || disabled"
v-model:show="isFocus"
@close="handleBlur"
>
<div
:class="classes(n('select'), [errorMessage, n('--error')], [formDisabled || disabled, n('--disabled')])"
:style="{
Expand Down Expand Up @@ -74,14 +81,14 @@
>
{{ placeholder }}
</label>
</div>

<template #menu>
<div ref="menuEl" :class="n('scroller')">
<slot />
</div>
</template>
</var-menu>
<template #menu>
<div ref="menuEl" :class="n('scroller')">
<slot />
</div>
</template>
</var-menu>
</div>

<div :class="classes(n('icon'), [!hint, n('--non-hint')])">
<slot name="append-icon">
Expand Down Expand Up @@ -114,7 +121,7 @@

<script lang="ts">
import VarIcon from '../icon'
import VarMenu from '../menu'
import VarMenu from '../menu-v2'
import VarChip from '../chip'
import VarFormDetails from '../form-details'
import { computed, defineComponent, ref, watch, nextTick } from 'vue'
Expand All @@ -123,7 +130,7 @@ import { props } from './props'
import { useValidation, createNamespace, call } from '../utils/components'
import { useOptions } from './provide'
import { useForm } from '../form/provide'
import { getTop, toPxNum } from '../utils/elements'
import { toPxNum } from '../utils/elements'
import type { Ref, ComputedRef } from 'vue'
import type { SelectValidateTrigger } from './props'
import type { SelectProvider } from './provide'
Expand Down Expand Up @@ -214,11 +221,6 @@ export default defineComponent({
return (wrapEl.value && window.getComputedStyle(wrapEl.value as HTMLElement).width) || '0px'
}
const getOffsetY = () => {
const paddingTop = (wrapEl.value && window.getComputedStyle(wrapEl.value as HTMLElement).paddingTop) || '0px'
return toPxNum(paddingTop) * 1.5
}
const handleFocus = () => {
const { disabled, readonly, onFocus } = props
Expand All @@ -227,13 +229,12 @@ export default defineComponent({
}
wrapWidth.value = getWrapWidth()
offsetY.value = getOffsetY() + toPxNum(props.offsetY)
offsetY.value = toPxNum(props.offsetY)
isFocus.value = true
call(onFocus)
validateWithTrigger('onFocus')
detectBoundary()
}
const handleBlur = () => {
Expand Down Expand Up @@ -322,9 +323,8 @@ export default defineComponent({
// expose
const focus = () => {
wrapWidth.value = getWrapWidth()
offsetY.value = getOffsetY() + toPxNum(props.offsetY)
offsetY.value = toPxNum(props.offsetY)
isFocus.value = true
detectBoundary()
}
// expose
Expand All @@ -341,24 +341,6 @@ export default defineComponent({
resetValidation()
}
const detectBoundary = () => {
const { body } = document
const bodyScrollHeight = body.scrollHeight
nextTick(() => {
const { offsetHeight: menuOffsetHeight } = menuEl.value?.parentElement as HTMLElement
const wrapOffsetTop = getTop(wrapEl.value as HTMLElement)
if (wrapOffsetTop + offsetY.value < 0) {
offsetY.value = getOffsetY()
}
if (menuOffsetHeight + wrapOffsetTop + offsetY.value > bodyScrollHeight) {
offsetY.value -= menuOffsetHeight - getOffsetY()
}
})
}
watch(
() => props.multiple,
() => {
Expand Down Expand Up @@ -416,7 +398,7 @@ export default defineComponent({
<style lang="less">
@import '../styles/common';
@import '../icon/icon';
@import '../menu/menu';
@import '../menu-v2/menuV2';
@import '../form-details/formDetails';
@import '../chip/chip';
@import './select';
Expand Down
Loading

0 comments on commit f582c78

Please sign in to comment.