@fruits-chain/react-native-xiaoshu
Version:
🌈 React Native UI library
94 lines (93 loc) • 2.56 kB
JavaScript
import React, { createContext, useCallback, useContext, useMemo, useRef, useState } from 'react';
import useDebounceFn from "../hooks/useDebounceFn.js";
import { jsx as _jsx } from "react/jsx-runtime";
const ElevatorContext = /*#__PURE__*/createContext({
// targetRefMap: {},
// scrollRef: {
// current: null,
// },
elevator: [],
registerTarget: function () {
throw new Error('Function not implemented.');
},
cancelTarget: function () {
throw new Error('Function not implemented.');
},
registerScroll: function () {
throw new Error('Function not implemented.');
}
});
export const useElevator = () => useContext(ElevatorContext);
const getTargetRelativeLayout = (target, scroll) => new Promise((resolve, reject) => {
target.current?.measureLayout(scroll.current,
// eslint-disable-next-line max-params
(left, top, width, height) => {
resolve({
left,
top,
width,
height
});
}, reject);
});
export const ElevatorContextProvider = ({
children
}) => {
const TargetRefMap = useRef({});
const ScrollRef = useRef(null);
const [elevator, setElevator] = useState([]);
const {
run: initNav
} = useDebounceFn(() => {
const refs = Object.keys(TargetRefMap.current).map(key => {
return {
label: key,
ref: TargetRefMap.current[key]
};
}).filter(item => !!item.ref);
Promise.all(refs.map(item => getTargetRelativeLayout(item.ref, ScrollRef.current))).then(datas => {
setElevator(datas.map(({
top
}, index) => {
return {
label: refs[index].label,
top
};
}).sort((a, b) => a.top - b.top));
}).catch(() => {
setElevator([]);
});
}, {
wait: 200,
leading: false,
trailing: true
});
const registerScroll = useCallback(ref => {
if (!ScrollRef.current || ScrollRef.current.current !== ref.current) {
ScrollRef.current = ref;
initNav();
}
}, [initNav]);
const registerTarget = useCallback((id, ref) => {
TargetRefMap.current[id] = ref;
initNav();
}, [initNav]);
const cancelTarget = useCallback(id => {
TargetRefMap.current[id] = undefined;
initNav();
}, [initNav]);
const value = useMemo(() => {
return {
elevator,
registerScroll,
registerTarget,
cancelTarget
};
}, [cancelTarget, elevator, registerScroll, registerTarget]);
return /*#__PURE__*/_jsx(ElevatorContext.Provider, {
value: value,
children: children
});
};
//# sourceMappingURL=context.js.map
;