UNPKG

@eslam-elmeniawy/react-native-common-components

Version:

Common `ReactNative` components packed in library for usage in projects.

128 lines (124 loc) 4.05 kB
"use strict"; // External imports. import * as React from 'react'; import { StyleSheet, View } from 'react-native'; import { withTheme, TouchableRipple } from 'react-native-paper'; // Types imports. // Internal imports. import styles from "./Accordion.styles.js"; import { IconButton } from "../IconButton/index.js"; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; const SafeAccordion = /*#__PURE__*/React.memo(props => { const { containerStyle, headerContainerStyle, headerContent, iconButtonProps, children, theme } = props; const { iconName, color, onPress: onIconPress, ...restIconProps } = iconButtonProps ?? {}; const Animated = require('react-native-reanimated').default; const useSharedValue = require('react-native-reanimated').useSharedValue; const useAnimatedStyle = require('react-native-reanimated').useAnimatedStyle; const withTiming = require('react-native-reanimated').withTiming; const Easing = require('react-native-reanimated').Easing; const [isExpanded, setIsExpanded] = React.useState(false); const [measuredHeight, setMeasuredHeight] = React.useState(0); const height = useSharedValue(0); const rotation = useSharedValue(0); const onTogglePress = React.useCallback(() => { setIsExpanded(!isExpanded); if (!isExpanded) { height.value = withTiming(measuredHeight, { duration: 300, easing: Easing.inOut(Easing.ease) }); rotation.value = withTiming(180, { duration: 300, easing: Easing.inOut(Easing.ease) }); } else { height.value = withTiming(0, { duration: 300, easing: Easing.inOut(Easing.ease) }); rotation.value = withTiming(0, { duration: 300, easing: Easing.inOut(Easing.ease) }); } onIconPress?.(); }, [Easing, height, isExpanded, measuredHeight, onIconPress, rotation, withTiming]); const onLayout = React.useCallback(event => { if (measuredHeight === 0) { setMeasuredHeight(event.nativeEvent.layout.height); } }, [measuredHeight]); const animatedHeightStyle = useAnimatedStyle(() => ({ height: height.value, overflow: 'hidden' })); const animatedArrowStyle = useAnimatedStyle(() => ({ transform: [{ rotateZ: `${rotation.value}deg` }] })); return /*#__PURE__*/_jsxs(View, { style: StyleSheet.flatten([{ backgroundColor: theme.colors.background }, containerStyle]), children: [/*#__PURE__*/_jsxs(View, { style: styles.headerRow, children: [/*#__PURE__*/_jsx(TouchableRipple, { style: styles.headerRipple, onPress: onTogglePress, children: /*#__PURE__*/_jsx(View, { style: headerContainerStyle, children: headerContent }) }), /*#__PURE__*/_jsx(Animated.View, { style: animatedArrowStyle, children: /*#__PURE__*/_jsx(IconButton, { iconName: iconName ?? 'chevron-down', color: color ?? (theme.isV3 ? theme.colors.onBackground : theme.colors.text), onPress: onTogglePress, ...restIconProps }) })] }), /*#__PURE__*/_jsxs(Animated.View, { style: animatedHeightStyle, children: [/*#__PURE__*/_jsx(View, { style: styles.measuringContainer, onLayout: onLayout, children: children }), /*#__PURE__*/_jsx(View, { children: children })] })] }); }); const AccordionWithFallback = /*#__PURE__*/React.memo(props => { try { require('react-native-reanimated'); return /*#__PURE__*/_jsx(SafeAccordion, { ...props }); } catch (error) { console.warn('Error loading `react-native-reanimated`:', error); return null; } }); const Accordion = withTheme(AccordionWithFallback); /** * AccordionComponent (unwrapped, for testing) * @internal For testing purposes only. Do not use in production code. */ export { AccordionWithFallback as AccordionComponent }; export default Accordion; //# sourceMappingURL=Accordion.js.map