fix(SwipeCell): unintended stopPropagation when canceling a swipe (#13350)

This commit is contained in:
yuhengshen
2025-02-22 15:37:29 +08:00
committed by GitHub
parent 7efce4ba05
commit 0702ba898b
3 changed files with 81 additions and 8 deletions

View File

@@ -190,8 +190,8 @@ export default defineComponent({
};
const getClickHandler =
(position: SwipeCellPosition, stop?: boolean) => (event: MouseEvent) => {
if (stop) {
(position: SwipeCellPosition) => (event: MouseEvent) => {
if (lockClick || opened) {
event.stopPropagation();
}
@@ -209,11 +209,7 @@ export default defineComponent({
const contentSlot = slots[side];
if (contentSlot) {
return (
<div
ref={ref}
class={bem(side)}
onClick={getClickHandler(side, true)}
>
<div ref={ref} class={bem(side)} onClick={getClickHandler(side)}>
{contentSlot()}
</div>
);
@@ -244,7 +240,7 @@ export default defineComponent({
<div
ref={root}
class={bem()}
onClick={getClickHandler('cell', lockClick)}
onClick={getClickHandler('cell')}
onTouchstartPassive={onTouchStart}
onTouchend={onTouchEnd}
onTouchcancel={onTouchEnd}

View File

@@ -223,3 +223,69 @@ test('should not trigger close event again if already closed', () => {
wrapper.vm.close();
expect(wrapper.emitted('close')).toHaveLength(1);
});
const createWithNativeWrapper = () => {
const onWrapperClick = vi.fn();
const component = {
template: `
<div class="native-wrapper" @click="onWrapperClick">
<swipe-cell v-bind="props" />
</div>
`,
components: {
SwipeCell,
},
setup() {
return {
props: defaultProps.props,
onWrapperClick,
};
},
};
const wrapper = mount(component);
const track = wrapper.find('.van-swipe-cell__wrapper').element;
const triggerNativeClick = () => {
const clickEvent = new MouseEvent('click', {
bubbles: true,
cancelable: true,
});
track.dispatchEvent(clickEvent);
};
const swipeCell = wrapper.findComponent(SwipeCell);
return {
wrapper,
swipeCell,
onWrapperClick,
triggerNativeClick,
};
};
test('should not stop propagation of native click event when canceling swipe', async () => {
const { onWrapperClick, triggerNativeClick, swipeCell } =
createWithNativeWrapper();
triggerDrag(swipeCell, 5, 0);
await later();
triggerNativeClick();
expect(onWrapperClick).toHaveBeenCalled();
});
test('should not trigger native click event after drag operations in desktop simulation scenarios', async () => {
const { onWrapperClick, swipeCell } = createWithNativeWrapper();
triggerDrag(swipeCell, 50, 0);
await later();
expect(onWrapperClick).not.toHaveBeenCalled();
triggerDrag(swipeCell, -50, 0);
await later();
expect(onWrapperClick).not.toHaveBeenCalled();
});

View File

@@ -51,6 +51,10 @@ export function trigger(
return nextTick();
}
interface TriggerDragOptions {
simulateDesktop?: boolean;
}
// simulate drag gesture
export function triggerDrag(
el:
@@ -59,6 +63,9 @@ export function triggerDrag(
| HTMLElement,
relativeX = 0,
relativeY = 0,
options: TriggerDragOptions = {
simulateDesktop: true,
},
) {
let x = relativeX;
let y = relativeY;
@@ -79,5 +86,9 @@ export function triggerDrag(
trigger(el, 'touchmove', x, y);
trigger(el, 'touchend', x, y);
if (options.simulateDesktop) {
trigger(el, 'click', x, y);
}
return nextTick();
}