import React, { useRef, useState, useCallback, useEffect } from 'react';
import { View, StyleSheet, Animated, Pressable } from 'react-native';
import { isNil, isUndefined } from 'lodash';
import ShouldRender from '../ShouldRender';
import createStyle from './styles/descriptions.style';
import { useTheme } from '../Theme/Theme';
import { DescriptionsProps } from './interface';
import { renderTextLikeJSX } from '../../core/helpers';
import { IconXRightsmall1 } from '../../icons';
import { getComputedTitleAndContentStyles } from '../../core/descriptions/helper';
const Descriptions = ({
bordered = false,
extra,
expanded = true,
value,
defaultValue = true,
onChange,
style,
horizontal,
title,
titleStyle,
items,
itemStyle,
itemTitleStyle,
itemContentStyle,
selectable = true,
}: DescriptionsProps) => {
const token = useTheme();
const styles = createStyle(token);
const arrowAnim = useRef(new Animated.Value(0)).current;
const [isExpanded, setIsExpaned] = useState(defaultValue);
const isFirst = useRef(true); // 首次渲染动画问题
const onExpand = useCallback(() => {
Animated.parallel([
Animated.timing(arrowAnim, {
toValue: 1,
duration: isFirst.current ? 0 : 150,
useNativeDriver: true,
}),
]).start();
isFirst.current = false;
}, [arrowAnim, isFirst]);
const onClose = useCallback(() => {
Animated.parallel([
Animated.timing(arrowAnim, {
toValue: 0,
duration: isFirst.current ? 0 : 150,
useNativeDriver: true,
}),
]).start();
isFirst.current = false;
}, [arrowAnim, isFirst]);
useEffect(() => {
if (value ?? isExpanded) {
onExpand();
} else {
onClose();
}
}, [value, isExpanded, onClose, onExpand]);
const onPress = () => {
if (!expanded) return; //不允许操作展开收起
const nextValue = !(value ?? isExpanded);
onChange?.(nextValue);
if (isUndefined(value)) {
setIsExpaned(nextValue);
}
};
const header = (
{renderTextLikeJSX(title, [styles.title, titleStyle])}
{renderTextLikeJSX(extra, [styles.extra])}
);
const listMaxIndex = (items?.length ?? 0) - 1;
const lists = (
<>
{items?.map((item, i) => {
const computedTitleAndContentStyles =
getComputedTitleAndContentStyles(
item?.title,
item?.content,
horizontal
);
return (
{renderTextLikeJSX(item?.title, [
styles.itemTitle,
horizontal && styles.itemTitleRow,
horizontal && computedTitleAndContentStyles.titleStyle,
itemTitleStyle,
])}
{renderTextLikeJSX(
item?.content,
[
styles.itemContent,
horizontal && styles.itemContentRow,
horizontal && computedTitleAndContentStyles.contentStyle,
itemContentStyle,
],
{
selectable,
}
)}
);
})}
>
);
return (
{header}
{lists}
);
};
export default Descriptions;