alicia-design-system 1.2.0 → 1.3.0

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 (30) hide show
  1. package/package.json +1 -1
  2. package/src/alicia/common/Buttons/Buttons.tsx +11 -11
  3. package/src/alicia/common/Checkbox/Checkbox.stories.tsx +2 -1
  4. package/src/alicia/common/Checkbox/Checkbox.tsx +4 -4
  5. package/src/alicia/common/DateInput/DateInput.stories.tsx +2 -2
  6. package/src/alicia/common/DateInput/DateInput.tsx +6 -6
  7. package/src/alicia/common/Header/Header.spec.tsx +102 -0
  8. package/src/alicia/common/Header/Header.stories.tsx +86 -0
  9. package/src/alicia/common/Header/Header.tsx +198 -0
  10. package/src/alicia/common/Header/index.ts +1 -0
  11. package/src/alicia/common/ProgressBar/ProgressBar.spec.tsx +50 -0
  12. package/src/alicia/common/ProgressBar/ProgressBar.stories.tsx +56 -0
  13. package/src/alicia/common/ProgressBar/ProgressBar.tsx +55 -0
  14. package/src/alicia/common/ProgressBar/index.ts +1 -0
  15. package/src/alicia/common/RadioButtonGroup/RadioButtonGroup.stories.tsx +1 -1
  16. package/src/alicia/common/RadioButtonGroup/RadioButtonGroup.tsx +6 -6
  17. package/src/alicia/common/Step/Step.stories.tsx +20 -0
  18. package/src/alicia/common/Step/Step.test.tsx +14 -0
  19. package/src/alicia/common/Step/Step.tsx +22 -0
  20. package/src/alicia/common/icons/ChevronDownIcon.tsx +16 -0
  21. package/src/alicia/common/icons/ChevronUpIcon.tsx +16 -0
  22. package/src/alicia/common/icons/GlobeIcon.tsx +16 -0
  23. package/src/alicia/common/icons/SupportIcon.tsx +11 -0
  24. package/src/alicia/common/icons/index.ts +5 -1
  25. package/src/assets/vectors/alicia.svg +17 -0
  26. package/src/setupTests.ts +8 -0
  27. package/src/styles/chakraTheme.ts +4 -2
  28. package/src/types/index.ts +1 -0
  29. package/src/types/route.ts +19 -0
  30. package/src/App.test.tsx +0 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alicia-design-system",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "private": false,
