@tra-tech/react-native-kitra
Version:
UI kit for React Native
181 lines • 6.85 kB
JavaScript
/* eslint-disable no-unsafe-optional-chaining */
import React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
import { Dimensions, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import Animated, { FadeIn, FadeOut, useAnimatedStyle, useSharedValue, withSpring } from 'react-native-reanimated';
import { ScrollView } from 'react-native-gesture-handler';
import FeatherIcon from '../Icons/Feather';
const windowsHeight = Dimensions.get('window').height;
const Dropdown = _ref => {
let {
left,
right,
theme,
typography,
data,
displayedRowValue,
displayedButtonValue,
listContainerStyle,
defaultValue = {},
buttonTitle,
rowStyle,
buttonStyle,
disabled,
buttonTextStyle,
onSelect,
rowTextStyle,
containerStyle,
iconStyle,
autoPosition = true,
testID,
buttonBackgrounColor = {
focusBackground: theme === null || theme === void 0 ? void 0 : theme.primary5,
defaultBackground: theme === null || theme === void 0 ? void 0 : theme.darkWhite
}
} = _ref;
const [visible, setVisible] = useState(false);
const [selectedObject, setSelectedObject] = useState(defaultValue);
const [cord, setCord] = useState({
x: 0,
y: 0,
height: 0,
width: 0
});
const openAnimation = useSharedValue(0);
const dropdown = useRef(null);
const rightElement = useMemo(() => typeof right === 'function' ? right(visible) : right, [visible, right]);
const leftElement = useMemo(() => typeof left === 'function' ? left(visible) : left, [visible, left]);
const dropdownAnimation = useAnimatedStyle(() => ({
transform: [{
rotate: `${openAnimation.value * 180}deg`
}]
}), []);
const isObjectSelected = Object.keys(selectedObject).length === 0;
const isSelectedObject = value => displayedButtonValue(selectedObject) === displayedButtonValue(value);
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]);
return /*#__PURE__*/React.createElement(View, {
testID: testID,
style: [containerStyle, {
opacity: disabled ? 0.5 : 1,
zIndex: visible ? 1000 : 0
}]
}, /*#__PURE__*/React.createElement(TouchableOpacity, {
ref: dropdown,
activeOpacity: 0.9,
disabled: disabled,
onLayout: event => setCord(event.nativeEvent.layout),
onPress: () => {
setVisible(!visible);
},
style: [Style.button, buttonStyle, {
backgroundColor: visible ? buttonBackgrounColor.focusBackground : buttonBackgrounColor.defaultBackground
}]
}, leftElement, /*#__PURE__*/React.createElement(Animated.Text, {
numberOfLines: 1,
key: displayedButtonValue(selectedObject),
entering: FadeIn.delay(100),
exiting: FadeOut,
style: [{
flex: 1,
marginLeft: 12,
color: isObjectSelected || disabled ? theme === null || theme === void 0 ? void 0 : theme.grey : theme === null || theme === void 0 ? void 0 : theme.primary
}, typography === null || typography === void 0 ? void 0 : typography.body.medium, buttonTextStyle]
}, isObjectSelected ? buttonTitle || 'Please Select' : displayedButtonValue(selectedObject)), rightElement || /*#__PURE__*/React.createElement(View, {
style: [Style.rightIcon, {
backgroundColor: visible ? buttonBackgrounColor.focusBackground : buttonBackgrounColor.defaultBackground
}, iconStyle === null || iconStyle === void 0 ? void 0 : iconStyle.container]
}, /*#__PURE__*/React.createElement(Animated.View, {
style: dropdownAnimation
}, /*#__PURE__*/React.createElement(FeatherIcon, {
name: "chevron-down",
size: 14,
color: (iconStyle === null || iconStyle === void 0 ? void 0 : iconStyle.color) || (visible ? theme === null || theme === void 0 ? void 0 : theme.primary : theme === null || theme === void 0 ? void 0 : theme.grey)
})))), visible && cord.x >= 0 && cord.y >= 0 && /*#__PURE__*/React.createElement(Animated.View, {
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, autoPosition ? windowsHeight - (cord === null || cord === void 0 ? void 0 : cord.y) <= windowsHeight / 3 ? {
bottom: (cord === null || cord === void 0 ? void 0 : cord.height) + 5
} : {
top: (cord === null || cord === void 0 ? void 0 : cord.height) + 5
} : {
top: (cord === null || cord === void 0 ? void 0 : cord.height) + 5
}]
}, /*#__PURE__*/React.createElement(ScrollView, {
nestedScrollEnabled: true
}, data === null || data === void 0 ? void 0 : data.map((value, index) => /*#__PURE__*/React.createElement(TouchableOpacity, {
activeOpacity: 0.8,
key: index,
onPress: () => {
setSelectedObject(value);
setVisible(false);
onSelect === null || onSelect === void 0 ? void 0 : onSelect(value);
},
style: [Style.row, {
backgroundColor: isSelectedObject(value) ? theme === null || theme === void 0 ? void 0 : theme.primary15 : theme === null || theme === void 0 ? void 0 : theme.darkWhite
}, index === data.length - 1 ? {
borderBottomLeftRadius: 5,
borderBottomRightRadius: 5
} : null, rowStyle]
}, /*#__PURE__*/React.createElement(Text, {
style: [typography === null || typography === void 0 ? void 0 : typography.body.smedium, {
color: isSelectedObject(value) ? theme === null || theme === void 0 ? void 0 : theme.primary : theme === null || theme === void 0 ? void 0 : theme.black,
marginVertical: 10,
marginHorizontal: 10
}, rowTextStyle]
}, displayedRowValue(value)))))));
};
export default Dropdown;
export const Style = StyleSheet.create({
button: {
height: 38,
width: '100%',
flexDirection: 'row',
alignItems: 'center',
borderRadius: 5
},
listContainer: {
zIndex: 100,
padding: 10,
height: 36 * 4.5,
width: '100%',
position: 'absolute',
borderTopWidth: 0,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2
},
shadowOpacity: 0.37,
elevation: 4,
borderRadius: 5
},
row: {
height: 38,
borderRadius: 3,
borderWidth: 0,
justifyContent: 'center'
},
rightIcon: {
borderRadius: 3,
paddingVertical: 2,
paddingHorizontal: 6,
marginRight: 12
}
});
//# sourceMappingURL=Dropdown.js.map