Skip to content

Commit 36c6fde

Browse files
committed
Merge branch 'dev' of github.com:DevCloudFE/vue-devui into dev
2 parents bdbc24d + 60d43d6 commit 36c6fde

File tree

4 files changed

+43
-46
lines changed

4 files changed

+43
-46
lines changed

packages/devui-vue/devui/overlay/src/flexible-overlay/use-flexible-overlay.ts

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import { ref, unref, watch, nextTick, onUnmounted } from 'vue';
2-
import { arrow, autoPlacement, computePosition, offset, shift } from '@floating-ui/dom';
1+
import { ref, unref, watch, nextTick, onUnmounted, toRefs } from 'vue';
2+
import { arrow, computePosition, offset, flip } from '@floating-ui/dom';
33
import { FlexibleOverlayProps, Placement, Point, UseOverlayFn, EmitEventFn, Rect } from './flexible-overlay-types';
4-
import { getScrollParent } from './utils';
54

65
function adjustArrowPosition(isArrowCenter: boolean, point: Point, placement: Placement, originRect: Rect): Point {
76
let { x, y } = point;
@@ -25,9 +24,10 @@ function adjustArrowPosition(isArrowCenter: boolean, point: Point, placement: Pl
2524
}
2625

2726
export function useOverlay(props: FlexibleOverlayProps, emit: EmitEventFn): UseOverlayFn {
27+
const { position, showArrow } = toRefs(props);
2828
const overlayRef = ref<HTMLElement | undefined>();
2929
const arrowRef = ref<HTMLElement | undefined>();
30-
let originParent = null;
30+
3131
const updateArrowPosition = (arrowEl: HTMLElement, placement: Placement, point: Point, overlayEl: HTMLElement) => {
3232
const { x, y } = adjustArrowPosition(props.isArrowCenter, point, placement, overlayEl.getBoundingClientRect());
3333
const staticSide = {
@@ -48,54 +48,46 @@ export function useOverlay(props: FlexibleOverlayProps, emit: EmitEventFn): UseO
4848
const hostEl = <HTMLElement>props.origin;
4949
const overlayEl = <HTMLElement>unref(overlayRef.value);
5050
const arrowEl = <HTMLElement>unref(arrowRef.value);
51-
const middleware = [
52-
offset(props.offset),
53-
autoPlacement({
54-
alignment: props.align,
55-
allowedPlacements: props.position,
56-
}),
57-
];
58-
props.showArrow && middleware.push(arrow({ element: arrowEl }));
59-
props.shiftOffset !== undefined && middleware.push(shift());
60-
if (!overlayEl) {
61-
return;
51+
52+
const [mainPosition, ...fallbackPosition] = position.value;
53+
const middleware = [offset(props.offset)];
54+
middleware.push(fallbackPosition.length ? flip({ fallbackPlacements: fallbackPosition }) : flip());
55+
if (showArrow.value) {
56+
middleware.push(arrow({ element: arrowRef.value! }));
6257
}
6358
const { x, y, placement, middlewareData } = await computePosition(hostEl, overlayEl, {
6459
strategy: 'fixed',
60+
placement: mainPosition,
6561
middleware,
6662
});
6763
let applyX = x;
6864
let applyY = y;
69-
if (props.shiftOffset !== undefined) {
70-
const { x: shiftX, y: shiftY } = middlewareData.shift;
71-
shiftX < 0 && (applyX -= props.shiftOffset);
72-
shiftX > 0 && (applyX += props.shiftOffset);
73-
shiftY < 0 && (applyY -= props.shiftOffset);
74-
shiftY > 0 && (applyY += props.shiftOffset);
75-
}
7665
emit('positionChange', placement);
7766
Object.assign(overlayEl.style, { top: `${applyY}px`, left: `${applyX}px` });
7867
props.showArrow && updateArrowPosition(arrowEl, placement, middlewareData.arrow, overlayEl);
7968
};
69+
70+
const scrollCallback = (e: Event) => {
71+
const scrollElement = e.target as HTMLElement;
72+
if (scrollElement?.contains(props.origin?.$el ?? props.origin)) {
73+
updatePosition();
74+
}
75+
};
8076
watch(
8177
() => props.modelValue,
8278
() => {
8379
if (props.modelValue && props.origin) {
84-
originParent = getScrollParent(props.origin);
8580
nextTick(updatePosition);
86-
originParent?.addEventListener('scroll', updatePosition);
87-
originParent !== window && window.addEventListener('scroll', updatePosition);
81+
window.addEventListener('scroll', scrollCallback, true);
8882
window.addEventListener('resize', updatePosition);
8983
} else {
90-
originParent?.removeEventListener('scroll', updatePosition);
91-
originParent !== window && window.removeEventListener('scroll', updatePosition);
84+
window.removeEventListener('scroll', scrollCallback, true);
9285
window.removeEventListener('resize', updatePosition);
9386
}
9487
}
9588
);
9689
onUnmounted(() => {
97-
originParent?.removeEventListener('scroll', updatePosition);
98-
originParent !== window && window.removeEventListener('scroll', updatePosition);
90+
window.removeEventListener('scroll', scrollCallback, true);
9991
window.removeEventListener('resize', updatePosition);
10092
});
10193

packages/devui-vue/docs/components/dropdown/index.md

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
```vue
1414
<template>
15-
<d-dropdown style="width: 100px;" :position="position" align="start">
15+
<d-dropdown style="width: 100px;" :position="position">
1616
<d-button>Click Me</d-button>
1717
<template #menu>
1818
<ul class="list-menu">
@@ -31,7 +31,7 @@ import { defineComponent, ref } from 'vue';
3131
export default defineComponent({
3232
setup() {
3333
return {
34-
position: ref(['bottom-start', 'top-start']),
34+
position: ref(['bottom-start', 'right','top-end']),
3535
};
3636
},
3737
});
@@ -74,7 +74,7 @@ export default defineComponent({
7474
</d-radio-group>
7575
</div>
7676
</div>
77-
<d-dropdown :visible="isOpen" :trigger="trigger" :position="position" align="start" @toggle="handleToggle">
77+
<d-dropdown :visible="isOpen" :trigger="trigger" :position="position" @toggle="handleToggle">
7878
<d-button class="mt-1">More</d-button>
7979
<template #menu>
8080
<ul class="list-menu">
@@ -125,7 +125,7 @@ export default defineComponent({
125125
</d-radio-group>
126126
</div>
127127
</div>
128-
<d-dropdown :close-scope="closeScope" :position="position" align="start" style="width: 100px;">
128+
<d-dropdown :close-scope="closeScope" :position="position" style="width: 100px;">
129129
<d-button class="mt-1">More</d-button>
130130
<template #menu>
131131
<ul class="list-menu">
@@ -165,14 +165,14 @@ export default defineComponent({
165165
<d-button>Click Me</d-button>
166166
<template #menu>
167167
<ul class="list-menu">
168-
<d-dropdown :position="position" :offset="0" align="start">
168+
<d-dropdown :position="position" :offset="0">
169169
<li class="menu-item">
170170
Item 1
171171
<i class="icon icon-chevron-right"></i>
172172
</li>
173173
<template #menu>
174174
<ul class="list-menu">
175-
<d-dropdown :position="position" :offset="0" align="start">
175+
<d-dropdown :position="position" :offset="0" >
176176
<li class="menu-item">
177177
Item 1-1
178178
<i class="icon icon-chevron-right"></i>
@@ -261,8 +261,7 @@ export default defineComponent({
261261
| visible | `boolean` | false | 可选,可以显式指定 dropdown 是否打开 | [触发方式](#触发方式) |
262262
| trigger | [TriggerType](#triggertype) | click | 可选,dropdown 触发方式, click 为点、hover 为悬停、manually 为完全手动控制 | [触发方式](#触发方式) |
263263
| close-scope | [CloseScopeArea](#closescopearea) | all | 可选,点击关闭区域,blank 点击非菜单空白关闭, all 点击菜单内外关闭,none 仅触发元素关闭 | [可关闭区域](#可关闭区域) |
264-
| position | [Placement[]](#placement) | ['bottom'] | 可选,展开位置,若位置包含`start``end`,需通过`align`参数设置对齐方式 | [基本用法](#基本用法) |
265-
| align | `start \| end \| null` | null | 可选,对齐方式,默认居中对齐。若指定`start`对齐,当`start`位置放不下时,会自动调整为`end`对齐 | [基本用法](#基本用法) |
264+
| position | [Placement[]](#placement) | ['bottom'] | 可选,展开位置,按照顺序自动选择位置 | [基本用法](#基本用法) |
266265
| offset | `number` \| [OffsetOptions](#offsetoptions) | 4 | 可选,指定与触发元素的间距 | [多级菜单](#多级菜单) |
267266
| shift-offset | `number` | -- | 可选,当设置该参数时,表示启用贴边功能,当指定的 position 放不下时,选择最近的视图边界对齐,此参数可设置相对视图边界的偏移量 |
268267
| close-on-mouse-leave-menu | `boolean` | false | 可选,是否进入菜单后离开菜单的时候关闭菜单 |

packages/devui-vue/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vue-devui",
3-
"version": "1.6.14",
3+
"version": "1.6.15",
44
"license": "MIT",
55
"description": "DevUI components based on Vite and Vue3",
66
"keywords": [
@@ -47,7 +47,7 @@
4747
"dependencies": {
4848
"@babel/helper-hoist-variables": "^7.22.5",
4949
"@devui-design/icons": "^1.3.0",
50-
"@floating-ui/dom": "^0.4.4",
50+
"@floating-ui/dom": "1.2.5",
5151
"@iktakahiro/markdown-it-katex": "^4.0.1",
5252
"@types/codemirror": "0.0.97",
5353
"@types/lodash-es": "^4.17.4",

pnpm-lock.yaml

Lines changed: 13 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)