UNPKG

@nutui/nutui-react

Version:

京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序

75 lines (74 loc) 2.91 kB
import { _ as __rest } from "./tslib.es6.js"; import React__default, { useState, useRef, useEffect } from "react"; import { useDrag } from "@use-gesture/react"; import { useSpring, animated } from "@react-spring/web"; import { C as ComponentDefaults } from "./typings.js"; const defaultProps = Object.assign(Object.assign({}, ComponentDefaults), { attract: false, direction: void 0, boundary: { top: 0, left: 0, right: 0, bottom: 0 } }); const Drag = (props) => { const _a = Object.assign(Object.assign({}, defaultProps), props), { attract, direction, boundary, onDrag, onDragStart, onDragEnd, children, className, style } = _a, reset = __rest(_a, ["attract", "direction", "boundary", "onDrag", "onDragStart", "onDragEnd", "children", "className", "style"]); const classPrefix = "nut-drag"; const [boundaryState, setBoundaryState] = useState(boundary); const myDrag = useRef(null); const [currstyle, api] = useSpring(() => ({ x: 0, y: 0 })); const middleLine = useRef(0); const getInfo = () => { const el = myDrag.current; if (el) { const { offsetTop, offsetLeft } = el; const { offsetWidth, offsetHeight } = el.querySelector(`.${classPrefix}-inner`); const { clientWidth, clientHeight } = document.documentElement; const { top, left, bottom, right } = boundary; setBoundaryState({ top: -offsetTop + top, left: -offsetLeft + left, bottom: clientHeight - offsetHeight - offsetTop - bottom, right: clientWidth - offsetWidth - offsetLeft - right }); middleLine.current = clientWidth - offsetWidth - offsetLeft - (clientWidth - offsetWidth) / 2; } }; const bind = useDrag((state) => { const { down, last, offset: [x, y], first } = state; first && (onDragStart === null || onDragStart === void 0 ? void 0 : onDragStart()); onDrag === null || onDrag === void 0 ? void 0 : onDrag({ offset: [x, y] }); last && (onDragEnd === null || onDragEnd === void 0 ? void 0 : onDragEnd({ offset: [x, y] })); api.start({ x, y, immediate: down }); if (last) { if (direction !== "y" && attract) { if (x < middleLine.current) { api.start({ x: boundaryState.left, y, immediate: down }); } else { api.start({ x: boundaryState.right, y, immediate: down }); } } } }, { from: () => [currstyle.x.get(), currstyle.y.get()], axis: direction, bounds: boundaryState }); useEffect(() => { getInfo(); }, [myDrag]); return React__default.createElement( "div", Object.assign({ style, className: `${classPrefix} ${className}` }, reset, { ref: myDrag }), React__default.createElement(animated.div, Object.assign({ style: currstyle }, bind(), { className: `${classPrefix}-inner` }), children) ); }; Drag.displayName = "NutDrag"; export { Drag as default };