Co-authored-by: neverland <jait.chen@foxmail.com>
This commit is contained in:
co-authored by
neverland
parent
5a7042c182
commit
d739f678b4
@@ -20,7 +20,7 @@ import {
|
||||
addUnit,
|
||||
closest,
|
||||
createNamespace,
|
||||
makeNumberProp,
|
||||
isObject,
|
||||
makeStringProp,
|
||||
windowWidth,
|
||||
windowHeight,
|
||||
@@ -38,11 +38,15 @@ import {
|
||||
FloatingBubbleAxis,
|
||||
FloatingBubbleMagnetic,
|
||||
FloatingBubbleOffset,
|
||||
FloatingBubbleGap,
|
||||
FloatingBubbleBoundary,
|
||||
} from './types';
|
||||
|
||||
export const floatingBubbleProps = {
|
||||
gap: makeNumberProp(24),
|
||||
gap: {
|
||||
type: [Number, Object] as unknown as PropType<FloatingBubbleGap>,
|
||||
default: 24,
|
||||
},
|
||||
icon: String,
|
||||
axis: makeStringProp<FloatingBubbleAxis>('y'),
|
||||
magnetic: String as PropType<FloatingBubbleMagnetic>,
|
||||
@@ -79,11 +83,17 @@ export default defineComponent({
|
||||
height: 0,
|
||||
});
|
||||
|
||||
const gapX = computed(() =>
|
||||
isObject(props.gap) ? props.gap.x : props.gap,
|
||||
);
|
||||
const gapY = computed(() =>
|
||||
isObject(props.gap) ? props.gap.y : props.gap,
|
||||
);
|
||||
const boundary = computed<FloatingBubbleBoundary>(() => ({
|
||||
top: props.gap,
|
||||
right: windowWidth.value - state.value.width - props.gap,
|
||||
bottom: windowHeight.value - state.value.height - props.gap,
|
||||
left: props.gap,
|
||||
top: gapY.value,
|
||||
right: windowWidth.value - state.value.width - gapX.value,
|
||||
bottom: windowHeight.value - state.value.height - gapY.value,
|
||||
left: gapX.value,
|
||||
}));
|
||||
|
||||
const dragging = ref(false);
|
||||
@@ -110,8 +120,8 @@ export default defineComponent({
|
||||
const { width, height } = useRect(rootRef.value!);
|
||||
const { offset } = props;
|
||||
state.value = {
|
||||
x: offset.x > -1 ? offset.x : windowWidth.value - width - props.gap,
|
||||
y: offset.y > -1 ? offset.y : windowHeight.value - height - props.gap,
|
||||
x: offset.x > -1 ? offset.x : windowWidth.value - width - gapX.value,
|
||||
y: offset.y > -1 ? offset.y : windowHeight.value - height - gapY.value,
|
||||
width,
|
||||
height,
|
||||
};
|
||||
@@ -203,7 +213,7 @@ export default defineComponent({
|
||||
});
|
||||
|
||||
watch(
|
||||
[windowWidth, windowHeight, () => props.gap, () => props.offset],
|
||||
[windowWidth, windowHeight, gapX, gapY, () => props.offset],
|
||||
updateState,
|
||||
{ deep: true },
|
||||
);
|
||||
|
||||
@@ -94,7 +94,7 @@ export default {
|
||||
| axis | Drag direction, `xy` stands for free drag, `lock` stands for disable drag | _'x' \| 'y' \| 'xy' \| 'lock'_ | `y` |
|
||||
| magnetic | Direction of automatic magnetic absorption | _'x' \| 'y'_ | - |
|
||||
| icon | Bubble icon | _string_ | - |
|
||||
| gap | Minimum gap between the bubble and the window, unit `px` | _number_ | `24` |
|
||||
| gap | Minimum gap between the bubble and the window, unit `px` | _number \| { x: number, y: number }_ | `24` |
|
||||
| teleport | Specifies a target element where BackTop will be mounted | _string \| Element_ | `body` |
|
||||
|
||||
### Events
|
||||
|
||||
@@ -94,7 +94,7 @@ export default {
|
||||
| axis | 拖拽的方向,`xy` 代表自由拖拽,`lock` 代表禁止拖拽 | _'x' \| 'y' \| 'xy' \| 'lock'_ | `y` |
|
||||
| magnetic | 自动磁吸的方向 | _'x' \| 'y'_ | - |
|
||||
| icon | 气泡图标名称或图片链接,等同于 Icon 组件的 [name 属性](#/zh-CN/icon#props) | _string_ | - |
|
||||
| gap | 气泡与窗口的最小间距,单位为 `px` | _number_ | `24` |
|
||||
| gap | 气泡与窗口的最小间距,单位为 `px` | _number \| { x: number, y: number }_ | `24` |
|
||||
| teleport | 指定挂载的节点,等同于 Teleport 组件的 [to 属性](https://cn.vuejs.org/api/built-in-components.html#teleport) | _string \| Element_ | `body` |
|
||||
|
||||
### Events
|
||||
|
||||
@@ -62,6 +62,33 @@ test('should render correctly when all props set', async () => {
|
||||
restore();
|
||||
});
|
||||
|
||||
test('should render with xy gaps', async () => {
|
||||
useWindowSize();
|
||||
const restore = mockGetBoundingClientRect({ width: 48, height: 48 });
|
||||
|
||||
const root = document.createElement('div');
|
||||
mount(FloatingBubble, {
|
||||
props: {
|
||||
teleport: root,
|
||||
gap: { x: 50, y: 27 },
|
||||
},
|
||||
});
|
||||
|
||||
const floatingBubbleEl = root.querySelector<HTMLDivElement>(
|
||||
'.van-floating-bubble',
|
||||
)!;
|
||||
|
||||
await later();
|
||||
|
||||
expect(floatingBubbleEl.style.transform).toEqual(
|
||||
`translate3d(${window.innerWidth - 48 - 50}px, ${
|
||||
window.innerHeight - 48 - 27
|
||||
}px, 0)`,
|
||||
);
|
||||
|
||||
restore();
|
||||
});
|
||||
|
||||
test('should only y axis direction move when axis is default', async () => {
|
||||
const restore = mockGetBoundingClientRect({ width: 48, height: 48 });
|
||||
|
||||
|
||||
@@ -16,6 +16,13 @@ export type FloatingBubbleOffset = {
|
||||
y: number;
|
||||
};
|
||||
|
||||
export type FloatingBubbleGap =
|
||||
| number
|
||||
| {
|
||||
x: number;
|
||||
y: number;
|
||||
};
|
||||
|
||||
export type FloatingBubbleBoundary = {
|
||||
top: number;
|
||||
right: number;
|
||||
|
||||
Reference in New Issue
Block a user