@onewelcome/react-lib-components 0.1.1-alpha → 0.1.4-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 (180) 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 +3 -4
  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 +4 -4
  9. package/dist/Form/FormControl/FormControl.d.ts +5 -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 +7 -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 +4 -6
  29. package/dist/Notifications/BaseModal/BaseModal.d.ts +3 -4
  30. package/dist/Notifications/BaseModal/BaseModalActions/BaseModalActions.d.ts +3 -3
  31. package/dist/Notifications/BaseModal/BaseModalContent/BaseModalContent.d.ts +3 -3
  32. package/dist/Notifications/BaseModal/BaseModalHeader/BaseModalHeader.d.ts +3 -3
  33. package/dist/Notifications/Dialog/Dialog.d.ts +3 -3
  34. package/dist/Notifications/Dialog/DialogActions/DialogActions.d.ts +3 -3
  35. package/dist/Notifications/Dialog/DialogTitle/DialogTitle.d.ts +3 -3
  36. package/dist/Notifications/DiscardChangesModal/DiscardChangesDialog/DiscardChangesDialog.d.ts +5 -4
  37. package/dist/Notifications/DiscardChangesModal/DiscardChangesModal.d.ts +3 -1
  38. package/dist/Pagination/Pagination.d.ts +19 -0
  39. package/dist/Popover/Popover.d.ts +3 -3
  40. package/dist/Tabs/Tab.d.ts +11 -0
  41. package/dist/Tabs/TabButton.d.ts +10 -0
  42. package/dist/Tabs/TabPanel.d.ts +8 -0
  43. package/dist/Tabs/Tabs.d.ts +9 -0
  44. package/dist/TextEllipsis/TextEllipsis.d.ts +6 -0
  45. package/dist/Tiles/Tile.d.ts +3 -3
  46. package/dist/Tiles/Tiles.d.ts +3 -3
  47. package/dist/Tooltip/Tooltip.d.ts +3 -3
  48. package/dist/Typography/Typography.d.ts +6 -4
  49. package/dist/Wizard/BaseWizardSteps/BaseWizardSteps.d.ts +3 -3
  50. package/dist/Wizard/WizardSteps/WizardSteps.d.ts +3 -3
  51. package/dist/_BaseStyling_/BaseStyling.d.ts +9 -0
  52. package/dist/hooks/useRepeater.d.ts +10 -0
  53. package/dist/hooks/useSpacing.d.ts +2 -2
  54. package/dist/hooks/useWrapper.d.ts +1 -1
  55. package/dist/index.d.ts +6 -0
  56. package/dist/interfaces.d.ts +2 -11
  57. package/dist/react-lib-components.cjs.development.js +2395 -1696
  58. package/dist/react-lib-components.cjs.development.js.map +1 -1
  59. package/dist/react-lib-components.cjs.production.min.js +1 -1
  60. package/dist/react-lib-components.cjs.production.min.js.map +1 -1
  61. package/dist/react-lib-components.esm.js +2391 -1698
  62. package/dist/react-lib-components.esm.js.map +1 -1
  63. package/dist/util/helper.d.ts +6 -1
  64. package/package.json +30 -24
  65. package/src/Breadcrumbs/Breadcrumbs.tsx +39 -37
  66. package/src/Button/BaseButton.test.tsx +65 -19
  67. package/src/Button/BaseButton.tsx +2 -3
  68. package/src/Button/Button.test.tsx +63 -17
  69. package/src/Button/Button.tsx +15 -4
  70. package/src/Button/IconButton.test.tsx +57 -22
  71. package/src/Button/IconButton.tsx +14 -9
  72. package/src/ContextMenu/ContextMenu.test.tsx +27 -1
  73. package/src/ContextMenu/ContextMenu.tsx +70 -65
  74. package/src/Form/Checkbox/Checkbox.test.tsx +28 -2
  75. package/src/Form/Checkbox/Checkbox.tsx +132 -122
  76. package/src/Form/Fieldset/Fieldset.test.tsx +28 -2
  77. package/src/Form/Fieldset/Fieldset.tsx +96 -50
  78. package/src/Form/FormControl/FormControl.test.tsx +27 -1
  79. package/src/Form/FormControl/FormControl.tsx +36 -39
  80. package/src/Form/FormGroup/FormGroup.test.tsx +51 -1
  81. package/src/Form/FormGroup/FormGroup.tsx +64 -58
  82. package/src/Form/FormHelperText/FormHelperText.test.tsx +27 -1
  83. package/src/Form/FormHelperText/FormHelperText.tsx +20 -16
  84. package/src/Form/FormSelectorWrapper/FormSelectorWrapper.test.tsx +78 -0
  85. package/src/Form/FormSelectorWrapper/FormSelectorWrapper.tsx +61 -55
  86. package/src/Form/Input/Input.module.scss +34 -15
  87. package/src/Form/Input/Input.test.tsx +27 -1
  88. package/src/Form/Input/Input.tsx +88 -47
  89. package/src/Form/Label/Label.test.tsx +27 -1
  90. package/src/Form/Label/Label.tsx +18 -14
  91. package/src/Form/Radio/Radio.test.tsx +28 -2
  92. package/src/Form/Radio/Radio.tsx +98 -90
  93. package/src/Form/Select/Option.test.tsx +27 -1
  94. package/src/Form/Select/Option.tsx +49 -42
  95. package/src/Form/Select/Select.module.scss +5 -1
  96. package/src/Form/Select/Select.test.tsx +224 -30
  97. package/src/Form/Select/Select.tsx +248 -182
  98. package/src/Form/Textarea/Textarea.module.scss +2 -1
  99. package/src/Form/Textarea/Textarea.test.tsx +28 -2
  100. package/src/Form/Textarea/Textarea.tsx +44 -29
  101. package/src/Form/Toggle/Toggle.module.scss +9 -0
  102. package/src/Form/Toggle/Toggle.test.tsx +27 -1
  103. package/src/Form/Toggle/Toggle.tsx +25 -12
  104. package/src/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.test.tsx +27 -1
  105. package/src/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.tsx +45 -48
  106. package/src/Form/Wrapper/InputWrapper/InputWrapper.module.scss +17 -1
  107. package/src/Form/Wrapper/InputWrapper/InputWrapper.test.tsx +89 -1
  108. package/src/Form/Wrapper/InputWrapper/InputWrapper.tsx +134 -74
  109. package/src/Form/Wrapper/RadioWrapper/RadioWrapper.tsx +64 -59
  110. package/src/Form/Wrapper/SelectWrapper/SelectWrapper.module.scss +1 -1
  111. package/src/Form/Wrapper/SelectWrapper/SelectWrapper.test.tsx +43 -1
  112. package/src/Form/Wrapper/SelectWrapper/SelectWrapper.tsx +54 -44
  113. package/src/Form/Wrapper/TextareaWrapper/TextareaWrapper.module.scss +5 -7
  114. package/src/Form/Wrapper/TextareaWrapper/TextareaWrapper.test.tsx +43 -1
  115. package/src/Form/Wrapper/TextareaWrapper/TextareaWrapper.tsx +100 -85
  116. package/src/Form/Wrapper/Wrapper/Wrapper.module.scss +1 -1
  117. package/src/Form/Wrapper/Wrapper/Wrapper.test.tsx +27 -1
  118. package/src/Form/Wrapper/Wrapper/Wrapper.tsx +76 -71
  119. package/src/Form/form.interfaces.ts +4 -3
  120. package/src/Icon/Icon.module.scss +4 -0
  121. package/src/Icon/Icon.test.tsx +30 -2
  122. package/src/Icon/Icon.tsx +5 -5
  123. package/src/Link/Link.test.tsx +27 -1
  124. package/src/Link/Link.tsx +10 -7
  125. package/src/Notifications/BaseModal/BaseModal.test.tsx +27 -1
  126. package/src/Notifications/BaseModal/BaseModal.tsx +59 -54
  127. package/src/Notifications/BaseModal/BaseModalActions/BaseModalActions.test.tsx +26 -1
  128. package/src/Notifications/BaseModal/BaseModalActions/BaseModalActions.tsx +11 -9
  129. package/src/Notifications/BaseModal/BaseModalContent/BaseModalContent.test.tsx +27 -1
  130. package/src/Notifications/BaseModal/BaseModalContent/BaseModalContent.tsx +27 -26
  131. package/src/Notifications/BaseModal/BaseModalHeader/BaseModalHeader.test.tsx +29 -1
  132. package/src/Notifications/BaseModal/BaseModalHeader/BaseModalHeader.tsx +18 -16
  133. package/src/Notifications/Dialog/Dialog.test.tsx +39 -1
  134. package/src/Notifications/Dialog/Dialog.tsx +84 -78
  135. package/src/Notifications/Dialog/DialogActions/DialogActions.test.tsx +27 -1
  136. package/src/Notifications/Dialog/DialogActions/DialogActions.tsx +15 -12
  137. package/src/Notifications/Dialog/DialogTitle/DialogTitle.test.tsx +28 -2
  138. package/src/Notifications/Dialog/DialogTitle/DialogTitle.tsx +13 -11
  139. package/src/Notifications/DiscardChangesModal/DiscardChangesDialog/DiscardChangesDialog.test.tsx +41 -1
  140. package/src/Notifications/DiscardChangesModal/DiscardChangesDialog/DiscardChangesDialog.tsx +43 -36
  141. package/src/Notifications/DiscardChangesModal/DiscardChangesModal.test.tsx +52 -1
  142. package/src/Notifications/DiscardChangesModal/DiscardChangesModal.tsx +8 -3
  143. package/src/Notifications/Snackbar/SnackbarItem/SnackbarItem.tsx +1 -1
  144. package/src/Pagination/Pagination.module.scss +120 -0
  145. package/src/Pagination/Pagination.test.tsx +176 -0
  146. package/src/Pagination/Pagination.tsx +205 -0
  147. package/src/Popover/Popover.tsx +3 -3
  148. package/src/Tabs/Tab.test.tsx +71 -0
  149. package/src/Tabs/Tab.tsx +17 -0
  150. package/src/Tabs/TabButton.module.scss +36 -0
  151. package/src/Tabs/TabButton.test.tsx +77 -0
  152. package/src/Tabs/TabButton.tsx +58 -0
  153. package/src/Tabs/TabPanel.module.scss +7 -0
  154. package/src/Tabs/TabPanel.test.tsx +76 -0
  155. package/src/Tabs/TabPanel.tsx +27 -0
  156. package/src/Tabs/Tabs.module.scss +41 -0
  157. package/src/Tabs/Tabs.test.tsx +268 -0
  158. package/src/Tabs/Tabs.tsx +149 -0
  159. package/src/TextEllipsis/TextEllipsis.module.scss +18 -0
  160. package/src/TextEllipsis/TextEllipsis.test.tsx +80 -0
  161. package/src/TextEllipsis/TextEllipsis.tsx +55 -0
  162. package/src/Tiles/Tile.test.tsx +27 -1
  163. package/src/Tiles/Tile.tsx +59 -62
  164. package/src/Tiles/Tiles.test.tsx +27 -1
  165. package/src/Tiles/Tiles.tsx +42 -39
  166. package/src/Tooltip/Tooltip.test.tsx +27 -1
  167. package/src/Tooltip/Tooltip.tsx +104 -92
  168. package/src/Typography/Typography.test.tsx +27 -1
  169. package/src/Typography/Typography.tsx +66 -68
  170. package/src/Wizard/BaseWizardSteps/BaseWizardSteps.tsx +67 -62
  171. package/src/Wizard/WizardSteps/WizardSteps.tsx +24 -21
  172. package/src/_BaseStyling_/BaseStyling.tsx +19 -1
  173. package/src/hooks/useRepeater.test.tsx +139 -0
  174. package/src/hooks/useRepeater.ts +34 -0
  175. package/src/hooks/useSpacing.ts +1 -1
  176. package/src/hooks/useWrapper.ts +7 -2
  177. package/src/index.ts +15 -1
  178. package/src/interfaces.ts +2 -12
  179. package/src/util/helper.test.tsx +38 -1
  180. package/src/util/helper.tsx +21 -0
