@crossed/sheet
Version:
A Cross Platform(Android & iOS) ActionSheet with a robust and flexible api, native performance and zero dependency code for react native. Create anything you want inside ActionSheet.
163 lines (162 loc) • 4.77 kB
JavaScript
import React, { useCallback, useEffect, useRef, useState } from "react";
import {
Platform
} from "react-native";
import {
useDraggableNodesContext,
usePanGestureContext
} from "../context";
const ScrollState = {
END: -1
};
const InitialLayoutRect = {
w: 0,
h: 0,
x: 0,
y: 0,
px: 0,
py: 0
};
function resolveScrollRef(ref) {
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
if ((_a = ref.current) == null ? void 0 : _a._listRef) {
return (_b = ref.current._listRef) == null ? void 0 : _b._scrollRef;
}
if ((_c = ref.current) == null ? void 0 : _c.rlvRef) {
return (_f = (_e = (_d = ref.current) == null ? void 0 : _d.rlvRef) == null ? void 0 : _e._scrollComponent) == null ? void 0 : _f._scrollViewRef;
}
if ((_i = (_h = (_g = ref.current) == null ? void 0 : _g._wrapperListRef) == null ? void 0 : _h._listRef) == null ? void 0 : _i._scrollRef) {
return (_l = (_k = (_j = ref.current) == null ? void 0 : _j._wrapperListRef) == null ? void 0 : _k._listRef) == null ? void 0 : _l._scrollRef;
}
return ref.current;
}
function useDraggable(options) {
const gestureContext = usePanGestureContext();
const draggableNodes = useDraggableNodesContext();
const nodeRef = useRef(null);
const offset = useRef({ x: 0, y: 0 });
const layout = useRef(InitialLayoutRect);
useEffect(() => {
const pushNode = () => {
var _a, _b;
const index = (_a = draggableNodes.nodes.current) == null ? void 0 : _a.findIndex(
(node) => node.ref === nodeRef
);
if (index === void 0 || index === -1) {
(_b = draggableNodes.nodes.current) == null ? void 0 : _b.push({
ref: nodeRef,
offset,
rect: layout,
handlerConfig: options
});
}
};
const popNode = () => {
var _a, _b;
const index = (_a = draggableNodes.nodes.current) == null ? void 0 : _a.findIndex(
(node) => node.ref === nodeRef
);
if (index === void 0 || index > -1) {
(_b = draggableNodes.nodes.current) == null ? void 0 : _b.splice(index, 1);
}
};
pushNode();
return () => {
popNode();
};
}, [draggableNodes.nodes, options]);
return {
nodeRef,
offset,
draggableNodes,
layout,
gestureContext
};
}
function useScrollHandlers(options) {
const [, setRender] = useState(false);
const { nodeRef, gestureContext, offset, layout } = useDraggable(options);
const timer = useRef();
const subscription = useRef();
const onMeasure = useCallback(
(x, y, w, h, px, py) => {
layout.current = {
x,
y,
w,
h: h + 10,
px,
py
};
},
[layout]
);
const measureAndLayout = React.useCallback(() => {
clearTimeout(timer.current);
timer.current = setTimeout(() => {
var _a;
const ref = resolveScrollRef(nodeRef);
if (Platform.OS == "web") {
if (!ref)
return;
const rect = ref.getBoundingClientRect();
ref.style.overflow = "auto";
onMeasure(rect.x, rect.y, rect.width, rect.height, rect.left, rect.top);
} else {
(_a = ref == null ? void 0 : ref.measure) == null ? void 0 : _a.call(ref, onMeasure);
}
}, 300);
}, [nodeRef, onMeasure]);
useEffect(() => {
if (Platform.OS === "web" || !gestureContext.ref)
return;
const interval = setInterval(() => {
if (gestureContext.ref.current) {
clearInterval(interval);
setRender(true);
}
}, 10);
}, [gestureContext.ref]);
const memoizedProps = React.useMemo(() => {
return {
ref: nodeRef,
simultaneousHandlers: gestureContext.ref,
onScroll: (event) => {
const { x, y } = event.nativeEvent.contentOffset;
const maxOffsetX = event.nativeEvent.contentSize.width - layout.current.w;
const maxOffsetY = event.nativeEvent.contentSize.height - layout.current.h;
offset.current = {
x: x === maxOffsetX || x > maxOffsetX - 5 ? ScrollState.END : x,
y: y === maxOffsetY || y > maxOffsetY - 5 ? ScrollState.END : y
};
},
scrollEventThrottle: 1,
onLayout: () => {
var _a;
measureAndLayout();
(_a = subscription.current) == null ? void 0 : _a.unsubscribe();
subscription.current = gestureContext.eventManager.subscribe(
"onoffsetchange",
() => {
measureAndLayout();
}
);
}
};
}, [
gestureContext.eventManager,
gestureContext.ref,
layout,
measureAndLayout,
nodeRef,
offset
]);
return memoizedProps;
}
export {
ScrollState,
resolveScrollRef,
useDraggable,
useScrollHandlers
};
//# sourceMappingURL=use-scroll-handlers.js.map