88 <teleport to =" body" :disabled =" !appendToBody" >
99 <div
1010 v-show =" modelValue"
11- class =" shadow p-y-xs absolute radius-m"
12- :class =" `${namespace}-options-wrapper ${namespace}-align-${align}`"
13- :style =" {...optionsStyle}" >
14- <div :class =" `${namespace}-options relative`" @click =" handleClickOption" >
15- <slot name =" options" ></slot >
11+ class =" absolute pos-origin"
12+ :class =" [
13+ appendToBody ? '' : 'absolute pos-origin no-append-to-body',
14+ ]"
15+ :style =" { zIndex: level }" >
16+ <div
17+ class =" shadow p-y-xs absolute radius-m pos-origin"
18+ :class =" `${namespace}-options-wrapper ${namespace}-align-${align}`"
19+ :style =" { ...offsetStyle, ...optionsStyle }" >
20+ <div :class =" `${namespace}-options relative`" @click =" handleClickOption" >
21+ <slot name =" options" ></slot >
22+ </div >
1623 </div >
1724 </div >
1825 </teleport >
2330import { onMounted , shallowRef , watch } from " vue"
2431import useClickOutside from " @hooks/use-click-outside"
2532import { Trigger , Position , Align } from " @type/interface"
33+ import { getOffsetStyle , getPosStyle } from " @components/utils/common"
2634
2735interface IProps {
2836 /** 是否显示下拉菜单 */
2937 modelValue: boolean
3038 /** 触发下拉的行为 */
3139 trigger? : string
3240 /** 菜单显示的位置 */
33- position? : Position
41+ position? : Position | string
3442 /** 菜单沿着哪一边对齐 */
35- align? : Align
43+ align? : Align | string
3644 /** 是否显示三角 */
3745 showTriangle? : boolean
3846 /** 是否将选择项列表插入到body中 */
3947 appendToBody? : boolean
48+ /** 层级,对应z-index */
49+ level? : string | number
4050}
4151
4252const props = withDefaults (defineProps <IProps >(), {
4353 position: Position .BOTTOM ,
4454 align: Align .LEFT ,
4555 trigger: Trigger .CLICK ,
4656 modelValue: false ,
57+ level: " auto" ,
4758})
4859const emits = defineEmits ([" update:modelValue" ])
4960
@@ -68,21 +79,22 @@ watch(isClickOutSide, () => {
6879
6980/** 定位样式 */
7081const optionsStyle = shallowRef <Record <string , string >>({})
82+ /** 偏移样式 */
83+ const offsetStyle = getOffsetStyle (0 , props .position as Position )
7184const setOptionStyle = () => {
7285 if (! props .appendToBody || ! dropdownOptsRef .value ) { return }
73- const { height = 0 , width = 0 , top = 0 , left = 0 , right = 0 } = dropdownOptsRef .value .getBoundingClientRect ()
74- const { align } = props
86+ const {
87+ height = 0 , width = 0 , bottom = 0 , top = 0 , left = 0 , right = 0 ,
88+ } = dropdownOptsRef .value .getBoundingClientRect ()
7589 optionsStyle .value = {
76- width: " auto" ,
77- transform: " none" ,
78- top: ` ${top + height }px ` ,
79- right: align === Align .RIGHT ? ` calc(100% - ${right }px) ` : " auto" ,
80- bottom: " auto" ,
81- left: align === Align .LEFT
90+ ... getPosStyle ({ left , top , bottom , right , width , height , position: props .position as Position }),
91+ right: props .align === Align .RIGHT ? ` calc(100% - ${right }px) ` : " auto" ,
92+ left: props .align === Align .LEFT
8293 ? ` ${left }px `
83- : align === Align .MIDDLE
94+ : props . align === Align .MIDDLE
8495 ? ` ${left - width / 2 }px `
8596 : " auto" ,
97+ transform: " none" ,
8698 }
8799}
88100onMounted (() => {
0 commit comments