UNPKG

@fruits-chain/react-native-xiaoshu

Version:
139 lines (131 loc) 4.69 kB
import isUndefined from 'lodash/isUndefined'; import React, { useRef, useCallback, useEffect, memo } from 'react'; import { Animated, View } from 'react-native'; import Card from '../card'; import Cell from '../cell'; import Divider from '../divider'; import { easing, getDefaultValue } from '../helpers'; import { usePersistFn, useControllableValue } from '../hooks'; import { getArrowOutline } from '../icon/helper/arrow'; import Theme from '../theme'; import { varCreator, styleCreator } from './style'; /** * Collapse 折叠面板 */ const Collapse = _ref => { let { children, title, titleStyle, titleTextStyle, iconStyle, iconColor, iconSize, bodyStyle, renderTitle, renderTitleExtra, renderBody, type = 'cell', onAnimationEnd, bodyPadding = true, headerDivider = true, bodyDivider, lazyRender = true, ...restProps } = _ref; const TOKENS = Theme.useThemeTokens(); const CV = Theme.createVar(TOKENS, varCreator); const STYLES = Theme.createStyle(CV, styleCreator, TOKENS); bodyDivider = getDefaultValue(bodyDivider, type === 'cell'); const [collapse, onCollapse] = useControllableValue(restProps, { defaultValuePropName: 'defaultCollapse', valuePropName: 'collapse', trigger: 'onCollapse', defaultValue: false }); const onAnimationEndPersistFn = usePersistFn(v => { onAnimationEnd === null || onAnimationEnd === void 0 ? void 0 : onAnimationEnd(v); }); /** 记录当前是否可见,在不断 onLayout 的时候可以有一个判断的依据 */ const Visible = useRef(collapse); const BodyHeight = useRef(0); const MountedRef = useRef(false); const AnimatedValue = useRef(new Animated.Value(0)).current; const toggleBody = useCallback((v, immediately) => { const action = Animated.timing(AnimatedValue, { toValue: v ? BodyHeight.current : 0, duration: immediately ? 0 : CV.collapse_transition_duration, useNativeDriver: false, easing: v ? easing.easeOutCirc : easing.easeInCubic }); action.start(_ref2 => { let { finished } = _ref2; if (finished) { onAnimationEndPersistFn(v); } }); }, [AnimatedValue, onAnimationEndPersistFn, CV.collapse_transition_duration]); // 初始化好组件 useEffect(() => { MountedRef.current = true; }, []); useEffect(() => { // 同步当前的状态 Visible.current = collapse; toggleBody(collapse, false); }, [collapse, toggleBody]); const onPressTitle = useCallback(() => { onCollapse(!Visible.current); }, [onCollapse]); const onLayoutBody = useCallback(e => { // 有点疑惑,折叠的过程中,高度在动态变化,通过 absolute 布局解决无法完全渲染 BodyHeight.current = e.nativeEvent.layout.height; // 当收齐的时候已知高度 toggleBody(Visible.current, Visible.current); }, [toggleBody]); const ArrowOutline = getArrowOutline(collapse ? 'up' : 'down'); const arrowJSX = /*#__PURE__*/React.createElement(ArrowOutline, { style: iconStyle, color: !isUndefined(iconColor) ? iconColor : CV.collapse_icon_color, size: !isUndefined(iconSize) ? iconSize : CV.collapse_icon_size }); const titleJSX = renderTitle ? renderTitle(collapse) : title; const titleExtraJSX = renderTitleExtra ? renderTitleExtra(collapse, arrowJSX) : arrowJSX; const bodyJSX = lazyRender && !MountedRef.current && !collapse ? null : renderBody ? renderBody() : children; const ctxJSX = /*#__PURE__*/React.createElement(Animated.View, { style: [STYLES.collapse, { height: AnimatedValue }] }, /*#__PURE__*/React.createElement(View, { collapsable: false, style: STYLES.body, onLayout: onLayoutBody }, /*#__PURE__*/React.createElement(View, { style: [bodyPadding ? STYLES.body_padding : undefined, bodyStyle] }, bodyJSX), bodyDivider ? /*#__PURE__*/React.createElement(Divider, { type: "light", style: STYLES.divider }) : null)); if (type === 'card') { return /*#__PURE__*/React.createElement(Card, { square: true, title: titleJSX, extra: titleExtraJSX, headerDivider: headerDivider, titleStyle: titleStyle, titleTextStyle: titleTextStyle, bodyPadding: false, onPressHeader: onPressTitle }, ctxJSX); } return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Cell, { title: titleJSX, style: titleStyle, titleTextStyle: titleTextStyle, valueExtra: titleExtraJSX, onPress: onPressTitle, divider: headerDivider }), ctxJSX); }; export default /*#__PURE__*/memo(Collapse); //# sourceMappingURL=index.js.map