fix(SwipeCell): incorrect position param when clicking outside (#8108)

* fix(SwipeCell): incorrect position param when clicking outside

* chore: update order
This commit is contained in:
neverland 2021-02-09 17:28:49 +08:00 committed by GitHub
parent 0897d46143
commit 85da57e583
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,8 +1,8 @@
import { ref, reactive, computed } from 'vue'; import { ref, Ref, reactive, computed, PropType } from 'vue';
// Utils // Utils
import { range, createNamespace, preventDefault } from '../utils'; import { range, isDef, createNamespace, preventDefault } from '../utils';
import { callInterceptor } from '../utils/interceptor'; import { callInterceptor, Interceptor } from '../utils/interceptor';
// Composition // Composition
import { useRect, useClickAway } from '@vant/use'; import { useRect, useClickAway } from '@vant/use';
@ -11,12 +11,15 @@ import { useExpose } from '../composables/use-expose';
const [createComponent, bem] = createNamespace('swipe-cell'); const [createComponent, bem] = createNamespace('swipe-cell');
export type SwipeCellSide = 'left' | 'right';
export type SwipeCellPosition = SwipeCellSide | 'cell' | 'outside';
export default createComponent({ export default createComponent({
props: { props: {
disabled: Boolean, disabled: Boolean,
leftWidth: [Number, String], leftWidth: [Number, String],
rightWidth: [Number, String], rightWidth: [Number, String],
beforeClose: Function, beforeClose: Function as PropType<Interceptor>,
stopPropagation: Boolean, stopPropagation: Boolean,
name: { name: {
type: [Number, String], type: [Number, String],
@ -27,13 +30,13 @@ export default createComponent({
emits: ['open', 'close', 'click'], emits: ['open', 'close', 'click'],
setup(props, { emit, slots }) { setup(props, { emit, slots }) {
let opened; let opened: boolean;
let lockClick; let lockClick: boolean;
let startOffset; let startOffset: number;
const root = ref(); const root = ref<HTMLElement>();
const leftRef = ref(); const leftRef = ref<HTMLElement>();
const rightRef = ref(); const rightRef = ref<HTMLElement>();
const state = reactive({ const state = reactive({
offset: 0, offset: 0,
@ -42,27 +45,28 @@ export default createComponent({
const touch = useTouch(); const touch = useTouch();
const getWidthByRef = (ref) => (ref.value ? useRect(ref).width : 0); const getWidthByRef = (ref: Ref<HTMLElement | undefined>) =>
ref.value ? useRect(ref).width : 0;
const leftWidth = computed( const leftWidth = computed(() =>
() => +props.leftWidth || getWidthByRef(leftRef) isDef(props.leftWidth) ? +props.leftWidth : getWidthByRef(leftRef)
); );
const rightWidth = computed( const rightWidth = computed(() =>
() => +props.rightWidth || getWidthByRef(rightRef) isDef(props.rightWidth) ? +props.rightWidth : getWidthByRef(rightRef)
); );
const open = (position) => { const open = (side: SwipeCellSide) => {
opened = true; opened = true;
state.offset = position === 'left' ? leftWidth.value : -rightWidth.value; state.offset = side === 'left' ? leftWidth.value : -rightWidth.value;
emit('open', { emit('open', {
name: props.name, name: props.name,
position, position: side,
}); });
}; };
const close = (position) => { const close = (position: SwipeCellPosition) => {
state.offset = 0; state.offset = 0;
if (opened) { if (opened) {
@ -74,31 +78,27 @@ export default createComponent({
} }
}; };
const toggle = (position) => { const toggle = (side: SwipeCellSide) => {
const offset = Math.abs(state.offset); const offset = Math.abs(state.offset);
const THRESHOLD = 0.15; const THRESHOLD = 0.15;
const threshold = opened ? 1 - THRESHOLD : THRESHOLD; const threshold = opened ? 1 - THRESHOLD : THRESHOLD;
const width = side === 'left' ? leftWidth.value : rightWidth.value;
if (position === 'left' || position === 'right') { if (width && offset > width * threshold) {
const width = position === 'left' ? leftWidth.value : rightWidth.value; open(side);
} else {
if (width && offset > width * threshold) { close(side);
open(position);
return;
}
} }
close();
}; };
const onTouchStart = (event) => { const onTouchStart = (event: TouchEvent) => {
if (!props.disabled) { if (!props.disabled) {
startOffset = state.offset; startOffset = state.offset;
touch.start(event); touch.start(event);
} }
}; };
const onTouchMove = (event) => { const onTouchMove = (event: TouchEvent) => {
if (props.disabled) { if (props.disabled) {
return; return;
} }
@ -135,7 +135,7 @@ export default createComponent({
} }
}; };
const onClick = (position = 'outside') => { const onClick = (position: SwipeCellPosition = 'outside') => {
emit('click', position); emit('click', position);
if (opened && !lockClick) { if (opened && !lockClick) {
@ -154,22 +154,28 @@ export default createComponent({
} }
}; };
const getClickHandler = (position, stop) => (event) => { const getClickHandler = (position: SwipeCellPosition, stop?: boolean) => (
event: MouseEvent
) => {
if (stop) { if (stop) {
event.stopPropagation(); event.stopPropagation();
} }
onClick(position); onClick(position);
}; };
const renderSideContent = (position, ref) => { const renderSideContent = (
if (slots[position]) { side: SwipeCellSide,
ref: Ref<HTMLElement | undefined>
) => {
const contentSlot = slots[side];
if (contentSlot) {
return ( return (
<div <div
ref={ref} ref={ref}
class={bem(position)} class={bem(side)}
onClick={getClickHandler(position, true)} onClick={getClickHandler(side, true)}
> >
{slots[position]()} {contentSlot()}
</div> </div>
); );
} }
@ -180,7 +186,13 @@ export default createComponent({
close, close,
}); });
useClickAway(root, onClick, { eventName: 'touchstart' }); useClickAway(
root,
() => {
onClick('outside');
},
{ eventName: 'touchstart' }
);
return () => { return () => {
const wrapperStyle = { const wrapperStyle = {