@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.
- package/README.md +16 -1
- package/dist/Breadcrumbs/Breadcrumbs.d.ts +3 -3
- package/dist/Button/BaseButton.d.ts +3 -4
- package/dist/Button/Button.d.ts +3 -4
- package/dist/Button/IconButton.d.ts +3 -4
- package/dist/ContextMenu/ContextMenu.d.ts +3 -3
- package/dist/Form/Checkbox/Checkbox.d.ts +5 -5
- package/dist/Form/Fieldset/Fieldset.d.ts +4 -4
- package/dist/Form/FormControl/FormControl.d.ts +5 -5
- package/dist/Form/FormGroup/FormGroup.d.ts +4 -4
- package/dist/Form/FormHelperText/FormHelperText.d.ts +4 -5
- package/dist/Form/FormSelectorWrapper/FormSelectorWrapper.d.ts +8 -12
- package/dist/Form/Input/Input.d.ts +7 -6
- package/dist/Form/Label/Label.d.ts +4 -5
- package/dist/Form/Radio/Radio.d.ts +5 -5
- package/dist/Form/Select/Option.d.ts +3 -4
- package/dist/Form/Select/Select.d.ts +4 -4
- package/dist/Form/Textarea/Textarea.d.ts +9 -5
- package/dist/Form/Toggle/Toggle.d.ts +3 -3
- package/dist/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.d.ts +4 -3
- package/dist/Form/Wrapper/InputWrapper/InputWrapper.d.ts +5 -5
- package/dist/Form/Wrapper/RadioWrapper/RadioWrapper.d.ts +4 -4
- package/dist/Form/Wrapper/SelectWrapper/SelectWrapper.d.ts +7 -4
- package/dist/Form/Wrapper/TextareaWrapper/TextareaWrapper.d.ts +3 -3
- package/dist/Form/Wrapper/Wrapper/Wrapper.d.ts +6 -6
- package/dist/Form/form.interfaces.d.ts +4 -3
- package/dist/Icon/Icon.d.ts +4 -4
- package/dist/Link/Link.d.ts +4 -6
- package/dist/Notifications/BaseModal/BaseModal.d.ts +3 -4
- package/dist/Notifications/BaseModal/BaseModalActions/BaseModalActions.d.ts +3 -3
- package/dist/Notifications/BaseModal/BaseModalContent/BaseModalContent.d.ts +3 -3
- package/dist/Notifications/BaseModal/BaseModalHeader/BaseModalHeader.d.ts +3 -3
- package/dist/Notifications/Dialog/Dialog.d.ts +3 -3
- package/dist/Notifications/Dialog/DialogActions/DialogActions.d.ts +3 -3
- package/dist/Notifications/Dialog/DialogTitle/DialogTitle.d.ts +3 -3
- package/dist/Notifications/DiscardChangesModal/DiscardChangesDialog/DiscardChangesDialog.d.ts +5 -4
- package/dist/Notifications/DiscardChangesModal/DiscardChangesModal.d.ts +3 -1
- package/dist/Pagination/Pagination.d.ts +19 -0
- package/dist/Popover/Popover.d.ts +3 -3
- package/dist/Tabs/Tab.d.ts +11 -0
- package/dist/Tabs/TabButton.d.ts +10 -0
- package/dist/Tabs/TabPanel.d.ts +8 -0
- package/dist/Tabs/Tabs.d.ts +9 -0
- package/dist/TextEllipsis/TextEllipsis.d.ts +6 -0
- package/dist/Tiles/Tile.d.ts +3 -3
- package/dist/Tiles/Tiles.d.ts +3 -3
- package/dist/Tooltip/Tooltip.d.ts +3 -3
- package/dist/Typography/Typography.d.ts +6 -4
- package/dist/Wizard/BaseWizardSteps/BaseWizardSteps.d.ts +3 -3
- package/dist/Wizard/WizardSteps/WizardSteps.d.ts +3 -3
- package/dist/_BaseStyling_/BaseStyling.d.ts +9 -0
- package/dist/hooks/useRepeater.d.ts +10 -0
- package/dist/hooks/useSpacing.d.ts +2 -2
- package/dist/hooks/useWrapper.d.ts +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/interfaces.d.ts +2 -11
- package/dist/react-lib-components.cjs.development.js +2395 -1696
- package/dist/react-lib-components.cjs.development.js.map +1 -1
- package/dist/react-lib-components.cjs.production.min.js +1 -1
- package/dist/react-lib-components.cjs.production.min.js.map +1 -1
- package/dist/react-lib-components.esm.js +2391 -1698
- package/dist/react-lib-components.esm.js.map +1 -1
- package/dist/util/helper.d.ts +6 -1
- package/package.json +30 -24
- package/src/Breadcrumbs/Breadcrumbs.tsx +39 -37
- package/src/Button/BaseButton.test.tsx +65 -19
- package/src/Button/BaseButton.tsx +2 -3
- package/src/Button/Button.test.tsx +63 -17
- package/src/Button/Button.tsx +15 -4
- package/src/Button/IconButton.test.tsx +57 -22
- package/src/Button/IconButton.tsx +14 -9
- package/src/ContextMenu/ContextMenu.test.tsx +27 -1
- package/src/ContextMenu/ContextMenu.tsx +70 -65
- package/src/Form/Checkbox/Checkbox.test.tsx +28 -2
- package/src/Form/Checkbox/Checkbox.tsx +132 -122
- package/src/Form/Fieldset/Fieldset.test.tsx +28 -2
- package/src/Form/Fieldset/Fieldset.tsx +96 -50
- package/src/Form/FormControl/FormControl.test.tsx +27 -1
- package/src/Form/FormControl/FormControl.tsx +36 -39
- package/src/Form/FormGroup/FormGroup.test.tsx +51 -1
- package/src/Form/FormGroup/FormGroup.tsx +64 -58
- package/src/Form/FormHelperText/FormHelperText.test.tsx +27 -1
- package/src/Form/FormHelperText/FormHelperText.tsx +20 -16
- package/src/Form/FormSelectorWrapper/FormSelectorWrapper.test.tsx +78 -0
- package/src/Form/FormSelectorWrapper/FormSelectorWrapper.tsx +61 -55
- package/src/Form/Input/Input.module.scss +34 -15
- package/src/Form/Input/Input.test.tsx +27 -1
- package/src/Form/Input/Input.tsx +88 -47
- package/src/Form/Label/Label.test.tsx +27 -1
- package/src/Form/Label/Label.tsx +18 -14
- package/src/Form/Radio/Radio.test.tsx +28 -2
- package/src/Form/Radio/Radio.tsx +98 -90
- package/src/Form/Select/Option.test.tsx +27 -1
- package/src/Form/Select/Option.tsx +49 -42
- package/src/Form/Select/Select.module.scss +5 -1
- package/src/Form/Select/Select.test.tsx +224 -30
- package/src/Form/Select/Select.tsx +248 -182
- package/src/Form/Textarea/Textarea.module.scss +2 -1
- package/src/Form/Textarea/Textarea.test.tsx +28 -2
- package/src/Form/Textarea/Textarea.tsx +44 -29
- package/src/Form/Toggle/Toggle.module.scss +9 -0
- package/src/Form/Toggle/Toggle.test.tsx +27 -1
- package/src/Form/Toggle/Toggle.tsx +25 -12
- package/src/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.test.tsx +27 -1
- package/src/Form/Wrapper/CheckboxWrapper/CheckboxWrapper.tsx +45 -48
- package/src/Form/Wrapper/InputWrapper/InputWrapper.module.scss +17 -1
- package/src/Form/Wrapper/InputWrapper/InputWrapper.test.tsx +89 -1
- package/src/Form/Wrapper/InputWrapper/InputWrapper.tsx +134 -74
- package/src/Form/Wrapper/RadioWrapper/RadioWrapper.tsx +64 -59
- package/src/Form/Wrapper/SelectWrapper/SelectWrapper.module.scss +1 -1
- package/src/Form/Wrapper/SelectWrapper/SelectWrapper.test.tsx +43 -1
- package/src/Form/Wrapper/SelectWrapper/SelectWrapper.tsx +54 -44
- package/src/Form/Wrapper/TextareaWrapper/TextareaWrapper.module.scss +5 -7
- package/src/Form/Wrapper/TextareaWrapper/TextareaWrapper.test.tsx +43 -1
- package/src/Form/Wrapper/TextareaWrapper/TextareaWrapper.tsx +100 -85
- package/src/Form/Wrapper/Wrapper/Wrapper.module.scss +1 -1
- package/src/Form/Wrapper/Wrapper/Wrapper.test.tsx +27 -1
- package/src/Form/Wrapper/Wrapper/Wrapper.tsx +76 -71
- package/src/Form/form.interfaces.ts +4 -3
- package/src/Icon/Icon.module.scss +4 -0
- package/src/Icon/Icon.test.tsx +30 -2
- package/src/Icon/Icon.tsx +5 -5
- package/src/Link/Link.test.tsx +27 -1
- package/src/Link/Link.tsx +10 -7
- package/src/Notifications/BaseModal/BaseModal.test.tsx +27 -1
- package/src/Notifications/BaseModal/BaseModal.tsx +59 -54
- package/src/Notifications/BaseModal/BaseModalActions/BaseModalActions.test.tsx +26 -1
- package/src/Notifications/BaseModal/BaseModalActions/BaseModalActions.tsx +11 -9
- package/src/Notifications/BaseModal/BaseModalContent/BaseModalContent.test.tsx +27 -1
- package/src/Notifications/BaseModal/BaseModalContent/BaseModalContent.tsx +27 -26
- package/src/Notifications/BaseModal/BaseModalHeader/BaseModalHeader.test.tsx +29 -1
- package/src/Notifications/BaseModal/BaseModalHeader/BaseModalHeader.tsx +18 -16
- package/src/Notifications/Dialog/Dialog.test.tsx +39 -1
- package/src/Notifications/Dialog/Dialog.tsx +84 -78
- package/src/Notifications/Dialog/DialogActions/DialogActions.test.tsx +27 -1
- package/src/Notifications/Dialog/DialogActions/DialogActions.tsx +15 -12
- package/src/Notifications/Dialog/DialogTitle/DialogTitle.test.tsx +28 -2
- package/src/Notifications/Dialog/DialogTitle/DialogTitle.tsx +13 -11
- package/src/Notifications/DiscardChangesModal/DiscardChangesDialog/DiscardChangesDialog.test.tsx +41 -1
- package/src/Notifications/DiscardChangesModal/DiscardChangesDialog/DiscardChangesDialog.tsx +43 -36
- package/src/Notifications/DiscardChangesModal/DiscardChangesModal.test.tsx +52 -1
- package/src/Notifications/DiscardChangesModal/DiscardChangesModal.tsx +8 -3
- package/src/Notifications/Snackbar/SnackbarItem/SnackbarItem.tsx +1 -1
- package/src/Pagination/Pagination.module.scss +120 -0
- package/src/Pagination/Pagination.test.tsx +176 -0
- package/src/Pagination/Pagination.tsx +205 -0
- package/src/Popover/Popover.tsx +3 -3
- package/src/Tabs/Tab.test.tsx +71 -0
- package/src/Tabs/Tab.tsx +17 -0
- package/src/Tabs/TabButton.module.scss +36 -0
- package/src/Tabs/TabButton.test.tsx +77 -0
- package/src/Tabs/TabButton.tsx +58 -0
- package/src/Tabs/TabPanel.module.scss +7 -0
- package/src/Tabs/TabPanel.test.tsx +76 -0
- package/src/Tabs/TabPanel.tsx +27 -0
- package/src/Tabs/Tabs.module.scss +41 -0
- package/src/Tabs/Tabs.test.tsx +268 -0
- package/src/Tabs/Tabs.tsx +149 -0
- package/src/TextEllipsis/TextEllipsis.module.scss +18 -0
- package/src/TextEllipsis/TextEllipsis.test.tsx +80 -0
- package/src/TextEllipsis/TextEllipsis.tsx +55 -0
- package/src/Tiles/Tile.test.tsx +27 -1
- package/src/Tiles/Tile.tsx +59 -62
- package/src/Tiles/Tiles.test.tsx +27 -1
- package/src/Tiles/Tiles.tsx +42 -39
- package/src/Tooltip/Tooltip.test.tsx +27 -1
- package/src/Tooltip/Tooltip.tsx +104 -92
- package/src/Typography/Typography.test.tsx +27 -1
- package/src/Typography/Typography.tsx +66 -68
- package/src/Wizard/BaseWizardSteps/BaseWizardSteps.tsx +67 -62
- package/src/Wizard/WizardSteps/WizardSteps.tsx +24 -21
- package/src/_BaseStyling_/BaseStyling.tsx +19 -1
- package/src/hooks/useRepeater.test.tsx +139 -0
- package/src/hooks/useRepeater.ts +34 -0
- package/src/hooks/useSpacing.ts +1 -1
- package/src/hooks/useWrapper.ts +7 -2
- package/src/index.ts +15 -1
- package/src/interfaces.ts +2 -12
- package/src/util/helper.test.tsx +38 -1
- package/src/util/helper.tsx +21 -0
|
@@ -1,10 +1,22 @@
|
|
|
1
|
-
import React, { ReactElement } from 'react';
|
|
1
|
+
import React, { ComponentPropsWithRef, ReactNode, ReactElement } from 'react';
|
|
2
2
|
import readyclasses from '../../readyclasses.module.scss';
|
|
3
3
|
import classes from './Fieldset.module.scss';
|
|
4
|
-
import { HTMLProps } from '../../interfaces';
|
|
5
4
|
import { Typography, Variant } from '../../Typography/Typography';
|
|
5
|
+
import { Input } from '../Input/Input';
|
|
6
|
+
import { Select } from '../Select/Select';
|
|
7
|
+
import { Radio } from '../Radio/Radio';
|
|
8
|
+
import { Checkbox } from '../Checkbox/Checkbox';
|
|
9
|
+
import { Textarea } from '../Textarea/Textarea';
|
|
10
|
+
import { Toggle } from '../Toggle/Toggle';
|
|
11
|
+
import { Label } from '../Label/Label';
|
|
12
|
+
import { FormControl } from '../FormControl/FormControl';
|
|
13
|
+
import { FormSelectorWrapper } from '../FormSelectorWrapper/FormSelectorWrapper';
|
|
14
|
+
import { FormHelperText } from '../FormHelperText/FormHelperText';
|
|
15
|
+
import { InputWrapper } from '../Wrapper/InputWrapper/InputWrapper';
|
|
16
|
+
import { SelectWrapper } from '../Wrapper/SelectWrapper/SelectWrapper';
|
|
17
|
+
import { TextareaWrapper } from '../Wrapper/TextareaWrapper/TextareaWrapper';
|
|
6
18
|
|
|
7
|
-
export interface Props extends
|
|
19
|
+
export interface Props extends ComponentPropsWithRef<'fieldset'> {
|
|
8
20
|
children?: ReactElement | ReactElement[];
|
|
9
21
|
legend: string;
|
|
10
22
|
legendStyle?: Variant;
|
|
@@ -14,54 +26,88 @@ export interface Props extends HTMLProps<HTMLFieldSetElement> {
|
|
|
14
26
|
noBackground?: boolean;
|
|
15
27
|
required?: boolean;
|
|
16
28
|
error?: boolean;
|
|
29
|
+
disablePropagation?: boolean;
|
|
17
30
|
}
|
|
18
31
|
|
|
19
|
-
export const Fieldset = (
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
export const Fieldset = React.forwardRef<HTMLFieldSetElement, Props>(
|
|
33
|
+
(
|
|
34
|
+
{
|
|
35
|
+
children,
|
|
36
|
+
className,
|
|
37
|
+
legend,
|
|
38
|
+
legendStyle = 'body',
|
|
39
|
+
hideLegend = false,
|
|
40
|
+
noBackground,
|
|
41
|
+
background = noBackground ? '' : '#FFF',
|
|
42
|
+
noPadding = false,
|
|
43
|
+
disabled = false,
|
|
44
|
+
required = false,
|
|
45
|
+
error = false,
|
|
46
|
+
disablePropagation = false,
|
|
47
|
+
...rest
|
|
48
|
+
}: Props,
|
|
49
|
+
ref
|
|
50
|
+
) => {
|
|
51
|
+
const renderChildren = () => {
|
|
52
|
+
if (!children) return;
|
|
35
53
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
54
|
+
/* All right, so the issue is that whenever we try to add disabled and error to a component that doesn't accept it,
|
|
55
|
+
React will throw an error. However, it might occur that we want a component inside of Fieldset because of aesthetic purposes
|
|
56
|
+
(fieldset applies a sort of container with white background and if we want to display it inside of this container... then yea).
|
|
57
|
+
So instead we supply an array of components that we want to add the disabled and error prop to and check if child.type equals one of these. */
|
|
58
|
+
const allowedComponents: ReactNode[] = [
|
|
59
|
+
Input,
|
|
60
|
+
Select,
|
|
61
|
+
Radio,
|
|
62
|
+
Checkbox,
|
|
63
|
+
Textarea,
|
|
64
|
+
Toggle,
|
|
65
|
+
Label,
|
|
66
|
+
FormControl,
|
|
67
|
+
FormSelectorWrapper,
|
|
68
|
+
FormHelperText,
|
|
69
|
+
InputWrapper,
|
|
70
|
+
SelectWrapper,
|
|
71
|
+
TextareaWrapper,
|
|
72
|
+
];
|
|
73
|
+
|
|
74
|
+
return React.Children.map(children, (child: ReactElement) => {
|
|
75
|
+
if (allowedComponents.includes(child.type) && !disablePropagation) {
|
|
76
|
+
return React.cloneElement(child, {
|
|
77
|
+
disabled: child.props.disabled ?? disabled,
|
|
78
|
+
error: child.props.error ?? error,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
43
81
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
82
|
+
return child;
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<fieldset
|
|
88
|
+
{...rest}
|
|
89
|
+
ref={ref}
|
|
90
|
+
disabled={disabled}
|
|
91
|
+
style={{ backgroundColor: background, ...rest.style }}
|
|
92
|
+
className={`${classes.fieldset} ${noPadding ? classes['no-padding'] : ''} ${
|
|
93
|
+
className ?? ''
|
|
94
|
+
}`}
|
|
95
|
+
>
|
|
96
|
+
{legend && <legend className={readyclasses['sr-only']}>{legend}</legend>}
|
|
97
|
+
{legend && !hideLegend && (
|
|
98
|
+
<Typography
|
|
99
|
+
variant={legendStyle}
|
|
100
|
+
tag="span"
|
|
101
|
+
aria-hidden="true"
|
|
102
|
+
className={`${classes['legend']} ${required ? classes['required'] : ''} ${
|
|
103
|
+
error ? classes['error'] : ''
|
|
104
|
+
}`}
|
|
105
|
+
>
|
|
106
|
+
{legend}
|
|
107
|
+
</Typography>
|
|
108
|
+
)}
|
|
109
|
+
{renderChildren()}
|
|
110
|
+
</fieldset>
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useEffect, useRef } from 'react';
|
|
2
2
|
import { FormControl, Props } from './FormControl';
|
|
3
3
|
import { render } from '@testing-library/react';
|
|
4
4
|
import { Input } from '../Input/Input';
|
|
@@ -35,6 +35,32 @@ describe('FormControl should render', () => {
|
|
|
35
35
|
});
|
|
36
36
|
});
|
|
37
37
|
|
|
38
|
+
describe('ref should work', () => {
|
|
39
|
+
it('should give back the proper data prop, this also checks if the component propagates ...rest properly', () => {
|
|
40
|
+
const ExampleComponent = ({
|
|
41
|
+
propagateRef,
|
|
42
|
+
}: {
|
|
43
|
+
propagateRef?: (ref: React.RefObject<HTMLElement>) => void;
|
|
44
|
+
}) => {
|
|
45
|
+
const ref = useRef(null);
|
|
46
|
+
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
if (ref.current) {
|
|
49
|
+
propagateRef && propagateRef(ref);
|
|
50
|
+
}
|
|
51
|
+
}, [ref]);
|
|
52
|
+
|
|
53
|
+
return <FormControl {...defaultParams} data-ref="testing" ref={ref} />;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const refCheck = (ref: React.RefObject<HTMLElement>) => {
|
|
57
|
+
expect(ref.current).toHaveAttribute('data-ref', 'testing');
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
render(<ExampleComponent propagateRef={refCheck} />);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
38
64
|
describe('FormControl attributes should be working correctly', () => {
|
|
39
65
|
it('has the right classes and attributes', () => {
|
|
40
66
|
const { formcontrol } = createFormControl();
|
|
@@ -1,50 +1,47 @@
|
|
|
1
|
-
import React, { ReactElement } from 'react';
|
|
1
|
+
import React, { ComponentPropsWithRef, ReactElement } from 'react';
|
|
2
2
|
import classes from './FormControl.module.scss';
|
|
3
|
-
import { HTMLProps } from '../../interfaces';
|
|
4
3
|
|
|
5
|
-
export interface Props extends
|
|
6
|
-
children
|
|
4
|
+
export interface Props extends ComponentPropsWithRef<'div'> {
|
|
5
|
+
children?: ReactElement | ReactElement[];
|
|
7
6
|
grid?: 1 | 2 | 3;
|
|
8
7
|
align?: 'top' | 'start' | 'middle' | 'center' | 'bottom' | 'end' | 'stretch';
|
|
9
8
|
error?: boolean;
|
|
9
|
+
disabled?: boolean;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
export const FormControl = (
|
|
13
|
-
children,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
...rest
|
|
20
|
-
}: Props) => {
|
|
21
|
-
const renderChildren = () =>
|
|
22
|
-
React.Children.map(children, (child) => {
|
|
23
|
-
if (!child) {
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
12
|
+
export const FormControl = React.forwardRef<HTMLDivElement, Props>(
|
|
13
|
+
({ children, disabled, error, className, grid, align = 'center', ...rest }: Props, ref) => {
|
|
14
|
+
const renderChildren = () =>
|
|
15
|
+
React.Children.map(children, (child) => {
|
|
16
|
+
if (!child) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
26
19
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
20
|
+
const childElement = React.cloneElement(child, {
|
|
21
|
+
disabled: child.props.disabled !== undefined ? child.props.disabled : disabled,
|
|
22
|
+
error: child.props.error !== undefined ? child.props.error : error,
|
|
23
|
+
});
|
|
31
24
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
25
|
+
if (grid && grid > 1) {
|
|
26
|
+
return (
|
|
27
|
+
<div className={`${classes['col-' + grid]} ${classes.column}`}>{childElement}</div>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
35
30
|
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
return childElement;
|
|
32
|
+
});
|
|
38
33
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
34
|
+
return (
|
|
35
|
+
<div
|
|
36
|
+
{...rest}
|
|
37
|
+
ref={ref}
|
|
38
|
+
data-formcontrol
|
|
39
|
+
className={`${classes['form-control']} ${className ? className : ''} ${
|
|
40
|
+
grid && grid > 1 ? `${classes.grid} ${classes['grid-' + grid]}` : ''
|
|
41
|
+
} ${classes[align]}`}
|
|
42
|
+
>
|
|
43
|
+
{renderChildren()}
|
|
44
|
+
</div>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useEffect, useRef } from 'react';
|
|
2
2
|
import { FormGroup, Props } from './FormGroup';
|
|
3
3
|
import { render } from '@testing-library/react';
|
|
4
4
|
|
|
@@ -44,6 +44,32 @@ describe('FormSelectorGroup should render', () => {
|
|
|
44
44
|
});
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
+
describe('ref should work', () => {
|
|
48
|
+
it('should give back the proper data prop, this also checks if the component propagates ...rest properly', () => {
|
|
49
|
+
const ExampleComponent = ({
|
|
50
|
+
propagateRef,
|
|
51
|
+
}: {
|
|
52
|
+
propagateRef?: (ref: React.RefObject<HTMLElement>) => void;
|
|
53
|
+
}) => {
|
|
54
|
+
const ref = useRef(null);
|
|
55
|
+
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
if (ref.current) {
|
|
58
|
+
propagateRef && propagateRef(ref);
|
|
59
|
+
}
|
|
60
|
+
}, [ref]);
|
|
61
|
+
|
|
62
|
+
return <FormGroup {...defaultParams} data-ref="testing" ref={ref} />;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const refCheck = (ref: React.RefObject<HTMLElement>) => {
|
|
66
|
+
expect(ref.current).toHaveAttribute('data-ref', 'testing');
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
render(<ExampleComponent propagateRef={refCheck} />);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
47
73
|
describe('Correct error state', () => {
|
|
48
74
|
it('has the correct state', () => {
|
|
49
75
|
const { formgroup } = createFormGroup((defaultParams) => ({
|
|
@@ -59,3 +85,27 @@ describe('Correct error state', () => {
|
|
|
59
85
|
expect(errorMessage?.querySelector('#error_id')).toHaveTextContent('example error message');
|
|
60
86
|
});
|
|
61
87
|
});
|
|
88
|
+
|
|
89
|
+
describe('no helpertext, but errorMessage is defined', () => {
|
|
90
|
+
it("doesn't show the div with 'default-helper' class when there's no error and no helpertext defined", () => {
|
|
91
|
+
const { formgroup } = createFormGroup((defaultParams) => ({
|
|
92
|
+
...defaultParams,
|
|
93
|
+
error: false,
|
|
94
|
+
helperText: undefined,
|
|
95
|
+
errorMessage: 'example error message',
|
|
96
|
+
}));
|
|
97
|
+
|
|
98
|
+
expect(formgroup.querySelector('.default-helper')).toBeFalsy();
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it("does show the div with 'default-helper' class when there's an error and no helpertext defined", () => {
|
|
102
|
+
const { formgroup } = createFormGroup((defaultParams) => ({
|
|
103
|
+
...defaultParams,
|
|
104
|
+
error: true,
|
|
105
|
+
helperText: undefined,
|
|
106
|
+
errorMessage: 'example error message',
|
|
107
|
+
}));
|
|
108
|
+
|
|
109
|
+
expect(formgroup.querySelector('.default-helper')).toBeTruthy();
|
|
110
|
+
});
|
|
111
|
+
});
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
/** The empty className property on FormHelperText is on purpose! We want to basically "filter" out the className from helperProps because we're adding this to the surrounding div. This makes it so also the errormessage receives this styling. */
|
|
2
2
|
|
|
3
|
-
import React, { ReactChild } from 'react';
|
|
3
|
+
import React, { ComponentPropsWithRef, ReactChild } from 'react';
|
|
4
4
|
import classes from './FormGroup.module.scss';
|
|
5
5
|
import { FormHelperText, Props as HelperProps } from '../FormHelperText/FormHelperText';
|
|
6
6
|
import { Icon, Icons } from '../../Icon/Icon';
|
|
7
|
-
import { HTMLProps } from '../../interfaces';
|
|
8
7
|
|
|
9
|
-
export interface Props extends
|
|
8
|
+
export interface Props extends ComponentPropsWithRef<'div'> {
|
|
10
9
|
children: ReactChild[] | ReactChild;
|
|
11
10
|
error?: boolean;
|
|
12
11
|
errorMessageIcon?: Icons;
|
|
@@ -17,62 +16,69 @@ export interface Props extends HTMLProps<HTMLDivElement> {
|
|
|
17
16
|
helperText?: string;
|
|
18
17
|
helperId?: string;
|
|
19
18
|
helperProps?: HelperProps;
|
|
19
|
+
disabled?: boolean;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export const FormGroup = (
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
22
|
+
export const FormGroup = React.forwardRef<HTMLDivElement, Props>(
|
|
23
|
+
(
|
|
24
|
+
{
|
|
25
|
+
children,
|
|
26
|
+
className,
|
|
27
|
+
error,
|
|
28
|
+
errorMessage,
|
|
29
|
+
errorId,
|
|
30
|
+
errorMessageIcon,
|
|
31
|
+
errorMessageIconPosition = 'before',
|
|
32
|
+
helperText,
|
|
33
|
+
helperId,
|
|
34
|
+
helperProps,
|
|
35
|
+
helperIndent,
|
|
36
|
+
...rest
|
|
37
|
+
}: Props,
|
|
38
|
+
ref
|
|
39
|
+
) => {
|
|
40
|
+
return (
|
|
41
|
+
<div
|
|
42
|
+
{...rest}
|
|
43
|
+
ref={ref}
|
|
44
|
+
className={`${classes['form-group']} ${error ? classes.error : ''} ${className ?? ''}`}
|
|
45
|
+
>
|
|
46
|
+
{children}
|
|
42
47
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
48
|
+
{(helperText || (errorMessage && error)) && (
|
|
49
|
+
<div
|
|
50
|
+
style={{ marginLeft: `${helperIndent}px` }}
|
|
51
|
+
className={`${classes['default-helper']} ${
|
|
52
|
+
helperProps?.className ? helperProps.className : ''
|
|
53
|
+
}`}
|
|
54
|
+
>
|
|
55
|
+
{helperText && !error && (
|
|
56
|
+
<FormHelperText {...helperProps} className={''} id={helperId}>
|
|
57
|
+
{(helperProps && helperProps.children) || helperText}
|
|
58
|
+
</FormHelperText>
|
|
59
|
+
)}
|
|
60
|
+
{error && errorMessage && (
|
|
61
|
+
<span className={classes['error-message']}>
|
|
62
|
+
<span className={classes.message} id={errorId}>
|
|
63
|
+
{errorMessageIcon && errorMessageIconPosition === 'before' && (
|
|
64
|
+
<Icon
|
|
65
|
+
className={`${classes['error-icon']} ${classes['error-icon-before']}`}
|
|
66
|
+
icon={errorMessageIcon}
|
|
67
|
+
/>
|
|
68
|
+
)}
|
|
69
|
+
{errorMessage}
|
|
70
|
+
{errorMessageIcon && errorMessageIconPosition === 'after' && (
|
|
71
|
+
<Icon
|
|
72
|
+
className={`${classes['error-icon']} ${classes['error-icon-after']}`}
|
|
73
|
+
icon={errorMessageIcon}
|
|
74
|
+
/>
|
|
75
|
+
)}
|
|
76
|
+
</span>
|
|
71
77
|
</span>
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
78
|
+
)}
|
|
79
|
+
</div>
|
|
80
|
+
)}
|
|
81
|
+
</div>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useEffect, useRef } from 'react';
|
|
2
2
|
import { FormHelperText, Props } from './FormHelperText';
|
|
3
3
|
import { render } from '@testing-library/react';
|
|
4
4
|
|
|
@@ -29,6 +29,32 @@ describe('FormHelperText 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 <FormHelperText {...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('Attributes', () => {
|
|
33
59
|
it('contains the error class', () => {
|
|
34
60
|
const { formhelpertext } = createFormHelperText((defaultParams) => ({
|
|
@@ -1,22 +1,26 @@
|
|
|
1
|
-
import React, { ReactNode } from 'react';
|
|
1
|
+
import React, { ComponentPropsWithRef, ReactNode } from 'react';
|
|
2
2
|
import classes from './FormHelperText.module.scss';
|
|
3
|
-
import { HTMLProps } from '../../interfaces';
|
|
4
3
|
import { Typography } from '../../Typography/Typography';
|
|
4
|
+
import { FormElement } from '../form.interfaces';
|
|
5
5
|
|
|
6
|
-
export interface Props extends
|
|
6
|
+
export interface Props extends ComponentPropsWithRef<'div'>, FormElement {
|
|
7
7
|
children?: ReactNode;
|
|
8
|
-
error?: boolean;
|
|
9
8
|
}
|
|
10
9
|
|
|
11
|
-
export const FormHelperText =
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
10
|
+
export const FormHelperText = React.forwardRef<HTMLDivElement, Props>(
|
|
11
|
+
({ children, error, className, ...rest }: Props, ref) => {
|
|
12
|
+
return (
|
|
13
|
+
<Typography
|
|
14
|
+
{...rest}
|
|
15
|
+
ref={ref}
|
|
16
|
+
variant="sub-text"
|
|
17
|
+
tag="div"
|
|
18
|
+
className={`${classes['form-helper-text']} ${error ? classes.error : ''} ${
|
|
19
|
+
className ?? ''
|
|
20
|
+
}`}
|
|
21
|
+
>
|
|
22
|
+
{children}
|
|
23
|
+
</Typography>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
);
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import React, { useRef, useEffect } from 'react';
|
|
2
|
+
import { FormSelectorWrapper, Props } from './FormSelectorWrapper';
|
|
3
|
+
import { render } from '@testing-library/react';
|
|
4
|
+
|
|
5
|
+
const defaultParams: Props = {};
|
|
6
|
+
|
|
7
|
+
const createFormSelectorWrapper = (params?: (defaultParams: Props) => Props) => {
|
|
8
|
+
let parameters: Props = defaultParams;
|
|
9
|
+
if (params) {
|
|
10
|
+
parameters = params(defaultParams);
|
|
11
|
+
}
|
|
12
|
+
const queries = render(
|
|
13
|
+
<FormSelectorWrapper {...parameters} data-testid="formSelectorWrapper">
|
|
14
|
+
formSelectorWrapper content
|
|
15
|
+
</FormSelectorWrapper>
|
|
16
|
+
);
|
|
17
|
+
const formSelectorWrapper = queries.getByTestId('formSelectorWrapper');
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
...queries,
|
|
21
|
+
formSelectorWrapper,
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
describe('FormSelectorWrapper should render', () => {
|
|
26
|
+
it('renders without crashing', () => {
|
|
27
|
+
const { formSelectorWrapper } = createFormSelectorWrapper();
|
|
28
|
+
|
|
29
|
+
expect(formSelectorWrapper).toBeDefined();
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
describe('ref should work', () => {
|
|
34
|
+
it('should give back the proper data prop, this also checks if the component propagates ...rest properly', () => {
|
|
35
|
+
const ExampleComponent = ({
|
|
36
|
+
propagateRef,
|
|
37
|
+
}: {
|
|
38
|
+
propagateRef?: (
|
|
39
|
+
ref: React.RefObject<HTMLElement>,
|
|
40
|
+
ref2: React.RefObject<HTMLElement>,
|
|
41
|
+
ref3: React.RefObject<HTMLElement>
|
|
42
|
+
) => void;
|
|
43
|
+
}) => {
|
|
44
|
+
const ref = useRef(null);
|
|
45
|
+
const helperRef = useRef(null);
|
|
46
|
+
const containerRef = useRef(null);
|
|
47
|
+
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
if (ref.current) {
|
|
50
|
+
propagateRef && propagateRef(ref, helperRef, containerRef);
|
|
51
|
+
}
|
|
52
|
+
}, [ref]);
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<FormSelectorWrapper
|
|
56
|
+
{...defaultParams}
|
|
57
|
+
containerProps={{ 'data-ref': 'testing', ref: containerRef }}
|
|
58
|
+
helperText="helpertext"
|
|
59
|
+
helperProps={{ 'data-ref': 'testing', ref: helperRef }}
|
|
60
|
+
data-ref="testing"
|
|
61
|
+
ref={ref}
|
|
62
|
+
/>
|
|
63
|
+
);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const refCheck = (
|
|
67
|
+
ref: React.RefObject<HTMLElement>,
|
|
68
|
+
ref2: React.RefObject<HTMLElement>,
|
|
69
|
+
ref3: React.RefObject<HTMLElement>
|
|
70
|
+
) => {
|
|
71
|
+
expect(ref.current).toHaveAttribute('data-ref', 'testing');
|
|
72
|
+
expect(ref2.current).toHaveAttribute('data-ref', 'testing');
|
|
73
|
+
expect(ref3.current).toHaveAttribute('data-ref', 'testing');
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
render(<ExampleComponent propagateRef={refCheck} />);
|
|
77
|
+
});
|
|
78
|
+
});
|