@nutui/nutui-react
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
75 lines (74 loc) • 2.91 kB
JavaScript
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
};