mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-05-22 06:31:45 +08:00
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:
parent
0897d46143
commit
85da57e583
@ -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') {
|
|
||||||
const width = position === 'left' ? leftWidth.value : rightWidth.value;
|
|
||||||
|
|
||||||
if (width && offset > width * threshold) {
|
if (width && offset > width * threshold) {
|
||||||
open(position);
|
open(side);
|
||||||
return;
|
} else {
|
||||||
|
close(side);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
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 = {
|
Loading…
x
Reference in New Issue
Block a user