@nutui/nutui-react
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
121 lines (120 loc) • 4.72 kB
JavaScript
import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props";
import { _ as _object_without_properties } from "@swc/helpers/_/_object_without_properties";
import { _ as _sliced_to_array } from "@swc/helpers/_/_sliced_to_array";
import React, { useState, useEffect, useRef } from "react";
import { useDrag } from "@use-gesture/react";
import { useSpring, animated } from "@react-spring/web";
import { ComponentDefaults } from "../../utils/typings";
var defaultProps = _object_spread_props(_object_spread({}, ComponentDefaults), {
attract: false,
direction: undefined,
boundary: {
top: 0,
left: 0,
right: 0,
bottom: 0
}
});
export var Drag = function(props) {
var _ref = _object_spread({}, defaultProps, props), attract = _ref.attract, direction = _ref.direction, boundary = _ref.boundary, onDrag = _ref.onDrag, onDragStart = _ref.onDragStart, onDragEnd = _ref.onDragEnd, children = _ref.children, className = _ref.className, style = _ref.style, reset = _object_without_properties(_ref, [
"attract",
"direction",
"boundary",
"onDrag",
"onDragStart",
"onDragEnd",
"children",
"className",
"style"
]);
var classPrefix = 'nut-drag';
var _useState = _sliced_to_array(useState(boundary), 2), boundaryState = _useState[0], setBoundaryState = _useState[1];
var myDrag = useRef(null);
var _useSpring = _sliced_to_array(useSpring(function() {
return {
x: 0,
y: 0
};
}), 2), currstyle = _useSpring[0], api = _useSpring[1];
var middleLine = useRef(0);
var getInfo = function() {
var el = myDrag.current;
if (el) {
var offsetTop = el.offsetTop, offsetLeft = el.offsetLeft;
var _el_querySelector = el.querySelector(".".concat(classPrefix, "-inner")), offsetWidth = _el_querySelector.offsetWidth, offsetHeight = _el_querySelector.offsetHeight;
var _document_documentElement = document.documentElement, clientWidth = _document_documentElement.clientWidth, clientHeight = _document_documentElement.clientHeight;
var top = boundary.top, left = boundary.left, bottom = boundary.bottom, right = boundary.right;
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;
}
};
var bind = useDrag(function(state) {
var down = state.down, last = state.last, _state_offset = _sliced_to_array(state.offset, 2), x = _state_offset[0], y = _state_offset[1], first = state.first;
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: x,
y: y,
immediate: down
});
if (last) {
if (direction !== 'y' && attract) {
if (x < middleLine.current) {
api.start({
x: boundaryState.left,
y: y,
immediate: down
});
} else {
api.start({
x: boundaryState.right,
y: y,
immediate: down
});
}
}
}
}, {
from: function() {
return [
currstyle.x.get(),
currstyle.y.get()
];
},
axis: direction,
bounds: boundaryState
});
useEffect(function() {
getInfo();
}, [
myDrag
]);
return /*#__PURE__*/ React.createElement("div", _object_spread_props(_object_spread({
style: style,
className: "".concat(classPrefix, " ").concat(className)
}, reset), {
ref: myDrag
}), /*#__PURE__*/ React.createElement(animated.div, _object_spread_props(_object_spread({
style: currstyle
}, bind()), {
className: "".concat(classPrefix, "-inner")
}), children));
};
Drag.displayName = 'NutDrag';