feat(SwipeCell): Fix triggered close by clickAway when in running beforeClose (#12309)

This commit is contained in:
Nined 2023-09-20 19:28:23 +08:00 committed by GitHub
parent 1f0e3a1f2a
commit 829afd5dbd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 79 additions and 14 deletions

View File

@ -91,7 +91,9 @@ export default {
return new Promise((resolve) => {
showConfirmDialog({
title: 'Are you sure to delete?',
}).then(resolve);
})
.then(resolve)
.catch(resolve);
});
}
};

View File

@ -98,7 +98,9 @@ export default {
return new Promise((resolve) => {
showConfirmDialog({
title: '确定删除吗?',
}).then(resolve);
})
.then(resolve)
.catch(resolve);
});
}
};

View File

@ -56,6 +56,7 @@ export default defineComponent({
let opened: boolean;
let lockClick: boolean;
let startOffset: number;
let isInBeforeClosing: boolean;
const root = ref<HTMLElement>();
const leftRef = ref<HTMLElement>();
@ -161,9 +162,12 @@ export default defineComponent({
};
const onClick = (position: SwipeCellPosition = 'outside') => {
if (isInBeforeClosing) return;
emit('click', position);
if (opened && !lockClick) {
isInBeforeClosing = true;
callInterceptor(props.beforeClose, {
args: [
{
@ -171,7 +175,12 @@ export default defineComponent({
position,
},
],
done: () => close(position),
done: () => {
isInBeforeClosing = false;
close(position);
},
canceled: () => (isInBeforeClosing = false),
error: () => (isInBeforeClosing = false),
});
}
};

View File

@ -38,13 +38,9 @@ const beforeClose = ({ position }: { position: string }) => {
case 'outside':
return true;
case 'right':
return new Promise<boolean>((resolve) => {
showConfirmDialog({
title: t('confirm'),
}).then(() => {
resolve(true);
});
});
return showConfirmDialog({
title: t('confirm'),
}) as Promise<boolean>;
}
};
</script>

View File

@ -37,15 +37,29 @@ test('should allow to drag to show right part', async () => {
expect(track.style.transform).toEqual('translate3d(-100px, 0, 0)');
});
test('should call beforeClose before closing', () => {
test('should call beforeClose before closing', async () => {
let position;
let clickPosition;
let usePromise;
let promiseRet;
const wrapper = mount(SwipeCell, {
...defaultProps,
props: {
...defaultProps.props,
onClick(position) {
clickPosition = position;
},
beforeClose(params) {
({ position } = params);
if (usePromise) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(promiseRet);
}, 100);
});
} else {
({ position } = params);
}
},
},
});
@ -66,6 +80,17 @@ test('should call beforeClose before closing', () => {
wrapper.vm.close();
expect(track.style.transform).toEqual('translate3d(0px, 0, 0)');
usePromise = true;
promiseRet = false;
wrapper.vm.open('right');
wrapper.find('.van-swipe-cell__right').trigger('click');
expect(clickPosition).toEqual('right');
wrapper.trigger('click');
expect(clickPosition).toEqual('right');
await later(200);
wrapper.trigger('click');
expect(clickPosition).toEqual('cell');
});
test('should close swipe cell after clicked', async () => {

View File

@ -10,10 +10,12 @@ export function callInterceptor(
args = [],
done,
canceled,
error,
}: {
args?: unknown[];
done: () => void;
canceled?: () => void;
error?: () => void;
},
) {
if (interceptor) {
@ -29,7 +31,7 @@ export function callInterceptor(
canceled();
}
})
.catch(noop);
.catch(error || noop);
} else if (returnVal) {
done();
} else if (canceled) {

View File

@ -3,36 +3,61 @@ import { callInterceptor } from '../interceptor';
test('callInterceptor', async () => {
const done = vi.fn();
callInterceptor(undefined, { done });
const canceled = vi.fn();
const error = vi.fn();
callInterceptor(undefined, { done, canceled, error });
expect(done).toHaveBeenCalledTimes(1);
expect(canceled).toHaveBeenCalledTimes(0);
expect(error).toHaveBeenCalledTimes(0);
callInterceptor(() => false, {
done,
canceled,
error,
});
expect(done).toHaveBeenCalledTimes(1);
expect(canceled).toHaveBeenCalledTimes(1);
expect(error).toHaveBeenCalledTimes(0);
callInterceptor(() => true, {
done,
canceled,
error,
});
expect(done).toHaveBeenCalledTimes(2);
expect(canceled).toHaveBeenCalledTimes(1);
expect(error).toHaveBeenCalledTimes(0);
callInterceptor(() => Promise.resolve(false), {
done,
canceled,
error,
});
await later();
expect(done).toHaveBeenCalledTimes(2);
expect(canceled).toHaveBeenCalledTimes(2);
expect(error).toHaveBeenCalledTimes(0);
callInterceptor(() => Promise.resolve(true), {
done,
canceled,
error,
});
await later();
expect(done).toHaveBeenCalledTimes(3);
expect(canceled).toHaveBeenCalledTimes(2);
expect(error).toHaveBeenCalledTimes(0);
callInterceptor(() => Promise.reject(), {
done,
canceled,
error,
});
await later();
expect(done).toHaveBeenCalledTimes(3);
expect(canceled).toHaveBeenCalledTimes(2);
expect(error).toHaveBeenCalledTimes(1);
callInterceptor(
(...args) => {
@ -42,8 +67,12 @@ test('callInterceptor', async () => {
{
args: ['foo'],
done,
canceled,
error,
},
);
expect(done).toHaveBeenCalledTimes(3);
expect(canceled).toHaveBeenCalledTimes(3);
expect(error).toHaveBeenCalledTimes(1);
});