@onewelcome/react-lib-components 0.1.0-alpha → 0.1.3-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 (240) hide show
  1. package/README.md +16 -1
  2. package/dist/Breadcrumbs/Breadcrumbs.d.ts +3 -3
  3. package/dist/Button/BaseButton.d.ts +3 -4
  4. package/dist/Button/Button.d.ts +3 -4
  5. package/dist/Button/IconButton.d.ts +4 -5
  6. package/dist/ContextMenu/ContextMenu.d.ts +3 -3
  7. package/dist/Form/Checkbox/Checkbox.d.ts +5 -5
  8. package/dist/Form/Fieldset/Fieldset.d.ts +9 -7
  9. package/dist/Form/FormControl/FormControl.d.ts +6 -5
  10. package/dist/Form/FormGroup/FormGroup.d.ts +4 -4
  11. package/dist/Form/FormHelperText/FormHelperText.d.ts +4 -5
  12. package/dist/Form/FormSelectorWrapper/FormSelectorWrapper.d.ts +8 -12
  13. package/dist/Form/Input/Input.d.ts +7 -6
  14. package/dist/Form/Label/Label.d.ts +4 -5
  15. package/dist/Form/Radio/Radio.d.ts +5 -5
  16. package/dist/Form/Select/Option.d.ts +3 -4
  17. package/dist/Form/Select/Select.d.ts +4 -4
  18. package/dist/Form/Textarea/Textarea.d.ts +9 -5
  19. package/dist/Form/Toggle/Toggle.d.ts +3 -3
  20. package/dist/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.d.ts +4 -3
  21. package/dist/Form/Wrapper/InputWrapper/InputWrapper.d.ts +5 -5
  22. package/dist/Form/Wrapper/RadioWrapper/RadioWrapper.d.ts +4 -4
  23. package/dist/Form/Wrapper/SelectWrapper/SelectWrapper.d.ts +8 -4
  24. package/dist/Form/Wrapper/TextareaWrapper/TextareaWrapper.d.ts +3 -3
  25. package/dist/Form/Wrapper/Wrapper/Wrapper.d.ts +6 -6
  26. package/dist/Form/form.interfaces.d.ts +4 -3
  27. package/dist/Icon/Icon.d.ts +4 -4
  28. package/dist/Link/Link.d.ts +3 -5
  29. package/dist/Notifications/BaseModal/BaseModal.d.ts +17 -0
  30. package/dist/Notifications/BaseModal/BaseModalActions/BaseModalActions.d.ts +5 -0
  31. package/dist/Notifications/BaseModal/BaseModalContent/BaseModalContent.d.ts +8 -0
  32. package/dist/{BaseModal → Notifications/BaseModal}/BaseModalContext.d.ts +0 -0
  33. package/dist/Notifications/BaseModal/BaseModalHeader/BaseModalHeader.d.ts +8 -0
  34. package/dist/Notifications/Dialog/Dialog.d.ts +19 -0
  35. package/dist/Notifications/Dialog/DialogActions/DialogActions.d.ts +6 -0
  36. package/dist/Notifications/Dialog/DialogTitle/DialogTitle.d.ts +6 -0
  37. package/dist/Notifications/DiscardChangesModal/DiscardChangesDialog/DiscardChangesDialog.d.ts +13 -0
  38. package/dist/Notifications/DiscardChangesModal/DiscardChangesModal.d.ts +13 -0
  39. package/dist/{Modal → Notifications/Modal}/Modal.d.ts +0 -0
  40. package/dist/{Modal → Notifications/Modal}/ModalActions/ModalActions.d.ts +0 -0
  41. package/dist/{Modal → Notifications/Modal}/ModalContent/ModalContent.d.ts +0 -0
  42. package/dist/{Modal → Notifications/Modal}/ModalHeader/ModalHeader.d.ts +0 -0
  43. package/dist/{Snackbar → Notifications/Snackbar}/SnackbarContainer/SnackbarContainer.d.ts +0 -0
  44. package/dist/{Snackbar → Notifications/Snackbar}/SnackbarItem/SnackbarItem.d.ts +0 -0
  45. package/dist/{Snackbar → Notifications/Snackbar}/SnackbarProvider/SnackbarProvider.d.ts +1 -1
  46. package/dist/{Snackbar → Notifications/Snackbar}/SnackbarProvider/SnackbarStateProvider.d.ts +0 -0
  47. package/dist/{Snackbar → Notifications/Snackbar}/interfaces.d.ts +0 -0
  48. package/dist/{Snackbar → Notifications/Snackbar}/useSnackbar.d.ts +0 -0
  49. package/dist/Pagination/Pagination.d.ts +19 -0
  50. package/dist/Popover/Popover.d.ts +3 -3
  51. package/dist/Tabs/Tab.d.ts +11 -0
  52. package/dist/Tabs/TabButton.d.ts +10 -0
  53. package/dist/Tabs/TabPanel.d.ts +8 -0
  54. package/dist/Tabs/Tabs.d.ts +9 -0
  55. package/dist/TextEllipsis/TextEllipsis.d.ts +6 -0
  56. package/dist/Tiles/Tile.d.ts +6 -7
  57. package/dist/Tiles/Tiles.d.ts +3 -3
  58. package/dist/Tooltip/Tooltip.d.ts +3 -3
  59. package/dist/Typography/Typography.d.ts +6 -4
  60. package/dist/Wizard/BaseWizardSteps/BaseWizardSteps.d.ts +3 -3
  61. package/dist/Wizard/WizardSteps/WizardSteps.d.ts +3 -3
  62. package/dist/_BaseStyling_/BaseStyling.d.ts +9 -0
  63. package/dist/hooks/useRepeater.d.ts +10 -0
  64. package/dist/hooks/useSpacing.d.ts +2 -2
  65. package/dist/hooks/useWrapper.d.ts +1 -1
  66. package/dist/index.d.ts +12 -7
  67. package/dist/interfaces.d.ts +2 -11
  68. package/dist/react-lib-components.cjs.development.js +1861 -1287
  69. package/dist/react-lib-components.cjs.development.js.map +1 -1
  70. package/dist/react-lib-components.cjs.production.min.js +1 -1
  71. package/dist/react-lib-components.cjs.production.min.js.map +1 -1
  72. package/dist/react-lib-components.esm.js +1858 -1289
  73. package/dist/react-lib-components.esm.js.map +1 -1
  74. package/dist/util/helper.d.ts +6 -1
  75. package/package.json +30 -24
  76. package/src/Breadcrumbs/Breadcrumbs.tsx +39 -37
  77. package/src/Button/BaseButton.test.tsx +65 -19
  78. package/src/Button/BaseButton.tsx +2 -3
  79. package/src/Button/Button.test.tsx +63 -17
  80. package/src/Button/Button.tsx +15 -4
  81. package/src/Button/IconButton.test.tsx +57 -22
  82. package/src/Button/IconButton.tsx +21 -12
  83. package/src/ContextMenu/ContextMenu.test.tsx +27 -1
  84. package/src/ContextMenu/ContextMenu.tsx +70 -65
  85. package/src/Form/Checkbox/Checkbox.module.scss +4 -0
  86. package/src/Form/Checkbox/Checkbox.test.tsx +28 -2
  87. package/src/Form/Checkbox/Checkbox.tsx +132 -117
  88. package/src/Form/Fieldset/Fieldset.module.scss +11 -1
  89. package/src/Form/Fieldset/Fieldset.test.tsx +30 -4
  90. package/src/Form/Fieldset/Fieldset.tsx +101 -43
  91. package/src/Form/FormControl/FormControl.test.tsx +27 -1
  92. package/src/Form/FormControl/FormControl.tsx +37 -37
  93. package/src/Form/FormGroup/FormGroup.test.tsx +27 -1
  94. package/src/Form/FormGroup/FormGroup.tsx +64 -58
  95. package/src/Form/FormHelperText/FormHelperText.test.tsx +27 -1
  96. package/src/Form/FormHelperText/FormHelperText.tsx +20 -16
  97. package/src/Form/FormSelectorWrapper/FormSelectorWrapper.test.tsx +78 -0
  98. package/src/Form/FormSelectorWrapper/FormSelectorWrapper.tsx +61 -55
  99. package/src/Form/Input/Input.module.scss +34 -15
  100. package/src/Form/Input/Input.test.tsx +27 -1
  101. package/src/Form/Input/Input.tsx +88 -47
  102. package/src/Form/Label/Label.test.tsx +27 -1
  103. package/src/Form/Label/Label.tsx +18 -14
  104. package/src/Form/Radio/Radio.module.scss +4 -0
  105. package/src/Form/Radio/Radio.test.tsx +28 -2
  106. package/src/Form/Radio/Radio.tsx +98 -80
  107. package/src/Form/Select/Option.test.tsx +27 -1
  108. package/src/Form/Select/Option.tsx +49 -42
  109. package/src/Form/Select/Select.module.scss +5 -1
  110. package/src/Form/Select/Select.test.tsx +224 -30
  111. package/src/Form/Select/Select.tsx +248 -182
  112. package/src/Form/Textarea/Textarea.module.scss +2 -1
  113. package/src/Form/Textarea/Textarea.test.tsx +28 -2
  114. package/src/Form/Textarea/Textarea.tsx +44 -29
  115. package/src/Form/Toggle/Toggle.module.scss +9 -0
  116. package/src/Form/Toggle/Toggle.test.tsx +27 -1
  117. package/src/Form/Toggle/Toggle.tsx +25 -12
  118. package/src/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.test.tsx +28 -2
  119. package/src/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.tsx +45 -48
  120. package/src/Form/Wrapper/InputWrapper/InputWrapper.module.scss +17 -1
  121. package/src/Form/Wrapper/InputWrapper/InputWrapper.test.tsx +89 -1
  122. package/src/Form/Wrapper/InputWrapper/InputWrapper.tsx +134 -74
  123. package/src/Form/Wrapper/RadioWrapper/RadioWrapper.test.tsx +1 -1
  124. package/src/Form/Wrapper/RadioWrapper/RadioWrapper.tsx +64 -59
  125. package/src/Form/Wrapper/SelectWrapper/SelectWrapper.module.scss +1 -1
  126. package/src/Form/Wrapper/SelectWrapper/SelectWrapper.test.tsx +43 -1
  127. package/src/Form/Wrapper/SelectWrapper/SelectWrapper.tsx +55 -44
  128. package/src/Form/Wrapper/TextareaWrapper/TextareaWrapper.module.scss +5 -7
  129. package/src/Form/Wrapper/TextareaWrapper/TextareaWrapper.test.tsx +43 -1
  130. package/src/Form/Wrapper/TextareaWrapper/TextareaWrapper.tsx +100 -85
  131. package/src/Form/Wrapper/Wrapper/Wrapper.module.scss +1 -1
  132. package/src/Form/Wrapper/Wrapper/Wrapper.test.tsx +27 -1
  133. package/src/Form/Wrapper/Wrapper/Wrapper.tsx +76 -71
  134. package/src/Form/form.interfaces.ts +4 -3
  135. package/src/Icon/Icon.module.scss +4 -0
  136. package/src/Icon/Icon.test.tsx +30 -2
  137. package/src/Icon/Icon.tsx +5 -5
  138. package/src/Link/Link.test.tsx +27 -1
  139. package/src/Link/Link.tsx +4 -6
  140. package/src/{BaseModal → Notifications/BaseModal}/BaseModal.module.scss +0 -0
  141. package/src/{BaseModal → Notifications/BaseModal}/BaseModal.test.tsx +35 -16
  142. package/src/Notifications/BaseModal/BaseModal.tsx +105 -0
  143. package/src/{BaseModal → Notifications/BaseModal}/BaseModalActions/BaseModalActions.module.scss +0 -0
  144. package/src/Notifications/BaseModal/BaseModalActions/BaseModalActions.test.tsx +42 -0
  145. package/src/Notifications/BaseModal/BaseModalActions/BaseModalActions.tsx +16 -0
  146. package/src/{BaseModal → Notifications/BaseModal}/BaseModalContent/BaseModalContent.module.scss +0 -0
  147. package/src/{BaseModal → Notifications/BaseModal}/BaseModalContent/BaseModalContent.test.tsx +27 -1
  148. package/src/Notifications/BaseModal/BaseModalContent/BaseModalContent.tsx +36 -0
  149. package/src/{BaseModal → Notifications/BaseModal}/BaseModalContext.ts +0 -0
  150. package/src/{BaseModal → Notifications/BaseModal}/BaseModalHeader/BaseModalHeader.module.scss +0 -0
  151. package/src/{BaseModal → Notifications/BaseModal}/BaseModalHeader/BaseModalHeader.test.tsx +29 -1
  152. package/src/Notifications/BaseModal/BaseModalHeader/BaseModalHeader.tsx +30 -0
  153. package/src/{Dialog → Notifications/Dialog}/Dialog.module.scss +0 -0
  154. package/src/{Dialog → Notifications/Dialog}/Dialog.test.tsx +52 -17
  155. package/src/Notifications/Dialog/Dialog.tsx +113 -0
  156. package/src/{Dialog → Notifications/Dialog}/DialogActions/DialogActions.module.scss +0 -0
  157. package/src/Notifications/Dialog/DialogActions/DialogActions.test.tsx +51 -0
  158. package/src/Notifications/Dialog/DialogActions/DialogActions.tsx +24 -0
  159. package/src/{Dialog → Notifications/Dialog}/DialogTitle/DialogTitle.module.scss +0 -0
  160. package/src/Notifications/Dialog/DialogTitle/DialogTitle.test.tsx +44 -0
  161. package/src/Notifications/Dialog/DialogTitle/DialogTitle.tsx +20 -0
  162. package/src/Notifications/DiscardChangesModal/DiscardChangesDialog/DiscardChangesDialog.test.tsx +95 -0
  163. package/src/Notifications/DiscardChangesModal/DiscardChangesDialog/DiscardChangesDialog.tsx +55 -0
  164. package/src/Notifications/DiscardChangesModal/DiscardChangesModal.test.tsx +162 -0
  165. package/src/Notifications/DiscardChangesModal/DiscardChangesModal.tsx +61 -0
  166. package/src/{Modal → Notifications/Modal}/Modal.test.tsx +0 -0
  167. package/src/{Modal → Notifications/Modal}/Modal.tsx +0 -0
  168. package/src/{Modal → Notifications/Modal}/ModalActions/ModalActions.tsx +0 -0
  169. package/src/{Modal → Notifications/Modal}/ModalContent/ModalContent.tsx +0 -0
  170. package/src/{Modal → Notifications/Modal}/ModalHeader/ModalHeader.tsx +0 -0
  171. package/src/{Snackbar → Notifications/Snackbar}/SnackbarContainer/SnackbarContainer.module.scss +0 -0
  172. package/src/{Snackbar → Notifications/Snackbar}/SnackbarContainer/SnackbarContainer.test.tsx +0 -0
  173. package/src/{Snackbar → Notifications/Snackbar}/SnackbarContainer/SnackbarContainer.tsx +0 -0
  174. package/src/{Snackbar → Notifications/Snackbar}/SnackbarItem/SnackbarItem.module.scss +1 -1
  175. package/src/{Snackbar → Notifications/Snackbar}/SnackbarItem/SnackbarItem.test.tsx +0 -0
  176. package/src/{Snackbar → Notifications/Snackbar}/SnackbarItem/SnackbarItem.tsx +6 -7
  177. package/src/{Snackbar → Notifications/Snackbar}/SnackbarProvider/SnackbarProvider.test.tsx +0 -0
  178. package/src/{Snackbar → Notifications/Snackbar}/SnackbarProvider/SnackbarProvider.tsx +2 -2
  179. package/src/{Snackbar → Notifications/Snackbar}/SnackbarProvider/SnackbarStateProvider.tsx +0 -0
  180. package/src/{Snackbar → Notifications/Snackbar}/interfaces.ts +0 -0
  181. package/src/{Snackbar → Notifications/Snackbar}/useSnackbar.ts +0 -0
  182. package/src/Pagination/Pagination.module.scss +120 -0
  183. package/src/Pagination/Pagination.test.tsx +176 -0
  184. package/src/Pagination/Pagination.tsx +205 -0
  185. package/src/Popover/Popover.test.tsx +3 -3
  186. package/src/Popover/Popover.tsx +3 -3
  187. package/src/Tabs/Tab.test.tsx +71 -0
  188. package/src/Tabs/Tab.tsx +17 -0
  189. package/src/Tabs/TabButton.module.scss +36 -0
  190. package/src/Tabs/TabButton.test.tsx +77 -0
  191. package/src/Tabs/TabButton.tsx +58 -0
  192. package/src/Tabs/TabPanel.module.scss +7 -0
  193. package/src/Tabs/TabPanel.test.tsx +76 -0
  194. package/src/Tabs/TabPanel.tsx +27 -0
  195. package/src/Tabs/Tabs.module.scss +41 -0
  196. package/src/Tabs/Tabs.test.tsx +268 -0
  197. package/src/Tabs/Tabs.tsx +149 -0
  198. package/src/TextEllipsis/TextEllipsis.module.scss +18 -0
  199. package/src/TextEllipsis/TextEllipsis.test.tsx +80 -0
  200. package/src/TextEllipsis/TextEllipsis.tsx +55 -0
  201. package/src/Tiles/Tile.module.scss +1 -1
  202. package/src/Tiles/Tile.test.tsx +48 -12
  203. package/src/Tiles/Tile.tsx +68 -34
  204. package/src/Tiles/Tiles.test.tsx +38 -10
  205. package/src/Tiles/Tiles.tsx +42 -39
  206. package/src/Tooltip/Tooltip.test.tsx +27 -1
  207. package/src/Tooltip/Tooltip.tsx +104 -92
  208. package/src/Typography/Typography.test.tsx +27 -1
  209. package/src/Typography/Typography.tsx +66 -68
  210. package/src/Wizard/BaseWizardSteps/BaseWizardSteps.tsx +67 -62
  211. package/src/Wizard/Wizard.tsx +2 -2
  212. package/src/Wizard/WizardActions/WizardActions.tsx +3 -3
  213. package/src/Wizard/WizardSteps/WizardSteps.tsx +24 -21
  214. package/src/_BaseStyling_/BaseStyling.tsx +19 -1
  215. package/src/hooks/usePosition.test.tsx +3 -3
  216. package/src/hooks/useRepeater.test.tsx +139 -0
  217. package/src/hooks/useRepeater.ts +34 -0
  218. package/src/hooks/useSpacing.ts +1 -1
  219. package/src/hooks/useWrapper.ts +7 -2
  220. package/src/index.ts +20 -8
  221. package/src/interfaces.ts +2 -12
  222. package/src/util/helper.test.tsx +38 -1
  223. package/src/util/helper.tsx +21 -0
  224. package/dist/BaseModal/BaseModal.d.ts +0 -16
  225. package/dist/BaseModal/BaseModalActions/BaseModalActions.d.ts +0 -5
  226. package/dist/BaseModal/BaseModalContent/BaseModalContent.d.ts +0 -8
  227. package/dist/BaseModal/BaseModalHeader/BaseModalHeader.d.ts +0 -8
  228. package/dist/Dialog/Dialog.d.ts +0 -18
  229. package/dist/Dialog/DialogActions/DialogActions.d.ts +0 -6
  230. package/dist/Dialog/DialogTitle/DialogTitle.d.ts +0 -6
  231. package/src/BaseModal/BaseModal.tsx +0 -113
  232. package/src/BaseModal/BaseModalActions/BaseModalActions.test.tsx +0 -17
  233. package/src/BaseModal/BaseModalActions/BaseModalActions.tsx +0 -14
  234. package/src/BaseModal/BaseModalContent/BaseModalContent.tsx +0 -35
  235. package/src/BaseModal/BaseModalHeader/BaseModalHeader.tsx +0 -28
  236. package/src/Dialog/Dialog.tsx +0 -96
  237. package/src/Dialog/DialogActions/DialogActions.test.tsx +0 -25
  238. package/src/Dialog/DialogActions/DialogActions.tsx +0 -21
  239. package/src/Dialog/DialogTitle/DialogTitle.test.tsx +0 -18
  240. package/src/Dialog/DialogTitle/DialogTitle.tsx +0 -18
