dhre-ui-kit 0.0.3 → 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 (46) hide show
  1. package/package.json +1 -1
  2. package/src/assets/images/arrowLeft.svg +3 -0
  3. package/src/assets/images/caretDown.svg +3 -0
  4. package/src/assets/images/caretLeft.svg +3 -0
  5. package/src/assets/images/caretUp.svg +3 -0
  6. package/src/assets/images/circleTick.svg +3 -0
  7. package/src/assets/images/crossIcon.svg +3 -0
  8. package/src/assets/images/dotsThreeVertical.svg +5 -0
  9. package/src/assets/images/searchIcon.svg +4 -0
  10. package/src/assets/index.ts +20 -1
  11. package/src/components/accordion/Accordion.interface.ts +7 -0
  12. package/src/components/accordion/Accordion.styles.ts +28 -0
  13. package/src/components/accordion/Accordion.test.tsx +21 -0
  14. package/src/components/accordion/Accordion.tsx +64 -0
  15. package/src/components/accordion/index.ts +1 -0
  16. package/src/components/bottomDrawer/BottomDrawer.interface.ts +5 -0
  17. package/src/components/bottomDrawer/BottomDrawer.styles.ts +18 -10
  18. package/src/components/bottomDrawer/BottomDrawer.tsx +29 -12
  19. package/src/components/customHeader/CustomHeader.interface.tsx +10 -0
  20. package/src/components/customHeader/CustomHeader.styles.ts +24 -0
  21. package/src/components/customHeader/CustomHeader.test.tsx +14 -0
  22. package/src/components/customHeader/CustomHeader.tsx +46 -0
  23. package/src/components/customHeader/index.ts +1 -0
  24. package/src/components/customSearchBar/CustomSearchBar.interface.ts +9 -0
  25. package/src/components/customSearchBar/CustomSearchBar.styles.ts +23 -0
  26. package/src/components/customSearchBar/CustomSearchBar.test.tsx +19 -0
  27. package/src/components/customSearchBar/CustomSearchBar.tsx +55 -0
  28. package/src/components/customSearchBar/index.ts +1 -0
  29. package/src/components/customTypography/CustomTypography.test.tsx +12 -0
  30. package/src/components/customTypography/CustomTypography.tsx +5 -3
  31. package/src/components/swipableList/SwipableList.interface.ts +37 -0
  32. package/src/components/swipableList/SwipableList.styles.ts +24 -0
  33. package/src/components/{notification/Notification.test.tsx → swipableList/SwipableList.test.tsx} +20 -21
  34. package/src/components/swipableList/SwipableList.tsx +106 -0
  35. package/src/components/swipableList/index.ts +1 -0
  36. package/src/components/toast/Toast.interface.ts +8 -0
  37. package/src/components/toast/Toast.styles.ts +40 -0
  38. package/src/components/toast/Toast.test.tsx +21 -0
  39. package/src/components/toast/Toast.tsx +89 -0
  40. package/src/components/toast/index.ts +1 -0
  41. package/src/index.ts +5 -0
  42. package/src/theme/fonts.ts +4 -4
  43. package/src/utils/stylehelper.ts +1 -1
  44. package/src/components/notification/Notification.interface.ts +0 -61
  45. package/src/components/notification/Notification.styles.ts +0 -33
  46. package/src/components/notification/Notification.tsx +0 -156
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dhre-ui-kit",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "main": "src/index.ts",
5
5
  "files": [
6
6
  "src",
@@ -0,0 +1,3 @@
1
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M15.6006 4.1864C15.9252 4.46466 15.9628 4.9534 15.6846 5.27804L9.92289 12L15.6846 18.722C15.9628 19.0466 15.9252 19.5353 15.6006 19.8136C15.276 20.0919 14.7872 20.0543 14.5089 19.7296L8.31541 12.5038C8.0669 12.2139 8.0669 11.7861 8.31541 11.4962L14.5089 4.27037C14.7872 3.94573 15.276 3.90813 15.6006 4.1864Z" fill="white"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg width="20" height="21" viewBox="0 0 20 21" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M16.25 8L10 14.25L3.75 8" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M15 19.5L7.5 12L15 4.5" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg width="20" height="21" viewBox="0 0 20 21" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M3.75 13L10 6.75L16.25 13" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M14.0306 7.21937C14.1004 7.28903 14.1557 7.37175 14.1934 7.46279C14.2312 7.55384 14.2506 7.65144 14.2506 7.75C14.2506 7.84856 14.2312 7.94616 14.1934 8.03721C14.1557 8.12825 14.1004 8.21097 14.0306 8.28063L8.78063 13.5306C8.71097 13.6004 8.62826 13.6557 8.53721 13.6934C8.44616 13.7312 8.34857 13.7506 8.25 13.7506C8.15144 13.7506 8.05385 13.7312 7.9628 13.6934C7.87175 13.6557 7.78903 13.6004 7.71938 13.5306L5.46938 11.2806C5.32865 11.1399 5.24959 10.949 5.24959 10.75C5.24959 10.551 5.32865 10.3601 5.46938 10.2194C5.61011 10.0786 5.80098 9.99958 6 9.99958C6.19903 9.99958 6.3899 10.0786 6.53063 10.2194L8.25 11.9397L12.9694 7.21937C13.039 7.14964 13.1218 7.09432 13.2128 7.05658C13.3038 7.01884 13.4014 6.99941 13.5 6.99941C13.5986 6.99941 13.6962 7.01884 13.7872 7.05658C13.8783 7.09432 13.961 7.14964 14.0306 7.21937ZM19.5 10C19.5 11.9284 18.9282 13.8134 17.8568 15.4168C16.7855 17.0202 15.2627 18.2699 13.4812 19.0078C11.6996 19.7458 9.73919 19.9389 7.84787 19.5627C5.95656 19.1865 4.21927 18.2579 2.85571 16.8943C1.49215 15.5307 0.563554 13.7934 0.187348 11.9021C-0.188858 10.0108 0.00422448 8.05042 0.742179 6.26884C1.48013 4.48726 2.72982 2.96452 4.33319 1.89317C5.93657 0.821828 7.82164 0.25 9.75 0.25C12.335 0.25273 14.8134 1.28084 16.6413 3.10872C18.4692 4.93661 19.4973 7.41498 19.5 10ZM18 10C18 8.3683 17.5161 6.77325 16.6096 5.41655C15.7031 4.05984 14.4146 3.00242 12.9071 2.37799C11.3997 1.75357 9.74085 1.59019 8.14051 1.90852C6.54017 2.22685 5.07016 3.01259 3.91637 4.16637C2.76259 5.32015 1.97685 6.79016 1.65853 8.3905C1.3402 9.99085 1.50358 11.6496 2.128 13.1571C2.75242 14.6646 3.80984 15.9531 5.16655 16.8596C6.52326 17.7661 8.11831 18.25 9.75 18.25C11.9373 18.2475 14.0343 17.3775 15.5809 15.8309C17.1275 14.2843 17.9975 12.1873 18 10Z" fill="white"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M17.6569 8.03174C17.9247 7.76395 17.9247 7.32978 17.6569 7.06199C17.3892 6.7942 16.955 6.79419 16.6872 7.06197L12 11.749L7.31294 7.06187C7.04516 6.79407 6.61099 6.79407 6.34319 7.06185C6.0754 7.32963 6.0754 7.76381 6.34318 8.0316L11.0302 12.7188L6.34307 17.4058C6.07528 17.6736 6.07527 18.1077 6.34305 18.3755C6.61084 18.6433 7.04501 18.6433 7.3128 18.3755L11.9999 13.6885L16.687 18.3757C16.9548 18.6435 17.3889 18.6435 17.6567 18.3757C17.9245 18.108 17.9245 17.6738 17.6567 17.406L12.9697 12.7188L17.6569 8.03174Z" fill="white"/>
3
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M13.4375 6C13.4375 6.79391 12.7939 7.4375 12 7.4375C11.2061 7.4375 10.5625 6.79391 10.5625 6C10.5625 5.20609 11.2061 4.5625 12 4.5625C12.7939 4.5625 13.4375 5.20609 13.4375 6Z" fill="white" stroke="white" stroke-width="0.125"/>
3
+ <path d="M13.4375 12C13.4375 12.7939 12.7939 13.4375 12 13.4375C11.2061 13.4375 10.5625 12.7939 10.5625 12C10.5625 11.2061 11.2061 10.5625 12 10.5625C12.7939 10.5625 13.4375 11.2061 13.4375 12Z" fill="white" stroke="white" stroke-width="0.125"/>
4
+ <path d="M12 19.5C12.8284 19.5 13.5 18.8284 13.5 18C13.5 17.1716 12.8284 16.5 12 16.5C11.1716 16.5 10.5 17.1716 10.5 18C10.5 18.8284 11.1716 19.5 12 19.5Z" fill="white"/>
5
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M10.875 19.4688C15.2242 19.4688 18.75 15.943 18.75 11.5938C18.75 7.24451 15.2242 3.71875 10.875 3.71875C6.52576 3.71875 3 7.24451 3 11.5938C3 15.943 6.52576 19.4688 10.875 19.4688Z" stroke="#A7A7A7" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
3
+ <path d="M16.4438 17.1625L21 21.7188" stroke="#A7A7A7" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
4
+ </svg>
@@ -1,2 +1,21 @@
1
1
  import CalenderDots from './images/calenderDots.svg';
2
- export {CalenderDots};
2
+ import SearchIcon from './images/searchIcon.svg';
3
+ import CrossIcon from './images/crossIcon.svg';
4
+ import CaretUp from './images/caretUp.svg';
5
+ import CaretDown from './images/caretDown.svg';
6
+ import CaretLeft from './images/caretLeft.svg';
7
+ import HeaderIcon from './images/dotsThreeVertical.svg';
8
+ import CircleTick from './images/circleTick.svg';
9
+ import ArrowLeft from './images/arrowLeft.svg';
10
+
11
+ export {
12
+ CalenderDots,
13
+ SearchIcon,
14
+ CrossIcon,
15
+ CaretUp,
16
+ CaretDown,
17
+ CaretLeft,
18
+ HeaderIcon,
19
+ CircleTick,
20
+ ArrowLeft,
21
+ };
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+
3
+ export interface AccordionProps {
4
+ title: string;
5
+ children: React.ReactNode;
6
+ testId?: string;
7
+ }
@@ -0,0 +1,28 @@
1
+ import {StyleSheet} from 'react-native';
2
+ import {
3
+ horizontalScale,
4
+ moderateScale,
5
+ verticalScale,
6
+ } from '../../utils/stylehelper';
7
+
8
+ const styles = StyleSheet.create({
9
+ container: {
10
+ paddingVertical: verticalScale(16),
11
+ borderBottomWidth: moderateScale(1),
12
+ borderBottomColor: '#282828',
13
+ },
14
+ header: {
15
+ flexDirection: 'row',
16
+ justifyContent: 'space-between',
17
+ alignItems: 'center',
18
+ },
19
+ title: {flex: 1, color: '#FFFFFF'},
20
+ iconStyle: {marginLeft: horizontalScale(20)},
21
+ content: {
22
+ overflow: 'scroll',
23
+ marginTop: verticalScale(16),
24
+ marginHorizontal: horizontalScale(16),
25
+ },
26
+ });
27
+
28
+ export default styles;
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import {render, fireEvent, waitFor} from '@testing-library/react-native';
3
+ import Accordion from './Accordion';
4
+ import CustomTypography from '../customTypography/CustomTypography';
5
+
6
+ describe('Accordion Component', () => {
7
+ test('Component renders correctly', async () => {
8
+ const {getByTestId, getByText} = render(
9
+ <Accordion title="Test Title">
10
+ <CustomTypography variant="B4_REGULAR" text="Test Content" />
11
+ </Accordion>,
12
+ );
13
+
14
+ expect(getByTestId('ACCORDION')).toBeTruthy();
15
+ expect(getByText('Test Title')).toBeTruthy();
16
+ fireEvent.press(getByText('Test Title'));
17
+ await waitFor(() => {
18
+ expect(getByText('Test Content')).toBeTruthy();
19
+ });
20
+ });
21
+ });
@@ -0,0 +1,64 @@
1
+ import React, {useEffect, useRef, useState} from 'react';
2
+ import {View, Animated, LayoutChangeEvent, Pressable} from 'react-native';
3
+ import CustomTypography from '../customTypography/CustomTypography';
4
+ import {CaretDown, CaretUp} from '../../assets';
5
+ import {moderateScale} from '../../utils/stylehelper';
6
+ import {AccordionProps} from './Accordion.interface';
7
+ import styles from './Accordion.styles';
8
+
9
+ const Accordion = ({title, testId = 'ACCORDION', children}: AccordionProps) => {
10
+ const contentRef = useRef<View>(null);
11
+ const [animation] = useState(new Animated.Value(0));
12
+ const [contentHeight, setContentHeight] = useState(0);
13
+ const [expanded, setExpanded] = useState(false);
14
+
15
+ useEffect(() => {
16
+ if (contentRef.current) {
17
+ contentRef.current.measure((x, y, width, height) => {
18
+ setContentHeight(height);
19
+ });
20
+ }
21
+ }, [expanded]);
22
+
23
+ const toggleAccordion = () => {
24
+ Animated.timing(animation, {
25
+ toValue: expanded ? 0 : 1,
26
+ duration: 300,
27
+ useNativeDriver: false,
28
+ }).start();
29
+ setExpanded(!expanded);
30
+ };
31
+
32
+ const cardHeight = animation.interpolate({
33
+ inputRange: [0, 1],
34
+ outputRange: [0, contentHeight],
35
+ });
36
+
37
+ return (
38
+ <View style={styles.container} testID={testId}>
39
+ <Pressable style={styles.header} onPress={toggleAccordion}>
40
+ <CustomTypography
41
+ variant={'B4_REGULAR'}
42
+ text={title}
43
+ style={styles.title}
44
+ />
45
+ {React.cloneElement(expanded ? <CaretUp /> : <CaretDown />, {
46
+ width: moderateScale(20),
47
+ height: moderateScale(20),
48
+ style: styles.iconStyle,
49
+ })}
50
+ </Pressable>
51
+ <Animated.View style={[styles.content, {height: cardHeight}]}>
52
+ <View
53
+ ref={contentRef}
54
+ onLayout={(event: LayoutChangeEvent) => {
55
+ setContentHeight(event.nativeEvent.layout.height);
56
+ }}>
57
+ {children}
58
+ </View>
59
+ </Animated.View>
60
+ </View>
61
+ );
62
+ };
63
+
64
+ export default Accordion;
@@ -0,0 +1 @@
1
+ export {default} from './Accordion';
@@ -9,4 +9,9 @@ export interface BottomDrawerProps {
9
9
  testID?: string;
10
10
  style?: ViewStyle;
11
11
  modalContainerStyle?: ViewStyle;
12
+ leftIcon?: React.ReactElement;
13
+ rightIcon?: React.ReactElement;
14
+ showLeftIcon?: boolean;
15
+ showRightIcon?: boolean;
16
+ onLeftIconPress?: () => void;
12
17
  }
@@ -1,4 +1,3 @@
1
- import {DHRE_COLORS_TEXT, DHRE_COLORS_BG} from '../../theme/colors';
2
1
  import {
3
2
  horizontalScale,
4
3
  moderateScale,
@@ -9,23 +8,32 @@ import {StyleSheet} from 'react-native';
9
8
  const styles = StyleSheet.create({
10
9
  mainContainer: {
11
10
  flex: 1,
12
- backgroundColor: DHRE_COLORS_TEXT.DH_BLACK,
13
11
  justifyContent: 'flex-end',
14
12
  },
15
- modalContainer: {padding: moderateScale(16)},
13
+ modalContainer: {
14
+ flex: 0.5,
15
+ backgroundColor: '#000',
16
+ paddingTop: moderateScale(8),
17
+ paddingHorizontal: moderateScale(16),
18
+ borderTopLeftRadius: moderateScale(22),
19
+ borderTopRightRadius: moderateScale(22),
20
+ },
16
21
  separator: {
17
- height: verticalScale(2),
18
- width: horizontalScale(40),
22
+ height: verticalScale(3),
23
+ width: horizontalScale(32),
19
24
  alignSelf: 'center',
20
- backgroundColor: DHRE_COLORS_BG.DH_GREY1,
21
- marginBottom: verticalScale(16),
25
+ backgroundColor: '#A7A7A7',
22
26
  borderRadius: moderateScale(25),
23
27
  },
24
- headderContainer: {
28
+ headerContainer: {
25
29
  flexDirection: 'row',
26
- justifyContent: 'center',
27
- marginVertical: verticalScale(4),
30
+ justifyContent: 'space-between',
31
+ alignItems: 'center',
32
+ marginTop: verticalScale(24),
28
33
  },
34
+ title: {flex: 1, color: '#fff'},
35
+ leftIconStyle: {marginRight: 8},
36
+ rightIconStyle: {marginLeft: 8},
29
37
  });
30
38
 
31
39
  export default styles;
@@ -3,16 +3,22 @@ import {View, Modal} from 'react-native';
3
3
  import {BottomDrawerProps} from './BottomDrawer.interface';
4
4
  import styles from './BottomDrawer.styles';
5
5
  import CustomTypography from '../customTypography/CustomTypography';
6
+ import {ArrowLeft, CrossIcon} from '../../assets';
7
+ import {moderateScale} from '../../utils/stylehelper';
6
8
 
7
9
  const BottomDrawer: React.FC<BottomDrawerProps> = ({
8
10
  isModalVisible,
9
11
  toggleModal,
10
- isFullScreen = true,
11
12
  children,
12
13
  title,
13
14
  testID = 'BOTTOM-DRAWER',
14
15
  style,
15
16
  modalContainerStyle,
17
+ showLeftIcon = false,
18
+ showRightIcon = true,
19
+ leftIcon = <ArrowLeft />,
20
+ rightIcon = <CrossIcon />,
21
+ onLeftIconPress,
16
22
  }) => {
17
23
  return (
18
24
  <Modal
@@ -21,19 +27,30 @@ const BottomDrawer: React.FC<BottomDrawerProps> = ({
21
27
  visible={isModalVisible}
22
28
  onRequestClose={toggleModal}>
23
29
  <View style={[styles.mainContainer, style]} testID={testID}>
24
- <View
25
- style={[
26
- {
27
- flex: isFullScreen ? 1 : 0.5,
28
- },
29
- styles.modalContainer,
30
- modalContainerStyle,
31
- ]}>
30
+ <View style={[styles.modalContainer, modalContainerStyle]}>
32
31
  <View style={styles.separator} />
33
- <View style={styles.headderContainer}>
34
- <CustomTypography variant="H7bold" text={title} />
32
+ <View style={styles.headerContainer}>
33
+ {showLeftIcon &&
34
+ React.cloneElement(leftIcon, {
35
+ width: moderateScale(24),
36
+ height: moderateScale(24),
37
+ style: styles.leftIconStyle,
38
+ onPress: onLeftIconPress,
39
+ })}
40
+ <CustomTypography
41
+ variant="B2_REGULAR"
42
+ text={title}
43
+ style={styles.title}
44
+ />
45
+ {showRightIcon &&
46
+ React.cloneElement(rightIcon, {
47
+ width: moderateScale(24),
48
+ height: moderateScale(24),
49
+ style: styles.rightIconStyle,
50
+ onPress: toggleModal,
51
+ })}
35
52
  </View>
36
- <View>{children}</View>
53
+ {children}
37
54
  </View>
38
55
  </View>
39
56
  </Modal>
@@ -0,0 +1,10 @@
1
+ export interface CustomHeaderProps {
2
+ title: string;
3
+ testId?: string;
4
+ leftIcon?: React.ReactElement;
5
+ rightIcon?: React.ReactElement;
6
+ showLeftIcon?: boolean;
7
+ showRightIcon?: boolean;
8
+ onLeftPress?: () => void;
9
+ onRightPress?: () => void;
10
+ }
@@ -0,0 +1,24 @@
1
+ import {StyleSheet} from 'react-native';
2
+ import {horizontalScale, verticalScale} from '../../utils/stylehelper';
3
+
4
+ const styles = StyleSheet.create({
5
+ container: {
6
+ flexDirection: 'row',
7
+ justifyContent: 'space-between',
8
+ paddingHorizontal: horizontalScale(16),
9
+ paddingTop: verticalScale(74),
10
+ paddingBottom: verticalScale(16),
11
+ backgroundColor: '#000',
12
+ },
13
+ headderContainer: {
14
+ flexDirection: 'row',
15
+ alignItems: 'center',
16
+ },
17
+ headerTitle: {
18
+ color: '#FFFFFF',
19
+ },
20
+ leftIconStyle: {marginRight: horizontalScale(9)},
21
+ rightIconStyle: {marginLeft: horizontalScale(8)},
22
+ });
23
+
24
+ export default styles;
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import {render} from '@testing-library/react-native';
3
+ import CustomHeader from './CustomHeader';
4
+
5
+ describe('Custom Header Component', () => {
6
+ it('Component renders correctly', () => {
7
+ const {getByTestId, getByText} = render(
8
+ <CustomHeader title="Header Title" />,
9
+ );
10
+
11
+ expect(getByTestId('CUSTOM-HEADER')).toBeTruthy();
12
+ expect(getByText('Header Title')).toBeTruthy();
13
+ });
14
+ });
@@ -0,0 +1,46 @@
1
+ import React from 'react';
2
+ import {View} from 'react-native';
3
+ import {CaretLeft, HeaderIcon} from '../../assets';
4
+ import CustomTypography from '../customTypography/CustomTypography';
5
+ import {moderateScale} from '../../utils/stylehelper';
6
+ import styles from './CustomHeader.styles';
7
+ import {CustomHeaderProps} from './CustomHeader.interface';
8
+
9
+ const CustomHeader = ({
10
+ title,
11
+ testId = 'CUSTOM-HEADER',
12
+ leftIcon = <CaretLeft />,
13
+ rightIcon = <HeaderIcon />,
14
+ showLeftIcon = true,
15
+ showRightIcon = true,
16
+ onLeftPress,
17
+ onRightPress,
18
+ }: CustomHeaderProps) => {
19
+ return (
20
+ <View style={styles.container} testID={testId}>
21
+ <View style={styles.headderContainer}>
22
+ {showLeftIcon &&
23
+ React.cloneElement(leftIcon, {
24
+ width: moderateScale(24),
25
+ height: moderateScale(24),
26
+ onPress: onLeftPress,
27
+ style: styles.leftIconStyle,
28
+ })}
29
+ <CustomTypography
30
+ variant={'B2_REGULAR'}
31
+ text={title}
32
+ style={styles.headerTitle}
33
+ />
34
+ </View>
35
+ {showRightIcon &&
36
+ React.cloneElement(rightIcon, {
37
+ width: moderateScale(24),
38
+ height: moderateScale(24),
39
+ onPress: onRightPress,
40
+ style: styles.rightIconStyle,
41
+ })}
42
+ </View>
43
+ );
44
+ };
45
+
46
+ export default CustomHeader;
@@ -0,0 +1 @@
1
+ export {default} from './CustomHeader';
@@ -0,0 +1,9 @@
1
+ import {TextInputProps, ViewStyle} from 'react-native';
2
+
3
+ export interface CustomSearchBarProps extends TextInputProps {
4
+ height?: number;
5
+ testID?: string;
6
+ disabled?: boolean;
7
+ inputContainerStyle?: ViewStyle;
8
+ handleOnChangeText?: (text: string) => void;
9
+ }
@@ -0,0 +1,23 @@
1
+ import {StyleSheet} from 'react-native';
2
+ import {FONT_STYLES} from '../../theme/fonts';
3
+ import {horizontalScale, moderateScale} from '../../utils/stylehelper';
4
+
5
+ const styles = StyleSheet.create({
6
+ inputContainer: {
7
+ flexDirection: 'row',
8
+ justifyContent: 'center',
9
+ alignItems: 'center',
10
+ paddingHorizontal: horizontalScale(16),
11
+ borderRadius: moderateScale(8),
12
+ borderWidth: moderateScale(1),
13
+ },
14
+ input: {
15
+ flex: 1,
16
+ ...FONT_STYLES.B3_REGULAR,
17
+ color: '#fff',
18
+ },
19
+ crossIconStyle: {marginLeft: horizontalScale(8)},
20
+ searchIconStyle: {marginRight: horizontalScale(8)},
21
+ });
22
+
23
+ export default styles;
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import {it} from '@jest/globals';
3
+ import {fireEvent, render} from '@testing-library/react-native';
4
+ import CustomSearchBar from './CustomSearchBar';
5
+
6
+ const mockProps = {
7
+ testID: 'CUSTOM-SEARCH-BAR',
8
+ disabled: false,
9
+ handelOnChangeText: jest.fn(),
10
+ };
11
+
12
+ describe('Custom search bar component', () => {
13
+ it('Component renders correctly', () => {
14
+ const {getByTestId} = render(<CustomSearchBar {...mockProps} />);
15
+ expect(getByTestId(mockProps.testID)).toBeTruthy();
16
+ const textInput = getByTestId('CUSTOM-SEARCH-BAR-INPUT');
17
+ fireEvent.changeText(textInput, 'test@example.com');
18
+ });
19
+ });
@@ -0,0 +1,55 @@
1
+ import React, {useState} from 'react';
2
+ import {TextInput, View} from 'react-native';
3
+ import {CrossIcon, SearchIcon} from '../../assets';
4
+ import {moderateScale, verticalScale} from '../../utils/stylehelper';
5
+ import {CustomSearchBarProps} from './CustomSearchBar.interface';
6
+ import styles from './CustomSearchBar.styles';
7
+
8
+ const CustomSearchBar = ({
9
+ height = 40,
10
+ disabled = false,
11
+ testID = 'CUSTOM-SEARCH-BAR',
12
+ inputContainerStyle,
13
+ handleOnChangeText,
14
+ ...props
15
+ }: CustomSearchBarProps) => {
16
+ const [value, setValue] = useState('');
17
+ return (
18
+ <View
19
+ testID={testID}
20
+ style={[
21
+ styles.inputContainer,
22
+ {
23
+ height: verticalScale(height),
24
+ borderColor: disabled ? '#4F4F4F' : value ? '#fff' : '#A7A7A7',
25
+ },
26
+ inputContainerStyle,
27
+ ]}>
28
+ {React.cloneElement(<SearchIcon />, {
29
+ width: moderateScale(24),
30
+ height: moderateScale(24),
31
+ style: styles.searchIconStyle,
32
+ })}
33
+ <TextInput
34
+ {...props}
35
+ testID={`${testID}-INPUT`}
36
+ style={styles.input}
37
+ editable={!disabled}
38
+ value={value}
39
+ placeholderTextColor={disabled ? '#686868' : '#A7A7A7'}
40
+ onChangeText={val => {
41
+ setValue(val);
42
+ handleOnChangeText?.(val);
43
+ }}
44
+ />
45
+ {value &&
46
+ React.cloneElement(<CrossIcon onPress={() => setValue('')} />, {
47
+ width: moderateScale(24),
48
+ height: moderateScale(24),
49
+ style: styles.crossIconStyle,
50
+ })}
51
+ </View>
52
+ );
53
+ };
54
+
55
+ export default CustomSearchBar;
@@ -0,0 +1 @@
1
+ export {default} from './CustomSearchBar';
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import {render} from '@testing-library/react-native';
3
+ import CustomTypography from './CustomTypography';
4
+
5
+ describe('CustomTypography Component', () => {
6
+ it('renders text correctly', () => {
7
+ const {getByTestId} = render(
8
+ <CustomTypography variant={'H1_BOLD'} text={'TESTING TEXT'} />,
9
+ );
10
+ expect(getByTestId('CUSTOM_TYPOGRAPHY')).toBeTruthy();
11
+ });
12
+ });
@@ -1,22 +1,24 @@
1
1
  import React from 'react';
2
- import {FONT_STYLES} from '../../theme/fonts';
3
2
  import {Text, TextProps} from 'react-native';
3
+ import {FONT_STYLES} from '../../theme/fonts';
4
4
 
5
5
  interface TypoTextProps extends TextProps {
6
- variant: keyof typeof FONT_STYLES | string;
6
+ variant: keyof typeof FONT_STYLES;
7
7
  text?: string;
8
+ testID?: string;
8
9
  }
9
10
 
10
11
  const CustomTypography: React.FC<TypoTextProps> = ({
11
12
  variant,
12
13
  style,
13
14
  text,
15
+ testID = 'CUSTOM_TYPOGRAPHY',
14
16
  ...props
15
17
  }) => {
16
18
  const textStyle = FONT_STYLES[variant];
17
19
 
18
20
  return (
19
- <Text testID="Typo-Text" style={[textStyle, style]} {...props}>
21
+ <Text testID={testID} style={[textStyle, style]} {...props}>
20
22
  {text}
21
23
  </Text>
22
24
  );
@@ -0,0 +1,37 @@
1
+ import {ReactNode} from 'react';
2
+ import {ViewStyle} from 'react-native';
3
+
4
+ export interface ListItem {
5
+ id: string;
6
+ title: string;
7
+ isPinned: boolean;
8
+ isRead: boolean;
9
+ }
10
+
11
+ export interface ActionButtonProps {
12
+ icon: ReactNode;
13
+ title: string;
14
+ onPress: () => void;
15
+ style?: object;
16
+ testID: string;
17
+ }
18
+
19
+ export interface SwipableListProps {
20
+ data: ListItem[];
21
+ testId?: string;
22
+ renderItem: (item: ListItem) => ReactNode;
23
+ leftPrimaryActionIcon?: ReactNode;
24
+ leftPrimaryActionTitle?: string;
25
+ leftPrimaryActionHandler?: (id: string) => void;
26
+ leftPrimaryActionStyle?: ViewStyle;
27
+ leftSecondaryActionIcon?: ReactNode;
28
+ leftSecondaryActionTitle?: string;
29
+ leftSecondaryActionHandler?: (id: string) => void;
30
+ leftSecondaryActionStyle?: ViewStyle;
31
+ rightPrimaryActionIcon?: ReactNode;
32
+ rightPrimaryActionTitle?: string;
33
+ rightPrimaryActionHandler?: (id: string) => void;
34
+ rightPrimaryActionStyle?: ViewStyle;
35
+ itemStyle?: ViewStyle;
36
+ titleStyle?: ViewStyle;
37
+ }
@@ -0,0 +1,24 @@
1
+ import {moderateScale, verticalScale} from '../../utils/stylehelper';
2
+ import {StyleSheet} from 'react-native';
3
+
4
+ export const styles = StyleSheet.create({
5
+ container: {
6
+ flex: 1,
7
+ },
8
+ actionButton: {
9
+ justifyContent: 'center',
10
+ alignItems: 'center',
11
+ padding: moderateScale(24),
12
+ },
13
+ leftActions: {
14
+ flexDirection: 'row',
15
+ justifyContent: 'flex-start',
16
+ },
17
+ rightActions: {
18
+ flexDirection: 'row',
19
+ justifyContent: 'flex-end',
20
+ },
21
+ seprator: {
22
+ height: verticalScale(16),
23
+ },
24
+ });