@onewelcome/react-lib-components 0.1.0-alpha

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 (248) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +71 -0
  3. package/dist/BaseModal/BaseModal.d.ts +16 -0
  4. package/dist/BaseModal/BaseModalActions/BaseModalActions.d.ts +5 -0
  5. package/dist/BaseModal/BaseModalContent/BaseModalContent.d.ts +8 -0
  6. package/dist/BaseModal/BaseModalContext.d.ts +2 -0
  7. package/dist/BaseModal/BaseModalHeader/BaseModalHeader.d.ts +8 -0
  8. package/dist/Breadcrumbs/Breadcrumbs.d.ts +9 -0
  9. package/dist/Button/BaseButton.d.ts +8 -0
  10. package/dist/Button/Button.d.ts +10 -0
  11. package/dist/Button/IconButton.d.ts +10 -0
  12. package/dist/ContextMenu/ContextMenu.d.ts +18 -0
  13. package/dist/ContextMenu/ContextMenuItem.d.ts +6 -0
  14. package/dist/Dialog/Dialog.d.ts +18 -0
  15. package/dist/Dialog/DialogActions/DialogActions.d.ts +6 -0
  16. package/dist/Dialog/DialogTitle/DialogTitle.d.ts +6 -0
  17. package/dist/Form/Checkbox/Checkbox.d.ts +13 -0
  18. package/dist/Form/Fieldset/Fieldset.d.ts +13 -0
  19. package/dist/Form/Form.d.ts +5 -0
  20. package/dist/Form/FormControl/FormControl.d.ts +8 -0
  21. package/dist/Form/FormGroup/FormGroup.d.ts +18 -0
  22. package/dist/Form/FormHelperText/FormHelperText.d.ts +7 -0
  23. package/dist/Form/FormSelectorWrapper/FormSelectorWrapper.d.ts +18 -0
  24. package/dist/Form/Input/Input.d.ts +12 -0
  25. package/dist/Form/Label/Label.d.ts +6 -0
  26. package/dist/Form/Radio/Radio.d.ts +11 -0
  27. package/dist/Form/Select/Option.d.ts +12 -0
  28. package/dist/Form/Select/Select.d.ts +15 -0
  29. package/dist/Form/Textarea/Textarea.d.ts +7 -0
  30. package/dist/Form/Toggle/Toggle.d.ts +6 -0
  31. package/dist/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.d.ts +8 -0
  32. package/dist/Form/Wrapper/InputWrapper/InputWrapper.d.ts +17 -0
  33. package/dist/Form/Wrapper/RadioWrapper/RadioWrapper.d.ts +10 -0
  34. package/dist/Form/Wrapper/SelectWrapper/SelectWrapper.d.ts +12 -0
  35. package/dist/Form/Wrapper/TextareaWrapper/TextareaWrapper.d.ts +14 -0
  36. package/dist/Form/Wrapper/Wrapper/Wrapper.d.ts +28 -0
  37. package/dist/Form/form.interfaces.d.ts +12 -0
  38. package/dist/Icon/Icon.d.ts +75 -0
  39. package/dist/Link/Link.d.ts +15 -0
  40. package/dist/Modal/Modal.d.ts +1 -0
  41. package/dist/Modal/ModalActions/ModalActions.d.ts +1 -0
  42. package/dist/Modal/ModalContent/ModalContent.d.ts +1 -0
  43. package/dist/Modal/ModalHeader/ModalHeader.d.ts +1 -0
  44. package/dist/Popover/Popover.d.ts +11 -0
  45. package/dist/Snackbar/SnackbarContainer/SnackbarContainer.d.ts +12 -0
  46. package/dist/Snackbar/SnackbarItem/SnackbarItem.d.ts +13 -0
  47. package/dist/Snackbar/SnackbarProvider/SnackbarProvider.d.ts +18 -0
  48. package/dist/Snackbar/SnackbarProvider/SnackbarStateProvider.d.ts +14 -0
  49. package/dist/Snackbar/interfaces.d.ts +10 -0
  50. package/dist/Snackbar/useSnackbar.d.ts +1 -0
  51. package/dist/Tiles/Tile.d.ts +16 -0
  52. package/dist/Tiles/Tiles.d.ts +6 -0
  53. package/dist/Tooltip/Tooltip.d.ts +11 -0
  54. package/dist/Typography/Typography.d.ts +12 -0
  55. package/dist/Wizard/BaseWizardSteps/BaseWizardSteps.d.ts +13 -0
  56. package/dist/Wizard/Wizard.d.ts +12 -0
  57. package/dist/Wizard/WizardActions/WizardActions.d.ts +12 -0
  58. package/dist/Wizard/WizardStateProvider.d.ts +12 -0
  59. package/dist/Wizard/WizardSteps/WizardSteps.d.ts +5 -0
  60. package/dist/Wizard/wizardStateReducer.d.ts +26 -0
  61. package/dist/_BaseStyling_/BaseStyling.d.ts +47 -0
  62. package/dist/hooks/useAnimation.d.ts +6 -0
  63. package/dist/hooks/useBodyClick.d.ts +1 -0
  64. package/dist/hooks/useFormSelector.d.ts +13 -0
  65. package/dist/hooks/usePosition.d.ts +36 -0
  66. package/dist/hooks/useScroll.d.ts +2 -0
  67. package/dist/hooks/useSpacing.d.ts +18 -0
  68. package/dist/hooks/useWrapper.d.ts +11 -0
  69. package/dist/index.d.ts +43 -0
  70. package/dist/index.js +8 -0
  71. package/dist/interfaces.d.ts +13 -0
  72. package/dist/react-lib-components.cjs.development.js +3282 -0
  73. package/dist/react-lib-components.cjs.development.js.map +1 -0
  74. package/dist/react-lib-components.cjs.production.min.js +2 -0
  75. package/dist/react-lib-components.cjs.production.min.js.map +1 -0
  76. package/dist/react-lib-components.esm.js +3235 -0
  77. package/dist/react-lib-components.esm.js.map +1 -0
  78. package/dist/util/helper.d.ts +1 -0
  79. package/package.json +88 -0
  80. package/src/BaseModal/BaseModal.module.scss +58 -0
  81. package/src/BaseModal/BaseModal.test.tsx +59 -0
  82. package/src/BaseModal/BaseModal.tsx +113 -0
  83. package/src/BaseModal/BaseModalActions/BaseModalActions.module.scss +9 -0
  84. package/src/BaseModal/BaseModalActions/BaseModalActions.test.tsx +17 -0
  85. package/src/BaseModal/BaseModalActions/BaseModalActions.tsx +14 -0
  86. package/src/BaseModal/BaseModalContent/BaseModalContent.module.scss +6 -0
  87. package/src/BaseModal/BaseModalContent/BaseModalContent.test.tsx +29 -0
  88. package/src/BaseModal/BaseModalContent/BaseModalContent.tsx +35 -0
  89. package/src/BaseModal/BaseModalContext.ts +2 -0
  90. package/src/BaseModal/BaseModalHeader/BaseModalHeader.module.scss +17 -0
  91. package/src/BaseModal/BaseModalHeader/BaseModalHeader.test.tsx +30 -0
  92. package/src/BaseModal/BaseModalHeader/BaseModalHeader.tsx +28 -0
  93. package/src/Breadcrumbs/Breadcrumbs.module.scss +14 -0
  94. package/src/Breadcrumbs/Breadcrumbs.test.tsx +42 -0
  95. package/src/Breadcrumbs/Breadcrumbs.tsx +48 -0
  96. package/src/Button/BaseButton.module.scss +20 -0
  97. package/src/Button/BaseButton.test.tsx +59 -0
  98. package/src/Button/BaseButton.tsx +31 -0
  99. package/src/Button/Button.module.scss +336 -0
  100. package/src/Button/Button.test.tsx +76 -0
  101. package/src/Button/Button.tsx +44 -0
  102. package/src/Button/IconButton.module.scss +161 -0
  103. package/src/Button/IconButton.test.tsx +47 -0
  104. package/src/Button/IconButton.tsx +29 -0
  105. package/src/ContextMenu/ContextMenu.module.scss +20 -0
  106. package/src/ContextMenu/ContextMenu.test.tsx +93 -0
  107. package/src/ContextMenu/ContextMenu.tsx +91 -0
  108. package/src/ContextMenu/ContextMenuItem.module.scss +31 -0
  109. package/src/ContextMenu/ContextMenuItem.tsx +15 -0
  110. package/src/Dialog/Dialog.module.scss +16 -0
  111. package/src/Dialog/Dialog.test.tsx +79 -0
  112. package/src/Dialog/Dialog.tsx +96 -0
  113. package/src/Dialog/DialogActions/DialogActions.module.scss +11 -0
  114. package/src/Dialog/DialogActions/DialogActions.test.tsx +25 -0
  115. package/src/Dialog/DialogActions/DialogActions.tsx +21 -0
  116. package/src/Dialog/DialogTitle/DialogTitle.module.scss +7 -0
  117. package/src/Dialog/DialogTitle/DialogTitle.test.tsx +18 -0
  118. package/src/Dialog/DialogTitle/DialogTitle.tsx +18 -0
  119. package/src/Form/Checkbox/Checkbox.module.scss +65 -0
  120. package/src/Form/Checkbox/Checkbox.test.tsx +119 -0
  121. package/src/Form/Checkbox/Checkbox.tsx +145 -0
  122. package/src/Form/Fieldset/Fieldset.module.scss +19 -0
  123. package/src/Form/Fieldset/Fieldset.test.tsx +85 -0
  124. package/src/Form/Fieldset/Fieldset.tsx +55 -0
  125. package/src/Form/Form.module.scss +3 -0
  126. package/src/Form/Form.test.tsx +47 -0
  127. package/src/Form/Form.tsx +14 -0
  128. package/src/Form/FormControl/FormControl.module.scss +67 -0
  129. package/src/Form/FormControl/FormControl.test.tsx +56 -0
  130. package/src/Form/FormControl/FormControl.tsx +47 -0
  131. package/src/Form/FormGroup/FormGroup.module.scss +29 -0
  132. package/src/Form/FormGroup/FormGroup.test.tsx +61 -0
  133. package/src/Form/FormGroup/FormGroup.tsx +78 -0
  134. package/src/Form/FormHelperText/FormHelperText.module.scss +8 -0
  135. package/src/Form/FormHelperText/FormHelperText.test.tsx +42 -0
  136. package/src/Form/FormHelperText/FormHelperText.tsx +22 -0
  137. package/src/Form/FormSelectorWrapper/FormSelectorWrapper.module.scss +33 -0
  138. package/src/Form/FormSelectorWrapper/FormSelectorWrapper.tsx +65 -0
  139. package/src/Form/Input/Input.module.scss +65 -0
  140. package/src/Form/Input/Input.test.tsx +135 -0
  141. package/src/Form/Input/Input.tsx +72 -0
  142. package/src/Form/Label/Label.module.scss +5 -0
  143. package/src/Form/Label/Label.test.tsx +26 -0
  144. package/src/Form/Label/Label.tsx +19 -0
  145. package/src/Form/Radio/Radio.module.scss +100 -0
  146. package/src/Form/Radio/Radio.test.tsx +88 -0
  147. package/src/Form/Radio/Radio.tsx +98 -0
  148. package/src/Form/Select/Option.test.tsx +15 -0
  149. package/src/Form/Select/Option.tsx +57 -0
  150. package/src/Form/Select/Select.module.scss +189 -0
  151. package/src/Form/Select/Select.test.tsx +96 -0
  152. package/src/Form/Select/Select.tsx +217 -0
  153. package/src/Form/Textarea/Textarea.module.scss +53 -0
  154. package/src/Form/Textarea/Textarea.test.tsx +76 -0
  155. package/src/Form/Textarea/Textarea.tsx +33 -0
  156. package/src/Form/Toggle/Toggle.module.scss +58 -0
  157. package/src/Form/Toggle/Toggle.test.tsx +29 -0
  158. package/src/Form/Toggle/Toggle.tsx +20 -0
  159. package/src/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.module.scss +12 -0
  160. package/src/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.test.tsx +99 -0
  161. package/src/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.tsx +62 -0
  162. package/src/Form/Wrapper/InputWrapper/InputWrapper.module.scss +24 -0
  163. package/src/Form/Wrapper/InputWrapper/InputWrapper.test.tsx +93 -0
  164. package/src/Form/Wrapper/InputWrapper/InputWrapper.tsx +92 -0
  165. package/src/Form/Wrapper/RadioWrapper/RadioWrapper.module.scss +12 -0
  166. package/src/Form/Wrapper/RadioWrapper/RadioWrapper.test.tsx +101 -0
  167. package/src/Form/Wrapper/RadioWrapper/RadioWrapper.tsx +74 -0
  168. package/src/Form/Wrapper/SelectWrapper/SelectWrapper.module.scss +14 -0
  169. package/src/Form/Wrapper/SelectWrapper/SelectWrapper.test.tsx +101 -0
  170. package/src/Form/Wrapper/SelectWrapper/SelectWrapper.tsx +59 -0
  171. package/src/Form/Wrapper/TextareaWrapper/TextareaWrapper.module.scss +65 -0
  172. package/src/Form/Wrapper/TextareaWrapper/TextareaWrapper.test.tsx +125 -0
  173. package/src/Form/Wrapper/TextareaWrapper/TextareaWrapper.tsx +105 -0
  174. package/src/Form/Wrapper/Wrapper/Wrapper.module.scss +35 -0
  175. package/src/Form/Wrapper/Wrapper/Wrapper.test.tsx +17 -0
  176. package/src/Form/Wrapper/Wrapper/Wrapper.tsx +101 -0
  177. package/src/Form/form.interfaces.ts +14 -0
  178. package/src/Icon/Icon.module.scss +278 -0
  179. package/src/Icon/Icon.test.tsx +39 -0
  180. package/src/Icon/Icon.tsx +94 -0
  181. package/src/Link/Link.module.scss +46 -0
  182. package/src/Link/Link.test.tsx +122 -0
  183. package/src/Link/Link.tsx +80 -0
  184. package/src/Link/types.d.ts +9 -0
  185. package/src/Modal/Modal.test.tsx +16 -0
  186. package/src/Modal/Modal.tsx +1 -0
  187. package/src/Modal/ModalActions/ModalActions.tsx +4 -0
  188. package/src/Modal/ModalContent/ModalContent.tsx +4 -0
  189. package/src/Modal/ModalHeader/ModalHeader.tsx +4 -0
  190. package/src/Popover/Popover.module.scss +18 -0
  191. package/src/Popover/Popover.test.tsx +84 -0
  192. package/src/Popover/Popover.tsx +46 -0
  193. package/src/Snackbar/SnackbarContainer/SnackbarContainer.module.scss +35 -0
  194. package/src/Snackbar/SnackbarContainer/SnackbarContainer.test.tsx +37 -0
  195. package/src/Snackbar/SnackbarContainer/SnackbarContainer.tsx +28 -0
  196. package/src/Snackbar/SnackbarItem/SnackbarItem.module.scss +135 -0
  197. package/src/Snackbar/SnackbarItem/SnackbarItem.test.tsx +47 -0
  198. package/src/Snackbar/SnackbarItem/SnackbarItem.tsx +105 -0
  199. package/src/Snackbar/SnackbarProvider/SnackbarProvider.test.tsx +179 -0
  200. package/src/Snackbar/SnackbarProvider/SnackbarProvider.tsx +127 -0
  201. package/src/Snackbar/SnackbarProvider/SnackbarStateProvider.tsx +25 -0
  202. package/src/Snackbar/interfaces.ts +11 -0
  203. package/src/Snackbar/useSnackbar.ts +4 -0
  204. package/src/Tiles/Tile.module.scss +72 -0
  205. package/src/Tiles/Tile.test.tsx +129 -0
  206. package/src/Tiles/Tile.tsx +48 -0
  207. package/src/Tiles/Tiles.module.scss +11 -0
  208. package/src/Tiles/Tiles.test.tsx +118 -0
  209. package/src/Tiles/Tiles.tsx +48 -0
  210. package/src/Tooltip/Tooltip.module.scss +42 -0
  211. package/src/Tooltip/Tooltip.test.tsx +72 -0
  212. package/src/Tooltip/Tooltip.tsx +130 -0
  213. package/src/Typography/Typography.module.scss +46 -0
  214. package/src/Typography/Typography.test.tsx +114 -0
  215. package/src/Typography/Typography.tsx +84 -0
  216. package/src/Wizard/BaseWizardSteps/BaseWizardSteps.module.scss +192 -0
  217. package/src/Wizard/BaseWizardSteps/BaseWizardSteps.test.tsx +75 -0
  218. package/src/Wizard/BaseWizardSteps/BaseWizardSteps.tsx +86 -0
  219. package/src/Wizard/Wizard.test.tsx +198 -0
  220. package/src/Wizard/Wizard.tsx +49 -0
  221. package/src/Wizard/WizardActions/WizardActions.test.tsx +168 -0
  222. package/src/Wizard/WizardActions/WizardActions.tsx +100 -0
  223. package/src/Wizard/WizardStateProvider.tsx +26 -0
  224. package/src/Wizard/WizardSteps/WizardSteps.test.tsx +110 -0
  225. package/src/Wizard/WizardSteps/WizardSteps.tsx +30 -0
  226. package/src/Wizard/wizardStateReducer.ts +51 -0
  227. package/src/_BaseStyling_/BaseStyling.test.tsx +39 -0
  228. package/src/_BaseStyling_/BaseStyling.tsx +115 -0
  229. package/src/hooks/useAnimation.test.tsx +45 -0
  230. package/src/hooks/useAnimation.ts +20 -0
  231. package/src/hooks/useBodyClick.test.tsx +39 -0
  232. package/src/hooks/useBodyClick.ts +20 -0
  233. package/src/hooks/useFormSelector.test.ts +40 -0
  234. package/src/hooks/useFormSelector.ts +47 -0
  235. package/src/hooks/usePosition.test.tsx +494 -0
  236. package/src/hooks/usePosition.ts +347 -0
  237. package/src/hooks/useScroll.test.tsx +20 -0
  238. package/src/hooks/useScroll.ts +16 -0
  239. package/src/hooks/useSpacing.test.ts +70 -0
  240. package/src/hooks/useSpacing.ts +42 -0
  241. package/src/hooks/useWrapper.test.ts +49 -0
  242. package/src/hooks/useWrapper.ts +35 -0
  243. package/src/index.ts +52 -0
  244. package/src/interfaces.ts +15 -0
  245. package/src/readyclasses.module.scss +77 -0
  246. package/src/types.d.ts +4 -0
  247. package/src/util/helper.test.tsx +15 -0
  248. package/src/util/helper.tsx +80 -0
