UNPKG

@tra-tech/react-native-kitra

Version:
277 lines (276 loc) 10.1 kB
import { FlashList } from '@shopify/flash-list'; import { forwardRef, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'; import { Dimensions, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; import { ScrollView } from 'react-native-gesture-handler'; import Animated, { FadeIn, FadeOut, useAnimatedStyle, useSharedValue, withSpring } from 'react-native-reanimated'; import { defaultTheme } from '../../core/theme/theme'; import { defaultTypography } from '../../core/typography/typography'; import Button from '../Button/Button'; import FeatherIcon from '../Icons/Feather'; import IoniconsIcon from '../Icons/Ionicons'; import OcticonsIcon from '../Icons/Octicons'; const windowsHeight = Dimensions.get('window').height; let dataWithID; // eslint-disable-next-line no-undef const GScrollView = /*#__PURE__*/forwardRef((props, ref) => /*#__PURE__*/React.createElement(ScrollView, props)); const MultipleDropdown = _ref => { let { theme, typography, left, right, data, displayedRowValue, displayedButtonValue, listContainerStyle, defaultValue = [], displayLength = 4, buttonTitle, rowStyle, buttonStyle, buttonTextStyle, selectall = false, onSelect, onComplete, rowTextStyle, containerStyle, testID } = _ref; const [visible, setVisible] = useState(false); const [selectedObjects, setSelectedObjects] = useState(defaultValue || []); const [cord, setCord] = useState({ x: 0, y: 0, height: 0, width: 0 }); const openAnimation = useSharedValue(0); const dropdown = useRef(null); const dropdownAnimation = useAnimatedStyle(() => ({ transform: [{ rotate: `${openAnimation.value * 180}deg` }] }), []); const rightElement = useMemo(() => typeof right === 'function' ? right(visible) : right, [visible, right]); const leftElement = useMemo(() => typeof left === 'function' ? left(visible) : left, [visible, left]); const toggleCheckBox = value => { const selectedObjectsTemp = [...selectedObjects]; const valueIndex = selectedObjectsTemp.indexOf(value); if (valueIndex > -1) { selectedObjectsTemp.splice(valueIndex, 1); } else { selectedObjectsTemp.push(value); } onSelect === null || onSelect === void 0 ? void 0 : onSelect(selectedObjectsTemp); setSelectedObjects(selectedObjectsTemp); }; const isItemSelected = item => { const result = selectedObjects === null || selectedObjects === void 0 ? void 0 : selectedObjects.find(x => x ? displayedButtonValue(x) === displayedButtonValue(item) : false); return result; }; const isObjectSelected = !!(selectedObjects !== null && selectedObjects !== void 0 && selectedObjects.length); useLayoutEffect(() => { var _dropdown$current; dropdown === null || dropdown === void 0 ? void 0 : (_dropdown$current = dropdown.current) === null || _dropdown$current === void 0 ? void 0 : _dropdown$current.measure((x, y, width, height, pageX, pageY) => { setCord({ width, height, x: pageX, y: pageY }); }); }, [visible]); useEffect(() => { openAnimation.value = withSpring(visible ? 1 : 0); }, [visible]); useEffect(() => { // @ts-expect-error dataWithID = data === null || data === void 0 ? void 0 : data.map(x => { x.keyID = Math.random(); return x; }); }, []); return /*#__PURE__*/React.createElement(View, { testID: testID, style: [containerStyle, { zIndex: 100 }] }, /*#__PURE__*/React.createElement(TouchableOpacity, { testID: "dropdown-button", ref: dropdown, activeOpacity: 0.9, onPress: () => { setVisible(!visible); }, style: [Style.button, buttonStyle, { backgroundColor: visible ? theme === null || theme === void 0 ? void 0 : theme.primary5 : theme === null || theme === void 0 ? void 0 : theme.darkWhite }] }, leftElement, /*#__PURE__*/React.createElement(Animated.Text, { numberOfLines: 1, entering: FadeIn.delay(100), exiting: FadeOut, style: [buttonTextStyle, typography === null || typography === void 0 ? void 0 : typography.body.medium, { flex: 1, marginLeft: 12, color: isObjectSelected ? theme === null || theme === void 0 ? void 0 : theme.primary : theme === null || theme === void 0 ? void 0 : theme.grey }] }, !isObjectSelected ? buttonTitle || 'Please Select' : selectedObjects.length <= displayLength ? `${selectedObjects.map(item => displayedButtonValue(item))}` : `${selectedObjects === null || selectedObjects === void 0 ? void 0 : selectedObjects.length} Selected`), rightElement || /*#__PURE__*/React.createElement(View, { style: [Style.rightIcon, { backgroundColor: visible ? theme === null || theme === void 0 ? void 0 : theme.primary5 : theme === null || theme === void 0 ? void 0 : theme.lightGrey }] }, /*#__PURE__*/React.createElement(Animated.View, { style: dropdownAnimation }, /*#__PURE__*/React.createElement(FeatherIcon, { name: "chevron-down", size: 14, color: visible ? theme === null || theme === void 0 ? void 0 : theme.primary : theme === null || theme === void 0 ? void 0 : theme.grey })))), visible && /*#__PURE__*/React.createElement(Animated.View, { testID: "dropdown-list", entering: FadeIn, exiting: FadeOut, style: [Style.listContainer, { backgroundColor: theme === null || theme === void 0 ? void 0 : theme.darkWhite, width: cord === null || cord === void 0 ? void 0 : cord.width, left: 0 }, listContainerStyle, windowsHeight - ((cord === null || cord === void 0 ? void 0 : cord.y) + 38 * 4 || 0) <= windowsHeight / 3 ? { bottom: (cord === null || cord === void 0 ? void 0 : cord.height) || 0 + 5 } : { top: (cord === null || cord === void 0 ? void 0 : cord.height) || 0 + 5 }] }, /*#__PURE__*/React.createElement(FlashList, { extraData: selectedObjects, renderScrollComponent: GScrollView, data: dataWithID // @ts-expect-error , keyExtractor: item => item.keyID || displayedRowValue(item), estimatedItemSize: 38, renderItem: _ref2 => { let { item, index } = _ref2; const isSelected = isItemSelected(item || {}); return /*#__PURE__*/React.createElement(TouchableOpacity, { activeOpacity: 0.8, onPress: () => { setSelectedObjects(item); toggleCheckBox(item); }, style: [Style.row, { backgroundColor: theme === null || theme === void 0 ? void 0 : theme.darkWhite }, index === (data === null || data === void 0 ? void 0 : data.length) || 0 - 1 ? { borderBottomLeftRadius: 5, borderBottomRightRadius: 5 } : null, rowStyle] }, /*#__PURE__*/React.createElement(TouchableOpacity, { disabled: true, style: [Style.checkBox, { borderColor: theme === null || theme === void 0 ? void 0 : theme.disabledLight, backgroundColor: theme === null || theme === void 0 ? void 0 : theme.disabledLightDark }] }, isSelected && /*#__PURE__*/React.createElement(OcticonsIcon, { color: theme === null || theme === void 0 ? void 0 : theme.primary, name: "check", size: 12 })), /*#__PURE__*/React.createElement(Text, { style: [typography === null || typography === void 0 ? void 0 : typography.body.smedium, { color: isSelected ? theme === null || theme === void 0 ? void 0 : theme.primary : theme === null || theme === void 0 ? void 0 : theme.black, marginHorizontal: 10 }, rowTextStyle] }, displayedRowValue(item))); } }), selectall && /*#__PURE__*/React.createElement(TouchableOpacity, { activeOpacity: 0.8, onPress: () => { (data === null || data === void 0 ? void 0 : data.length) === selectedObjects.length ? setSelectedObjects([]) : setSelectedObjects(data); }, style: { flexDirection: 'row', justifyContent: 'flex-end' } }, /*#__PURE__*/React.createElement(Text, { style: [typography === null || typography === void 0 ? void 0 : typography.body.smedium, { textAlign: 'right', color: theme === null || theme === void 0 ? void 0 : theme.secondary }] }, "Select All"), /*#__PURE__*/React.createElement(IoniconsIcon, { name: "checkmark-done-outline", size: 16, style: { marginLeft: 5 }, color: theme === null || theme === void 0 ? void 0 : theme.secondary })), /*#__PURE__*/React.createElement(Button, { testID: "dropdown-complete-button", onPress: () => { if (onComplete) onComplete(selectedObjects); setVisible(false); }, size: "large", label: "Complete Selection", textStyle: { textAlign: 'center' }, style: Style.completeSelection, iconPosition: "left", theme: defaultTheme === null || defaultTheme === void 0 ? void 0 : defaultTheme.light, typography: defaultTypography }))); }; export default MultipleDropdown; export const Style = StyleSheet.create({ button: { height: 38, width: '100%', flexDirection: 'row', alignItems: 'center', borderRadius: 5 }, listContainer: { zIndex: 100, height: 38 * 4 + 78, position: 'absolute', padding: 10, paddingBottom: 14, borderTopWidth: 0, shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.37, elevation: 4, borderRadius: 5 }, row: { flexDirection: 'row', alignItems: 'center', justifyContent: 'flex-start', paddingHorizontal: 10, height: 38, borderRadius: 3 }, completeSelection: { height: 42, width: '100%', paddingVertical: 12, paddingHorizontal: 30.5, marginTop: 10 }, rightIcon: { borderRadius: 3, paddingVertical: 2, paddingHorizontal: 6, marginRight: 12 }, checkBox: { height: 20, width: 20, borderWidth: 1, alignItems: 'center', justifyContent: 'center', borderRadius: 4 } }); //# sourceMappingURL=MultipleSelectDropdown.js.map