fix(FloatingBubble): should handle negative gap values (#13544)
This commit is contained in:
@@ -44,16 +44,13 @@ import {
|
|||||||
|
|
||||||
export const floatingBubbleProps = {
|
export const floatingBubbleProps = {
|
||||||
gap: {
|
gap: {
|
||||||
type: [Number, Object] as unknown as PropType<FloatingBubbleGap>,
|
type: [Number, Object] as PropType<FloatingBubbleGap>,
|
||||||
default: 24,
|
default: 24,
|
||||||
},
|
},
|
||||||
icon: String,
|
icon: String,
|
||||||
axis: makeStringProp<FloatingBubbleAxis>('y'),
|
axis: makeStringProp<FloatingBubbleAxis>('y'),
|
||||||
magnetic: String as PropType<FloatingBubbleMagnetic>,
|
magnetic: String as PropType<FloatingBubbleMagnetic>,
|
||||||
offset: {
|
offset: Object as PropType<FloatingBubbleOffset>,
|
||||||
type: Object as unknown as PropType<FloatingBubbleOffset>,
|
|
||||||
default: () => ({ x: -1, y: -1 }),
|
|
||||||
},
|
|
||||||
teleport: {
|
teleport: {
|
||||||
type: [String, Object] as PropType<TeleportProps['to']>,
|
type: [String, Object] as PropType<TeleportProps['to']>,
|
||||||
default: 'body',
|
default: 'body',
|
||||||
@@ -120,8 +117,8 @@ export default defineComponent({
|
|||||||
const { width, height } = useRect(rootRef.value!);
|
const { width, height } = useRect(rootRef.value!);
|
||||||
const { offset } = props;
|
const { offset } = props;
|
||||||
state.value = {
|
state.value = {
|
||||||
x: offset.x > -1 ? offset.x : windowWidth.value - width - gapX.value,
|
x: offset ? offset.x : windowWidth.value - width - gapX.value,
|
||||||
y: offset.y > -1 ? offset.y : windowHeight.value - height - gapY.value,
|
y: offset ? offset.y : windowHeight.value - height - gapY.value,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,9 +9,16 @@ import {
|
|||||||
triggerDrag,
|
triggerDrag,
|
||||||
} from '../../../test';
|
} from '../../../test';
|
||||||
|
|
||||||
|
const bubbleWidth = 48;
|
||||||
|
const bubbleHeight = 48;
|
||||||
|
const defaultGap = 24;
|
||||||
|
|
||||||
test('should render correctly when all props set', async () => {
|
test('should render correctly when all props set', async () => {
|
||||||
useWindowSize();
|
useWindowSize();
|
||||||
const restore = mockGetBoundingClientRect({ width: 48, height: 48 });
|
const restore = mockGetBoundingClientRect({
|
||||||
|
width: bubbleWidth,
|
||||||
|
height: bubbleHeight,
|
||||||
|
});
|
||||||
|
|
||||||
const root = document.createElement('div');
|
const root = document.createElement('div');
|
||||||
const wrapper = mount(FloatingBubble, {
|
const wrapper = mount(FloatingBubble, {
|
||||||
@@ -27,8 +34,8 @@ test('should render correctly when all props set', async () => {
|
|||||||
await later();
|
await later();
|
||||||
|
|
||||||
expect(floatingBubbleEl.style.transform).toEqual(
|
expect(floatingBubbleEl.style.transform).toEqual(
|
||||||
`translate3d(${window.innerWidth - 48 - 24}px, ${
|
`translate3d(${window.innerWidth - bubbleWidth - defaultGap}px, ${
|
||||||
window.innerHeight - 48 - 24
|
window.innerHeight - bubbleHeight - defaultGap
|
||||||
}px, 0)`,
|
}px, 0)`,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -37,8 +44,8 @@ test('should render correctly when all props set', async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(floatingBubbleEl.style.transform).toEqual(
|
expect(floatingBubbleEl.style.transform).toEqual(
|
||||||
`translate3d(${window.innerWidth - 48 - 50}px, ${
|
`translate3d(${window.innerWidth - bubbleWidth - 50}px, ${
|
||||||
window.innerHeight - 48 - 50
|
window.innerHeight - bubbleHeight - 50
|
||||||
}px, 0)`,
|
}px, 0)`,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -64,7 +71,10 @@ test('should render correctly when all props set', async () => {
|
|||||||
|
|
||||||
test('should render with xy gaps', async () => {
|
test('should render with xy gaps', async () => {
|
||||||
useWindowSize();
|
useWindowSize();
|
||||||
const restore = mockGetBoundingClientRect({ width: 48, height: 48 });
|
const restore = mockGetBoundingClientRect({
|
||||||
|
width: bubbleWidth,
|
||||||
|
height: bubbleHeight,
|
||||||
|
});
|
||||||
|
|
||||||
const root = document.createElement('div');
|
const root = document.createElement('div');
|
||||||
mount(FloatingBubble, {
|
mount(FloatingBubble, {
|
||||||
@@ -81,8 +91,8 @@ test('should render with xy gaps', async () => {
|
|||||||
await later();
|
await later();
|
||||||
|
|
||||||
expect(floatingBubbleEl.style.transform).toEqual(
|
expect(floatingBubbleEl.style.transform).toEqual(
|
||||||
`translate3d(${window.innerWidth - 48 - 50}px, ${
|
`translate3d(${window.innerWidth - bubbleWidth - 50}px, ${
|
||||||
window.innerHeight - 48 - 27
|
window.innerHeight - bubbleHeight - 27
|
||||||
}px, 0)`,
|
}px, 0)`,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -90,7 +100,10 @@ test('should render with xy gaps', async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should only y axis direction move when axis is default', async () => {
|
test('should only y axis direction move when axis is default', async () => {
|
||||||
const restore = mockGetBoundingClientRect({ width: 48, height: 48 });
|
const restore = mockGetBoundingClientRect({
|
||||||
|
width: bubbleWidth,
|
||||||
|
height: bubbleHeight,
|
||||||
|
});
|
||||||
|
|
||||||
const root = document.createElement('div');
|
const root = document.createElement('div');
|
||||||
mount(FloatingBubble, {
|
mount(FloatingBubble, {
|
||||||
@@ -106,16 +119,19 @@ test('should only y axis direction move when axis is default', async () => {
|
|||||||
await triggerDrag(floatingBubbleEl, -100, -100);
|
await triggerDrag(floatingBubbleEl, -100, -100);
|
||||||
|
|
||||||
expect(floatingBubbleEl.style.transform).toEqual(
|
expect(floatingBubbleEl.style.transform).toEqual(
|
||||||
`translate3d(${window.innerWidth - 48 - 24}px, ${
|
`translate3d(${window.innerWidth - bubbleWidth - defaultGap}px, ${
|
||||||
window.innerHeight - 48 - 24 - 100
|
window.innerHeight - bubbleHeight - defaultGap - 100
|
||||||
}px, 0)`,
|
}px, 0)`,
|
||||||
);
|
);
|
||||||
|
|
||||||
restore();
|
restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should only x axis direction adn emit offsetChange move when axis is "x" ', async () => {
|
test('should only x axis direction and emit offsetChange move when axis is "x"', async () => {
|
||||||
const restore = mockGetBoundingClientRect({ width: 48, height: 48 });
|
const restore = mockGetBoundingClientRect({
|
||||||
|
width: bubbleWidth,
|
||||||
|
height: bubbleHeight,
|
||||||
|
});
|
||||||
|
|
||||||
const root = document.createElement('div');
|
const root = document.createElement('div');
|
||||||
const wrapper = mount(FloatingBubble, {
|
const wrapper = mount(FloatingBubble, {
|
||||||
@@ -132,8 +148,8 @@ test('should only x axis direction adn emit offsetChange move when axis is "x" '
|
|||||||
await triggerDrag(floatingBubbleEl, -100, -100);
|
await triggerDrag(floatingBubbleEl, -100, -100);
|
||||||
|
|
||||||
expect(floatingBubbleEl.style.transform).toEqual(
|
expect(floatingBubbleEl.style.transform).toEqual(
|
||||||
`translate3d(${window.innerWidth - 48 - 24 - 100}px, ${
|
`translate3d(${window.innerWidth - bubbleWidth - defaultGap - 100}px, ${
|
||||||
window.innerHeight - 48 - 24
|
window.innerHeight - bubbleHeight - defaultGap
|
||||||
}px, 0)`,
|
}px, 0)`,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -145,8 +161,11 @@ test('should only x axis direction adn emit offsetChange move when axis is "x" '
|
|||||||
restore();
|
restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should free direction move when axis is "xy" ', async () => {
|
test('should free direction move when axis is "xy"', async () => {
|
||||||
const restore = mockGetBoundingClientRect({ width: 48, height: 48 });
|
const restore = mockGetBoundingClientRect({
|
||||||
|
width: bubbleWidth,
|
||||||
|
height: bubbleHeight,
|
||||||
|
});
|
||||||
|
|
||||||
const root = document.createElement('div');
|
const root = document.createElement('div');
|
||||||
mount(FloatingBubble, {
|
mount(FloatingBubble, {
|
||||||
@@ -163,44 +182,21 @@ test('should free direction move when axis is "xy" ', async () => {
|
|||||||
await triggerDrag(floatingBubbleEl, -100, -100);
|
await triggerDrag(floatingBubbleEl, -100, -100);
|
||||||
|
|
||||||
expect(floatingBubbleEl.style.transform).toEqual(
|
expect(floatingBubbleEl.style.transform).toEqual(
|
||||||
`translate3d(${window.innerWidth - 48 - 24 - 100}px, ${
|
`translate3d(${window.innerWidth - bubbleWidth - defaultGap - 100}px, ${
|
||||||
window.innerHeight - 48 - 24 - 100
|
window.innerHeight - bubbleHeight - defaultGap - 100
|
||||||
}px, 0)`,
|
}px, 0)`,
|
||||||
);
|
);
|
||||||
|
|
||||||
restore();
|
restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should free direction move when axis is "xy" ', async () => {
|
test('should free direction move and magnetic to x axis when magnetic is "x" ', async () => {
|
||||||
const restore = mockGetBoundingClientRect({ width: 48, height: 48 });
|
|
||||||
|
|
||||||
const root = document.createElement('div');
|
|
||||||
mount(FloatingBubble, {
|
|
||||||
props: {
|
|
||||||
teleport: root,
|
|
||||||
axis: 'xy',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const floatingBubbleEl = root.querySelector<HTMLDivElement>(
|
|
||||||
'.van-floating-bubble',
|
|
||||||
)!;
|
|
||||||
|
|
||||||
await triggerDrag(floatingBubbleEl, -100, -100);
|
|
||||||
|
|
||||||
expect(floatingBubbleEl.style.transform).toEqual(
|
|
||||||
`translate3d(${window.innerWidth - 48 - 24 - 100}px, ${
|
|
||||||
window.innerHeight - 48 - 24 - 100
|
|
||||||
}px, 0)`,
|
|
||||||
);
|
|
||||||
|
|
||||||
restore();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should free direction move and magnetic to x axios when magnetic is "x" ', async () => {
|
|
||||||
vi.useFakeTimers();
|
vi.useFakeTimers();
|
||||||
|
|
||||||
const restore = mockGetBoundingClientRect({ width: 48, height: 48 });
|
const restore = mockGetBoundingClientRect({
|
||||||
|
width: bubbleWidth,
|
||||||
|
height: bubbleHeight,
|
||||||
|
});
|
||||||
const root = document.createElement('div');
|
const root = document.createElement('div');
|
||||||
mount(FloatingBubble, {
|
mount(FloatingBubble, {
|
||||||
props: {
|
props: {
|
||||||
@@ -218,8 +214,8 @@ test('should free direction move and magnetic to x axios when magnetic is "x" '
|
|||||||
await vi.advanceTimersByTimeAsync(400);
|
await vi.advanceTimersByTimeAsync(400);
|
||||||
|
|
||||||
expect(floatingBubbleEl.style.transform).toEqual(
|
expect(floatingBubbleEl.style.transform).toEqual(
|
||||||
`translate3d(${window.innerWidth - 48 - 24}px, ${
|
`translate3d(${window.innerWidth - bubbleWidth - defaultGap}px, ${
|
||||||
window.innerHeight - 48 - 24 - 100
|
window.innerHeight - bubbleHeight - defaultGap - 100
|
||||||
}px, 0)`,
|
}px, 0)`,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -227,17 +223,20 @@ test('should free direction move and magnetic to x axios when magnetic is "x" '
|
|||||||
await vi.advanceTimersByTimeAsync(400);
|
await vi.advanceTimersByTimeAsync(400);
|
||||||
|
|
||||||
expect(floatingBubbleEl.style.transform).toEqual(
|
expect(floatingBubbleEl.style.transform).toEqual(
|
||||||
`translate3d(${24}px, ${window.innerHeight - 48 - 24 - 200}px, 0)`,
|
`translate3d(${defaultGap}px, ${window.innerHeight - bubbleHeight - defaultGap - 200}px, 0)`,
|
||||||
);
|
);
|
||||||
|
|
||||||
restore();
|
restore();
|
||||||
vi.useRealTimers();
|
vi.useRealTimers();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should offset control positioning when use v-model:offset ', async () => {
|
test('should offset control positioning when use v-model:offset', async () => {
|
||||||
vi.useFakeTimers();
|
vi.useFakeTimers();
|
||||||
|
|
||||||
const restore = mockGetBoundingClientRect({ width: 48, height: 48 });
|
const restore = mockGetBoundingClientRect({
|
||||||
|
width: bubbleWidth,
|
||||||
|
height: bubbleHeight,
|
||||||
|
});
|
||||||
const root = document.createElement('div');
|
const root = document.createElement('div');
|
||||||
const wrapper = mount(FloatingBubble, {
|
const wrapper = mount(FloatingBubble, {
|
||||||
props: {
|
props: {
|
||||||
@@ -290,3 +289,37 @@ test('should emit click when click wrapper', async () => {
|
|||||||
|
|
||||||
expect(wrapper.emitted('click')).toBeFalsy();
|
expect(wrapper.emitted('click')).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should handle negative gap values', async () => {
|
||||||
|
const restore = mockGetBoundingClientRect({
|
||||||
|
width: bubbleWidth,
|
||||||
|
height: bubbleHeight,
|
||||||
|
});
|
||||||
|
|
||||||
|
const root = document.createElement('div');
|
||||||
|
mount(FloatingBubble, {
|
||||||
|
props: {
|
||||||
|
teleport: root,
|
||||||
|
axis: 'xy',
|
||||||
|
gap: -10,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const floatingBubbleEl = root.querySelector<HTMLDivElement>(
|
||||||
|
'.van-floating-bubble',
|
||||||
|
)!;
|
||||||
|
|
||||||
|
await triggerDrag(floatingBubbleEl, -1000, -1000);
|
||||||
|
|
||||||
|
expect(floatingBubbleEl.style.transform).toEqual(
|
||||||
|
`translate3d(-10px, -10px, 0)`,
|
||||||
|
);
|
||||||
|
|
||||||
|
await triggerDrag(floatingBubbleEl, 1000, 1000);
|
||||||
|
|
||||||
|
expect(floatingBubbleEl.style.transform).toEqual(
|
||||||
|
`translate3d(${window.innerWidth - bubbleWidth + 10}px, ${window.innerHeight - bubbleHeight + 10}px, 0)`,
|
||||||
|
);
|
||||||
|
|
||||||
|
restore();
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user