@@ -1,11 +1,11 @@
1
- import React, { ReactElement } from 'react';
1
+ import React, { ComponentPropsWithRef, ReactElement } from 'react';
2
2
  import { FormGroup, Props as FormGroupProps } from '../../FormGroup/FormGroup';
3
3
  import { Label, Props as LabelProps } from '../../Label/Label';
4
4
  import classes from './Wrapper.module.scss';
5
5
  import { Props as HelperProps } from '../../FormHelperText/FormHelperText';
6
- import { HTMLProps } from '../../../interfaces';
6
+ import { FormElement } from '../../form.interfaces';
7
7
 
8
- export interface Props extends Omit<FormGroupProps, 'children'> {
8
+ export interface Props extends ComponentPropsWithRef<'div'>, FormGroupProps {
9
9
  children: ReactElement | ReactElement[];
10
10
  floatingLabelActive?: boolean;
11
11
  floatingLabel?: boolean;
@@ -19,83 +19,88 @@ export interface Props extends Omit<FormGroupProps, 'children'> {
19
19
  }
20
20
 
21
21
  /** For components that extend this component we create an interface (InputWrapper, SelectWrapper, etc.) */
22
- export interface WrapperProps extends HTMLProps<HTMLDivElement> {
22
+ export interface WrapperProps extends FormElement {
23
23
  errorMessage?: string;
24
- error: boolean;
25
24
  helperText?: string;
26
25
  helperProps?: HelperProps;
27
26
  label?: string;
28
27
  name: string;
29
28
  required?: boolean;
29
+ disabled?: boolean;
30
30
  }
31
31
 
32
- export const Wrapper = ({
33
- children,
34
- className,
35
- error,
36
- errorMessage,
37
- errorId,
38
- errorMessageIcon,
39
- errorMessageIconPosition,
40
- helperText,
41
- helperId,
42
- floatingLabel = true,
43
- floatingLabelActive,
44
- required,
45
- helperProps,
46
- helperIndent,
47
- labelProps,
48
- label,
49
- disabled,
50
- name,
51
- innerClassName,
52
- ...rest
53
- }: Props) => {
54
- const renderChildren = () =>
55
- React.Children.map(children, (child) =>
56
- React.cloneElement(child, {
57
- disabled,
58
- })
59
- );
32
+ export const Wrapper = React.forwardRef<HTMLDivElement, Props>(
33
+ (
34
+ {
35
+ children,
36
+ className,
37
+ error,
38
+ errorMessage,
39
+ errorId,
40
+ errorMessageIcon,
41
+ errorMessageIconPosition,
42
+ helperText,
43
+ helperId,
44
+ floatingLabel = true,
45
+ floatingLabelActive,
46
+ required,
47
+ helperProps,
48
+ helperIndent,
49
+ labelProps,
50
+ label,
51
+ disabled,
52
+ name,
53
+ innerClassName,
54
+ ...rest
55
+ }: Props,
56
+ ref
57
+ ) => {
58
+ const renderChildren = () =>
59
+ React.Children.map(children, (child) =>
60
+ React.cloneElement(child, {
61
+ disabled,
62
+ })
63
+ );
60
64
 
61
- const labelClasses = [];
65
+ const labelClasses = [];
62
66
 
63
- floatingLabel && labelClasses.push(classes['floating-label']);
64
- floatingLabel && floatingLabelActive && labelClasses.push(classes['floating-label-active']);
65
- labelProps?.className && labelClasses.push(labelProps.className);
66
- required && labelClasses.push(classes['required']);
67
- error && labelClasses.push(classes['error']);
67
+ floatingLabel && labelClasses.push(classes['floating-label']);
68
+ floatingLabel && floatingLabelActive && labelClasses.push(classes['floating-label-active']);
69
+ labelProps?.className && labelClasses.push(labelProps.className);
70
+ required && labelClasses.push(classes['required']);
71
+ error && labelClasses.push(classes['error']);
68
72
 
69
- return (
70
- <div {...rest} className={`${classes.wrapper} ${className ? className : ''}`}>
71
- <FormGroup
72
- error={error}
73
- errorMessage={errorMessage}
74
- errorId={errorId}
75
- errorMessageIcon={errorMessageIcon}
76
- errorMessageIconPosition={errorMessageIconPosition}
77
- helperText={helperText}
78
- helperId={helperId}
79
- helperProps={helperProps}
80
- helperIndent={helperIndent}
81
- >
82
- <div
83
- className={`${floatingLabel ? classes['floating-wrapper'] : ''} ${
84
- innerClassName ? innerClassName : ''
85
- }`}
73
+ return (
74
+ <div {...rest} ref={ref} className={`${classes.wrapper} ${className ? className : ''}`}>
75
+ <FormGroup
76
+ error={error}
77
+ errorMessage={errorMessage}
78
+ errorId={errorId}
79
+ errorMessageIcon={errorMessageIcon}
80
+ errorMessageIconPosition={errorMessageIconPosition}
81
+ helperText={helperText}
82
+ helperId={helperId}
83
+ helperProps={helperProps}
84
+ helperIndent={helperIndent}
86
85
  >
87
- {label && (
88
- <Label
89
- {...labelProps}
90
- className={`${classes.label} ${labelClasses.join(' ')}`}
91
- htmlFor={name}
92
- >
93
- {label}
94
- </Label>
95
- )}
96
- {renderChildren()}
97
- </div>
98
- </FormGroup>
99
- </div>
100
- );
101
- };
86
+ <div
87
+ className={`${floatingLabel ? classes['floating-wrapper'] : ''} ${
88
+ innerClassName ? innerClassName : ''
89
+ }`}
90
+ >
91
+ {label && (
92
+ <Label
93
+ {...labelProps}
94
+ className={`${classes.label} ${labelClasses.join(' ')}`}
95
+ htmlFor={name}
96
+ >
97
+ {label}
98
+ </Label>
99
+ )}
100
+ {renderChildren()}
101
+ </div>
102
+ </FormGroup>
103
+ </div>
104
+ );
105
+ }
106
+ );
@@ -1,7 +1,7 @@
1
- import { HTMLProps } from '../interfaces';
1
+ import { DataAttributeKey } from '../interfaces';
2
2
 
3
3
  /** Radios */
4
- export interface FormSelector<T> extends FormElement<T> {
4
+ export interface FormSelector extends FormElement {
5
5
  helperText?: string;
6
6
  errorMessage?: string;
7
7
  parentHelperId?: string;
@@ -9,6 +9,7 @@ export interface FormSelector<T> extends FormElement<T> {
9
9
  }
10
10
 
11
11
  /** Default form elements */
12
- export interface FormElement<T> extends HTMLProps<T> {
12
+ export interface FormElement {
13
13
  error?: boolean;
14
+ [dataAttribute: DataAttributeKey]: any;
14
15
  }
@@ -272,6 +272,10 @@
272
272
  content: '\e93c';
273
273
  @include fontProperties();
274
274
  }
275
+ .icon-error-circle:before {
276
+ content: '\e93d';
277
+ @include fontProperties();
278
+ }
275
279
  .icon-circle:before {
276
280
  content: '\e93e';
277
281
  @include fontProperties();
@@ -1,8 +1,10 @@
1
- import React from 'react';
1
+ import React, { useEffect, useRef } from 'react';
2
2
  import { Icon, Props, Icons } from './Icon';
3
3
  import { render } from '@testing-library/react';
4
4
 
5
- const initParams: Props = {
5
+ interface PartialProps extends Omit<Props, 'ref'> {}
6
+
7
+ const initParams: PartialProps = {
6
8
  icon: Icons.Calendar,
7
9
  color: 'rgb(26, 153, 60)',
8
10
  };
@@ -37,3 +39,29 @@ describe('Icon', () => {
37
39
  expect(icon.tagName.toLowerCase()).toBe(tag);
38
40
  });
39
41
  });
42
+
43
+ describe('ref should work', () => {
44
+ it('should give back the proper data prop, this also checks if the component propagates ...rest properly', () => {
45
+ const ExampleComponent = ({
46
+ propagateRef,
47
+ }: {
48
+ propagateRef?: (ref: React.RefObject<HTMLElement>) => void;
49
+ }) => {
50
+ const ref = useRef(null);
51
+
52
+ useEffect(() => {
53
+ if (ref.current) {
54
+ propagateRef && propagateRef(ref);
55
+ }
56
+ }, [ref]);
57
+
58
+ return <Icon {...initParams} data-ref="testing" ref={ref} />;
59
+ };
60
+
61
+ const refCheck = (ref: React.RefObject<HTMLElement>) => {
62
+ expect(ref.current).toHaveAttribute('data-ref', 'testing');
63
+ };
64
+
65
+ render(<ExampleComponent propagateRef={refCheck} />);
66
+ });
67
+ });
package/src/Icon/Icon.tsx CHANGED
@@ -1,6 +1,5 @@
1
- import React from 'react';
1
+ import React, { ComponentPropsWithRef } from 'react';
2
2
  import classes from './Icon.module.scss';
3
- import { HTMLAttributes } from '../interfaces';
4
3
 
5
4
  export enum Icons {
6
5
  Bell = 'bell',
@@ -26,6 +25,7 @@ export enum Icons {
26
25
  Ellipsis = 'ellipsis',
27
26
  EllipsisAlt = 'ellipsis-alt',
28
27
  Equal = 'equal',
28
+ Error = 'error-circle',
29
29
  Eye = 'eye',
30
30
  Filter = 'filter',
31
31
  FilterAlt = 'filter-alt',
@@ -69,21 +69,21 @@ export enum Icons {
69
69
 
70
70
  type Tag = 'span' | 'div' | 'i';
71
71
 
72
- export interface Props extends Omit<HTMLAttributes<HTMLOrSVGElement>, 'size'> {
72
+ export interface Props extends ComponentPropsWithRef<'div'> {
73
73
  icon: Icons;
74
74
  color?: string;
75
75
  size?: string;
76
76
  tag?: Tag;
77
77
  }
78
78
 
79
- export const Icon = React.forwardRef(
79
+ export const Icon = React.forwardRef<HTMLDivElement, Props>(
80
80
  ({ icon, color, className, style, size, tag = 'span', ...rest }: Props, ref) => {
81
81
  const Component = tag;
82
82
 
83
83
  return (
84
84
  <Component
85
85
  {...rest}
86
- ref={ref as React.LegacyRef<HTMLDivElement>}
86
+ ref={ref}
87
87
  style={{ color: color, ...style, fontSize: size }}
88
88
  data-icon
89
89
  aria-hidden="true"
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useEffect, useRef } from 'react';
2
2
  import { Link, Props } from './Link';
3
3
  import { render } from '@testing-library/react';
4
4
  import { BrowserRouter, Link as RouterLink } from 'react-router-dom';
@@ -101,6 +101,32 @@ describe('Link should render', () => {
101
101
  });
102
102
  });
103
103
 
104
+ describe('ref should work', () => {
105
+ it('should give back the proper data prop, this also checks if the component propagates ...rest properly', () => {
106
+ const ExampleComponent = ({
107
+ propagateRef,
108
+ }: {
109
+ propagateRef?: (ref: React.RefObject<HTMLElement>) => void;
110
+ }) => {
111
+ const ref = useRef(null);
112
+
113
+ useEffect(() => {
114
+ if (ref.current) {
115
+ propagateRef && propagateRef(ref);
116
+ }
117
+ }, [ref]);
118
+
119
+ return <Link {...defaultParams} data-ref="testing" ref={ref} />;
120
+ };
121
+
122
+ const refCheck = (ref: React.RefObject<HTMLElement>) => {
123
+ expect(ref.current).toHaveAttribute('data-ref', 'testing');
124
+ };
125
+
126
+ render(<ExampleComponent propagateRef={refCheck} />);
127
+ });
128
+ });
129
+
104
130
  describe('colors', () => {
105
131
  it('should be color primary', () => {
106
132
  const { link } = createLink((defaultParams) => ({ ...defaultParams, color: 'primary' }));
package/src/Link/Link.tsx CHANGED
@@ -1,21 +1,24 @@
1
- import React, { ForwardRefExoticComponent, Ref, RefAttributes } from 'react';
2
- import { HTMLProps } from '../interfaces';
1
+ import React, {
2
+ ComponentPropsWithRef,
3
+ ForwardRefExoticComponent,
4
+ ReactNode,
5
+ RefAttributes,
6
+ } from 'react';
3
7
  import classes from './Link.module.scss';
4
8
  import { LinkProps } from './types';
5
9
 
6
10
  type AnchorType = 'external' | 'internal' | 'download';
7
11
 
8
- export interface Props extends HTMLProps<HTMLAnchorElement> {
9
- children?: string;
12
+ export interface Props extends ComponentPropsWithRef<'a'> {
13
+ children?: ReactNode;
10
14
  color?: 'primary' | 'secondary' | 'tertiary';
11
15
  type?: AnchorType;
12
16
  to: string;
13
17
  disabled?: boolean;
14
18
  component?: ForwardRefExoticComponent<LinkProps & RefAttributes<HTMLAnchorElement>>;
15
- ref?: Ref<HTMLAnchorElement>;
16
19
  }
17
20
 
18
- export const Link = React.forwardRef(
21
+ export const Link = React.forwardRef<HTMLAnchorElement, Props>(
19
22
  (
20
23
  {
21
24
  children,
@@ -27,7 +30,7 @@ export const Link = React.forwardRef(
27
30
  component,
28
31
  ...rest
29
32
  }: Props,
30
- ref: Ref<HTMLAnchorElement>
33
+ ref
31
34
  ) => {
32
35
  const determineTarget = () => {
33
36
  if (rest.target) {
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useEffect, useRef } from 'react';
2
2
  import { BaseModal, Props } from './BaseModal';
3
3
  import { render, getByText, queryByText, fireEvent } from '@testing-library/react';
4
4
  import userEvent from '@testing-library/user-event';
@@ -50,3 +50,29 @@ describe('BaseModal', () => {
50
50
  expect(initParams.onClose).toHaveBeenCalledTimes(2);
51
51
  });
52
52
  });
53
+
54
+ describe('ref should work', () => {
55
+ it('should give back the proper data prop, this also checks if the component propagates ...rest properly', () => {
56
+ const ExampleComponent = ({
57
+ propagateRef,
58
+ }: {
59
+ propagateRef?: (ref: React.RefObject<HTMLElement>) => void;
60
+ }) => {
61
+ const ref = useRef(null);
62
+
63
+ useEffect(() => {
64
+ if (ref.current) {
65
+ propagateRef && propagateRef(ref);
66
+ }
67
+ }, [ref]);
68
+
69
+ return <BaseModal id="test" children="test" open={true} data-ref="testing" ref={ref} />;
70
+ };
71
+
72
+ const refCheck = (ref: React.RefObject<HTMLElement>) => {
73
+ expect(ref.current).toHaveAttribute('data-ref', 'testing');
74
+ };
75
+
76
+ render(<ExampleComponent propagateRef={refCheck} />);
77
+ });
78
+ });
@@ -1,13 +1,12 @@
1
- import React, { useEffect } from 'react';
1
+ import React, { ComponentPropsWithRef, useEffect } from 'react';
2
2
  import { createPortal } from 'react-dom';
3
- import { HTMLAttributes } from '../../interfaces';
4
3
  import classes from './BaseModal.module.scss';
5
4
  import { labelId, descriptionId } from './BaseModalContext';
6
5
 
7
6
  const SCROLL_PROPERTY_NAME = 'overflow';
8
7
  const SCROLL_PROPERTY_VALUE = 'hidden';
9
8
 
10
- export interface Props extends HTMLAttributes<HTMLDivElement> {
9
+ export interface Props extends ComponentPropsWithRef<'div'> {
11
10
  id: string;
12
11
  children: React.ReactNode;
13
12
  open: boolean;
@@ -44,57 +43,63 @@ export const useSetBodyScroll = (open: boolean) => {
44
43
  }, [open]);
45
44
  };
46
45
 
47
- export const BaseModal = ({
48
- id,
49
- children,
50
- open,
51
- onClose,
52
- className = '',
53
- containerClassName = '',
54
- labelledby,
55
- describedby,
56
- disableEscapeKeyDown = false,
57
- disableBackdrop = false,
58
- zIndex,
59
- domRoot = document.body,
60
- ...restProps
61
- }: Props) => {
62
- useSetBodyScroll(open);
46
+ export const BaseModal = React.forwardRef<HTMLDivElement, Props>(
47
+ (
48
+ {
49
+ id,
50
+ children,
51
+ open,
52
+ onClose,
53
+ className = '',
54
+ containerClassName = '',
55
+ labelledby,
56
+ describedby,
57
+ disableEscapeKeyDown = false,
58
+ disableBackdrop = false,
59
+ zIndex,
60
+ domRoot = document.body,
61
+ ...rest
62
+ }: Props,
63
+ ref
64
+ ) => {
65
+ useSetBodyScroll(open);
63
66
 
64
- const handleEscKeyPress = (event: React.KeyboardEvent<HTMLDivElement>) => {
65
- if (!disableEscapeKeyDown && event.key === 'Escape') {
66
- event.stopPropagation();
67
- onClose && onClose();
68
- }
69
- };
67
+ const handleEscKeyPress = (event: React.KeyboardEvent<HTMLDivElement>) => {
68
+ if (!disableEscapeKeyDown && event.key === 'Escape') {
69
+ event.stopPropagation();
70
+ onClose && onClose();
71
+ }
72
+ };
70
73
 
71
- const handleBackdropClick = () => !disableBackdrop && onClose && onClose();
74
+ const handleBackdropClick = () => !disableBackdrop && onClose && onClose();
72
75
 
73
- return createPortal(
74
- <div
75
- {...restProps}
76
- id={id}
77
- className={`${classes['modal']} ${open && classes['visible']} ${className}`}
78
- role="dialog"
79
- aria-modal="true"
80
- aria-labelledby={labelledby || labelId(id)}
81
- aria-describedby={describedby || descriptionId(id)}
82
- aria-hidden={!open}
83
- tabIndex={-1}
84
- data-hidden={!open}
85
- onKeyDown={handleEscKeyPress}
86
- style={{ zIndex }}
87
- >
88
- <div className={classes['backdrop']} onClick={handleBackdropClick}></div>
89
- {open && (
90
- <div
91
- style={{ zIndex: zIndex && zIndex + 1 }}
92
- className={`${classes['container']} ${containerClassName}`}
93
- >
94
- {children}
95
- </div>
96
- )}
97
- </div>,
98
- domRoot
99
- );
100
- };
76
+ return createPortal(
77
+ <div
78
+ {...rest}
79
+ ref={ref}
80
+ id={id}
81
+ className={`${classes['modal']} ${open && classes['visible']} ${className}`}
82
+ role="dialog"
83
+ aria-modal="true"
84
+ aria-labelledby={labelledby || labelId(id)}
85
+ aria-describedby={describedby || descriptionId(id)}
86
+ aria-hidden={!open}
87
+ tabIndex={-1}
88
+ data-hidden={!open}
89
+ onKeyDown={handleEscKeyPress}
90
+ style={{ zIndex }}
91
+ >
92
+ <div className={classes['backdrop']} onClick={handleBackdropClick}></div>
93
+ {open && (
94
+ <div
95
+ style={{ zIndex: zIndex && zIndex + 1 }}
96
+ className={`${classes['container']} ${containerClassName}`}
97
+ >
98
+ {children}
99
+ </div>
100
+ )}
101
+ </div>,
102
+ domRoot
103
+ );
104
+ }
105
+ );
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useEffect, useRef } from 'react';
2
2
  import { BaseModalActions } from './BaseModalActions';
3
3
  import { render } from '@testing-library/react';
4
4
 
@@ -15,3 +15,28 @@ describe('BaseModalActions', () => {
15
15
  expect(dialogActionsContainer).toHaveTextContent(children);
16
16
  });
17
17
  });
18
+ describe('ref should work', () => {
19
+ it('should give back the proper data prop, this also checks if the component propagates ...rest properly', () => {
20
+ const ExampleComponent = ({
21
+ propagateRef,
22
+ }: {
23
+ propagateRef?: (ref: React.RefObject<HTMLElement>) => void;
24
+ }) => {
25
+ const ref = useRef(null);
26
+
27
+ useEffect(() => {
28
+ if (ref.current) {
29
+ propagateRef && propagateRef(ref);
30
+ }
31
+ }, [ref]);
32
+
33
+ return <BaseModalActions data-ref="testing" ref={ref} />;
34
+ };
35
+
36
+ const refCheck = (ref: React.RefObject<HTMLElement>) => {
37
+ expect(ref.current).toHaveAttribute('data-ref', 'testing');
38
+ };
39
+
40
+ render(<ExampleComponent propagateRef={refCheck} />);
41
+ });
42
+ });
@@ -1,14 +1,16 @@
1
- import React, { HTMLAttributes } from 'react';
1
+ import React, { ComponentPropsWithRef } from 'react';
2
2
  import classes from './BaseModalActions.module.scss';
3
3
 
4
- export interface Props extends HTMLAttributes<HTMLElement> {
4
+ export interface Props extends ComponentPropsWithRef<'footer'> {
5
5
  children?: React.ReactNode;
6
6
  }
7
7
 
8
- export const BaseModalActions = ({ children, className = '', ...restProps }: Props) => {
9
- return (
10
- <footer {...restProps} className={`${classes['actions']} ${className}`}>
11
- {children}
12
- </footer>
13
- );
14
- };
8
+ export const BaseModalActions = React.forwardRef<HTMLElement, Props>(
9
+ ({ children, className = '', ...rest }: Props, ref) => {
10
+ return (
11
+ <footer {...rest} ref={ref} className={`${classes['actions']} ${className}`}>
12
+ {children}
13
+ </footer>
14
+ );
15
+ }
16
+ );
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useEffect, useRef } from 'react';
2
2
  import { BaseModalContent, Props } from './BaseModalContent';
3
3
  import { render } from '@testing-library/react';
4
4
  import { descriptionId } from '../BaseModalContext';
@@ -20,6 +20,32 @@ describe('BaseModalContent', () => {
20
20
  expect(dialogContentContainer).toEqual(document.activeElement);
21
21
  });
22
22
 
23
+ describe('ref should work', () => {
24
+ it('should give back the proper data prop, this also checks if the component propagates ...rest properly', () => {
25
+ const ExampleComponent = ({
26
+ propagateRef,
27
+ }: {
28
+ propagateRef?: (ref: React.RefObject<HTMLElement>) => void;
29
+ }) => {
30
+ const ref = useRef(null);
31
+
32
+ useEffect(() => {
33
+ if (ref.current) {
34
+ propagateRef && propagateRef(ref);
35
+ }
36
+ }, [ref]);
37
+
38
+ return <BaseModalContent children="test" data-ref="testing" ref={ref} />;
39
+ };
40
+
41
+ const refCheck = (ref: React.RefObject<HTMLElement>) => {
42
+ expect(ref.current).toHaveAttribute('data-ref', 'testing');
43
+ };
44
+
45
+ render(<ExampleComponent propagateRef={refCheck} />);
46
+ });
47
+ });
48
+
23
49
  it('should renders not focused div', () => {
24
50
  const { container } = render(<BaseModalContent {...initParams} disableAutoFocus />);
25
51