dhre-ui-kit 0.0.1

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 (102) hide show
  1. package/README.md +1 -0
  2. package/package.json +104 -0
  3. package/src/App.tsx +146 -0
  4. package/src/assets/images/calenderDots.svg +1 -0
  5. package/src/assets/index.ts +2 -0
  6. package/src/components/autoOtpReader/AutoOtpReader.test.tsx +56 -0
  7. package/src/components/autoOtpReader/AutoOtpReader.tsx +79 -0
  8. package/src/components/autoOtpReader/index.ts +1 -0
  9. package/src/components/badge/Badge.styles.ts +20 -0
  10. package/src/components/badge/Badge.test.tsx +45 -0
  11. package/src/components/badge/Badge.tsx +47 -0
  12. package/src/components/badge/index.ts +1 -0
  13. package/src/components/bottomDrawer/BottomDrawer.interface.ts +12 -0
  14. package/src/components/bottomDrawer/BottomDrawer.styles.ts +31 -0
  15. package/src/components/bottomDrawer/BottomDrawer.test.tsx +19 -0
  16. package/src/components/bottomDrawer/BottomDrawer.tsx +43 -0
  17. package/src/components/bottomDrawer/index.ts +1 -0
  18. package/src/components/button/Button.interface.ts +18 -0
  19. package/src/components/button/Button.styles.ts +78 -0
  20. package/src/components/button/Button.test.tsx +43 -0
  21. package/src/components/button/Button.tsx +53 -0
  22. package/src/components/button/index.ts +1 -0
  23. package/src/components/cards/Cards.interface.ts +13 -0
  24. package/src/components/cards/Cards.styles.ts +59 -0
  25. package/src/components/cards/Cards.test.tsx +41 -0
  26. package/src/components/cards/Cards.tsx +69 -0
  27. package/src/components/cards/index.ts +1 -0
  28. package/src/components/checkBox/CheckBox.interface.ts +10 -0
  29. package/src/components/checkBox/CheckBox.styles.ts +36 -0
  30. package/src/components/checkBox/CheckBox.test.tsx +46 -0
  31. package/src/components/checkBox/CheckBox.tsx +42 -0
  32. package/src/components/checkBox/index.ts +1 -0
  33. package/src/components/customDropdown/CustomDropdown.interface.ts +15 -0
  34. package/src/components/customDropdown/CustomDropdown.styles.tsx +46 -0
  35. package/src/components/customDropdown/CustomDropdown.test.tsx +30 -0
  36. package/src/components/customDropdown/CustomDropdown.tsx +106 -0
  37. package/src/components/customDropdown/index.ts +1 -0
  38. package/src/components/customInputText/CustomInputText.interface.ts +20 -0
  39. package/src/components/customInputText/CustomInputText.styles.ts +56 -0
  40. package/src/components/customInputText/CustomInputText.test.tsx +37 -0
  41. package/src/components/customInputText/CustomInputText.tsx +120 -0
  42. package/src/components/customInputText/index.ts +1 -0
  43. package/src/components/customText/CustomText.tsx +31 -0
  44. package/src/components/customText/index.ts +1 -0
  45. package/src/components/customTooltip/CustomTooltip.interface.ts +14 -0
  46. package/src/components/customTooltip/CustomTooltip.styles.ts +23 -0
  47. package/src/components/customTooltip/CustomTooltip.test.tsx +18 -0
  48. package/src/components/customTooltip/CustomTooltip.tsx +46 -0
  49. package/src/components/customTooltip/index.ts +1 -0
  50. package/src/components/customTypography/CustomTypography.tsx +25 -0
  51. package/src/components/fileUpload/FileUpload.styles.ts +41 -0
  52. package/src/components/fileUpload/FileUpload.test.tsx +39 -0
  53. package/src/components/fileUpload/FileUpload.tsx +65 -0
  54. package/src/components/fileUpload/index.ts +1 -0
  55. package/src/components/notification/Notification.interface.ts +61 -0
  56. package/src/components/notification/Notification.styles.ts +33 -0
  57. package/src/components/notification/Notification.test.tsx +116 -0
  58. package/src/components/notification/Notification.tsx +156 -0
  59. package/src/components/pdfView/PdfView.test.tsx +10 -0
  60. package/src/components/pdfView/PdfView.tsx +18 -0
  61. package/src/components/pdfView/index.ts +1 -0
  62. package/src/components/popup/PopUp.interface.ts +9 -0
  63. package/src/components/popup/PopUp.styles.ts +52 -0
  64. package/src/components/popup/PopUp.test.tsx +35 -0
  65. package/src/components/popup/PopUp.tsx +60 -0
  66. package/src/components/popup/index.ts +1 -0
  67. package/src/components/progressBar/ProgressBar.test.tsx +78 -0
  68. package/src/components/progressBar/ProgressBar.tsx +93 -0
  69. package/src/components/progressBar/index.ts +1 -0
  70. package/src/components/property360View/Property360View.test.tsx +24 -0
  71. package/src/components/property360View/Property360View.tsx +19 -0
  72. package/src/components/property360View/index.ts +1 -0
  73. package/src/components/rating/Rating.styles.ts +13 -0
  74. package/src/components/rating/Rating.test.tsx +61 -0
  75. package/src/components/rating/Rating.tsx +96 -0
  76. package/src/components/rating/index.ts +1 -0
  77. package/src/components/tabs/Tabs.interface.ts +13 -0
  78. package/src/components/tabs/Tabs.styles.ts +36 -0
  79. package/src/components/tabs/Tabs.test.tsx +20 -0
  80. package/src/components/tabs/Tabs.tsx +65 -0
  81. package/src/components/tabs/index.ts +1 -0
  82. package/src/components/tags/Tags.interface.ts +12 -0
  83. package/src/components/tags/Tags.styles.ts +36 -0
  84. package/src/components/tags/Tags.test.tsx +22 -0
  85. package/src/components/tags/Tags.tsx +76 -0
  86. package/src/components/tags/index.ts +1 -0
  87. package/src/components/toggleButton/ToggleButton.styles.ts +40 -0
  88. package/src/components/toggleButton/ToggleButton.test.tsx +33 -0
  89. package/src/components/toggleButton/ToggleButton.tsx +78 -0
  90. package/src/components/toggleButton/index.ts +1 -0
  91. package/src/index.ts +19 -0
  92. package/src/theme/ThemeContext.tsx +32 -0
  93. package/src/theme/colors.ts +156 -0
  94. package/src/theme/fonts.ts +303 -0
  95. package/src/theme/themes.ts +20 -0
  96. package/src/theme/withThemeProvider.tsx +14 -0
  97. package/src/utils/appEnum.ts +17 -0
  98. package/src/utils/commonStyles.ts +17 -0
  99. package/src/utils/constants.ts +17 -0
  100. package/src/utils/deviceUtils.ts +9 -0
  101. package/src/utils/regex.ts +1 -0
  102. package/src/utils/stylehelper.ts +13 -0
