import React, { useRef, useState } from 'react'; import './SwipeCell.css'; /* 与 CSS 的 --kole-m-swipecell-action-width 默认值保持一致: 展开位移 = 操作区宽度 × 操作数量(规格 §5.8 明确该宽度无标准档位,这里是实现默认值) */ const ACTION_WIDTH = 72; /* 滑动单元格(移动端)— 规格 §5;横向位移 > 10px 判定为滑动, 纵向位移更大时取消滑动(让位给页面滚动);松手按是否超过操作区宽度一半决定展开/回弹。 */ export default function SwipeCell({ direction = 'left', actions = [], open = false, onAction, children, }) { const [offset, setOffset] = useState(0); const [dragging, setDragging] = useState(false); const gestures = useRef({ startX: 0, startY: 0, dx: 0, width: ACTION_WIDTH, decided: false, dragging: false }); const rootRef = useRef(null); /** 展开态位移:右侧操作向左滑(负),左侧操作向右滑(正) */ const openOffset = (direction === 'right' ? 1 : -1) * ACTION_WIDTH * Math.max(1, actions.length); function measure() { const el = rootRef.current && rootRef.current.querySelector('.kole-m-swipecell__actions'); return (el && el.offsetWidth) || ACTION_WIDTH; } function settle(isOpen) { const w = measure(); setOffset(isOpen ? (direction === 'right' ? w : -w) : 0); } function onPointerDown(e) { const g = gestures.current; g.startX = e.clientX; g.startY = e.clientY; g.dx = 0; g.decided = false; g.dragging = false; g.width = measure(); } function onPointerMove(e) { const g = gestures.current; g.dx = e.clientX - g.startX; const dy = e.clientY - g.startY; if (!g.decided) { if (Math.abs(g.dx) < 10 && Math.abs(dy) < 10) return; g.decided = true; if (Math.abs(dy) > Math.abs(g.dx)) return; g.dragging = true; setDragging(true); } if (!g.dragging) return; setOffset(Math.max(-g.width, Math.min(g.width, g.dx))); } function onPointerEnd() { const g = gestures.current; if (g.dragging) { g.dragging = false; setDragging(false); settle(Math.abs(g.dx) > g.width / 2); } else if (open) { settle(false); } g.decided = false; } const appliedOffset = dragging || offset !== 0 ? offset : open ? openOffset : 0; return (