@@ -1,65 +1,71 @@
1
- import React, { ReactNode } from 'react';
1
+ import React, { ComponentPropsWithRef, createRef, ReactNode } from 'react';
2
2
  import { Icon, Icons } from '../../Icon/Icon';
3
- import { HTMLProps } from '../../interfaces';
3
+ import { KeyValuePair } from '../../interfaces';
4
+ import { FormSelector } from '../form.interfaces';
4
5
  import { FormHelperText, Props as FormHelperTextProps } from '../FormHelperText/FormHelperText';
5
6
  import classes from './FormSelectorWrapper.module.scss';
6
7
 
7
- export interface Props extends HTMLProps<HTMLDivElement> {
8
+ export interface Props extends ComponentPropsWithRef<'div'>, FormSelector {
8
9
  children?: ReactNode;
9
10
  nestedChildren?: ReactNode;
10
- containerProps: HTMLProps<HTMLDivElement>;
11
+ containerProps?: ComponentPropsWithRef<'div'> & KeyValuePair;
11
12
  helperProps?: FormHelperTextProps;
12
- error?: boolean;
13
13
  disabled?: boolean;
14
- helperText?: string;
15
- errorMessage?: string;
16
- parentHelperId?: string;
17
- parentErrorId?: string;
18
- errorId: string;
19
- identifier: string;
14
+ errorId?: string;
15
+ identifier?: string;
20
16
  }
21
17
 
22
- export const FormSelectorWrapper = ({
23
- children,
24
- className,
25
- nestedChildren,
26
- containerProps,
27
- helperProps,
28
- error,
29
- disabled,
30
- helperText,
31
- errorMessage,
32
- parentErrorId,
33
- errorId,
34
- identifier,
35
- ...rest
36
- }: Props) => {
37
- return (
38
- <div
39
- {...rest}
40
- className={`${error ? classes['error'] : ''} ${disabled ? classes['disabled'] : ''} ${
41
- className ?? ''
42
- }`}
43
- >
44
- <div {...containerProps}>{children}</div>
45
- {helperText && (!error || parentErrorId || !errorMessage) && (
46
- <FormHelperText
47
- {...helperProps}
48
- id={`${identifier}`}
49
- className={`${classes['helper-text']} ${helperProps?.className ?? ''} ${
50
- error ? classes['error'] : ''
51
- }`}
52
- >
53
- {helperText}
54
- </FormHelperText>
55
- )}
56
- {errorMessage && !parentErrorId && error && (
57
- <span className={classes['error-message']}>
58
- <Icon className={classes['error-icon']} icon={Icons.Warning} />
59
- <span id={errorId}>{errorMessage}</span>
60
- </span>
61
- )}
62
- {nestedChildren}
63
- </div>
64
- );
65
- };
18
+ export const FormSelectorWrapper = React.forwardRef<HTMLDivElement, Props>(
19
+ (
20
+ {
21
+ children,
22
+ className,
23
+ nestedChildren,
24
+ containerProps,
25
+ helperProps,
26
+ error,
27
+ disabled,
28
+ helperText,
29
+ errorMessage,
30
+ parentErrorId,
31
+ errorId,
32
+ identifier,
33
+ ...rest
34
+ }: Props,
35
+ ref
36
+ ) => {
37
+ const helperRef = helperProps?.ref || createRef();
38
+
39
+ return (
40
+ <div
41
+ {...rest}
42
+ ref={ref}
43
+ className={`${error ? classes['error'] : ''} ${disabled ? classes['disabled'] : ''} ${
44
+ className ?? ''
45
+ }`}
46
+ >
47
+ <div {...containerProps}>{children}</div>
48
+ {(helperText || (helperProps && helperProps.children)) &&
49
+ (!error || parentErrorId || !errorMessage) && (
50
+ <FormHelperText
51
+ {...helperProps}
52
+ ref={helperRef}
53
+ id={`${identifier}`}
54
+ className={`${classes['helper-text']} ${helperProps?.className ?? ''} ${
55
+ error ? classes['error'] : ''
56
+ }`}
57
+ >
58
+ {(helperProps && helperProps.children) || helperText}
59
+ </FormHelperText>
60
+ )}
61
+ {errorMessage && !parentErrorId && error && (
62
+ <span className={classes['error-message']}>
63
+ <Icon className={classes['error-icon']} icon={Icons.Error} />
64
+ <span id={errorId}>{errorMessage}</span>
65
+ </span>
66
+ )}
67
+ {nestedChildren}
68
+ </div>
69
+ );
70
+ }
71
+ );
@@ -1,31 +1,44 @@
1
1
  .input-wrapper {
2
2
  position: relative;
3
- }
4
-
5
- .input {
6
- height: 4rem;
3
+ display: flex;
4
+ align-items: center;
7
5
  padding: 0 1.25rem;
6
+ background-color: var(--input-background-color);
8
7
  border-color: var(--input-border-color);
9
8
  border-style: var(--input-border-style);
10
9
  border-width: var(--input-border-width);
11
10
  border-radius: var(--input-border-radius);
12
11
  transition: all 0.2s ease-in-out;
13
- color: var(--greyed-out);
14
- font-size: var(--font-size);
15
- font-family: var(--font-family);
16
- width: 100%;
17
- box-sizing: border-box;
18
12
 
19
- &:disabled {
20
- color: var(--greyed-out);
13
+ &:hover:not(:disabled) {
14
+ border-color: var(--default);
15
+ }
16
+
17
+ &.disabled,
18
+ &.disabled input {
21
19
  background-color: var(--disabled);
22
20
  border-color: #fff;
23
21
  cursor: not-allowed;
24
22
  }
25
23
 
26
- &:hover:not(:disabled) {
27
- border-color: var(--default);
24
+ &.error {
25
+ border-color: var(--error);
26
+ }
27
+
28
+ &.focus {
29
+ border-color: var(--color-primary);
28
30
  }
31
+ }
32
+
33
+ .input {
34
+ height: 4rem;
35
+ border: 0;
36
+ color: var(--greyed-out);
37
+ font-size: var(--font-size);
38
+ font-family: var(--font-family);
39
+ width: 100%;
40
+ box-sizing: border-box;
41
+ padding: 0;
29
42
 
30
43
  &:focus:not(:disabled) {
31
44
  outline: none;
@@ -33,8 +46,7 @@
33
46
  }
34
47
  }
35
48
 
36
- .error {
37
- border-color: var(--error);
49
+ .error input {
38
50
  color: var(--error);
39
51
  padding-right: 3.75rem;
40
52
 
@@ -63,3 +75,10 @@
63
75
  right: 3.75rem;
64
76
  }
65
77
  }
78
+
79
+ .input-wrapper [data-prefix],
80
+ .input-wrapper [data-suffix] {
81
+ transition: all 0.2s ease-in-out;
82
+ display: block;
83
+ z-index: 1;
84
+ }
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useEffect, useRef } from 'react';
2
2
  import { Input, Props } from './Input';
3
3
  import { render } from '@testing-library/react';
4
4
  import userEvent from '@testing-library/user-event';
@@ -29,6 +29,32 @@ describe('Input should render', () => {
29
29
  });
30
30
  });