@@ -0,0 +1,93 @@
1
+ import commonStyles from '../../utils/commonStyles';
2
+ import React, {useEffect} from 'react';
3
+ import {View} from 'react-native';
4
+ import * as Progress from 'react-native-progress';
5
+ import {ShapeType} from '../../utils/appEnum';
6
+
7
+ interface CustomProgressBarProps {
8
+ value: number; // Current progress value (0 to 100)
9
+ type: ShapeType.LINE | ShapeType.CIRCLE; // Type of progress bar
10
+ width: number; // Width of the progress bar
11
+ height?: number; // Optional height (default behavior depends on library)
12
+ fillColor: string; // Color of the progress fill
13
+ unfilledColor: string; // Color of the unfilled area
14
+ borderWidth?: number; // Optional border width
15
+ borderRadius?: number; // Optional border radius
16
+ circleSize?: number; // Size of the circle progress bar (if type is CIRCLE)
17
+ thickness?: number; // Thickness of the circle progress bar (if type is CIRCLE)
18
+ progress: number; // filled area
19
+ setProgress: React.Dispatch<React.SetStateAction<number>>;
20
+ increment?: number; // Optional increment value for progress update
21
+ interval?: number; // Optional interval time (ms) for progress update
22
+ }
23
+
24
+ const CustomProgressBar: React.FC<CustomProgressBarProps> = ({
25
+ value,
26
+ type,
27
+ width,
28
+ height,
29
+ fillColor,
30
+ unfilledColor,
31
+ borderWidth,
32
+ borderRadius,
33
+ circleSize,
34
+ thickness,
35
+ progress,
36
+ setProgress,
37
+ increment = 1, // Default increment to 1
38
+ interval = 100, // Default interval to 100ms
39
+ }) => {
40
+ useEffect(() => {
41
+ const progressInterval = setInterval(() => {
42
+ if (progress < value) {
43
+ setProgress((prevProgress: number) => prevProgress + increment);
44
+ } else {
45
+ clearInterval(progressInterval);
46
+ }
47
+ }, interval);
48
+
49
+ return () => clearInterval(progressInterval);
50
+ }, [progress, value, increment, interval]);
51
+
52
+ const renderProgressBar = () => {
53
+ switch (type) {
54
+ case ShapeType.LINE:
55
+ return (
56
+ <Progress.Bar
57
+ progress={progress / 100}
58
+ width={width}
59
+ height={height}
60
+ color={fillColor}
61
+ unfilledColor={unfilledColor}
62
+ borderWidth={borderWidth}
63
+ borderRadius={borderRadius}
64
+ testID="custom-progress-bar-line"
65
+ />
66
+ );
67
+ case ShapeType.CIRCLE:
68
+ return (
69
+ <Progress.Circle
70
+ progress={progress / 100}
71
+ size={circleSize}
72
+ thickness={thickness}
73
+ color={fillColor}
74
+ unfilledColor={unfilledColor}
75
+ borderWidth={borderWidth}
76
+ showsText={true}
77
+ formatText={() => `${value}%`}
78
+ testID="custom-progress-bar-circle"
79
+ />
80
+ );
81
+ default:
82
+ return null;
83
+ }
84
+ };
85
+
86
+ return (
87
+ <View style={commonStyles.centeredContainer} testID="custom-progress-bar">
88
+ {renderProgressBar()}
89
+ </View>
90
+ );
91
+ };
92
+
93
+ export default CustomProgressBar;
@@ -0,0 +1 @@
1
+ export {default} from './ProgressBar';
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import {render} from '@testing-library/react-native';
3
+ import Property360View from './Property360View';
4
+ import WebView from 'react-native-webview';
5
+
6
+ describe('Property360View Component', () => {
7
+ it('should render the WebView with the correct URI', () => {
8
+ const imageURI = 'https://example.com/360image.jpg';
9
+ const {getByTestId} = render(<Property360View imageURI={imageURI} />);
10
+ const propertyView = getByTestId('PROPERTY_360_VIEW');
11
+ expect(propertyView).toBeTruthy();
12
+ expect(WebView).toHaveBeenCalledWith(
13
+ expect.objectContaining({
14
+ source: {uri: imageURI},
15
+ }),
16
+ {},
17
+ );
18
+ });
19
+ it('should apply the commonStyles.flexOne style to the View and WebView components', () => {
20
+ const imageURI = 'https://example.com/360image.jpg';
21
+ const {getByTestId} = render(<Property360View imageURI={imageURI} />);
22
+ expect(getByTestId('PROPERTY_360_VIEW')).toBeTruthy();
23
+ });
24
+ });
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import {View} from 'react-native';
3
+ import WebView from 'react-native-webview';
4
+ import commonStyles from '../../utils/commonStyles';
5
+
6
+ const Property360View = ({imageURI}: {imageURI: string}) => {
7
+ return (
8
+ <View style={commonStyles.flexOne} testID="PROPERTY_360_VIEW">
9
+ <WebView
10
+ source={{
11
+ uri: imageURI,
12
+ }}
13
+ style={commonStyles.flexOne}
14
+ />
15
+ </View>
16
+ );
17
+ };
18
+
19
+ export default Property360View;
@@ -0,0 +1 @@
1
+ export {default} from './Property360View';
@@ -0,0 +1,13 @@
1
+ import {horizontalScale} from '../../utils/stylehelper';
2
+ import {StyleSheet} from 'react-native';
3
+
4
+ const styles = StyleSheet.create({
5
+ container: {
6
+ flexDirection: 'row',
7
+ alignItems: 'center',
8
+ },
9
+ star: {
10
+ marginHorizontal: horizontalScale(2),
11
+ },
12
+ });
13
+ export default styles;
@@ -0,0 +1,61 @@
1
+ import React from 'react';
2
+ import {render, screen} from '@testing-library/react-native';
3
+ import StarRating from './Rating';
4
+ import {CalenderDots} from '../../assets';
5
+
6
+ describe('Star component', () => {
7
+ it('renders a full star for a rating of 1', () => {
8
+ const rating = 1;
9
+ const count = 5;
10
+ const size = 20;
11
+
12
+ render(
13
+ <StarRating
14
+ rating={rating}
15
+ count={count}
16
+ size={size}
17
+ fullStarIcon={<CalenderDots />}
18
+ halfStarIcon={<CalenderDots />}
19
+ />,
20
+ );
21
+
22
+ const stars = screen.getAllByTestId('star');
23
+ expect(stars.length).toBe(1);
24
+ });
25
+
26
+ it('renders a half star for a rating of 1.5', () => {
27
+ const rating = 1.5;
28
+ const count = 5;
29
+ const size = 20;
30
+
31
+ render(
32
+ <StarRating
33
+ rating={rating}
34
+ count={count}
35
+ size={size}
36
+ fullStarIcon={<CalenderDots />}
37
+ halfStarIcon={<CalenderDots />}
38
+ />,
39
+ );
40
+ const stars = screen.getAllByTestId('star');
41
+ expect(stars.length).toBe(1);
42
+ });
43
+
44
+ it('renders empty stars for a rating below 1', () => {
45
+ const rating = 0.5;
46
+ const count = 5;
47
+ const size = 20;
48
+
49
+ render(
50
+ <StarRating
51
+ rating={rating}
52
+ count={count}
53
+ size={size}
54
+ fullStarIcon={<CalenderDots />}
55
+ halfStarIcon={<CalenderDots />}
56
+ />,
57
+ );
58
+ const stars = screen.getAllByTestId('star');
59
+ expect(stars.length).toBe(1);
60
+ });
61
+ });
@@ -0,0 +1,96 @@
1
+ import React from 'react';
2
+ import {View, ViewStyle} from 'react-native';
3
+ import styles from './Rating.styles';
4
+
5
+ interface StarProps {
6
+ rating: number;
7
+ count: number;
8
+ size: number;
9
+ fullStarIcon: React.ReactElement;
10
+ halfStarIcon: React.ReactElement;
11
+ fullStarColor?: string;
12
+ emptyStarColor?: string;
13
+ starStyle?: ViewStyle;
14
+ }
15
+
16
+ const splitRating = (rating: number): [number, number] => {
17
+ const isDecimal = rating !== Math.floor(rating);
18
+ if (isDecimal) {
19
+ const integerPart = Math.floor(rating);
20
+ const decimalPart = rating - integerPart;
21
+ return [integerPart, decimalPart];
22
+ } else {
23
+ return [rating, 0];
24
+ }
25
+ };
26
+
27
+ const drawStar = (
28
+ starIndex: number,
29
+ ratingArray: [number, number],
30
+ size: number,
31
+ fullStarIcon: React.ReactElement,
32
+ halfStarIcon: React.ReactElement,
33
+ fullStarColor: string,
34
+ emptyStarColor: string,
35
+ ): JSX.Element => {
36
+ const [fullStars, decimalPart] = ratingArray;
37
+
38
+ if (starIndex <= fullStars) {
39
+ return React.cloneElement(fullStarIcon, {
40
+ style: {height: size, width: size},
41
+ fill: fullStarColor,
42
+ testID: `star-${starIndex}`,
43
+ });
44
+ } else if (starIndex === fullStars + 1 && decimalPart >= 0.5) {
45
+ return React.cloneElement(halfStarIcon, {
46
+ style: {height: size, width: size},
47
+ fill: fullStarColor,
48
+ testID: `star-${starIndex}`,
49
+ });
50
+ } else {
51
+ return React.cloneElement(fullStarIcon, {
52
+ style: {height: size, width: size},
53
+ fill: emptyStarColor,
54
+ testID: `star-${starIndex}`,
55
+ });
56
+ }
57
+ };
58
+
59
+ const Star: React.FC<StarProps> = ({
60
+ rating,
61
+ count,
62
+ size,
63
+ fullStarIcon,
64
+ halfStarIcon,
65
+ fullStarColor = 'gold',
66
+ emptyStarColor = 'gray',
67
+ starStyle,
68
+ }) => {
69
+ const stars: React.ReactElement[] = [];
70
+ for (let i = 0; i < count; i++) {
71
+ const starIndex = i + 1;
72
+ const ratingArray = splitRating(rating);
73
+ const starType = drawStar(
74
+ starIndex,
75
+ ratingArray,
76
+ size,
77
+ fullStarIcon,
78
+ halfStarIcon,
79
+ fullStarColor,
80
+ emptyStarColor,
81
+ );
82
+ stars.push(
83
+ <View key={i} style={[styles.star, starStyle]}>
84
+ {starType}
85
+ </View>,
86
+ );
87
+ }
88
+
89
+ return (
90
+ <View style={styles.container} testID="star">
91
+ {stars}
92
+ </View>
93
+ );
94
+ };
95
+
96
+ export default Star;
@@ -0,0 +1 @@
1
+ export {default} from './Rating';
@@ -0,0 +1,13 @@
1
+ import {ReactElement} from 'react';
2
+ import {ViewStyle} from 'react-native';
3
+
4
+ export interface TabsProps {
5
+ tabs: {label: string}[];
6
+ onTabPress?: (index: number) => void;
7
+ testID?: string;
8
+ hideTitle?: boolean;
9
+ hideIcon?: boolean;
10
+ initialTab?: number;
11
+ icon?: ReactElement;
12
+ iconStyle?: ViewStyle;
13
+ }
@@ -0,0 +1,36 @@
1
+ import {DHRE_COLORS_TEXT} from '../../theme/colors';
2
+ import {horizontalScale, verticalScale} from '../../utils/stylehelper';
3
+ import {StyleSheet} from 'react-native';
4
+
5
+ const styles = StyleSheet.create({
6
+ tabsContainer: {
7
+ flexDirection: 'row',
8
+ alignItems: 'center',
9
+ },
10
+ tabItem: {
11
+ flex: 1,
12
+ flexDirection: 'row',
13
+ alignItems: 'center',
14
+ justifyContent: 'center',
15
+ paddingVertical: verticalScale(6),
16
+ paddingHorizontal: horizontalScale(12),
17
+ marginHorizontal: horizontalScale(8),
18
+ borderRadius: 50,
19
+ gap: horizontalScale(8),
20
+ backgroundColor: DHRE_COLORS_TEXT.DH_BLACK,
21
+ },
22
+ label: {
23
+ color: DHRE_COLORS_TEXT.DH_WHITE,
24
+ },
25
+ activeTab: {
26
+ backgroundColor: DHRE_COLORS_TEXT.DH_BLACK,
27
+ },
28
+ inactiveTab: {
29
+ backgroundColor: DHRE_COLORS_TEXT.DH_WHITE,
30
+ },
31
+ inActiveLabel: {
32
+ color: DHRE_COLORS_TEXT.DH_TEXTLIGHTEST,
33
+ },
34
+ });
35
+
36
+ export default styles;
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import {it} from '@jest/globals';
3
+ import {render} from '@testing-library/react-native';
4
+ import Tabs from './Tabs';
5
+
6
+ const mockProps = {
7
+ tabs: [{label: 'Tabs'}],
8
+ hideTitle: false,
9
+ hideIcon: false,
10
+ initialTab: 1,
11
+ onTabPress: jest.fn(),
12
+ testID: 'TABS-COMPONENT',
13
+ };
14
+
15
+ describe('Tabs Component', () => {
16
+ it('Component renders correctly', () => {
17
+ const {getByTestId} = render(<Tabs {...mockProps} />);
18
+ expect(getByTestId('TABS-COMPONENT')).toBeTruthy();
19
+ });
20
+ });
@@ -0,0 +1,65 @@
1
+ import React, {useState} from 'react';
2
+ import {ScrollView, Pressable, View} from 'react-native';
3
+ import CustomTypography from '../customTypography/CustomTypography';
4
+ import styles from './Tabs.styles';
5
+ import {TabsProps} from './Tabs.interface';
6
+ import {DHRE_COLORS_TEXT} from '../../theme/colors';
7
+
8
+ const Tabs: React.FC<TabsProps> = ({
9
+ tabs,
10
+ onTabPress,
11
+ testID,
12
+ hideTitle = false,
13
+ hideIcon = true,
14
+ initialTab = 0,
15
+ icon: Icon,
16
+ iconStyle,
17
+ }) => {
18
+ const [activeTab, setActiveTab] = useState(initialTab);
19
+
20
+ const handleTabPress = (index: number) => {
21
+ setActiveTab(index);
22
+ if (onTabPress) {
23
+ onTabPress(index);
24
+ }
25
+ };
26
+
27
+ return (
28
+ <ScrollView
29
+ testID={testID}
30
+ horizontal
31
+ showsHorizontalScrollIndicator={false}
32
+ contentContainerStyle={styles.tabsContainer}>
33
+ {tabs?.map((tab, index) => (
34
+ <Pressable
35
+ testID={`Press-Tab-${index}`}
36
+ key={index}
37
+ onPress={() => handleTabPress(index)}
38
+ style={[
39
+ styles.tabItem,
40
+ activeTab === index ? styles.activeTab : styles.inactiveTab,
41
+ ]}>
42
+ {!hideIcon && Icon && (
43
+ <View style={iconStyle}>
44
+ {React.cloneElement(Icon, {
45
+ fill:
46
+ activeTab === index
47
+ ? DHRE_COLORS_TEXT.DH_WHITE
48
+ : DHRE_COLORS_TEXT.DH_TEXTLIGHTEST,
49
+ })}
50
+ </View>
51
+ )}
52
+ {!hideTitle && (
53
+ <CustomTypography
54
+ variant={activeTab === index ? 'H8semiBold' : 'H8medium'}
55
+ style={activeTab === index ? styles.label : styles.inActiveLabel}
56
+ text={tab?.label}
57
+ />
58
+ )}
59
+ </Pressable>
60
+ ))}
61
+ </ScrollView>
62
+ );
63
+ };
64
+
65
+ export default Tabs;
@@ -0,0 +1 @@
1
+ export {default} from './Tabs';
@@ -0,0 +1,12 @@
1
+ import {ReactElement} from 'react';
2
+ import {ViewStyle} from 'react-native';
3
+
4
+ export interface TagsProps {
5
+ tags: string[];
6
+ tagStyles?: ViewStyle;
7
+ handleSetSelectedTagsOptions: (tags: string[]) => void;
8
+ handleTagsChange: (tag: string) => void;
9
+ testID?: string;
10
+ icon?: ReactElement;
11
+ iconStyle?: ViewStyle;
12
+ }
@@ -0,0 +1,36 @@
1
+ import {DHRE_COLORS_BG, DHRE_COLORS_TEXT} from '../../theme/colors';
2
+ import {horizontalScale, verticalScale} from '../../utils/stylehelper';
3
+ import {StyleSheet} from 'react-native';
4
+
5
+ const styles = StyleSheet.create({
6
+ container: {
7
+ width: '100%',
8
+ },
9
+ contentContainer: {
10
+ flexWrap: 'wrap',
11
+ flexDirection: 'row',
12
+ },
13
+ tag: {
14
+ paddingVertical: verticalScale(8),
15
+ paddingHorizontal: horizontalScale(12),
16
+ borderRadius: 20,
17
+ margin: horizontalScale(8),
18
+ flexDirection: 'row',
19
+ alignItems: 'center',
20
+ },
21
+ selectedTag: {
22
+ backgroundColor: DHRE_COLORS_TEXT.DH_BLACK,
23
+ },
24
+ tagText: {
25
+ color: DHRE_COLORS_TEXT.DH_WHITE,
26
+ marginRight: horizontalScale(8),
27
+ },
28
+ tagUnSelected: {
29
+ backgroundColor: DHRE_COLORS_BG.DH_GREY1,
30
+ },
31
+ tagUnselectedText: {
32
+ color: DHRE_COLORS_TEXT.DH_TEXTLIGHT,
33
+ },
34
+ });
35
+
36
+ export default styles;
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ import {it} from '@jest/globals';
3
+ import {fireEvent, render} from '@testing-library/react-native';
4
+ import Tags from './Tags';
5
+
6
+ const customStyle = {backgroundColor: 'red', padding: 20};
7
+
8
+ const mockProps = {
9
+ tags: ['One', 'Two', 'Three'],
10
+ tagStyles: customStyle,
11
+ handleSetSelectedTagsOptions: jest.fn(),
12
+ handleTagsChange: jest.fn(),
13
+ testID: 'TAGS-COMPONENT',
14
+ };
15
+
16
+ describe('Tags Component', () => {
17
+ it('Component renders correctly', () => {
18
+ const {getByTestId} = render(<Tags {...mockProps} />);
19
+ expect(getByTestId('TAGS-COMPONENT')).toBeTruthy();
20
+ fireEvent.press(getByTestId('TAGS-COMPONENT-One-BTN'));
21
+ });
22
+ });
@@ -0,0 +1,76 @@
1
+ import React, {useState} from 'react';
2
+ import {ScrollView, Pressable} from 'react-native';
3
+ import CustomTypography from '../customTypography/CustomTypography';
4
+ import {TagsProps} from './Tags.interface';
5
+ import styles from './Tags.styles';
6
+
7
+ const Tags: React.FC<TagsProps> = ({
8
+ tags,
9
+ tagStyles,
10
+ handleSetSelectedTagsOptions,
11
+ handleTagsChange,
12
+ testID,
13
+ icon,
14
+ iconStyle,
15
+ }) => {
16
+ const [selectedTags, setSelectedTags] = useState<string[]>([]);
17
+
18
+ const toggleTag = (tag: string) => {
19
+ setSelectedTags(prevSelectedTags => {
20
+ const selectedTagsSet = new Set(prevSelectedTags);
21
+ selectedTagsSet.has(tag)
22
+ ? selectedTagsSet.delete(tag)
23
+ : selectedTagsSet.add(tag);
24
+ handleSetSelectedTagsOptions([...selectedTagsSet]);
25
+ return [...selectedTagsSet];
26
+ });
27
+ };
28
+
29
+ const removeTag = (tag: string) => {
30
+ setSelectedTags(prevSelectedTags =>
31
+ prevSelectedTags.filter(t => t !== tag),
32
+ );
33
+ handleTagsChange(tag);
34
+ };
35
+
36
+ return (
37
+ <ScrollView
38
+ testID={testID}
39
+ style={styles.container}
40
+ contentContainerStyle={styles.contentContainer}
41
+ horizontal={false}>
42
+ {tags?.map(tag => (
43
+ <Pressable
44
+ testID={`${testID}-${tag}-BTN`}
45
+ key={tag}
46
+ onPress={() => toggleTag(tag)}
47
+ style={[
48
+ styles.tag,
49
+ tagStyles,
50
+ selectedTags.includes(tag)
51
+ ? styles.selectedTag
52
+ : styles.tagUnSelected,
53
+ ]}>
54
+ <CustomTypography
55
+ variant={selectedTags.includes(tag) ? 'H9semiBold' : 'P4regular'}
56
+ style={
57
+ selectedTags.includes(tag)
58
+ ? styles.tagText
59
+ : styles.tagUnselectedText
60
+ }
61
+ text={tag}
62
+ />
63
+ {selectedTags.includes(tag) && icon && (
64
+ <Pressable
65
+ testID={`${testID}-${tag}-PRESS`}
66
+ onPress={() => removeTag(tag)}>
67
+ {React.cloneElement(icon, {style: [icon.props.style, iconStyle]})}
68
+ </Pressable>
69
+ )}
70
+ </Pressable>
71
+ ))}
72
+ </ScrollView>
73
+ );
74
+ };
75
+
76
+ export default Tags;
@@ -0,0 +1 @@
1
+ export {default} from './Tags';
@@ -0,0 +1,40 @@
1
+ import {DHRE_COLORS_TEXT} from '../../theme/colors';
2
+ import {horizontalScale, verticalScale} from '../../utils/stylehelper';
3
+ import {StyleSheet} from 'react-native';
4
+
5
+ const styles = StyleSheet.create({
6
+ container: {
7
+ width: horizontalScale(70),
8
+ height: verticalScale(25),
9
+ borderRadius: 15,
10
+ justifyContent: 'center',
11
+ },
12
+ track: {
13
+ position: 'absolute',
14
+ top: 0,
15
+ left: 0,
16
+ right: 0,
17
+ bottom: 0,
18
+ justifyContent: 'center',
19
+ borderRadius: 15,
20
+ },
21
+ thumb: {
22
+ position: 'absolute',
23
+ width: horizontalScale(20),
24
+ height: verticalScale(20),
25
+ borderRadius: 16,
26
+ justifyContent: 'center',
27
+ alignItems: 'center',
28
+ backgroundColor: DHRE_COLORS_TEXT.DH_WHITE,
29
+ left: horizontalScale(2),
30
+ },
31
+ text: {
32
+ color: DHRE_COLORS_TEXT.DH_WHITE,
33
+ textAlign: 'left',
34
+ marginHorizontal: horizontalScale(10),
35
+ },
36
+ textRight: {
37
+ textAlign: 'right',
38
+ },
39
+ });
40
+ export default styles;
@@ -0,0 +1,33 @@
1
+ import React from 'react';
2
+ import {render, screen, fireEvent} from '@testing-library/react-native';
3
+ import CustomSwitch from './ToggleButton';
4
+
5
+ describe('CustomSwitch', () => {
6
+ it('renders correctly with default type', () => {
7
+ const onValueChangeMock = jest.fn();
8
+ render(<CustomSwitch onValueChange={onValueChangeMock} value={false} />);
9
+
10
+ const switchElement = screen.getByTestId('custom-switch');
11
+ expect(switchElement).toBeTruthy();
12
+ });
13
+
14
+ it('renders correctly with custom type', () => {
15
+ const onValueChangeMock = jest.fn();
16
+ render(<CustomSwitch onValueChange={onValueChangeMock} value={true} />);
17
+
18
+ const switchElement = screen.getByTestId('custom-switch');
19
+ expect(switchElement).toBeTruthy();
20
+ });
21
+
22
+ it('toggles switch on press', () => {
23
+ const onValueChangeMock = jest.fn();
24
+ const {getByTestId} = render(
25
+ <CustomSwitch onValueChange={onValueChangeMock} value={false} />,
26
+ );
27
+
28
+ const switchElement = getByTestId('custom-switch');
29
+ fireEvent.press(switchElement);
30
+
31
+ expect(onValueChangeMock).toHaveBeenCalledWith(true);
32
+ });
33
+ });