UNPKG

respond-framework

Version:
93 lines (86 loc) 3.25 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = require("react"); var _reactNative = require("react-native"); var _utils = require("../../../utils.js"); const useDragAndDrop = (index, height, event, setIndex, openSlot, toggleScroll, longPressing) => { const y = (0, _react.useRef)(new _reactNative.Animated.Value(0)); const [dragging, set] = (0, _react.useState)(false); const pan = _reactNative.PanResponder.create({ onStartShouldSetPanResponder: () => false, onMoveShouldSetPanResponder: () => _utils.isNative ? longPressing : true, onPanResponderTerminationRequest: () => false, // allow dragging out of bounds to the bottom onPanResponderGrant: () => toggleScroll(false), onPanResponderMove: (e, { dy }) => { const delta = Math.round(dy / height); // index delta const dist = Math.abs(dy % height); const snap = dist < 7 || height - dist < 7; const bump = delta >= 0 ? 1 : 0; // bump up index for drag down, so slot is opened in row beneath const i = index + delta + bump; // create index for slot const clamp = isClamped(i, index, dist, dy); const next = index === 0 && clamp ? 1 : i; // openSlot on index 1 when dragging index 0 up into clampped territory setIndex(Math.max(0, next)); // openSlot for index set(true); // absolute position / dragging if (clamp) { y.current.setValue(-index * height); // clamp to index 0 } else if (snap) { y.current.setValue(delta * height); // snap to indexes } else { y.current.setValue(dy); // smooth dragging } }, onPanResponderRelease: (e, { dy }) => { setIndex(null); // remove openSlot set(false); // remove absolute position / dragging toggleScroll(true); const delta = Math.round(dy / height); if (delta === 0) { y.current.setValue(0); // put back (didn't drag far enough) } else { event.trigger({ index, delta }); } } }); const props = (0, _react.useMemo)(() => pan, [event, set, y, longPressing]); // important: without `event` as a dep, replays will have stale events assigned, bringing along with it stale state when tapped const transform = [{ translateY: y.current }]; const top = index * height; // place element in exact same place via absolute positioning const h = openSlot ? height * 2 : height; // openSlot: increase height of row, and inner View will be attached to the bottom, due to flex-end const style = dragging ? { ...base, ...drag, transform, top, height: h } : { ...base, height: h }; return { ...props.panHandlers, style }; }; var _default = exports.default = useDragAndDrop; const base = { width: '100%', justifyContent: 'flex-end' }; const drag = { zIndex: 1, position: 'absolute', backgroundColor: 'rgba(100, 45, 55, .85)' }; const isClamped = (i, index, dist, dy) => i < 0 || i === 0 && dist <= 25 || index === 0 && dy <= 0; // dist <= 25 clamps due to modulo -- (why? performant rendering in this file is achieved by not needing to know scroll position or state.evs.length)