5
5
  "dependencies": {
6
6
  "@chakra-ui/icons": "^2.0.17",
@@ -1,15 +1,15 @@
1
- import { Button as ChakraButton, ButtonProps as ChakraButtonProps} from '@chakra-ui/react'
1
+ import { Button as ChakraButton, ButtonProps as ChakraButtonProps } from '@chakra-ui/react';
2
2
 
3
- export const Button = ( { children , ...rest } : ButtonProps) => {
3
+ export const Button = ({ children, ...rest }: ButtonProps) => {
4
4
 
5
- return (
6
- <>
7
- <ChakraButton w="full" {...rest}>{children}</ChakraButton>
8
- </>
9
- );
10
- };
5
+ return (
6
+ <>
7
+ <ChakraButton {...rest}>{children}</ChakraButton>
8
+ </>
9
+ );
10
+ };
11
11
 
12
12
 
13
- interface ButtonProps extends ChakraButtonProps{
14
-
15
- }
13
+ interface ButtonProps extends ChakraButtonProps {
14
+
15
+ }
@@ -17,8 +17,9 @@ const Template: ComponentStory<typeof CheckBox> = (args) => {
17
17
  return (
18
18
  <CheckBox
19
19
  {...args}
20
+ mt="4"
20
21
  isActive={isChecked}
21
- onChange={() => setIsChecked(!isChecked)}
22
+ onChange={() => { setIsChecked(!isChecked); }}
22
23
  />
23
24
  );
24
25
  };
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import {
3
- Checkbox,
3
+ Checkbox, CheckboxProps as defaultProps
4
4
  } from '@chakra-ui/react';
5
5
 
6
6
  export const CheckBox: React.FC<CheckboxProps> = ({
@@ -11,13 +11,13 @@ export const CheckBox: React.FC<CheckboxProps> = ({
11
11
  }) => {
12
12
 
13
13
  return (
14
- <Checkbox {...props} onChange={onChange} isChecked={isActive} variant="primary">{label}</Checkbox>
14
+ <Checkbox {...props} onChange={(e) => onChange(e.target.checked)} isChecked={isActive} variant="primary">{label}</Checkbox>
15
15
  );
16
16
  };
17
17
 
18
- export type CheckboxProps = {
18
+ export type CheckboxProps = defaultProps & {
19
19
  customClass?: string;
20
20
  isActive?: boolean;
21
21
  label?: string;
22
- onChange: () => void;
22
+ onChange: (value: boolean) => void;
23
23
  };
@@ -18,8 +18,8 @@ Primary.args = {
18
18
  title: '',
19
19
  dateString: '',
20
20
  message: '',
21
- minDate: { date: '2009-12-12', error: 'Date cannot be older than 2009-12-12' },
22
- maxDate: { date: '2010-12-12', error: 'Date cannot be newer than 2010-12-12' },
21
+ minDate: { date: '2020-12-12', error: 'Date cannot be older than 2020-12-12' },
22
+ maxDate: { date: '2023-12-12', error: 'Date cannot be newer than 2023-12-12' },
23
23
  controlName: 'birthdate',
24
24
  infoMessage: ''
25
25
  };
@@ -1,9 +1,9 @@
1
- import { FormControl, FormLabel, Input, Text, Tooltip, Flex } from '@chakra-ui/react';
1
+ import { FormControl, FormLabel, Input, Text, Tooltip, Flex, ChakraProps } from '@chakra-ui/react';
2
2
  import { FC, useState, useEffect } from 'react';
3
3
  import { differenceInMilliseconds } from 'date-fns';
4
4
  import { InfoIcon } from '../icons';
5
5
 
6
- export const DateInput: FC<DateInputProps> = ({ title, dateString, message, isRequired = false, minDate, maxDate, controlName, infoMessage }) => {
6
+ export const DateInput: FC<DateInputProps> = ({ title, dateString, message, isRequired = false, minDate, maxDate, controlName, infoMessage, ...props }) => {
7
7
  const [value, setValue] = useState<string>('');
8
8
  const [errorMessage, setErrorMessage] = useState(message);
9
9
 
@@ -38,16 +38,16 @@ export const DateInput: FC<DateInputProps> = ({ title, dateString, message, isRe
38
38
 
39
39
  return (
40
40
  <FormControl isRequired={isRequired}>
41
- {title && (<Flex color='white'><FormLabel htmlFor={controlName} color={errorMessage ? 'error' : 'black'}>{title}</FormLabel>
42
- {infoMessage && (<Tooltip bg='white' color="black" label={infoMessage} aria-label='A tooltip' hasArrow ><InfoIcon width={16} /></Tooltip>)}
41
+ {title && (<Flex align="center" color='white'><FormLabel mb="0" htmlFor={controlName} color={errorMessage ? 'error' : 'black'}>{title}</FormLabel>
42
+ {infoMessage && (<Tooltip bg='white' color="black" label={infoMessage} aria-label='A tooltip' hasArrow ><InfoIcon width={20} /></Tooltip>)}
43
43
  </Flex>)}
44
- <Input color={errorMessage ? 'error' : 'black'} placeholder="DD-MM-YYYY" value={value} variant='flushed' id={controlName} name={controlName} type="date" data-date-format="DD MMMM YYYY" onChange={(e) => { onChange(e.target.value); }} />
44
+ <Input {...props} color={errorMessage ? 'error' : 'black'} placeholder="DD-MM-YYYY" value={value} variant='flushed' id={controlName} name={controlName} type="date" data-date-format="DD MMMM YYYY" onChange={(e) => { onChange(e.target.value); }} />
45
45
  {errorMessage && (<Text fontSize='xs' color="error">{errorMessage}</Text>)}
46
46
  </FormControl>
47
47
  );
48
48
  };
49
49
 
50
- type DateInputProps = {
50
+ type DateInputProps = ChakraProps & {
51
51
  title?: string;
52
52
  dateString?: string;
53
53
  onDateChange: (value: string) => void;
@@ -0,0 +1,102 @@
1
+ import { render } from "@testing-library/react";
2
+ import '@testing-library/jest-dom';
3
+ import { Header } from "./index";
4
+ import AliciaLogo from "../../../assets/vectors/alicia.svg";
5
+ import { MultiStepRouteType } from 'types';
6
+
7
+ const DEFAULT_HEADER_PROPS = {
8
+ backgroundColor: 'headerBg',
9
+ textColor: 'black',
10
+ imageSrc: AliciaLogo,
11
+ imageFallbackSrc: AliciaLogo,
12
+ showSupport: false,
13
+ showLanguageSelector: false,
14
+ showProgressBar: false,
15
+ languages: [
16
+ {
17
+ label: 'English',
18
+ labelSm: 'EN',
19
+ value: 'en'
20
+ },
21
+ {
22
+ label: 'Netherland',
23
+ labelSm: 'NL',
24
+ value: 'nl'
25
+ },
26
+ {
27
+ label: 'Français',
28
+ labelSm: 'FR',
29
+ value: 'fr'
30
+ },
31
+ ],
32
+ showSteps: false,
33
+ steps: [
34
+ {
35
+ index: 1,
36
+ isNewSection: true,
37
+ sectionIndex: 0,
38
+ type: MultiStepRouteType.PERSONAL,
39
+ title: 'Your Claim'
40
+ },
41
+ {
42
+ index: 2,
43
+ isNewSection: true,
44
+ sectionIndex: 1,
45
+ type: MultiStepRouteType.CLAIM,
46
+ title: 'Personal Details'
47
+ },
48
+ {
49
+ index: 3,
50
+ isNewSection: false,
51
+ sectionIndex: 1,
52
+ type: MultiStepRouteType.CLAIM,
53
+ title: 'Address Details'
54
+ },
55
+ ],
56
+ currentStep: 1,
57
+ showCurrentStep: true
58
+ };
59
+
60
+ describe("Header component testing with testing-library", () => {
61
+ it("renders without crashing", () => {
62
+ const component = render(<Header {...DEFAULT_HEADER_PROPS} />);
63
+
64
+ expect(component).toBeTruthy();
65
+ });
66
+ });
67
+
68
+ describe('Check if component Renders with support label', () => {
69
+ it('component includes support label text', () => {
70
+ const { getAllByText } = render(<Header {...{ ...DEFAULT_HEADER_PROPS, showSupport: true }} />);
71
+ expect(getAllByText('Support')).toBeTruthy();
72
+ });
73
+ });
74
+
75
+ describe('Check if component Renders with language selector label', () => {
76
+ it('component includes english label text', () => {
77
+ const { getAllByText } = render(<Header {...{ ...DEFAULT_HEADER_PROPS, showLanguageSelector: true }} />);
78
+ expect(getAllByText('English')).toBeTruthy();
79
+ });
80
+ it('component includes netherland label text', () => {
81
+ const { getAllByText } = render(<Header {...{ ...DEFAULT_HEADER_PROPS, showLanguageSelector: true, language: DEFAULT_HEADER_PROPS.languages[1] }} />);
82
+ expect(getAllByText('Netherland')).toBeTruthy();
83
+ });
84
+ });
85
+
86
+ describe('Check if component Renders with steps header labels', () => {
87
+ it('component includes which step label text', () => {
88
+ const { getAllByText } = render(<Header {...{ ...DEFAULT_HEADER_PROPS, showSteps: true }} />);
89
+ expect(getAllByText('Step 1 of 3')).toBeTruthy();
90
+ });
91
+ it('component includes step title label text', () => {
92
+ const { getAllByText } = render(<Header {...{ ...DEFAULT_HEADER_PROPS, showSteps: true }} />);
93
+ expect(getAllByText('Your Claim')).toBeTruthy();
94
+ });
95
+ });
96
+
97
+ describe('Check if component Renders with progress bar', () => {
98
+ it('component includes progress bar aria label', () => {
99
+ const { getAllByLabelText } = render(<Header {...{ ...DEFAULT_HEADER_PROPS, showProgressBar: true }} />);
100
+ expect(getAllByLabelText('progress-bar')).toBeTruthy();
101
+ });
102
+ });
@@ -0,0 +1,86 @@
1
+ import { useState } from "react";
2
+ import { ComponentStory, ComponentMeta } from "@storybook/react";
3
+ import { Header, Language } from "./Header";
4
+ import AliciaLogo from "../../../assets/vectors/alicia.svg";
5
+ import { MultiStepRouteType } from 'types';
6
+
7
+ const LANGUAGES: Language[] = [
8
+ {
9
+ label: 'English',
10
+ labelSm: 'EN',
11
+ value: 'en'
12
+ },
13
+ {
14
+ label: 'Netherland',
15
+ labelSm: 'NL',
16
+ value: 'nl'
17
+ },
18
+ {
19
+ label: 'Français',
20
+ labelSm: 'FR',
21
+ value: 'fr'
22
+ },
23
+ ];
24
+
25
+ export default {
26
+ title: "Alicia/common/Header",
27
+ component: Header,
28
+ } as ComponentMeta<typeof Header>;
29
+
30
+ const Template: ComponentStory<typeof Header> = (args) => {
31
+ const [language, setLanguage] = useState<Language>(LANGUAGES[0]);
32
+ return (
33
+ <Header
34
+ {...args}
35
+ language={language}
36
+ setLanguage={(lan: Language) => setLanguage(lan)}
37
+ onSupportClick={() => alert('support clicked...')}
38
+ />
39
+ );
40
+ };
41
+
42
+ export const Primary = Template.bind({});
43
+
44
+ Primary.args = {
45
+ backgroundColor: 'headerBg',
46
+ textColor: 'black',
47
+ imageSrc: AliciaLogo,
48
+ imageFallbackSrc: AliciaLogo,
49
+ showSupport: false,
50
+ showLanguageSelector: false,
51
+ languages: LANGUAGES,
52
+ showSteps: false,
53
+ showProgressBar: false,
54
+ steps: [{
55
+ index: 1,
56
+ isNewSection: true,
57
+ sectionIndex: 0,
58
+ type: MultiStepRouteType.PERSONAL,
59
+ title: 'Your Claim'
60
+ },
61
+ {
62
+ index: 2,
63
+ isNewSection: true,
64
+ sectionIndex: 1,
65
+ type: MultiStepRouteType.CLAIM,
66
+ title: 'Personal Details'
67
+ },
68
+ {
69
+ index: 3,
70
+ isNewSection: false,
71
+ sectionIndex: 1,
72
+ type: MultiStepRouteType.CLAIM,
73
+ title: 'Address Details'
74
+ }, {
75
+ index: 4,
76
+ isNewSection: true,
77
+ sectionIndex: 1,
78
+ type: MultiStepRouteType.PAYMENT,
79
+ title: 'Approval'
80
+ }],
81
+ routeStepsWithoutProgress: [MultiStepRouteType.INTRO],
82
+ currentStep: 1,
83
+ progressBarPrimaryColor: "#006A70",
84
+ progressBarBackgroundColor: "#EEEEEE",
85
+ showCurrentStep: true
86
+ };
@@ -0,0 +1,198 @@
1
+ import React from "react";
2
+ import {
3
+ Box,
4
+ Grid,
5
+ GridItem,
6
+ Flex,
7
+ Text,
8
+ Image,
9
+ Menu,
10
+ MenuButton,
11
+ MenuList,
12
+ MenuItem,
13
+ useMediaQuery,
14
+ } from '@chakra-ui/react';
15
+ import { SupportIcon, ChevronUpIcon, ChevronDownIcon, GlobeIcon } from "../icons";
16
+ import AliciaLogo from "../../../assets/vectors/alicia.svg";
17
+ import { ProgressBar } from '../ProgressBar/ProgressBar';
18
+ import { HeaderStep, MultiStepRouteType } from 'types';
19
+ import { Step } from '../Step/Step';
20
+
21
+ export const Header: React.FC<HeaderProps> = ({
22
+ backgroundColor = 'headerBg',
23
+ textColor = 'black',
24
+ imageSrc = AliciaLogo,
25
+ imageFallbackSrc = AliciaLogo,
26
+ showSupport = undefined,
27
+ onSupportClick = undefined,
28
+ showLanguageSelector = undefined,
29
+ languages = undefined,
30
+ language = undefined,
31
+ setLanguage = undefined,
32
+ showSteps = undefined,
33
+ steps = undefined,
34
+ currentStep = undefined,
35
+ showProgressBar = false,
36
+ routeStepsWithoutProgress = [],
37
+ progressBarBackgroundColor,
38
+ progressBarPrimaryColor,
39
+ showCurrentStep = false,
40
+ }) => {
41
+ const [isMobile] = useMediaQuery('(max-width: 768px)');
42
+
43
+ return (
44
+ <Flex direction="column">
45
+ <Grid
46
+ bg={backgroundColor}
47
+ height={68}
48
+ padding={`0px ${isMobile ? 16 : 24}px`}
49
+ templateColumns="repeat(3, 1fr)"
50
+ gap={2}
51
+ >
52
+ <GridItem
53
+ display="flex"
54
+ alignItems="center"
55
+ colStart={1}
56
+ colEnd={2}
57
+ >
58
+ <Image
59
+ width={isMobile ? '50px' : '82px'}
60
+ height='32px'
61
+ objectFit='fill'
62
+ alt='logo-image'
63
+ src={imageSrc}
64
+ fallbackSrc={imageFallbackSrc}
65
+ />
66
+ </GridItem>
67
+ {showSteps && steps &&
68
+ (
69
+ <GridItem
70
+ display="flex"
71
+ flexDirection="column"
72
+ alignItems="center"
73
+ justifyContent="center"
74
+ colStart={2}
75
+ colEnd={3}
76
+ >
77
+ <Step isMobile={isMobile} stepTitle={showCurrentStep ? `Step ${currentStep ?? ""} of ${steps.length}` : ''} mainTitle={steps?.find((step) => step.index === currentStep)?.title} />
78
+ </GridItem>
79
+ )}
80
+ <GridItem
81
+ display="flex"
82
+ alignItems="center"
83
+ justifyContent="flex-end"
84
+ colStart={3}
85
+ colEnd={4}
86
+ >
87
+ {showLanguageSelector &&
88
+ (
89
+ <Flex
90
+ direction="row"
91
+ justifyContent="center"
92
+ alignItems="center"
93
+ cursor="pointer"
94
+ >
95
+ <Box marginRight={showSupport ? isMobile ? 2 : 8 : 0}>
96
+ <Menu>
97
+ {({ isOpen }) => (
98
+ <>
99
+ <MenuButton>
100
+ <Box display='flex' flexDirection='row' alignItems='center'>
101
+ <GlobeIcon
102
+ sx={{
103
+ "@media (max-width: 768px)": {
104
+ display: "none",
105
+ },
106
+ }}
107
+ />
108
+ <Text fontSize={14} marginLeft="8px" marginRight="7px">{isMobile ? language?.labelSm : language?.label}</Text>
109
+ {isOpen ? <ChevronDownIcon /> : <ChevronUpIcon />}
110
+ </Box>
111
+ </MenuButton>
112
+ <MenuList border='none' sx={{
113
+ padding: '4px',
114
+ minW:'150px'
115
+ }} >
116
+ {languages?.map((lan) => <MenuItem sx={{
117
+ bg: 'headerBg',
118
+ '_hover': {
119
+ bg: 'dropDownHover'
120
+ }
121
+ }} onClick={() => setLanguage?.(lan)} key={lan.value}>
122
+ <Text fontSize={14}>{isMobile ? lan.labelSm : lan?.label}</Text>
123
+ </MenuItem>)}
124
+ </MenuList>
125
+ </>
126
+ )}
127
+ </Menu>
128
+ </Box>
129
+ </Flex>
130
+ )
131
+ }
132
+ {showSupport && (
133
+ <Flex
134
+ direction="row"
135
+ justifyContent="center"
136
+ alignItems="center"
137
+ cursor="pointer"
138
+ onClick={onSupportClick}
139
+ >
140
+ <SupportIcon sx={{
141
+ 'fill': textColor
142
+ }} />
143
+ <Text
144
+ marginLeft="12.3px"
145
+ color={textColor}
146
+ sx={{
147
+ "@media (max-width: 768px)": {
148
+ display: "none",
149
+ },
150
+ }}
151
+ fontSize={14}
152
+ >
153
+ Support
154
+ </Text>
155
+ </Flex>
156
+ )}
157
+ </GridItem>
158
+ </Grid>
159
+ {
160
+ showProgressBar && steps &&
161
+ <ProgressBar
162
+ current={currentStep ?? 1}
163
+ routeStepsWithoutProgress={routeStepsWithoutProgress}
164
+ progressBarSteps={steps}
165
+ primaryColor={progressBarPrimaryColor}
166
+ backgroundColor={progressBarBackgroundColor} />
167
+ }
168
+ </Flex >
169
+ );
170
+ };
171
+
172
+ export type Language = {
173
+ label: string;
174
+ labelSm: string;
175
+ value: string;
176
+ };
177
+
178
+
179
+ export type HeaderProps = {
180
+ backgroundColor: string;
181
+ textColor: string;
182
+ imageSrc: string;
183
+ imageFallbackSrc: string;
184
+ showSupport?: boolean;
185
+ onSupportClick?: () => void;
186
+ showLanguageSelector?: boolean;
187
+ languages?: Language[];
188
+ language?: Language;
189
+ setLanguage?: (lan: Language) => void;
190
+ showSteps?: boolean;
191
+ steps?: HeaderStep[];
192
+ currentStep?: number;
193
+ showProgressBar?: boolean;
194
+ routeStepsWithoutProgress?: MultiStepRouteType[];
195
+ progressBarPrimaryColor?: string;
196
+ progressBarBackgroundColor?: string;
197
+ showCurrentStep?: boolean;
198
+ };
@@ -0,0 +1 @@
1
+ export { Header } from "./Header";
@@ -0,0 +1,50 @@
1
+ import { render } from "@testing-library/react";
2
+ import '@testing-library/jest-dom';
3
+ import { ProgressBar } from "./index";
4
+ import { MultiStepRouteType } from 'types';
5
+ const DEFAULT_HEADER_PROPS = {
6
+ progressBarSteps: [{
7
+ index: 1,
8
+ isNewSection: true,
9
+ sectionIndex: 0,
10
+ type: MultiStepRouteType.PERSONAL,
11
+ title: 'Your Claim'
12
+ },
13
+ {
14
+ index: 2,
15
+ isNewSection: true,
16
+ sectionIndex: 1,
17
+ type: MultiStepRouteType.CLAIM,
18
+ title: 'Personal Details'
19
+ },
20
+ {
21
+ index: 3,
22
+ isNewSection: false,
23
+ sectionIndex: 1,
24
+ type: MultiStepRouteType.CLAIM,
25
+ title: 'Address Details'
26
+ }, {
27
+ index: 4,
28
+ isNewSection: true,
29
+ sectionIndex: 1,
30
+ type: MultiStepRouteType.PAYMENT,
31
+ title: 'Approval'
32
+ }],
33
+ routeStepsWithoutProgress: [MultiStepRouteType.INTRO],
34
+ current: 1,
35
+ };
36
+
37
+ describe("Progress bar component testing with testing-library", () => {
38
+ it("renders without crashing", () => {
39
+ const component = render(<ProgressBar {...DEFAULT_HEADER_PROPS} />);
40
+
41
+ expect(component).toBeTruthy();
42
+ });
43
+ });
44
+
45
+ describe("Progress bar citems to be rendered properly", () => {
46
+ it("item with index 2 to be be in dom", () => {
47
+ const { getByLabelText } = render(<ProgressBar {...DEFAULT_HEADER_PROPS} />);
48
+ expect(getByLabelText('item-2')).toBeTruthy();
49
+ });
50
+ });
@@ -0,0 +1,56 @@
1
+ import { ComponentStory, ComponentMeta } from "@storybook/react";
2
+ import { MultiStepRouteType } from 'types';
3
+
4
+ import { ProgressBar } from "./index";
5
+
6
+ export default {
7
+ title: "Alicia/Common/ProgressBar",
8
+ component: ProgressBar,
9
+ argTypes: {},
10
+ } as ComponentMeta<typeof ProgressBar>;
11
+
12
+ const Template: ComponentStory<typeof ProgressBar> = (args) => {
13
+ return <ProgressBar {...args} />;
14
+ };
15
+
16
+ export const Primary = Template.bind({});
17
+ Primary.args = {
18
+ primaryColor: '#006A70',
19
+ backgroundColor: '#EEEEEE',
20
+ current: 1,
21
+ routeStepsWithoutProgress: [],
22
+ progressBarSteps: [{
23
+ index: 1,
24
+ isNewSection: true,
25
+ sectionIndex: 0,
26
+ type: MultiStepRouteType.ADDITIONAL,
27
+ title: "step 1"
28
+ },
29
+ {
30
+ index: 2,
31
+ isNewSection: false,
32
+ sectionIndex: 0,
33
+ type: MultiStepRouteType.ADDITIONAL,
34
+ title: "step 2"
35
+ },
36
+ {
37
+ index: 3,
38
+ isNewSection: true,
39
+ sectionIndex: 1,
40
+ type: MultiStepRouteType.PAYMENT,
41
+ title: "step 3"
42
+ }, {
43
+ index: 4,
44
+ isNewSection: false,
45
+ sectionIndex: 1,
46
+ type: MultiStepRouteType.PAYMENT,
47
+ title: "step 4"
48
+ }, {
49
+ index: 5,
50
+ isNewSection: false,
51
+ sectionIndex: 1,
52
+ type: MultiStepRouteType.PAYMENT,
53
+ title: "step 5"
54
+ }]
55
+ };
56
+
@@ -0,0 +1,55 @@
1
+ import { Box, Flex } from '@chakra-ui/react';
2
+ import { FC } from "react";
3
+ import { HeaderStep, MultiStepRouteType } from 'types';
4
+
5
+ export const ProgressBar: FC<ProgressBarProps> = ({
6
+ routeStepsWithoutProgress,
7
+ current = 0,
8
+ progressBarSteps,
9
+ primaryColor = 'primary',
10
+ backgroundColor = 'gray.medium'
11
+ }) => {
12
+
13
+ return (
14
+ <Flex width="100%" aria-label="progress-bar">
15
+ {progressBarSteps.filter((item) => !routeStepsWithoutProgress.includes(item.type)).map(({ index, isNewSection }, i) => (
16
+ <ProgressBarStepItem
17
+ index={index}
18
+ key={index}
19
+ backgroundColor={current >= index ? primaryColor : backgroundColor}
20
+ isNewSection={isNewSection && i !== 0} />
21
+ ))}
22
+ </Flex>
23
+ );
24
+ };
25
+
26
+ const ProgressBarStepItem: FC<ProgressBarStepItemProps> = ({
27
+ backgroundColor,
28
+ isNewSection = false,
29
+ index
30
+ }) => {
31
+ return (
32
+ <Box
33
+ aria-label={`item-${index}`}
34
+ width="100%" height="4px"
35
+ bg={backgroundColor}
36
+ marginStart={isNewSection ? '4px' : "0"} />
37
+ );
38
+ };
39
+
40
+ type ProgressBarStepItemProps = {
41
+ backgroundColor: string;
42
+ isNewSection: boolean;
43
+ index: number;
44
+ };
45
+
46
+ type ProgressBarProps = {
47
+ routeStepsWithoutProgress: MultiStepRouteType[];
48
+ current: number;
49
+ progressBarSteps: HeaderStep[];
50
+ primaryColor?: string;
51
+ backgroundColor?: string;
52
+ };
53
+
54
+
55
+
@@ -0,0 +1 @@
1
+ export { ProgressBar } from "./ProgressBar";
@@ -23,7 +23,7 @@ const Template: ComponentStory<typeof RadioButtonGroup> = (args) => {
23
23
  export const Primary = Template.bind({});
24
24
 
25
25
  Primary.args = {
26
- isShownInColumn: true,
26
+ variant: 'column',
27
27
  options: [{ value: '1', label: 'label - 1' }, { value: '2', label: 'label - 2' }],
28
28
  spacing: 5,
29
29
  };
@@ -1,11 +1,11 @@
1
- import { Radio, RadioGroup, Stack } from '@chakra-ui/react';
1
+ import { Radio, RadioGroup, Stack, RadioGroupProps as RadioGroupDefaultProps } from '@chakra-ui/react';
2
2
  import { FC } from 'react';
3
3
 
4
- export const RadioButtonGroup: FC<RadioButtonGroupProps> = ({ isShownInColumn = true, onChange, value, options, spacing = 1 }) => {
4
+ export const RadioButtonGroup: FC<RadioButtonGroupProps> = ({ variant = 'row', onChange, value, options, spacing = 1, ...props }) => {
5
5
 
6
6
  return (
7
- <RadioGroup onChange={onChange} value={value} >
8
- <Stack direction={isShownInColumn ? 'column' : 'row'} spacing={spacing}>
7
+ <RadioGroup onChange={onChange} value={value} {...props}>
8
+ <Stack direction={variant} spacing={spacing}>
9
9
  {options.map((item) => (
10
10
  <Radio key={item.value} value={item.value}>{item.label}</Radio>
11
11
  ))}
@@ -15,8 +15,8 @@ export const RadioButtonGroup: FC<RadioButtonGroupProps> = ({ isShownInColumn =
15
15
 
16
16
  };
17
17
 
18
- type RadioButtonGroupProps = {
19
- isShownInColumn?: boolean;
18
+ type RadioButtonGroupProps = RadioGroupDefaultProps & {
19
+ variant?: 'column' | 'row';
20
20
  onChange: (value: any) => void;
21
21
  value: any;
22
22
  options: RadioButtonOptions[];
@@ -0,0 +1,20 @@
1
+ import { ComponentStory, ComponentMeta } from "@storybook/react";
2
+
3
+ import { Step } from "./Step";
4
+
5
+ export default {
6
+ title: "Alicia/Common/Step",
7
+ component: Step,
8
+ argTypes: {},
9
+ } as ComponentMeta<typeof Step>;
10
+
11
+ const Template: ComponentStory<typeof Step> = (args) => {
12
+ return <Step {...args} />;
13
+ };
14
+
15
+ export const Primary = Template.bind({});
16
+ Primary.args = {
17
+ stepTitle: "Step 1 of 3",
18
+ mainTitle: 'Partner acceptance',
19
+ isMobile: false
20
+ };
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import { Step } from './Step';
4
+
5
+ test('Render main title', () => {
6
+ render(<Step mainTitle="Main title" stepTitle="" isMobile />);
7
+ expect(screen.getByText("Main title")).toBeInTheDocument();
8
+ });
9
+
10
+ test('Render main title and step title', () => {
11
+ render(<Step mainTitle="Main title" stepTitle="Step title" isMobile />);
12
+ expect(screen.getByText("Main title")).toBeInTheDocument();
13
+ expect(screen.getByText("Step title")).toBeInTheDocument();
14
+ });
@@ -0,0 +1,22 @@
1
+ import { Flex, Text } from '@chakra-ui/react';
2
+ import { FC } from 'react';
3
+
4
+ export const Step: FC<StepProps> = ({ stepTitle = "", mainTitle = "", isMobile }) => {
5
+
6
+ return (
7
+ <Flex
8
+ direction="column"
9
+ align="center"
10
+ justify="center"
11
+ >
12
+ {stepTitle !== "" && (<Text fontSize="10">{stepTitle}</Text>)}
13
+ {mainTitle !== "" && (<Text noOfLines={1} textAlign="center" fontSize={isMobile ? '12' : '18'} fontWeight="700">{mainTitle}</Text>)}
14
+ </Flex>
15
+ );
16
+ };
17
+
18
+ type StepProps = {
19
+ isMobile: boolean;
20
+ stepTitle?: string;
21
+ mainTitle?: string;
22
+ };
@@ -0,0 +1,16 @@
1
+ import { createIcon } from '@chakra-ui/icons';
2
+
3
+ export const ChevronDownIcon = createIcon({
4
+ displayName: 'ChevronDownIcon',
5
+ viewBox: '0 0 24 24',
6
+ path: (
7
+ <>
8
+ <mask id="mask0_268_1515" maskUnits="userSpaceOnUse" x="0" y="0" width="24" height="24">
9
+ <rect width="24" height="24" fill="#D9D9D9" />
10
+ </mask>
11
+ <g mask="url(#mask0_268_1515)">
12
+ <path d="M7.40002 14.4999L6.90002 13.9999L12 8.8999L17.1 13.9999L16.6 14.4999L12 9.8999L7.40002 14.4999Z" fill="#1E1E1E" />
13
+ </g>
14
+ </>
15
+ ),
16
+ });
@@ -0,0 +1,16 @@
1
+ import { createIcon } from '@chakra-ui/icons';
2
+
3
+ export const ChevronUpIcon = createIcon({
4
+ displayName: 'ChevronUpIcon',
5
+ viewBox: '0 0 24 24',
6
+ path: (
7
+ <>
8
+ <mask id="mask0_268_1377" maskUnits="userSpaceOnUse" x="0" y="0" width="24" height="24">
9
+ <rect width="24" height="24" fill="#D9D9D9" />
10
+ </mask>
11
+ <g mask="url(#mask0_268_1377)">
12
+ <path d="M12 14.4999L6.90002 9.3999L7.40002 8.8999L12 13.4999L16.6 8.8999L17.1 9.3999L12 14.4999Z" fill="#1E1E1E" />
13
+ </g>
14
+ </>
15
+ ),
16
+ });
@@ -0,0 +1,16 @@
1
+ import { createIcon } from '@chakra-ui/icons';
2
+
3
+ export const GlobeIcon = createIcon({
4
+ displayName: 'GlobeIcon',
5
+ viewBox: '0 0 24 24',
6
+ path: (
7
+ <>
8
+ <mask id="mask0_268_1509" maskUnits="userSpaceOnUse" x="0" y="0" width="24" height="24">
9
+ <rect width="24" height="24" fill="#D9D9D9" />
10
+ </mask>
11
+ <g mask="url(#mask0_268_1509)">
12
+ <path d="M12 20.6998C10.8 20.6998 9.67105 20.4705 8.61305 20.0118C7.55438 19.5538 6.63338 18.9331 5.85005 18.1498C5.06672 17.3665 4.44572 16.4455 3.98705 15.3868C3.52905 14.3288 3.30005 13.1998 3.30005 11.9998C3.30005 10.7998 3.52905 9.67047 3.98705 8.6118C4.44572 7.5538 5.06672 6.63314 5.85005 5.8498C6.63338 5.06647 7.55438 4.44547 8.61305 3.9868C9.67105 3.5288 10.8 3.2998 12 3.2998C13.2 3.2998 14.3294 3.5288 15.388 3.9868C16.446 4.44547 17.3667 5.06647 18.15 5.8498C18.9334 6.63314 19.5544 7.5538 20.0131 8.6118C20.4711 9.67047 20.7001 10.7998 20.7001 11.9998C20.7001 13.1998 20.4711 14.3288 20.0131 15.3868C19.5544 16.4455 18.9334 17.3665 18.15 18.1498C17.3667 18.9331 16.446 19.5538 15.388 20.0118C14.3294 20.4705 13.2 20.6998 12 20.6998ZM12 20.0248C12.6334 19.2248 13.15 18.4498 13.55 17.6998C13.95 16.9498 14.275 16.0998 14.525 15.1498H9.47505C9.75838 16.1665 10.0917 17.0498 10.475 17.7998C10.8584 18.5498 11.3667 19.2915 12 20.0248ZM11.125 19.9498C10.6084 19.3998 10.1334 18.6871 9.70005 17.8118C9.26672 16.9371 8.95005 16.0498 8.75005 15.1498H4.65005C5.25005 16.5165 6.12505 17.6248 7.27505 18.4748C8.42505 19.3248 9.70838 19.8165 11.125 19.9498ZM12.875 19.9498C14.2917 19.8165 15.575 19.3248 16.725 18.4748C17.875 17.6248 18.75 16.5165 19.35 15.1498H15.25C14.9667 16.0665 14.6084 16.9621 14.175 17.8368C13.7417 18.7121 13.3084 19.4165 12.875 19.9498ZM4.37505 14.4498H8.60005C8.51672 14.0165 8.45838 13.5958 8.42505 13.1878C8.39172 12.7791 8.37505 12.3831 8.37505 11.9998C8.37505 11.6165 8.39172 11.2205 8.42505 10.8118C8.45838 10.4038 8.51672 9.98314 8.60005 9.5498H4.37505C4.25838 9.8998 4.16672 10.2915 4.10005 10.7248C4.03338 11.1581 4.00005 11.5831 4.00005 11.9998C4.00005 12.4165 4.03338 12.8415 4.10005 13.2748C4.16672 13.7081 4.25838 14.0998 4.37505 14.4498ZM9.30005 14.4498H14.7C14.7834 14.0165 14.8417 13.6038 14.875 13.2118C14.9084 12.8205 14.925 12.4165 14.925 11.9998C14.925 11.5831 14.9084 11.1788 14.875 10.7868C14.8417 10.3955 14.7834 9.98314 14.7 9.5498H9.30005C9.21672 9.98314 9.15838 10.3955 9.12505 10.7868C9.09172 11.1788 9.07505 11.5831 9.07505 11.9998C9.07505 12.4165 9.09172 12.8205 9.12505 13.2118C9.15838 13.6038 9.21672 14.0165 9.30005 14.4498ZM15.4 14.4498H19.625C19.7417 14.0998 19.8334 13.7081 19.9 13.2748C19.9667 12.8415 20 12.4165 20 11.9998C20 11.5831 19.9667 11.1581 19.9 10.7248C19.8334 10.2915 19.7417 9.8998 19.625 9.5498H15.4C15.4834 9.98314 15.5417 10.4038 15.575 10.8118C15.6084 11.2205 15.625 11.6165 15.625 11.9998C15.625 12.3831 15.6084 12.7791 15.575 13.1878C15.5417 13.5958 15.4834 14.0165 15.4 14.4498ZM15.25 8.8498H19.35C18.7334 7.4498 17.871 6.34147 16.763 5.5248C15.6544 4.70814 14.3584 4.20814 12.875 4.0248C13.3917 4.65814 13.8584 5.3998 14.275 6.2498C14.6917 7.0998 15.0167 7.96647 15.25 8.8498ZM9.47505 8.8498H14.525C14.2417 7.8498 13.896 6.9538 13.488 6.1618C13.0794 5.37047 12.5834 4.64147 12 3.9748C11.4167 4.64147 10.9207 5.37047 10.512 6.1618C10.104 6.9538 9.75838 7.8498 9.47505 8.8498ZM4.65005 8.8498H8.75005C8.98338 7.96647 9.30838 7.0998 9.72505 6.2498C10.1417 5.3998 10.6084 4.65814 11.125 4.0248C9.62505 4.20814 8.32505 4.71214 7.22505 5.5368C6.12505 6.36214 5.26672 7.46647 4.65005 8.8498Z" fill="#1E1E1E" />
13
+ </g>
14
+ </>
15
+ ),
16
+ });
@@ -0,0 +1,11 @@
1
+ import { createIcon } from "@chakra-ui/icons";
2
+
3
+ export const SupportIcon = createIcon({
4
+ displayName: "SupportIcon",
5
+ viewBox: "0 0 16 18",
6
+ path: (
7
+ <path
8
+ d="M8.00005 17.9V17.2H14.2C14.4334 17.2 14.625 17.125 14.775 16.975C14.925 16.825 15 16.6333 15 16.4V15.7H12.2V10.1H15V7.99999C15 6.06665 14.3167 4.41665 12.95 3.04999C11.5834 1.68332 9.93338 0.999988 8.00005 0.999988C6.06672 0.999988 4.41672 1.68332 3.05005 3.04999C1.68338 4.41665 1.00005 6.06665 1.00005 7.99999V10.1H3.80005V15.7H1.80005C1.36672 15.7 1.00838 15.5583 0.725049 15.275C0.441715 14.9917 0.300049 14.6333 0.300049 14.2V7.99999C0.300049 6.93332 0.500049 5.93332 0.900049 4.99999C1.30005 4.06665 1.85005 3.24999 2.55005 2.54999C3.25005 1.84999 4.06672 1.29999 5.00005 0.899988C5.93338 0.499988 6.93338 0.299988 8.00005 0.299988C9.06672 0.299988 10.0667 0.499988 11 0.899988C11.9334 1.29999 12.75 1.84999 13.45 2.54999C14.15 3.24999 14.7 4.06665 15.1 4.99999C15.5 5.93332 15.7 6.93332 15.7 7.99999V16.4C15.7 16.8333 15.5584 17.1917 15.275 17.475C14.9917 17.7583 14.6334 17.9 14.2 17.9H8.00005ZM1.80005 15H3.10005V10.8H1.00005V14.2C1.00005 14.4333 1.07505 14.625 1.22505 14.775C1.37505 14.925 1.56672 15 1.80005 15ZM12.9 15H15V10.8H12.9V15ZM15 15H12.9H15ZM3.10005 15H1.00005H3.10005Z"
9
+ />
10
+ ),
11
+ });
@@ -1,4 +1,8 @@
1
1
  export * from './DeleteIcon';
2
2
  export * from './PdfIcon';
3
3
  export * from './UploadIcon';
4
- export * from './InfoIcon';
4
+ export * from './InfoIcon';
5
+ export * from './SupportIcon';
6
+ export * from './ChevronUpIcon';
7
+ export * from './ChevronDownIcon';
8
+ export * from './GlobeIcon';
@@ -0,0 +1,17 @@
1
+ <svg width="83" height="32" viewBox="0 0 83 32" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <g clip-path="url(#clip0_268_1358)">
3
+ <path d="M16.4388 21.7486H6.26221L4.11629 27.2823H0L9.06637 4.71729H13.7751L22.8459 27.2823H18.5453L16.4388 21.7486ZM7.56116 18.4968H15.175L11.4449 8.76336H11.3527L7.56116 18.4968Z" fill="#1E1E1E"/>
4
+ <path d="M24.101 27.2823V4.02393H28.1426V27.2823H24.101Z" fill="#1E1E1E"/>
5
+ <path d="M31.0959 4.55957H35.3966V8.5091H31.0959V4.55957ZM31.2232 11.2299H35.2693V27.2826H31.2232V11.2299Z" fill="#1E1E1E"/>
6
+ <path d="M45.4064 10.8481C49.3911 10.8481 51.9495 13.1564 52.3927 16.7242H48.566C48.2501 14.9688 47.21 13.8805 45.3757 13.8805C42.8173 13.8805 41.3954 16.0001 41.3954 19.2563C41.3954 22.5124 42.8173 24.6276 45.3757 24.6276C47.21 24.6276 48.2501 23.4867 48.566 21.784H52.3927C51.9539 25.3824 49.3911 27.66 45.4064 27.66C40.6977 27.66 37.3494 24.4696 37.3494 19.2563C37.3494 14.0429 40.6977 10.8481 45.4064 10.8481Z" fill="#1E1E1E"/>
7
+ <path d="M54.3062 4.55957H58.6068V8.5091H54.3062V4.55957ZM54.4334 11.2299H58.4795V27.2826H54.4159L54.4334 11.2299Z" fill="#1E1E1E"/>
8
+ <path d="M71.2759 24.7505C70.5167 26.5848 68.4937 27.6293 65.9353 27.6293C62.8064 27.6293 60.5332 25.8739 60.5332 22.982C60.5332 19.7609 63.0609 18.4312 66.3127 18.0538L71.118 17.5185V16.7593C71.118 14.7977 69.9155 13.8498 68.0856 13.8498C66.2556 13.8498 65.2419 14.8284 65.1147 16.3161H61.2266C61.5732 12.8712 64.2589 10.8481 68.2129 10.8481C72.5705 10.8481 75.0675 12.9019 75.0675 17.0752V23.2672C75.0368 24.6145 75.1465 25.9573 75.3834 27.2826H71.4954C71.3461 26.4488 71.2759 25.5975 71.2759 24.7505ZM71.118 21.0555V20.0769L67.5458 20.485C65.8387 20.7088 64.5442 21.0862 64.5442 22.7626C64.5442 24.0264 65.4218 24.8163 67.0412 24.8163C69.1256 24.8163 71.118 23.5832 71.118 21.0555Z" fill="#1E1E1E"/>
9
+ <path d="M82.1109 0V32H81.5184V0H82.1109Z" fill="#1E1E1E"/>
10
+ <path d="M78.9599 6.53846C78.9599 7.60045 78.0954 8.46057 77.0335 8.45618C75.9715 8.45179 75.1114 7.59167 75.1157 6.52969C75.1157 5.4677 75.9802 4.60758 77.0422 4.61197C78.0867 4.59881 78.9468 5.4326 78.9599 6.47703C78.9599 6.49897 78.9599 6.51652 78.9599 6.53846ZM78.6923 6.53846C78.6747 5.62568 77.9243 4.9016 77.0115 4.91916C76.0987 4.93671 75.3747 5.68712 75.3922 6.5999C75.4098 7.49952 76.1426 8.21921 77.0422 8.21921C77.9419 8.23238 78.6791 7.51268 78.6923 6.61307C78.6923 6.58674 78.6923 6.5648 78.6923 6.53846ZM76.2743 7.53024V5.48087H77.1519C77.6171 5.48087 77.9024 5.70906 77.9024 6.12596C77.9155 6.39365 77.7488 6.63501 77.4942 6.714L77.977 7.52585H77.5381L77.0993 6.78421H76.6604V7.52585H76.2743V7.53024ZM77.0993 6.45947C77.3758 6.45947 77.503 6.35854 77.503 6.13473C77.503 5.91093 77.3758 5.81438 77.0993 5.81438H76.6604V6.45947H77.0993Z" fill="#1E1E1E"/>
11
+ </g>
12
+ <defs>
13
+ <clipPath id="clip0_268_1358">
14
+ <rect width="82.1108" height="32" fill="white"/>
15
+ </clipPath>
16
+ </defs>
17
+ </svg>
package/src/setupTests.ts CHANGED
@@ -3,3 +3,11 @@
3
3
  // expect(element).toHaveTextContent(/react/i)
4
4
  // learn more: https://github.com/testing-library/jest-dom
5
5
  import '@testing-library/jest-dom';
6
+
7
+ window.matchMedia = window.matchMedia || function () {
8
+ return {
9
+ matches: false,
10
+ addListener: function () { },
11
+ removeListener: function () { }
12
+ };
13
+ };
@@ -24,6 +24,7 @@ export const chakraTheme = extendTheme({
24
24
  colors: {
25
25
  error: '#AC0000',
26
26
  cardBg: '#F2F2F2',
27
+ headerBg: '#F3F3F3',
27
28
  whiteDe: ({ colorMode }: { colorMode: string; }) => colorModeValues(colorMode, '#000000', '#FFFFFF'),
28
29
  blackDe: ({ colorMode }: { colorMode: string; }) => colorModeValues(colorMode, '#FFFFFF', '#000000'),
29
30
  blackLi: ({ colorMode }: { colorMode: string; }) => colorModeValues(colorMode, '#FFFFFF', 'rgba(0,0,0,0.33)'),
@@ -40,7 +41,6 @@ export const chakraTheme = extendTheme({
40
41
  800: '#004a4e',
41
42
  900: '#004043',
42
43
  },
43
-
44
44
  black: Object.assign('#13100D', {
45
45
  light: 'rgba(0,0,0,0.33)',
46
46
  medium: 'rgba(0,0,0,0.8)',
@@ -69,6 +69,7 @@ export const chakraTheme = extendTheme({
69
69
  text: '#003957',
70
70
  textSecondary: '#275B76',
71
71
  hover: '#F5FcFc',
72
+ dropDownHover: 'rgba(181, 201, 255, 1)',
72
73
  },
73
74
  sizes: {
74
75
  md: '544px',
@@ -123,7 +124,8 @@ export const chakraTheme = extendTheme({
123
124
  Checkbox: {
124
125
  baseStyle: {
125
126
  control: {
126
- borderColor: "gray.light",
127
+ borderColor: "black.medium",
128
+ borderWidth: '1px',
127
129
  height: '24px',
128
130
  width: '24px',
129
131
  _checked: {
@@ -1,3 +1,4 @@
1
1
  // Modules
2
2
  export * from "./general";
3
3
  export * from "styles/types";
4
+ export * from "./route";
@@ -0,0 +1,19 @@
1
+ export type MultiStepRoute = {
2
+ name: string;
3
+ path: string;
4
+ component: React.FC;
5
+ type: MultiStepRouteType;
6
+ customTitle?: string;
7
+ };
8
+
9
+ export enum MultiStepRouteType {
10
+ PERSONAL, ADDITIONAL, PAYMENT, CLAIM, EXIT_SURVEY, INTRO,
11
+ }
12
+
13
+ export type HeaderStep = {
14
+ index: number;
15
+ isNewSection: boolean;
16
+ sectionIndex: number;
17
+ type: MultiStepRouteType;
18
+ title: string;
19
+ };
package/src/App.test.tsx DELETED
@@ -1,9 +0,0 @@
1
- import React from 'react';
2
- import { render, screen } from '@testing-library/react';
3
- import App from './App';
4
-
5
- test('renders learn react link', () => {
6
- render(<App />);
7
- const linkElement = screen.getByText(/learn react/i);
8
- expect(linkElement).toBeInTheDocument();
9
- });