ikualo-ui-kit-mobile 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/.expo/README.md +8 -0
  2. package/assets/images/_images.ts +5 -0
  3. package/assets/images/headerBack.png +0 -0
  4. package/assets/images/headerClose.png +0 -0
  5. package/assets/images/headerInfo.png +0 -0
  6. package/package.json +2 -4
  7. package/src/config/paper.config.ts +49 -0
  8. package/src/elements/alerts/Alert.tsx +31 -0
  9. package/src/elements/buttons/BtnContained.tsx +50 -0
  10. package/src/elements/buttons/BtnIcon.tsx +49 -0
  11. package/src/elements/buttons/BtnLightSmall.tsx +31 -0
  12. package/src/elements/buttons/BtnOutlined.tsx +43 -0
  13. package/src/elements/buttons/BtnText.tsx +34 -0
  14. package/src/elements/cards/CardComponent.tsx +62 -0
  15. package/src/elements/cards/CardInteractive.tsx +34 -0
  16. package/src/elements/cards/CardList.tsx +40 -0
  17. package/src/elements/checkbox/CheckboxComponent.tsx +14 -0
  18. package/src/elements/dialogs/DialogDown.tsx +36 -0
  19. package/src/elements/dialogs/DialogGeneral.tsx +47 -0
  20. package/src/elements/dropdown/Dropdown.tsx +84 -0
  21. package/src/elements/headers/HeaderPage.tsx +53 -0
  22. package/src/elements/inputs/Input.tsx +130 -0
  23. package/src/elements/inputs/InputEmail.tsx +119 -0
  24. package/src/elements/inputs/InputOtp.tsx +48 -0
  25. package/src/elements/inputs/InputPassword.tsx +130 -0
  26. package/src/elements/list/ListGroup.tsx +67 -0
  27. package/src/elements/pages/PageBasic.tsx +20 -0
  28. package/src/elements/pages/PageTouchable.tsx +25 -0
  29. package/src/elements/progressBar/ProgressBar.tsx +36 -0
  30. package/src/elements/progressBar/ProgressBarSteps.tsx +37 -0
  31. package/src/elements/select/Select.tsx +51 -0
  32. package/src/elements/select/SelectList.tsx +53 -0
  33. package/src/elements/tabs/Tab.tsx +38 -0
  34. package/src/elements/texts/Text.tsx +4 -0
  35. package/src/elements/timer/Timer.tsx +47 -0
  36. package/src/index.ts +40 -0
@@ -0,0 +1,8 @@
1
+ > Why do I have a folder named ".expo" in my project?
2
+ The ".expo" folder is created when an Expo project is started using "expo start" command.
3
+ > What do the files contain?
4
+ - "devices.json": contains information about devices that have recently opened this project. This is used to populate the "Development sessions" list in your development builds.
5
+ - "settings.json": contains the server configuration that is used to serve the application manifest.
6
+ > Should I commit the ".expo" folder?
7
+ No, you should not share the ".expo" folder. It does not contain any information that is relevant for other developers working on the project, it is specific to your machine.
8
+ Upon project creation, the ".expo" folder is already added to your ".gitignore" file.
@@ -45,4 +45,9 @@ export const images = {
45
45
  },
46
46
  validateIdentity: require('./validateIdentity.png'),
47
47
  validationFailed: require('./validationFailed.png'),