@@ -0,0 +1,65 @@
1
+ .checkbox-wrapper {
2
+ position: relative;
3
+
4
+ + .checkbox-wrapper {
5
+ margin-top: 1.25rem;
6
+ }
7
+ }
8
+
9
+ .checkbox-container {
10
+ display: flex;
11
+ align-items: center;
12
+
13
+ label {
14
+ display: inline-block;
15
+ margin-left: 0.5rem;
16
+ user-select: none;
17
+ font-size: var(--font-size);
18
+ }
19
+ }
20
+
21
+ .checkbox-list {
22
+ padding: 0;
23
+ margin: 1.25rem 0 0 1.75rem;
24
+ list-style: none;
25
+
26
+ li + li {
27
+ margin-top: 1.25rem;
28
+ }
29
+ }
30
+
31
+ .native-input {
32
+ position: absolute;
33
+ top: 0;
34
+ left: 0;
35
+ opacity: 0;
36
+ margin: 0;
37
+ width: 1.25rem;
38
+ height: 1.25rem;
39
+
40
+ &:not(.error):not(:disabled):focus,
41
+ &:not(.error):not(:disabled):active {
42
+ + * {
43
+ color: var(--color-primary);
44
+ }
45
+ }
46
+
47
+ &:focus-visible {
48
+ + * {
49
+ border-radius: 2px;
50
+ outline: 1px solid var(--color-primary);
51
+ outline-offset: 1px;
52
+ }
53
+ }
54
+
55
+ &.error:focus-visible {
56
+ + * {
57
+ outline-color: var(--color-error);
58
+ }
59
+ }
60
+ }
61
+
62
+ .input {
63
+ font-size: 1.25rem;
64
+ pointer-events: none;
65
+ }
@@ -0,0 +1,119 @@
1
+ import React from 'react';
2
+ import { Checkbox, CheckboxProps as Props } from './Checkbox';
3
+ import { render } from '@testing-library/react';
4
+ import userEvent from '@testing-library/user-event';
5
+
6
+ const onChangeHandeler = jest.fn();
7
+
8
+ const defaultParams: Props = {
9
+ name: 'Testing',
10
+ children: 'checkbox content',
11
+ helperText: 'example helper',
12
+ onChange: onChangeHandeler,
13
+ };
14
+
15
+ const createCheckbox = (params?: (defaultParams: Props) => Props) => {
16
+ let parameters: Props = defaultParams;
17
+ if (params) {
18
+ parameters = params(defaultParams);
19
+ }
20
+ const queries = render(<Checkbox {...parameters} data-testid="checkbox" />);
21
+ const checkbox = queries.getByTestId('checkbox');
22
+
23
+ return {
24
+ ...queries,
25
+ checkbox,
26
+ };
27
+ };
28
+
29
+ describe('Checkbox should render', () => {
30
+ it('renders without crashing', () => {
31
+ const { checkbox } = createCheckbox();
32
+ expect(checkbox).toBeTruthy();
33
+ });
34
+ });
35
+
36
+ describe('Checkbox should have proper attributes', () => {
37
+ it('should be unchecked', () => {
38
+ const { checkbox } = createCheckbox();
39
+
40
+ expect(checkbox).toHaveAttribute('aria-checked', 'false');
41
+ });
42
+
43
+ it('should be checked', () => {
44
+ const { checkbox } = createCheckbox((defaultParams) => ({ ...defaultParams, checked: true }));
45
+
46
+ expect(checkbox).toHaveAttribute('aria-checked', 'true');
47
+ });
48
+
49
+ it('should call the onChange function', () => {
50
+ const onChangeHandler = jest.fn();
51
+ const { checkbox } = createCheckbox((defaultParams) => ({
52
+ ...defaultParams,
53
+ onChange: onChangeHandler,
54
+ }));
55
+ userEvent.click(checkbox);
56
+ expect(onChangeHandler).toHaveBeenCalled();
57
+ });
58
+
59
+ it('should be disabled', () => {
60
+ const { checkbox } = createCheckbox((defaultParams) => ({ ...defaultParams, disabled: true }));
61
+
62
+ expect(checkbox).toHaveAttribute('disabled');
63
+ });
64
+
65
+ it('should have helpertext rendered', () => {
66
+ const { getByText } = createCheckbox();
67
+
68
+ const helperText = getByText('example helper');
69
+
70
+ expect(helperText).toBeTruthy();
71
+ });
72
+
73
+ it('should have the error state enabled', () => {
74
+ const { checkbox, container, getByTestId } = createCheckbox((defaultParams) => ({
75
+ ...defaultParams,
76
+ error: true,
77
+ errorMessage: 'This is an error',
78
+ wrapperProps: { 'data-testid': 'checkbox-wrapper' },
79
+ }));
80
+
81
+ expect(checkbox).toHaveAttribute(
82
+ 'aria-describedby',
83
+ container.querySelector('.error-message span:last-of-type')!.id
84
+ );
85
+
86
+ expect(checkbox).toHaveAttribute('aria-invalid', 'true');
87
+ expect(getByTestId('checkbox-wrapper')).toHaveClass('error');
88
+ });
89
+
90
+ it('should have a correctly linked label element', () => {
91
+ const { checkbox, container } = createCheckbox((defaultParams) => ({
92
+ ...defaultParams,
93
+ children: 'Label',
94
+ }));
95
+
96
+ const id = checkbox.getAttribute('id');
97
+ const label = container.querySelector(`label[for=${id}]`);
98
+
99
+ expect(label).toBeTruthy();
100
+ expect(label).toHaveTextContent('Label');
101
+ });
102
+ });
103
+
104
+ describe('Checkbox should be interactive', () => {
105
+ it('should call onChange when clicked', () => {
106
+ const { checkbox } = createCheckbox();
107
+
108
+ expect(onChangeHandeler).not.toBeCalled();
109
+ userEvent.click(checkbox);
110
+ expect(onChangeHandeler).toBeCalledTimes(1);
111
+ });
112
+
113
+ it('should not call onChange when disabled', () => {
114
+ const { checkbox } = createCheckbox((defaultParams) => ({ ...defaultParams, disabled: true }));
115
+
116
+ userEvent.click(checkbox);
117
+ expect(onChangeHandeler).not.toBeCalled();
118
+ });
119
+ });
@@ -0,0 +1,145 @@
1
+ import React, { ReactElement, ReactNode, useEffect } from 'react';
2
+ import { Icon, Icons } from '../../Icon/Icon';
3
+ import { Props as FormHelperTextProps } from '../FormHelperText/FormHelperText';
4
+ import classes from './Checkbox.module.scss';
5
+ import { useFormSelector } from '../../hooks/useFormSelector';
6
+ import { FormSelector } from '../form.interfaces';
7
+ import { HTMLProps } from '../../interfaces';
8
+ import { FormSelectorWrapper } from '../FormSelectorWrapper/FormSelectorWrapper';
9
+
10
+ const isToggle = (children: ReactNode) => (children as ReactElement)?.props?.['data-toggle'];
11
+
12
+ export interface CheckboxProps extends FormSelector<HTMLInputElement> {
13
+ children: ReactNode;
14
+ label?: string;
15
+ indeterminate?: boolean;
16
+ helperProps?: FormHelperTextProps;
17
+ wrapperProps?: HTMLProps<HTMLDivElement>;
18
+ onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
19
+ }
20
+
21
+ export const Checkbox = ({
22
+ children,
23
+ name,
24
+ helperText,
25
+ helperProps,
26
+ indeterminate,
27
+ parentErrorId,
28
+ errorMessage,
29
+ disabled,
30
+ label,
31
+ parentHelperId,
32
+ className,
33
+ error,
34
+ checked = false,
35
+ wrapperProps,
36
+ onChange,
37
+ ...rest
38
+ }: CheckboxProps) => {
39
+ const { errorId, identifier, describedBy } = useFormSelector({
40
+ name,
41
+ helperText,
42
+ parentErrorId,
43
+ errorMessage,
44
+ error,
45
+ parentHelperId,
46
+ });
47
+
48
+ useEffect(() => {
49
+ if (!name) {
50
+ console.error("Please pass a 'name' prop to your <Checkbox> component.");
51
+ }
52
+
53
+ if (typeof children === 'object' && !isToggle(children) && indeterminate === undefined) {
54
+ throw new Error(
55
+ 'If you have nested checkboxes you have to manage the indeterminate state by passing a boolean to the `indeterminate` prop.'
56
+ );
57
+ }
58
+ }, []);
59
+
60
+ const determineLabel = () => {
61
+ if (label) {
62
+ return label;
63
+ } else if (children === undefined) {
64
+ throw new Error(
65
+ 'Please make sure to pass either a string or more Checkbox components as a child of your Checkbox component.'
66
+ );
67
+ }
68
+
69
+ if (typeof children === 'string') {
70
+ return children;
71
+ }
72
+
73
+ throw new Error(
74
+ 'If you pass Checkboxes as a child component (to create nested checkbox tree) you need to pass a label to the parent checkbox.'
75
+ );
76
+ };
77
+
78
+ const renderNestedCheckboxes = () => (
79
+ <ul className={classes['checkbox-list']}>
80
+ {React.Children.map(children as ReactElement[], (child) => {
81
+ return (
82
+ <li>
83
+ <Checkbox
84
+ {...child.props}
85
+ parentHelperId={parentHelperId}
86
+ parentErrorId={parentErrorId}
87
+ error={error}
88
+ >
89
+ {child.props.children}
90
+ </Checkbox>
91
+ </li>
92
+ );
93
+ })}
94
+ </ul>
95
+ );
96
+
97
+ const onChangeHandler = (event: React.ChangeEvent<HTMLInputElement>) => {
98
+ if (disabled) {
99
+ return;
100
+ }
101
+ onChange && onChange(event);
102
+ };
103
+
104
+ const renderToggle = () => React.Children.toArray(children).filter(isToggle);
105
+
106
+ /** Default return value is the default checkbox */
107
+ return (
108
+ <FormSelectorWrapper
109
+ {...wrapperProps}
110
+ className={`${classes['checkbox-wrapper']} ${className ? className : ''}`}
111
+ containerProps={{ className: classes['checkbox-container'] }}
112
+ helperText={helperText}
113
+ helperProps={helperProps}
114
+ parentErrorId={parentErrorId}
115
+ errorId={errorId}
116
+ errorMessage={errorMessage}
117
+ error={error}
118
+ disabled={disabled}
119
+ identifier={identifier}
120
+ nestedChildren={
121
+ typeof children === 'object' && !isToggle(children) && renderNestedCheckboxes()
122
+ }
123
+ >
124
+ <input
125
+ {...rest}
126
+ disabled={disabled}
127
+ className={`${classes['native-input']} ${error ? classes['error'] : ''}`}
128
+ checked={checked}
129
+ onChange={onChangeHandler}
130
+ aria-invalid={error as boolean}
131
+ aria-checked={indeterminate ? 'mixed' : checked}
132
+ aria-describedby={describedBy}
133
+ id={`${identifier}-checkbox`}
134
+ name={name}
135
+ type="checkbox"
136
+ />
137
+ {renderToggle()}
138
+
139
+ {indeterminate && <Icon className={classes.input} icon={Icons.MinusSquare} />}
140
+ {checked && !indeterminate && <Icon className={classes.input} icon={Icons.CheckmarkSquare} />}
141
+ {!checked && !indeterminate && <Icon className={classes.input} icon={Icons.Square} />}
142
+ <label htmlFor={`${identifier}-checkbox`}>{determineLabel()}</label>
143
+ </FormSelectorWrapper>
144
+ );
145
+ };
@@ -0,0 +1,19 @@
1
+ .fieldset {
2
+ border: 0;
3
+ padding: 1rem 1.25rem;
4
+ border-radius: 0.5rem;
5
+ margin: 0;
6
+
7
+ &.no-padding {
8
+ padding: 0;
9
+ }
10
+
11
+ + .wrapper,
12
+ + .fieldset {
13
+ margin-top: 1rem;
14
+ }
15
+
16
+ .title {
17
+ display: block;
18
+ }
19
+ }
@@ -0,0 +1,85 @@
1
+ import React from 'react';
2
+ import { Fieldset, Props } from './Fieldset';
3
+ import { render } from '@testing-library/react';
4
+ import { FormControl } from '../FormControl/FormControl';
5
+ import { Input } from '../Input/Input';
6
+ import { Select } from '../Select/Select';
7
+ import { Option } from '../Select/Option';
8
+
9
+ const defaultParams: Props = {
10
+ title: 'Example',
11
+ titleVariant: 'h2',
12
+ children: [
13
+ <FormControl data-testid="form-control">
14
+ <Input placeholder="This is a placeholder" name="example" type="text" />
15
+ </FormControl>,
16
+ <FormControl data-testid="form-control">
17
+ <Select value="placeholder" onChange={jest.fn}>
18
+ <Option value="option1">Option1</Option>
19
+ <Option value="option2">Option2</Option>
20
+ <Option value="option3">Option3</Option>
21
+ </Select>
22
+ </FormControl>,
23
+ ],
24
+ };
25
+
26
+ const createFieldset = (params?: (defaultParams: Props) => Props) => {
27
+ let parameters: Props = defaultParams;
28
+ if (params) {
29
+ parameters = params(defaultParams);
30
+ }
31
+ const queries = render(<Fieldset {...parameters} data-testid="fieldset" />);
32
+ const fieldset = queries.getByTestId('fieldset');
33
+
34
+ return {
35
+ ...queries,
36
+ fieldset,
37
+ };
38
+ };
39
+
40
+ describe('Fieldset should render', () => {
41
+ it('renders without crashing', () => {
42
+ const { fieldset } = createFieldset();
43
+
44
+ expect(fieldset).toBeTruthy();
45
+ });
46
+ });
47
+
48
+ describe('Fieldset should get proper attributes and classes', () => {
49
+ it('has no padding class', () => {
50
+ const { fieldset } = createFieldset((defaultParams) => ({ ...defaultParams, noPadding: true }));
51
+
52
+ expect(fieldset).toHaveClass('no-padding');
53
+ });
54
+
55
+ it('has no background styling', () => {
56
+ const { fieldset } = createFieldset((defaultParams) => ({
57
+ ...defaultParams,
58
+ noBackground: true,
59
+ }));
60
+
61
+ expect(fieldset.style.backgroundColor).toBe('');
62
+ });
63
+
64
+ it('has a correct legend and title <span> element', () => {
65
+ const { getByText } = createFieldset();
66
+
67
+ const legend = getByText(/example/i, { selector: 'legend' });
68
+ const title = getByText(/example/i, { selector: 'span' });
69
+
70
+ expect(legend).toHaveTextContent('Example');
71
+ expect(legend).toBeTruthy();
72
+ expect(title).toHaveClass('typography_style_h2');
73
+ expect(title).toBeTruthy();
74
+ expect(title).toHaveTextContent('Example');
75
+ });
76
+
77
+ it('renders its children correctly', () => {
78
+ const { getAllByTestId } = createFieldset();
79
+
80
+ const formcontrols = getAllByTestId('form-control');
81
+
82
+ expect(formcontrols).toBeTruthy();
83
+ expect(formcontrols).toHaveLength(2);
84
+ });
85
+ });
@@ -0,0 +1,55 @@
1
+ import React, { ReactElement } from 'react';
2
+ import readyclasses from '../../readyclasses.module.scss';
3
+ import classes from './Fieldset.module.scss';
4
+ import { HTMLProps } from '../../interfaces';
5
+ import { Typography, Variant } from '../../Typography/Typography';
6
+
7
+ export interface Props extends HTMLProps<HTMLFieldSetElement> {
8
+ children?: ReactElement | ReactElement[];
9
+ title: string;
10
+ titleVariant?: Variant;
11
+ hideTitle?: boolean;
12
+ background?: string;
13
+ noPadding?: boolean;
14
+ noBackground?: boolean;
15
+ }
16
+
17
+ export const Fieldset = ({
18
+ children,
19
+ className,
20
+ title,
21
+ titleVariant = 'body',
22
+ hideTitle = false,
23
+ noBackground,
24
+ background = noBackground ? '' : '#FFF',
25
+ noPadding = false,
26
+ disabled = false,
27
+ ...rest
28
+ }: Props) => {
29
+ const renderChildren = () => {
30
+ if (!children) return;
31
+
32
+ return React.Children.map(children, (child: ReactElement) =>
33
+ React.cloneElement(child, {
34
+ disabled: child.props.disabled !== undefined ? child.props.disabled : disabled,
35
+ })
36
+ );
37
+ };
38
+
39
+ return (
40
+ <fieldset
41
+ {...rest}
42
+ disabled={disabled}
43
+ style={{ backgroundColor: background, ...rest.style }}
44
+ className={`${classes.fieldset} ${noPadding ? classes['no-padding'] : ''} ${className ?? ''}`}
45
+ >
46
+ {title && <legend className={readyclasses['sr-only']}>{title}</legend>}
47
+ {title && !hideTitle && (
48
+ <Typography variant={titleVariant} tag="span" aria-hidden="true" className={classes.title}>
49
+ {title}
50
+ </Typography>
51
+ )}
52
+ {renderChildren()}
53
+ </fieldset>
54
+ );
55
+ };
@@ -0,0 +1,3 @@
1
+ .form {
2
+ font-family: var(--font-family);
3
+ }
@@ -0,0 +1,47 @@
1
+ import React from 'react';
2
+ import { Form } from './Form';
3
+ import { render } from '@testing-library/react';
4
+ import { Button } from '../Button/Button';
5
+ import userEvent from '@testing-library/user-event';
6
+
7
+ describe('Form should render', () => {
8
+ it('renders without crashing', () => {
9
+ const { getByTestId } = render(<Form data-testid="component">Content</Form>);
10
+ const component = getByTestId('component');
11
+ expect(component).toBeDefined();
12
+ });
13
+ });
14
+
15
+ describe('Event should fire', () => {
16
+ it('should fire the onSubmitHandler function', () => {
17
+ const onSubmitHandler = jest.fn();
18
+
19
+ onSubmitHandler.mockImplementation((event) => {
20
+ event.preventDefault();
21
+ });
22
+
23
+ const { getByTestId } = render(
24
+ <Form onSubmit={onSubmitHandler}>
25
+ <Button data-testid="submit-button" type="submit"></Button>
26
+ </Form>
27
+ );
28
+
29
+ const button = getByTestId('submit-button');
30
+ userEvent.click(button);
31
+ expect(onSubmitHandler).toHaveBeenCalled();
32
+ });
33
+ });
34
+
35
+ describe('Should be able to set some default form properties', () => {
36
+ const { getByTestId } = render(
37
+ <Form data-testid="form" method="POST" action="./test.php">
38
+ Test
39
+ </Form>
40
+ );
41
+
42
+ const form = getByTestId('form');
43
+
44
+ expect(form.getAttribute('method')).toBe('POST');
45
+ expect(form.getAttribute('action')).toBe('./test.php');
46
+ expect(form.innerHTML).toBe('Test');
47
+ });
@@ -0,0 +1,14 @@
1
+ import React, { HTMLProps, ReactNode } from 'react';
2
+ import classes from './Form.module.scss';
3
+
4
+ export interface Props extends HTMLProps<HTMLFormElement> {
5
+ children?: ReactNode;
6
+ }
7
+
8
+ export const Form = ({ children, className, ...rest }: Props) => {
9
+ return (
10
+ <form className={`${classes.form} ${className ?? ''}`} {...rest}>
11
+ {children}
12
+ </form>
13
+ );
14
+ };
@@ -0,0 +1,67 @@
1
+ .form-control {
2
+ + .form-control {
3
+ margin-top: 1rem;
4
+ }
5
+
6
+ &.grid {
7
+ display: flex;
8
+ flex-wrap: wrap;
9
+
10
+ &.center,
11
+ &.middle {
12
+ align-items: center;
13
+ }
14
+
15
+ &.start,
16
+ &.top {
17
+ align-items: flex-start;
18
+ }
19
+
20
+ &.end,
21
+ &.bottom {
22
+ align-items: flex-end;
23
+ }
24
+
25
+ &.stretch {
26
+ align-items: stretch;
27
+
28
+ > * > * {
29
+ box-sizing: border-box;
30
+ height: 100%;
31
+ }
32
+ }
33
+ }
34
+ }
35
+
36
+ .column {
37
+ flex-grow: 1;
38
+ flex-shrink: 0;
39
+ }
40
+
41
+ .grid-2 {
42
+ .column:nth-child(even) {
43
+ margin-left: 1rem;
44
+ }
45
+
46
+ .column:nth-child(n + 3) {
47
+ margin-top: 1rem;
48
+ }
49
+ }
50
+
51
+ .grid-3 {
52
+ .column:not(:nth-child(3n + 1)) {
53
+ margin-left: 1rem;
54
+ }
55
+
56
+ .column:nth-child(n + 4) {
57
+ margin-top: 1rem;
58
+ }
59
+ }
60
+
61
+ .col-2 {
62
+ flex-basis: calc(calc(100% - 1rem) / 2);
63
+ }
64
+
65
+ .col-3 {
66
+ flex-basis: calc(calc(100% - 2rem) / 3);
67
+ }
@@ -0,0 +1,56 @@
1
+ import React from 'react';
2
+ import { FormControl, Props } from './FormControl';
3
+ import { render } from '@testing-library/react';
4
+ import { Input } from '../Input/Input';
5
+
6
+ const defaultParams: Props = {
7
+ grid: 3,
8
+ align: 'center',
9
+ children: [
10
+ <Input placeholder="This is a placeholder" name="example" data-testid="input" type="text" />,
11
+ <Input placeholder="This is a placeholder" name="example" data-testid="input" type="text" />,
12
+ <Input placeholder="This is a placeholder" name="example" data-testid="input" type="text" />,
13
+ ],
14
+ };
15
+
16
+ const createFormControl = (params?: (defaultParams: Props) => Props) => {
17
+ let parameters: Props = defaultParams;
18
+ if (params) {
19
+ parameters = params(defaultParams);
20
+ }
21
+ const queries = render(<FormControl {...parameters} data-testid="formcontrol" />);
22
+ const formcontrol = queries.getByTestId('formcontrol');
23
+
24
+ return {
25
+ ...queries,
26
+ formcontrol,
27
+ };
28
+ };
29
+
30
+ describe('FormControl should render', () => {
31
+ it('renders without crashing', () => {
32
+ const { formcontrol } = createFormControl();
33
+
34
+ expect(formcontrol).toBeTruthy();
35
+ });
36
+ });
37
+
38
+ describe('FormControl attributes should be working correctly', () => {
39
+ it('has the right classes and attributes', () => {
40
+ const { formcontrol } = createFormControl();
41
+
42
+ expect(formcontrol).toHaveClass('grid');
43
+ expect(formcontrol.firstChild).toHaveClass('col-3');
44
+ });
45
+ });
46
+
47
+ describe('FormControl children should render properly', () => {
48
+ it('renders children', () => {
49
+ const { getAllByTestId } = createFormControl();
50
+
51
+ const inputs = getAllByTestId('input');
52
+
53
+ expect(inputs).toBeTruthy();
54
+ expect(inputs).toHaveLength(3);
55
+ });
56
+ });