31
31
 
32
+ describe('ref should work', () => {
33
+ it('should give back the proper data prop, this also checks if the component propagates ...rest properly', () => {
34
+ const ExampleComponent = ({
35
+ propagateRef,
36
+ }: {
37
+ propagateRef?: (ref: React.RefObject<HTMLElement>) => void;
38
+ }) => {
39
+ const ref = useRef(null);
40
+
41
+ useEffect(() => {
42
+ if (ref.current) {
43
+ propagateRef && propagateRef(ref);
44
+ }
45
+ }, [ref]);
46
+
47
+ return <Input {...defaultParams} data-ref="testing" ref={ref} />;
48
+ };
49
+
50
+ const refCheck = (ref: React.RefObject<HTMLElement>) => {
51
+ expect(ref.current).toHaveAttribute('data-ref', 'testing');
52
+ };
53
+
54
+ render(<ExampleComponent propagateRef={refCheck} />);
55
+ });
56
+ });
57
+
32
58
  describe('Should have the appropriate attributes', () => {
33
59
  it('is disabled and has a class', () => {
34
60
  const { input } = createInput((defaultParams) => ({
@@ -1,8 +1,8 @@
1
- import React, { useEffect } from 'react';
1
+ import React, { ComponentPropsWithRef, Ref, useEffect, useState } from 'react';
2
2
  import classes from './Input.module.scss';
3
3
  import readyclasses from '../../readyclasses.module.scss';
4
4
  import { Icon, Icons } from '../../Icon/Icon';
5
- import { HTMLProps } from '../../interfaces';
5
+ import { FormElement } from '../form.interfaces';
6
6
 
7
7
  const dateTypes = ['date', 'time', 'datetime-local'] as const;
8
8
 
@@ -18,55 +18,96 @@ export type Type =
18
18
  | 'hidden'
19
19
  | typeof dateTypes[number];
20
20
 
21
- export interface Props extends HTMLProps<HTMLInputElement> {
22
- wrapperProps?: HTMLProps<HTMLInputElement>;
21
+ export interface Props extends ComponentPropsWithRef<'input'>, FormElement {
22
+ wrapperProps?: ComponentPropsWithRef<'div'>;
23
23
  labeledBy?: string;
24
24
  type: Type;
25
- error?: boolean;
25
+ suffix?: string;
26
+ prefix?: string;
26
27
  }
27
28
 
28
- export const Input = ({
29
- error = false,
30
- className,
31
- name,
32
- style,
33
- wrapperProps,
34
- type,
35
- labeledBy,
36
- ...rest
37
- }: Props) => {
38
- useEffect(() => {
39
- if (name === undefined) {
40
- throw new Error("Please give your <Input /> component a 'name' attribute");
41
- }
42
- }, []);
29
+ export const Input = React.forwardRef(
30
+ (
31
+ {
32
+ error = false,
33
+ className,
34
+ name,
35
+ style,
36
+ wrapperProps,
37
+ type,
38
+ labeledBy,
39
+ prefix,
40
+ suffix,
41
+ disabled,
42
+ onFocus,
43
+ onBlur,
44
+ ...rest
45
+ }: Props,
46
+ ref: Ref<HTMLInputElement>
47
+ ) => {
48
+ const [focus, setFocus] = useState(false);
43
49
 
44
- const inputClassNames = [classes['input']];
45
- error && inputClassNames.push(classes['error']);
46
- (dateTypes as ReadonlyArray<string>).includes(type) &&
47
- inputClassNames.push(classes['remove-extra-indent']);
48
- className && inputClassNames.push(className);
50
+ useEffect(() => {
51
+ if (name === undefined) {
52
+ throw new Error("Please give your <Input /> component a 'name' attribute");
53
+ }
54
+ }, []);
49
55
 
50
- const iconClassNames = [classes['warning']];
51
- (dateTypes as ReadonlyArray<string>).includes(type) &&
52
- iconClassNames.push(classes['extra-indent']);
56
+ const inputClassNames = [classes['input']];
53
57
 
54
- return (
55
- <div
56
- {...wrapperProps}
57
- style={{ ...style }}
58
- className={`${classes['input-wrapper']} ${wrapperProps?.className ?? ''} ${
59
- type === 'hidden' ? readyclasses['hidden'] : ''
60
- }`}
61
- >
62
- <input
63
- {...rest}
64
- aria-labelledby={labeledBy}
65
- type={type}
66
- name={name}
67
- className={inputClassNames.join(' ')}
68
- />
69
- {error && <Icon className={iconClassNames.join(' ')} icon={Icons.Warning} />}
70
- </div>
71
- );
72
- };
58
+ (dateTypes as ReadonlyArray<string>).includes(type) &&
59
+ inputClassNames.push(classes['remove-extra-indent']);
60
+ className && inputClassNames.push(className);
61
+
62
+ const iconClassNames = [classes['warning']];
63
+ (dateTypes as ReadonlyArray<string>).includes(type) &&
64
+ iconClassNames.push(classes['extra-indent']);
65
+
66
+ const wrapperClasses = [classes['input-wrapper']];
67
+
68
+ wrapperProps?.className && wrapperClasses.push(wrapperProps.className);
69
+ type === 'hidden' && wrapperClasses.push(readyclasses['hidden']);
70
+ prefix && wrapperClasses.push(classes['prefix']);
71
+ suffix && wrapperClasses.push(classes['suffix']);
72
+ disabled && wrapperClasses.push(classes['disabled']);
73
+ error && wrapperClasses.push(classes['error']);
74
+ focus && wrapperClasses.push(classes['focus']);
75
+
76
+ return (
77
+ <div
78
+ {...wrapperProps}
79
+ style={{ ...style }}
80
+ className={`${classes['input-wrapper']} ${wrapperClasses.join(' ')}`}
81
+ >
82
+ {prefix && (
83
+ <div data-prefix className={classes['prefix']}>
84
+ <span>{prefix}</span>
85
+ </div>
86
+ )}
87
+ <input
88
+ {...rest}
89
+ ref={ref}
90
+ onFocus={(event) => {
91
+ setFocus(true);
92
+ onFocus && onFocus(event);
93
+ }}
94
+ onBlur={(event) => {
95
+ setFocus(false);
96
+ onBlur && onBlur(event);
97
+ }}
98
+ aria-labelledby={labeledBy}
99
+ type={type}
100
+ name={name}
101
+ disabled={disabled}
102
+ className={inputClassNames.join(' ')}
103
+ />
104
+ {suffix && (
105
+ <div data-suffix className={classes['suffix']}>
106
+ <span>{suffix}</span>
107
+ </div>
108
+ )}
109
+ {error && <Icon className={iconClassNames.join(' ')} icon={Icons.Error} />}
110
+ </div>
111
+ );
112
+ }
113
+ );
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useEffect, useRef } from 'react';
2
2
  import { Label } from './Label';
3
3
  import { render } from '@testing-library/react';
4
4
 
@@ -24,3 +24,29 @@ describe('Label should render', () => {
24
24
  expect(component.getAttribute('for')).toBe('input-name');
25
25
  });
26
26
  });
27
+
28
+ describe('ref should work', () => {
29
+ it('should give back the proper data prop, this also checks if the component propagates ...rest properly', () => {
30
+ const ExampleComponent = ({
31
+ propagateRef,
32
+ }: {
33
+ propagateRef?: (ref: React.RefObject<HTMLElement>) => void;
34
+ }) => {
35
+ const ref = useRef(null);
36
+
37
+ useEffect(() => {
38
+ if (ref.current) {
39
+ propagateRef && propagateRef(ref);
40
+ }
41
+ }, [ref]);
42
+
43
+ return <Label data-ref="testing" ref={ref} />;
44
+ };
45
+
46
+ const refCheck = (ref: React.RefObject<HTMLElement>) => {
47
+ expect(ref.current).toHaveAttribute('data-ref', 'testing');
48
+ };
49
+
50
+ render(<ExampleComponent propagateRef={refCheck} />);
51
+ });
52
+ });
@@ -1,19 +1,23 @@
1
- import React from 'react';
1
+ import React, { ComponentPropsWithRef, ReactNode } from 'react';
2
2
  import classes from './Label.module.scss';
3
3
  import readyclasses from '../../readyclasses.module.scss';
4
- import { HTMLProps } from '../../interfaces';
5
4
 
6
- export interface Props extends HTMLProps<HTMLLabelElement> {
7
- children?: string;
5
+ export interface Props extends ComponentPropsWithRef<'label'> {
6
+ children?: ReactNode;
8
7
  }
9
8
 
10
- export const Label = ({ children, className, hidden = false, ...rest }: Props) => {
11
- return (
12
- <label
13
- {...rest}
14
- className={`${hidden ? readyclasses['sr-only'] : ''} ${classes['label']} ${className ?? ''}`}
15
- >
16
- {children}
17
- </label>
18
- );
19
- };
9
+ export const Label = React.forwardRef<HTMLLabelElement, Props>(
10
+ ({ children, className, hidden = false, ...rest }: Props, ref) => {
11
+ return (
12
+ <label
13
+ {...rest}
14
+ ref={ref}
15
+ className={`${hidden ? readyclasses['sr-only'] : ''} ${classes['label']} ${
16
+ className ?? ''
17
+ }`}
18
+ >
19
+ {children}
20
+ </label>
21
+ );
22
+ }
23
+ );
@@ -98,3 +98,7 @@
98
98
  color: var(--disabled);
99
99
  }
100
100
  }
101
+
102
+ .disabled {
103
+ color: var(--disabled);
104
+ }
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useEffect, useRef } from 'react';
2
2
  import { Radio, Props } from './Radio';
3
3
  import { render } from '@testing-library/react';
4
4
  import userEvent from '@testing-library/user-event';
@@ -12,7 +12,7 @@ const defaultParams: Props = {
12
12
  error: false,
13
13
  errorMessage: 'errormessage',
14
14
  disabled: false,
15
- wrapperProps: { 'data-testid': 'radiowrapper' },
15
+ formSelectorWrapperProps: { 'data-testid': 'radiowrapper' },
16
16
  helperText: 'helpertext',
17
17
  onChange: onChangeHandeler,
18
18
  };
@@ -70,6 +70,32 @@ describe('Radio should render', () => {
70
70
  });
71
71
  });
72
72
 
73
+ describe('ref should work', () => {
74
+ it('should give back the proper data prop, this also checks if the component propagates ...rest properly', () => {
75
+ const ExampleComponent = ({
76
+ propagateRef,
77
+ }: {
78
+ propagateRef?: (ref: React.RefObject<HTMLElement>) => void;
79
+ }) => {
80
+ const ref = useRef(null);
81
+
82
+ useEffect(() => {
83
+ if (ref.current) {
84
+ propagateRef && propagateRef(ref);
85
+ }
86
+ }, [ref]);
87
+
88
+ return <Radio {...defaultParams} data-ref="testing" ref={ref} />;
89
+ };
90
+
91
+ const refCheck = (ref: React.RefObject<HTMLElement>) => {
92
+ expect(ref.current).toHaveAttribute('data-ref', 'testing');
93
+ };
94
+
95
+ render(<ExampleComponent propagateRef={refCheck} />);
96
+ });
97
+ });
98
+
73
99
  describe('Radio should be interactive', () => {
74
100
  it('should call onChange when clicked', () => {
75
101
  const { radio } = createRadio();