48
+ header:{
49
+ back: require('./headerBack.png'),
50
+ close: require('./headerClose.png'),
51
+ help: require('./headerInfo.png'),
52
+ }
48
53
  };
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,11 +1,9 @@
1
1
  {
2
2
  "name": "ikualo-ui-kit-mobile",
3
- "version": "0.0.2",
4
- "main": "dist/index.ts",
3
+ "version": "0.0.4",
4
+ "main": "src/index.ts",
5
5
  "scripts": {
6
6
  "start": "expo start",
7
- "build": "babel src --out-dir dist",
8
- "prepublishOnly": "npm run build",
9
7
  "android": "expo start --android",
10
8
  "ios": "expo start --ios",
11
9
  "web": "expo start --web"
@@ -0,0 +1,49 @@
1
+ import { MD3DarkTheme as DefaultTheme } from 'react-native-paper';
2
+
3
+ export const theme = {
4
+ ...DefaultTheme,
5
+ colors: {
6
+ ...DefaultTheme.colors,
7
+ primary: '#512BDA',
8
+ secondary: '#00F993',
9
+ dark: '#29292C',
10
+ light: '#FFFFFF',
11
+ error: '#F13A59',
12
+ disabled: '#E6E0E9',
13
+ black: '#000000',
14
+ white: '#FFFFFF',
15
+ text: '#0A0A0A',
16
+ lightPrimary: '#F3EEFC',
17
+ lightBlue: '#00BACA',
18
+ blackText: '#0B041F',
19
+ grayText: '#B4B4B4',
20
+ boldDark: '#0F042D',
21
+ lightBlack: '#1E1E1E',
22
+ lightBlueBorder: '#AAEBEC',
23
+ boldBlack: '#0A0A0A',
24
+ darkGray: '#949494',
25
+ lightGray: '#E8E8E8',
26
+ darkRed: '#B3261E',
27
+ lightRed: '#EFD0D1',
28
+ lightInfo: '#d7eaf8',
29
+ darkInfo: '#004173',
30
+ lightWarning: '#FFF8C6',
31
+ darkWarning: '#FE9800',
32
+ lightSuccess: '#DAEEDF',
33
+ darkSuccess: '#328F45',
34
+ darkBlue: '#0F042D',
35
+ background: '#FAFAFC',
36
+ lightGrayBackground: '#E6E0E9',
37
+ cardDsc: '#1A1A1A',
38
+ lightPurpleBorder: '#EEE7FB',
39
+ lightPurpleShadow: '#E2D5FF',
40
+ transparent: 'transparent',
41
+ purple: '#947CE8',
42
+ boldBlue: '#160440',
43
+ deepGray: '#3A3A3A',
44
+ lightGrayText: '#585858',
45
+ disabledButtonBackground: '#E8E8E8',
46
+ disabledButtonBorder: '#949494',
47
+ },
48
+ dark: false,
49
+ };
@@ -0,0 +1,31 @@
1
+ import { View, Image, Animated } from 'react-native';
2
+ import { Portal, Text } from 'react-native-paper';
3
+ import { useEffect } from 'react';
4
+ import { styleAlerts } from '../../../assets/styles/elements/alert';
5
+ import { icons } from '../../../assets/icons/_icons';
6
+ interface IFAlertInfo {
7
+ title: string;
8
+ text: JSX.Element;
9
+ type: 'info' | 'warning' | 'error' | 'success';
10
+ onClose: () => void;
11
+ }
12
+ export const Alert = (props: IFAlertInfo) => {
13
+ const { text, title, type, onClose } = props;
14
+
15
+ useEffect(() => {
16
+ setTimeout(() => {
17
+ onClose();
18
+ }, 10000);
19
+ }, []);
20
+ return (
21
+ <Portal>
22
+ <Animated.View style={[styleAlerts['alert'], styleAlerts[`alert--${type}`]]}>
23
+ <View style={styleAlerts['alert-container-text']}>
24
+ <Image source={icons[type]} />
25
+ <Text style={styleAlerts['alert-container-title']}>{title}</Text>
26
+ </View>
27
+ <View style={styleAlerts['alert-body']}>{text}</View>
28
+ </Animated.View>
29
+ </Portal>
30
+ );
31
+ };
@@ -0,0 +1,50 @@
1
+ import { Button } from 'react-native-paper';
2
+ import { Image } from 'react-native';
3
+
4
+ import { stylesButtonContained } from '../../../assets/styles/elements/buttons';
5
+
6
+ interface IfBtnContained {
7
+ color?: 'primary' | 'secondary' | 'dark' | 'light' | 'lightPrimary';
8
+ text?: string;
9
+ size?: 'sm' | 'md' | 'xl';
10
+ labelStyle?: any;
11
+ contentStyle?: any;
12
+ style?: any;
13
+ isDisabled?: boolean;
14
+ isLoading?: boolean;
15
+ onPress: () => void;
16
+ icon?: any;
17
+ }
18
+
19
+ export const BtnContained = (props: IfBtnContained) => {
20
+ const { color, text, size, contentStyle, labelStyle, style, isDisabled, isLoading, onPress, icon } = props;
21
+
22
+ return (
23
+ <>
24
+ <Button
25
+ disabled={isDisabled}
26
+ loading={isLoading}
27
+ labelStyle={[
28
+ stylesButtonContained['btn-contained-text'],
29
+ stylesButtonContained[`btn-contained--${size ?? 'md'}`],
30
+ stylesButtonContained[`btn-contained--${color ?? 'primary'}`],
31
+ isDisabled && stylesButtonContained[`btn-contained--disabled`],
32
+ labelStyle ?? '',
33
+ ]}
34
+ contentStyle={[
35
+ stylesButtonContained['btn-contained'],
36
+ stylesButtonContained[`btn-contained--${color ?? 'primary'}`],
37
+ stylesButtonContained[`btn-contained--${size ?? 'md'}`],
38
+ isDisabled && stylesButtonContained[`btn-contained--disabled`],
39
+ contentStyle ?? '',
40
+ ]}
41
+ style={[stylesButtonContained['btn-contained'], style ?? '']}
42
+ mode="contained"
43
+ onPress={onPress}
44
+ >
45
+ {icon && <Image source={icon} />}
46
+ {text}
47
+ </Button>
48
+ </>
49
+ );
50
+ };
@@ -0,0 +1,49 @@
1
+ import { Button } from 'react-native-paper';
2
+ import { StyleSheet } from 'react-native';
3
+ import { theme } from '../../config/paper.config';
4
+ interface IFBtnIcon {
5
+ icon?: any;
6
+ text?: string;
7
+ contentStyle?: any;
8
+ labelStyle?: any;
9
+ style?: any;
10
+ direction?: 'left' | 'right';
11
+ isDisabled?: boolean;
12
+ onPress: () => void;
13
+ }
14
+ export const BtnIcon = (props: IFBtnIcon) => {
15
+ const { icon, text, onPress, isDisabled, direction, contentStyle, labelStyle, style } = props;
16
+ return (
17
+ <Button
18
+ disabled={isDisabled}
19
+ contentStyle={[stylesBtnIcon[`btn-icon--${direction ?? 'right'}`], contentStyle ?? '']}
20
+ labelStyle={[
21
+ stylesBtnIcon['btn-label'],
22
+ isDisabled && stylesBtnIcon['btn-label--disabled'],
23
+ labelStyle ?? '',
24
+ ]}
25
+ style={style}
26
+ icon={icon}
27
+ mode="text"
28
+ onPress={onPress}
29
+ >
30
+ {text}
31
+ </Button>
32
+ );
33
+ };
34
+ const stylesBtnIcon = StyleSheet.create({
35
+ 'btn-icon--right': {
36
+ flexDirection: 'row-reverse',
37
+ },
38
+ 'btn-icon--left': {
39
+ flexDirection: 'row',
40
+ },
41
+ 'btn-label': {
42
+ color: theme.colors.primary,
43
+ fontFamily: 'MontserratBold',
44
+ fontSize: 12,
45
+ },
46
+ 'btn-label--disabled': {
47
+ color: theme.colors.disabled,
48
+ },
49
+ });
@@ -0,0 +1,31 @@
1
+ import { Button, Text } from 'react-native-paper';
2
+ import { stylesBtnLightSmall } from '../../../assets/styles/elements/buttons';
3
+
4
+ interface IfBtnLightSmall {
5
+ onPress: () => void;
6
+ icon: any;
7
+ disabled?: boolean;
8
+ }
9
+ export const BtnLightSmall = (props: IfBtnLightSmall) => {
10
+ const { onPress, icon, disabled = false } = props;
11
+ const anything = '';
12
+
13
+ return (
14
+ <Button
15
+ style={[
16
+ stylesBtnLightSmall['btn-light-small'],
17
+ disabled && stylesBtnLightSmall['btn-light-small--disabled'],
18
+ ]}
19
+ contentStyle={stylesBtnLightSmall['btn-light-small-content']}
20
+ labelStyle={[
21
+ (stylesBtnLightSmall['btn-light-small-label'],
22
+ disabled && stylesBtnLightSmall['btn-light-small-label--disabled']),
23
+ ]}
24
+ onPress={onPress}
25
+ icon={icon}
26
+ disabled={disabled}
27
+ >
28
+ <Text>{anything}</Text>
29
+ </Button>
30
+ );
31
+ };
@@ -0,0 +1,43 @@
1
+ import { Button } from 'react-native-paper';
2
+
3
+ import { stylesButtonOutlined } from '../../../assets/styles/elements/buttons';
4
+
5
+ interface IfBtnOutlined {
6
+ color?: 'primary' | 'secondary' | 'dark' | 'light';
7
+ text?: string;
8
+ size?: 'sm' | 'md' | 'xl';
9
+ customStyles?: object;
10
+ isDisabled?: boolean;
11
+ isLoading?: boolean;
12
+ onPress: () => void;
13
+ }
14
+
15
+ export const BtnOutlined = (props: IfBtnOutlined) => {
16
+ const { color, text, size, customStyles, isDisabled, isLoading, onPress } = props;
17
+
18
+ return (
19
+ <>
20
+ <Button
21
+ disabled={isDisabled}
22
+ loading={isLoading}
23
+ labelStyle={[
24
+ stylesButtonOutlined['btn-outlined-text'],
25
+ stylesButtonOutlined[`btn-outlined--${color ?? 'primary'}`],
26
+ stylesButtonOutlined[`btn-outlined--${size ?? 'md'}`],
27
+ isDisabled && stylesButtonOutlined[`btn-outlined--disabled`],
28
+ ]}
29
+ style={[
30
+ stylesButtonOutlined['btn-outlined'],
31
+ stylesButtonOutlined[`btn-outlined--${color ?? 'primary'}`],
32
+ stylesButtonOutlined[`btn-outlined--${size ?? 'md'}`],
33
+ isDisabled && stylesButtonOutlined[`btn-outlined--disabled`],
34
+ customStyles,
35
+ ]}
36
+ mode="outlined"
37
+ onPress={onPress}
38
+ >
39
+ {text}
40
+ </Button>
41
+ </>
42
+ );
43
+ };
@@ -0,0 +1,34 @@
1
+ import { Button } from 'react-native-paper';
2
+ import { stylesButtonText } from '../../../assets/styles/elements/buttons';
3
+ interface IFBtnText {
4
+ color: 'primary' | 'secondary' | 'dark' | 'light' | 'generic';
5
+ text: string;
6
+ style?: any;
7
+ contentStyle?: any;
8
+ labelStyle?: any;
9
+ isDisabled?: boolean;
10
+ isLoading?: boolean;
11
+ onPress: () => void;
12
+ }
13
+
14
+ export const BtnText = (props: IFBtnText) => {
15
+ const { color, text, style, contentStyle, labelStyle, isDisabled, isLoading, onPress } = props;
16
+ return (
17
+ <Button
18
+ disabled={isDisabled}
19
+ loading={isLoading}
20
+ labelStyle={[
21
+ stylesButtonText['btn-text'],
22
+ stylesButtonText[`btn-text--${color}`],
23
+ isDisabled && stylesButtonText[`btn-text--disabled`],
24
+ labelStyle ?? '',
25
+ ]}
26
+ contentStyle={[stylesButtonText['btn-text'], contentStyle ?? '']}
27
+ style={[stylesButtonText['btn-text'], style ?? '']}
28
+ mode="text"
29
+ onPress={onPress}
30
+ >
31
+ {text}
32
+ </Button>
33
+ );
34
+ };
@@ -0,0 +1,62 @@
1
+ import { Card } from 'react-native-paper';
2
+ import { GestureResponderEvent } from 'react-native';
3
+ import { stylesCards } from '../../../assets/styles/elements/cards';
4
+ import { Text } from 'react-native-paper';
5
+
6
+ interface IfCardComponent {
7
+ mode?: 'elevated' | 'outlined' | 'contained';
8
+ children: React.ReactNode;
9
+ onLongPress?: () => void;
10
+ onPress?: (e: GestureResponderEvent) => void;
11
+ onPressIn?: (e: GestureResponderEvent) => void;
12
+ onPressOut?: (e: GestureResponderEvent) => void;
13
+ delayLongPress?: number;
14
+ disabled?: boolean;
15
+ elevation?: number;
16
+ contentStyle?: object;
17
+ style?: object;
18
+ theme?: any;
19
+ testID?: string;
20
+ accessible?: boolean;
21
+ title?: string;
22
+ titleStyle?: object;
23
+ }
24
+
25
+ export const CardComponent = (props: IfCardComponent) => {
26
+ const {
27
+ mode = 'elevated',
28
+ children,
29
+ onLongPress,
30
+ onPress,
31
+ onPressIn,
32
+ onPressOut,
33
+ delayLongPress,
34
+ disabled,
35
+ contentStyle,
36
+ style,
37
+ theme,
38
+ accessible,
39
+ title,
40
+ titleStyle,
41
+ } = props;
42
+
43
+ return (
44
+ <Card
45
+ mode={mode}
46
+ onLongPress={onLongPress}
47
+ onPress={onPress}
48
+ onPressIn={onPressIn}
49
+ onPressOut={onPressOut}
50
+ delayLongPress={delayLongPress}
51
+ disabled={disabled}
52
+ contentStyle={contentStyle}
53
+ style={[stylesCards['card'], style]}
54
+ theme={theme}
55
+ accessible={accessible}
56
+ >
57
+ {title && <Text style={titleStyle}>{title}</Text>}
58
+
59
+ {children}
60
+ </Card>
61
+ );
62
+ };
@@ -0,0 +1,34 @@
1
+ import { View, Image, Touchable, TouchableHighlight } from 'react-native';
2
+ import { Card, Text, TouchableRipple } from 'react-native-paper';
3
+ import { stylesCards } from '../../../assets/styles/elements/cards';
4
+ import { icons } from '../../../assets/icons/_icons';
5
+
6
+ interface IFCardInteractive {
7
+ iconSource?: any;
8
+ title: string;
9
+ description?: string;
10
+ onPress: () => void;
11
+
12
+ }
13
+
14
+ export const CardInteractive = (props: IFCardInteractive) => {
15
+ const { iconSource, title, description, onPress } = props;
16
+ return (
17
+ <TouchableRipple onPress={onPress}>
18
+ <Card style={stylesCards['card-interactive']}>
19
+ <View style={stylesCards['card-interactive-info']}>
20
+ <View style={stylesCards['card-interactive-container']}>
21
+ {iconSource && <Image source={iconSource} style={stylesCards['card-interactive-icon']} />}
22
+ <View>
23
+ <Text style={stylesCards['card-interactive-text']}>{title}</Text>
24
+ <View style={stylesCards['card-interactive-description']}>
25
+ {description && <Text style={stylesCards['card-interactive-subtext']}>{description}</Text>}
26
+ </View>
27
+ </View>
28
+ </View>
29
+ <Image source={icons.arrowRight} style={stylesCards['card-interactive-arrow']} />
30
+ </View>
31
+ </Card>
32
+ </TouchableRipple>
33
+ );
34
+ };
@@ -0,0 +1,40 @@
1
+ import { Card } from 'react-native-paper';
2
+ import { stylesCards } from '../../../assets/styles/elements/cards';
3
+ import { View, Text, TouchableHighlight } from 'react-native';
4
+ import { useState } from 'react';
5
+ import { ScrollView } from 'react-native-gesture-handler';
6
+
7
+ interface IfCardList {
8
+ options: { value: string | JSX.Element, id: string }[];
9
+ children?: React.ReactNode;
10
+ onSelectOption: (value: string) => void;
11
+ }
12
+
13
+ export const CardList = (props: IfCardList) => {
14
+ const { options, onSelectOption } = props;
15
+ const [selectedOption, setSelectOption] = useState(0);
16
+
17
+ return (
18
+ <ScrollView>
19
+ {options.map((option, index) => (
20
+ <TouchableHighlight
21
+ key={index}
22
+ onPress={() => {
23
+ setSelectOption(index);
24
+ onSelectOption(option.id);
25
+ }}
26
+ style={stylesCards['card-list-item']}
27
+ >
28
+ <Card
29
+ style={[
30
+ stylesCards['card-list'],
31
+ selectedOption === index ? stylesCards['card-list-selected'] : null,
32
+ ]}
33
+ >
34
+ <Text style={stylesCards['card-list-txt']}>{option.value}</Text>
35
+ </Card>
36
+ </TouchableHighlight>
37
+ ))}
38
+ </ScrollView>
39
+ );
40
+ };
@@ -0,0 +1,14 @@
1
+ import { TouchableWithoutFeedback, View, Image } from 'react-native';
2
+ import { icons } from '../../../assets/icons/_icons';
3
+ interface IFCheckboxComponent {
4
+ checked: boolean;
5
+ onChange: (value: boolean) => void;
6
+ }
7
+ export const CheckboxComponent = (props: IFCheckboxComponent) => {
8
+ const { checked, onChange } = props;
9
+ return (
10
+ <TouchableWithoutFeedback onPress={() => onChange(!checked)}>
11
+ <Image source={checked ? icons.checkbox : icons.checkboxOutline} />
12
+ </TouchableWithoutFeedback>
13
+ );
14
+ };
@@ -0,0 +1,36 @@
1
+ import { Button, Dialog, Icon, Portal } from 'react-native-paper';
2
+ import { stylesDialog } from '../../../assets/styles/elements/dialog';
3
+ import { ViewStyle, Image, ImageSourcePropType, View } from 'react-native';
4
+
5
+ interface IFDialogDown {
6
+ isVisible: boolean;
7
+ title: string;
8
+ children: any;
9
+ onDismiss: () => void;
10
+ style?: ViewStyle;
11
+ image?: ImageSourcePropType;
12
+ }
13
+
14
+ export const DialogDown = (props: IFDialogDown) => {
15
+ const { isVisible, title, children, onDismiss, style, image } = props;
16
+ return (
17
+ <Portal>
18
+ <Dialog style={[stylesDialog['dialog-down'], style]} visible={isVisible} onDismiss={onDismiss}>
19
+ <View style={stylesDialog['dialog-img']}>{image && <Image source={image} />}</View>
20
+
21
+ <View>
22
+ <Dialog.Title style={[stylesDialog['dialog-title']]}>{title}</Dialog.Title>
23
+ <Button onPress={onDismiss} style={stylesDialog['dialog-down-close']}>
24
+ <Icon
25
+ source="close"
26
+ color={stylesDialog['dialog-down-close-icon'].color}
27
+ size={stylesDialog['dialog-down-close-icon'].width}
28
+ />
29
+ </Button>
30
+ </View>
31
+
32
+ <Dialog.Content>{children}</Dialog.Content>
33
+ </Dialog>
34
+ </Portal>
35
+ );
36
+ };
@@ -0,0 +1,47 @@
1
+ import { Dialog, Portal, Text } from 'react-native-paper';
2
+ import { BtnOutlined, BtnContained } from '../../';
3
+ import { stylesDialog } from '../../../assets/styles/elements/dialog';
4
+ import { Image, View } from 'react-native';
5
+ import { icons } from '../../../assets/icons/_icons';
6
+
7
+ interface IFDialogIcon {
8
+ isVisible: boolean;
9
+ icon: 'error' | 'warning' | 'info' | 'success';
10
+ title: string;
11
+ text: JSX.Element | string;
12
+ textOk?: string;
13
+ textCancel?: string;
14
+ onDismiss: () => void;
15
+ onConfirm: () => void;
16
+ }
17
+
18
+ export const DialogGeneral = (props: IFDialogIcon) => {
19
+ const { isVisible, title, text, textCancel, textOk, icon, onDismiss, onConfirm } = props;
20
+
21
+ return (
22
+ <Portal>
23
+ <Dialog style={stylesDialog['dialog']} visible={isVisible} onDismiss={onDismiss}>
24
+ <View style={stylesDialog['dialog-container-icon']}>
25
+ <Image style={stylesDialog['dialog-icon']} source={icons[icon]} />
26
+ </View>
27
+ <Dialog.Title style={stylesDialog['dialog-title']}>{title}</Dialog.Title>
28
+ <Dialog.Content>
29
+ <Text style={stylesDialog['dialog-text']}>{text}</Text>
30
+ </Dialog.Content>
31
+ <Dialog.Actions style={stylesDialog['dialog-actions']}>
32
+ {textCancel && (
33
+ <BtnOutlined color="primary" size={!textOk ? 'xl' : 'sm'} onPress={onDismiss} text={textCancel} />
34
+ )}
35
+ {textOk && (
36
+ <BtnContained
37
+ color="primary"
38
+ size={!textCancel ? 'xl' : 'sm'}
39
+ onPress={onConfirm}
40
+ text={textOk}
41
+ />
42
+ )}
43
+ </Dialog.Actions>
44
+ </Dialog>
45
+ </Portal>
46
+ );
47
+ };
@@ -0,0 +1,84 @@
1
+ import { useState } from 'react';
2
+ import { View } from 'react-native';
3
+ import { Button, Divider, Menu, Portal } from 'react-native-paper';
4
+ import { BtnIcon } from '../buttons/BtnIcon';
5
+ import { icons } from '../../../assets/icons/_icons';
6
+ import { styleDropdown } from '../../../assets/styles/elements/dropdown';
7
+ import { theme } from '../../config/paper.config';
8
+ interface IFDropdown {
9
+ items: IFMenuItem[];
10
+ icon?: string;
11
+ label: string;
12
+ title?: string;
13
+ onPress: (value: string) => void;
14
+ }
15
+ interface IFMenuItem {
16
+ title: string;
17
+ icon?: string;
18
+ value: string;
19
+ divider?: boolean;
20
+ }
21
+ export const Dropdown = (props: IFDropdown) => {
22
+ const { items, icon, label, title, onPress } = props;
23
+ const [visible, setVisible] = useState(false);
24
+ const openMenu = () => setVisible(true);
25
+ const closeMenu = () => setVisible(false);
26
+
27
+ return (
28
+ <View style={styleDropdown['dropdown-container']}>
29
+ <Menu
30
+ anchorPosition="bottom"
31
+ contentStyle={{ backgroundColor: 'white', borderRadius: 16, padding: 16 }}
32
+ visible={visible}
33
+ onDismiss={closeMenu}
34
+ anchor={
35
+ <View style={styleDropdown['dropdown-menu']}>
36
+ <BtnIcon
37
+ labelStyle={styleDropdown['dropdown-label']}
38
+ contentStyle={styleDropdown['dropdown-label-content']}
39
+ icon={icon}
40
+ text={label}
41
+ direction={'left'}
42
+ onPress={openMenu}
43
+ />
44
+ <BtnIcon
45
+ labelStyle={styleDropdown['dropdown-label-arrow']}
46
+ contentStyle={styleDropdown['dropdown-label-width']}
47
+ icon={icons.arrowDropdown}
48
+ onPress={openMenu}
49
+ />
50
+ </View>
51
+ }
52
+ >
53
+ {title && (
54
+ <>
55
+ <Menu.Item titleStyle={styleDropdown['dropdown-menu-item']} title={title} />
56
+ <Divider
57
+ style={{
58
+ borderBottomColor: theme.colors.lightPrimary,
59
+ borderBottomWidth: 1,
60
+ }}
61
+ />
62
+ </>
63
+ )}
64
+ {items.map((item, index) => {
65
+ return (
66
+ <View key={index}>
67
+ <Menu.Item
68
+ titleStyle={styleDropdown['dropdown-menu-item']}
69
+ leadingIcon={item.icon}
70
+ onPress={() => {
71
+ closeMenu();
72
+ onPress(item.value);
73
+ }}
74
+ title={item.title}
75
+ />
76
+ {item.divider && <Divider />}
77
+ </View>
78
+ );
79
+ })}
80
+ </Menu>
81
+ <Portal>{visible && <View style={styleDropdown['dropdown-overlay']} />}</Portal>
82
+ </View>
83
+ );
84
+ };