UNPKG

@fruits-chain/react-native-xiaoshu

Version:
102 lines (99 loc) 3.38 kB
"use strict"; import React, { memo, useMemo, useRef } from 'react'; import { View, ScrollView } from 'react-native'; import { usePersistFn, useDifferentState, useUpdateEffect } from "../hooks/index.js"; import TabBar from "../tab-bar/index.js"; import { ElevatorContextProvider, useElevator } from "./context.js"; import STYLES from "./style.js"; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; const ElevatorNavInner = ({ triggerOffset = 100, tabBarHeight = 40, scrollComponent = ScrollView, children, onScroll, onMomentumScrollEnd, ...restProps }) => { const ScrollComponent = scrollComponent; const { registerScroll, elevator } = useElevator(); const ScrollViewRef = useRef(); const ScrollTop = useRef(0); const [showNav, setShowNav] = useDifferentState(false); const [tabBarValue, setTabBarValue] = useDifferentState(undefined); const tabBarOptions = useMemo(() => elevator.map(item => ({ value: item.label, label: item.label })), [elevator]); const tabBarKey = useMemo(() => JSON.stringify(tabBarOptions), [tabBarOptions]); const ActionChangeTabBarValue = useRef(false); const initTabBar = usePersistFn(y => { const _showNav = y >= triggerOffset - tabBarHeight; // 滚动距离增加 tabBarHeight,UI 上已经滚动过去了 // TODO 从体验上看,top 过了内容高度的三之一就算滚到了 const overElevators = elevator.filter(item => item.top <= y + tabBarHeight); const _tabBarValue = overElevators[overElevators.length - 1]?.label; setShowNav(_showNav); if (_showNav && _tabBarValue && !ActionChangeTabBarValue.current) { setTabBarValue(_tabBarValue); } }); useUpdateEffect(() => { // 当布局变化时重新定位 initTabBar(ScrollTop.current); }, [tabBarOptions]); // TODO 修复类型报错 registerScroll(ScrollViewRef); const onScrollPersist = usePersistFn(e => { onScroll?.(e); ScrollTop.current = e.nativeEvent.contentOffset.y; initTabBar(ScrollTop.current); }); const onChangeTabBar = usePersistFn(v => { setTabBarValue(v); ActionChangeTabBarValue.current = true; ScrollViewRef.current?.scrollTo({ y: elevator.filter(item => item.label === v)[0].top, animated: true }); }); const onMomentumScrollEndPersist = usePersistFn(e => { onMomentumScrollEnd?.(e); ActionChangeTabBarValue.current = false; }); return /*#__PURE__*/_jsxs(View, { style: STYLES.wrapper, collapsable: false, children: [showNav && tabBarValue ? /*#__PURE__*/_jsx(View, { style: STYLES.nav, children: /*#__PURE__*/_jsx(TabBar, { indicator: true, safeAreaInsetBottom: false, value: tabBarValue, onChange: onChangeTabBar, options: tabBarOptions }, tabBarKey) }) : null, /*#__PURE__*/_jsx(ScrollComponent, { scrollEventThrottle: 16, bounces: false, ...restProps, // TODO 修复类型报错 ref: ScrollViewRef, onScroll: onScrollPersist, onMomentumScrollEnd: onMomentumScrollEndPersist, children: children })] }); }; const ElevatorNav = props => { return /*#__PURE__*/_jsx(ElevatorContextProvider, { children: /*#__PURE__*/_jsx(ElevatorNavInner, { ...props }) }); }; export default /*#__PURE__*/memo(ElevatorNav); //# sourceMappingURL=elevator-nav.js.map