@tra-tech/react-native-kitra
Version:
UI kit for React Native
128 lines • 4.49 kB
JavaScript
import { FlashList } from '@shopify/flash-list';
import { useState } from 'react';
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import Animated, { FadeInUp, FadeOut, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
import { applyDefaults } from '../../core/KitraProvider';
import OcticonsIcon from '../Icons/Octicons';
const AnimatedIcon = Animated.createAnimatedComponent(OcticonsIcon);
const AccordionList = _ref => {
let {
data,
label,
left,
right,
labelContainerStyle,
labelStyle,
rowTextStyle,
rowStyle,
onSelect,
onExpand,
theme,
typography,
itemDisplay,
testID
} = _ref;
const [expanded, setExpanded] = useState(false);
const listHeight = useSharedValue(0);
const iconRotation = useSharedValue(0);
const [contentHeight, setContentHeight] = useState(0);
const animatedStyle = useAnimatedStyle(() => ({
height: listHeight.value
}), [contentHeight]);
const iconStyle = useAnimatedStyle(() => ({
transform: [{
rotateZ: `${iconRotation.value}deg`
}]
}), [contentHeight]);
const handleListOpen = () => {
if (expanded) {
listHeight.value = withTiming(0);
iconRotation.value = withTiming(0);
} else {
onExpand === null || onExpand === void 0 ? void 0 : onExpand();
listHeight.value = withTiming(contentHeight, {
duration: 600
});
iconRotation.value = withTiming(180, {
duration: 200
});
}
setExpanded(prev => !prev);
};
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(TouchableOpacity, {
activeOpacity: 0.8,
onPress: handleListOpen,
testID: testID
}, /*#__PURE__*/React.createElement(View, {
style: [{
backgroundColor: expanded ? theme === null || theme === void 0 ? void 0 : theme.primary15 : theme === null || theme === void 0 ? void 0 : theme.primary5
}, styles.labelContianer, labelContainerStyle]
}, left && left(expanded), /*#__PURE__*/React.createElement(Text, {
style: [{
color: expanded ? theme === null || theme === void 0 ? void 0 : theme.primary : theme === null || theme === void 0 ? void 0 : theme.lightBlack
}, typography === null || typography === void 0 ? void 0 : typography.body.medium, styles.labelText, labelStyle]
}, label), right && right(expanded), /*#__PURE__*/React.createElement(View, {
style: [{
backgroundColor: expanded ? theme === null || theme === void 0 ? void 0 : theme.primary30 : theme === null || theme === void 0 ? void 0 : theme.lightGrey
}, styles.iconContainer]
}, /*#__PURE__*/React.createElement(AnimatedIcon, {
color: expanded ? theme === null || theme === void 0 ? void 0 : theme.primary : theme === null || theme === void 0 ? void 0 : theme.disabledLight,
name: "chevron-down",
style: iconStyle,
size: 20
})))), /*#__PURE__*/React.createElement(Animated.View, {
style: [animatedStyle, {
overflow: 'hidden'
}]
}, /*#__PURE__*/React.createElement(FlashList, {
bounces: false,
data: data,
estimatedItemSize: 21,
onContentSizeChange: (w, h) => {
if (h > 0 && h !== contentHeight) setContentHeight(h);
},
renderItem: _ref2 => {
let {
item
} = _ref2;
return /*#__PURE__*/React.createElement(TouchableOpacity, {
activeOpacity: 0.9,
onPress: () => onSelect(item)
}, /*#__PURE__*/React.createElement(Animated.View, {
entering: FadeInUp,
exiting: FadeOut,
style: [styles.itemContainer, {
backgroundColor: theme === null || theme === void 0 ? void 0 : theme.primary5
}, rowStyle]
}, /*#__PURE__*/React.createElement(Text, {
style: [{
textAlign: 'center',
color: theme === null || theme === void 0 ? void 0 : theme.grey
}, typography === null || typography === void 0 ? void 0 : typography.body.smedium, rowTextStyle]
}, itemDisplay(item))));
}
})));
};
export default applyDefaults(AccordionList);
const styles = StyleSheet.create({
labelContianer: {
padding: 10,
flexDirection: 'row',
alignItems: 'center',
borderRadius: 3
},
labelText: {
textAlign: 'left',
marginHorizontal: 10,
flex: 1
},
iconContainer: {
borderRadius: 3,
paddingVertical: 6,
paddingHorizontal: 10
},
itemContainer: {
padding: 10
}
});
//# sourceMappingURL=AccordionList.js.map