@tra-tech/react-native-kitra
Version:
UI kit for React Native
277 lines (276 loc) • 10.1 kB
JavaScript
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