@ilo-org/react 0.7.7 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/lib/cjs/components/Checkbox/Checkbox.js +28 -16
- package/lib/cjs/components/Checkbox/index.js +25 -3
- package/lib/cjs/components/DatePicker/DatePicker.js +21 -16
- package/lib/cjs/components/DatePicker/index.js +4 -4
- package/lib/cjs/components/Dropdown/Dropdown.js +19 -15
- package/lib/cjs/components/Dropdown/index.js +3 -3
- package/lib/cjs/components/Fieldset/Fieldset.js +33 -9
- package/lib/cjs/components/Fieldset/index.js +2 -2
- package/lib/cjs/components/FileUpload/FileUpload.js +29 -15
- package/lib/cjs/components/FileUpload/index.js +3 -3
- package/lib/cjs/components/Form/Form.js +8 -55
- package/lib/cjs/components/Form/index.js +10 -20
- package/lib/cjs/components/FormControl/FormControl.js +79 -0
- package/lib/cjs/components/FormControl/index.js +16 -0
- package/lib/cjs/components/Input/Input.js +1 -1
- package/lib/cjs/components/NumberPicker/NumberPicker.js +21 -16
- package/lib/cjs/components/NumberPicker/index.js +4 -4
- package/lib/cjs/components/Radio/Radio.js +34 -17
- package/lib/cjs/components/Radio/index.js +19 -4
- package/lib/cjs/components/TextInput/TextInput.js +30 -0
- package/lib/cjs/components/TextInput/index.js +52 -0
- package/lib/cjs/components/Textarea/Textarea.js +19 -19
- package/lib/cjs/components/Textarea/index.js +26 -5
- package/lib/cjs/components/Toggle/Toggle.js +33 -0
- package/lib/cjs/components/Toggle/index.js +51 -0
- package/lib/cjs/components/Tooltip/Tooltip.js +2 -2
- package/lib/cjs/components/index.js +10 -11
- package/lib/cjs/hooks/usePrevious.js +20 -0
- package/lib/cjs/index.js +10 -11
- package/lib/esm/components/Checkbox/Checkbox.js +31 -19
- package/lib/esm/components/Checkbox/index.js +27 -2
- package/lib/esm/components/DatePicker/DatePicker.js +22 -17
- package/lib/esm/components/DatePicker/index.js +4 -4
- package/lib/esm/components/Dropdown/Dropdown.js +20 -16
- package/lib/esm/components/Dropdown/index.js +3 -3
- package/lib/esm/components/Fieldset/Fieldset.js +31 -11
- package/lib/esm/components/Fieldset/index.js +1 -1
- package/lib/esm/components/FileUpload/FileUpload.js +31 -17
- package/lib/esm/components/FileUpload/index.js +3 -3
- package/lib/esm/components/Form/Form.js +10 -57
- package/lib/esm/components/Form/index.js +13 -20
- package/lib/esm/components/FormControl/FormControl.js +73 -0
- package/lib/esm/components/{ChoiceGroup → FormControl}/index.js +3 -6
- package/lib/esm/components/NumberPicker/NumberPicker.js +21 -16
- package/lib/esm/components/NumberPicker/index.js +4 -4
- package/lib/esm/components/Radio/Radio.js +34 -17
- package/lib/esm/components/Radio/index.js +21 -3
- package/lib/esm/components/TextInput/TextInput.js +28 -0
- package/lib/esm/components/TextInput/index.js +49 -0
- package/lib/esm/components/Textarea/Textarea.js +19 -19
- package/lib/esm/components/Textarea/index.js +28 -4
- package/lib/esm/components/Toggle/Toggle.js +31 -0
- package/lib/esm/components/Toggle/index.js +48 -0
- package/lib/esm/components/Tooltip/Tooltip.js +2 -2
- package/lib/esm/components/index.js +8 -5
- package/lib/esm/hooks/usePrevious.js +15 -0
- package/lib/esm/index.js +8 -5
- package/lib/types/react/src/components/Checkbox/Checkbox.args.d.ts +52 -0
- package/lib/types/react/src/components/Checkbox/Checkbox.d.ts +5 -3
- package/lib/types/react/src/components/Checkbox/Checkbox.props.d.ts +4 -13
- package/lib/types/react/src/components/Checkbox/index.d.ts +1 -0
- package/lib/types/react/src/components/DatePicker/DatePicker.d.ts +4 -3
- package/lib/types/react/src/components/DatePicker/DatePicker.props.d.ts +10 -43
- package/lib/types/react/src/components/Dropdown/Dropdown.d.ts +5 -3
- package/lib/types/react/src/components/Dropdown/Dropdown.props.d.ts +16 -42
- package/lib/types/react/src/components/Fieldset/Fieldset.d.ts +6 -0
- package/lib/types/react/src/components/Fieldset/Fieldset.props.d.ts +14 -21
- package/lib/types/react/src/components/FileUpload/FileUpload.d.ts +5 -3
- package/lib/types/react/src/components/FileUpload/FileUpload.props.d.ts +7 -44
- package/lib/types/react/src/components/Form/Form.args.d.ts +2 -0
- package/lib/types/react/src/components/Form/Form.d.ts +1 -2
- package/lib/types/react/src/components/Form/Form.props.d.ts +4 -111
- package/lib/types/react/src/components/Form/index.d.ts +1 -0
- package/lib/types/react/src/components/FormControl/FormControl.d.ts +9 -0
- package/lib/types/react/src/components/FormControl/FormControl.props.d.ts +55 -0
- package/lib/types/react/src/components/FormControl/index.d.ts +2 -0
- package/lib/types/react/src/components/FormElement/FormElement.props.d.ts +2 -2
- package/lib/types/react/src/components/Input/Input.props.d.ts +2 -2
- package/lib/types/react/src/components/NumberPicker/NumberPicker.d.ts +5 -3
- package/lib/types/react/src/components/NumberPicker/NumberPicker.props.d.ts +5 -42
- package/lib/types/react/src/components/Radio/Radio.args.d.ts +8 -0
- package/lib/types/react/src/components/Radio/Radio.d.ts +5 -3
- package/lib/types/react/src/components/Radio/Radio.props.d.ts +4 -14
- package/lib/types/react/src/components/Radio/index.d.ts +1 -0
- package/lib/types/react/src/components/TextInput/TextInput.args.d.ts +10 -0
- package/lib/types/react/src/components/TextInput/TextInput.d.ts +6 -0
- package/lib/types/react/src/components/TextInput/TextInput.props.d.ts +17 -0
- package/lib/types/react/src/components/TextInput/index.d.ts +2 -0
- package/lib/types/react/src/components/Textarea/Textarea.args.d.ts +10 -0
- package/lib/types/react/src/components/Textarea/Textarea.d.ts +5 -3
- package/lib/types/react/src/components/Textarea/Textarea.props.d.ts +17 -39
- package/lib/types/react/src/components/Textarea/index.d.ts +2 -0
- package/lib/types/react/src/components/Toggle/Toggle.args.d.ts +12 -0
- package/lib/types/react/src/components/Toggle/Toggle.d.ts +5 -0
- package/lib/types/react/src/components/Toggle/Toggle.props.d.ts +22 -0
- package/lib/types/react/src/components/Toggle/index.d.ts +3 -0
- package/lib/types/react/src/components/Tooltip/Tooltip.props.d.ts +4 -0
- package/lib/types/react/src/components/index.d.ts +1 -5
- package/lib/types/react/src/hooks/usePrevious.d.ts +2 -0
- package/lib/types/react/src/types/index.d.ts +57 -1
- package/package.json +19 -18
- package/src/components/Checkbox/Checkbox.args.ts +31 -9
- package/src/components/Checkbox/Checkbox.props.ts +5 -13
- package/src/components/Checkbox/Checkbox.tsx +78 -76
- package/src/components/Checkbox/index.ts +1 -0
- package/src/components/DatePicker/DatePicker.args.ts +6 -32
- package/src/components/DatePicker/DatePicker.props.ts +11 -51
- package/src/components/DatePicker/DatePicker.tsx +71 -110
- package/src/components/Dropdown/Dropdown.args.ts +42 -192
- package/src/components/Dropdown/Dropdown.props.ts +18 -49
- package/src/components/Dropdown/Dropdown.tsx +73 -62
- package/src/components/Fieldset/Fieldset.props.ts +14 -23
- package/src/components/Fieldset/Fieldset.tsx +75 -69
- package/src/components/FileUpload/FileUpload.args.ts +25 -27
- package/src/components/FileUpload/FileUpload.props.ts +8 -53
- package/src/components/FileUpload/FileUpload.tsx +103 -72
- package/src/components/Form/Form.args.ts +2 -184
- package/src/components/Form/Form.props.ts +4 -133
- package/src/components/Form/Form.tsx +17 -77
- package/src/components/Form/index.ts +1 -0
- package/src/components/FormControl/FormControl.props.ts +72 -0
- package/src/components/FormControl/FormControl.tsx +169 -0
- package/src/components/FormControl/index.ts +2 -0
- package/src/components/FormElement/FormElement.props.ts +2 -2
- package/src/components/Input/Input.props.ts +2 -2
- package/src/components/Navigation/Navigation.args.ts +2 -1
- package/src/components/NumberPicker/NumberPicker.args.ts +18 -26
- package/src/components/NumberPicker/NumberPicker.props.ts +7 -52
- package/src/components/NumberPicker/NumberPicker.tsx +73 -56
- package/src/components/Radio/Radio.args.ts +1 -7
- package/src/components/Radio/Radio.props.ts +6 -14
- package/src/components/Radio/Radio.tsx +90 -52
- package/src/components/Radio/index.ts +1 -0
- package/src/components/TextInput/TextInput.args.ts +75 -0
- package/src/components/TextInput/TextInput.props.ts +20 -0
- package/src/components/TextInput/TextInput.tsx +71 -0
- package/src/components/TextInput/index.ts +2 -0
- package/src/components/Textarea/Textarea.args.ts +19 -37
- package/src/components/Textarea/Textarea.props.ts +18 -46
- package/src/components/Textarea/Textarea.tsx +44 -59
- package/src/components/Textarea/index.ts +2 -0
- package/src/components/Toggle/Toggle.args.ts +62 -0
- package/src/components/Toggle/Toggle.props.ts +27 -0
- package/src/components/Toggle/Toggle.tsx +85 -0
- package/src/components/Toggle/index.ts +3 -0
- package/src/components/Tooltip/Tooltip.props.ts +5 -0
- package/src/components/Tooltip/Tooltip.tsx +2 -0
- package/src/components/index.ts +1 -5
- package/src/hooks/usePrevious.ts +15 -0
- package/src/types/forms.args.ts +288 -0
- package/src/types/index.ts +69 -1
- package/tsconfig.json +2 -1
- package/lib/cjs/components/ChoiceGroup/ChoiceGroup.js +0 -34
- package/lib/cjs/components/ChoiceGroup/index.js +0 -19
- package/lib/cjs/components/FormGroup/FormGroup.js +0 -58
- package/lib/cjs/components/FormGroup/index.js +0 -26
- package/lib/esm/components/ChoiceGroup/ChoiceGroup.js +0 -32
- package/lib/esm/components/FormGroup/FormGroup.js +0 -56
- package/lib/esm/components/FormGroup/index.js +0 -20
- package/lib/types/react/src/components/ChoiceGroup/ChoiceGroup.d.ts +0 -4
- package/lib/types/react/src/components/ChoiceGroup/ChoiceGroup.props.d.ts +0 -20
- package/lib/types/react/src/components/ChoiceGroup/index.d.ts +0 -1
- package/lib/types/react/src/components/FormGroup/FormGroup.d.ts +0 -4
- package/lib/types/react/src/components/FormGroup/FormGroup.props.d.ts +0 -81
- package/lib/types/react/src/components/FormGroup/index.d.ts +0 -1
- package/src/components/ChoiceGroup/ChoiceGroup.args.ts +0 -95
- package/src/components/ChoiceGroup/ChoiceGroup.props.ts +0 -25
- package/src/components/ChoiceGroup/ChoiceGroup.tsx +0 -54
- package/src/components/ChoiceGroup/index.ts +0 -1
- package/src/components/FormGroup/FormGroup.args.ts +0 -85
- package/src/components/FormGroup/FormGroup.props.ts +0 -102
- package/src/components/FormGroup/FormGroup.tsx +0 -73
- package/src/components/FormGroup/index.ts +0 -1
|
@@ -1,137 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { DropdownProps } from "../Dropdown/Dropdown.props";
|
|
4
|
-
import { FileUploadProps } from "../FileUpload/FileUpload.props";
|
|
5
|
-
import { NumberPickerProps } from "../NumberPicker/NumberPicker.props";
|
|
6
|
-
import { RadioProps } from "../Radio/Radio.props";
|
|
7
|
-
import { TextareaProps } from "../Textarea/Textarea.props";
|
|
8
|
-
import { InputProps } from "../Input/Input.props";
|
|
9
|
-
import { FormGroupProps } from "../FormGroup/FormGroup.props";
|
|
10
|
-
|
|
11
|
-
export interface InputItem {
|
|
12
|
-
type: "input";
|
|
13
|
-
field: InputProps;
|
|
14
|
-
choicegroupid?: never;
|
|
15
|
-
legend?: never;
|
|
16
|
-
grouptooltip?: never;
|
|
17
|
-
grouperror?: never;
|
|
18
|
-
grouphelper?: never;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface DropdownItem {
|
|
22
|
-
type: "dropdown";
|
|
23
|
-
field: DropdownProps;
|
|
24
|
-
choicegroupid?: never;
|
|
25
|
-
legend?: never;
|
|
26
|
-
grouptooltip?: never;
|
|
27
|
-
grouperror?: never;
|
|
28
|
-
grouphelper?: never;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface CheckboxItem {
|
|
32
|
-
type: "checkbox";
|
|
33
|
-
field: CheckboxProps | CheckboxProps[];
|
|
34
|
-
choicegroupid: string;
|
|
35
|
-
legend?: string;
|
|
36
|
-
grouptooltip?: string;
|
|
37
|
-
grouperror?: string;
|
|
38
|
-
grouphelper?: string;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export interface RadioItem {
|
|
42
|
-
type: "radio";
|
|
43
|
-
field: RadioProps | RadioProps[];
|
|
44
|
-
choicegroupid: string;
|
|
45
|
-
legend?: string;
|
|
46
|
-
grouptooltip?: string;
|
|
47
|
-
grouperror?: string;
|
|
48
|
-
grouphelper?: string;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export interface FileUploadItem {
|
|
52
|
-
type: "file";
|
|
53
|
-
field: FileUploadProps;
|
|
54
|
-
choicegroupid?: never;
|
|
55
|
-
legend?: never;
|
|
56
|
-
grouptooltip?: never;
|
|
57
|
-
grouperror?: never;
|
|
58
|
-
grouphelper?: never;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export interface NumberPickerItem {
|
|
62
|
-
type: "number";
|
|
63
|
-
field: NumberPickerProps;
|
|
64
|
-
choicegroupid?: never;
|
|
65
|
-
legend?: never;
|
|
66
|
-
grouptooltip?: never;
|
|
67
|
-
grouperror?: never;
|
|
68
|
-
grouphelper?: never;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export interface DatePickerItem {
|
|
72
|
-
type: "date";
|
|
73
|
-
field: DatePickerProps;
|
|
74
|
-
choicegroupid?: never;
|
|
75
|
-
legend?: never;
|
|
76
|
-
grouptooltip?: never;
|
|
77
|
-
grouperror?: never;
|
|
78
|
-
grouphelper?: never;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export interface TextareaItem {
|
|
82
|
-
type: "textarea";
|
|
83
|
-
field: TextareaProps;
|
|
84
|
-
choicegroupid?: never;
|
|
85
|
-
legend?: never;
|
|
86
|
-
grouptooltip?: never;
|
|
87
|
-
grouperror?: never;
|
|
88
|
-
grouphelper?: never;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export interface FormGroupItem {
|
|
92
|
-
type: "formgroup";
|
|
93
|
-
field: FormGroupProps;
|
|
94
|
-
choicegroupid?: string;
|
|
95
|
-
legend?: string;
|
|
96
|
-
grouptooltip?: string;
|
|
97
|
-
grouperror?: string;
|
|
98
|
-
grouphelper?: string;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
type FormItem =
|
|
102
|
-
| InputItem
|
|
103
|
-
| DropdownItem
|
|
104
|
-
| CheckboxItem
|
|
105
|
-
| RadioItem
|
|
106
|
-
| FileUploadItem
|
|
107
|
-
| NumberPickerItem
|
|
108
|
-
| DatePickerItem
|
|
109
|
-
| TextareaItem
|
|
110
|
-
| FormGroupItem;
|
|
111
|
-
|
|
112
|
-
export interface FormProps {
|
|
113
|
-
/**
|
|
114
|
-
* The form's action attribute
|
|
115
|
-
*/
|
|
116
|
-
action: Required<string>;
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Specify an optional className to be added to your Form component.
|
|
120
|
-
*/
|
|
121
|
-
className?: string;
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* The ID of the form
|
|
125
|
-
*/
|
|
126
|
-
formid: Required<string>;
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* The inputs in this form group
|
|
130
|
-
*/
|
|
131
|
-
items: FormItem[];
|
|
1
|
+
export interface FormProps extends React.FormHTMLAttributes<HTMLFormElement> {
|
|
2
|
+
children?: React.ReactNode;
|
|
132
3
|
|
|
133
4
|
/**
|
|
134
|
-
* The
|
|
5
|
+
* The theme of the form. Also sets the theme of the form's children.
|
|
135
6
|
*/
|
|
136
|
-
|
|
7
|
+
theme?: "light" | "dark";
|
|
137
8
|
}
|
|
@@ -1,83 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import { useGlobalSettings } from "../../hooks";
|
|
2
3
|
import classNames from "classnames";
|
|
3
|
-
import useGlobalSettings from "../../hooks/useGlobalSettings";
|
|
4
|
-
import { Button } from "../Button";
|
|
5
4
|
import { FormProps } from "./Form.props";
|
|
6
|
-
import { FormGroup } from "../FormGroup";
|
|
7
|
-
import { Checkbox } from "../Checkbox";
|
|
8
|
-
import { ChoiceGroup } from "../ChoiceGroup";
|
|
9
|
-
import { DatePicker } from "../DatePicker";
|
|
10
|
-
import { Dropdown } from "../Dropdown";
|
|
11
|
-
import { FileUpload } from "../FileUpload";
|
|
12
|
-
import { Input } from "../Input";
|
|
13
|
-
import { NumberPicker } from "../NumberPicker";
|
|
14
|
-
import { Textarea } from "../Textarea";
|
|
15
5
|
|
|
16
|
-
const Form
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
formid,
|
|
20
|
-
items,
|
|
21
|
-
submitlabel,
|
|
22
|
-
}) => {
|
|
23
|
-
const { prefix } = useGlobalSettings();
|
|
24
|
-
const baseClass = `${prefix}--form`;
|
|
25
|
-
const formClasses = classNames(className, {
|
|
26
|
-
[baseClass]: true,
|
|
27
|
-
});
|
|
6
|
+
const Form = forwardRef<HTMLFormElement, FormProps>(
|
|
7
|
+
({ children, theme = "light", ...props }, ref) => {
|
|
8
|
+
const { prefix } = useGlobalSettings();
|
|
28
9
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if (
|
|
42
|
-
(item?.type === "checkbox" || item?.type === "radio") &&
|
|
43
|
-
Array.isArray(item?.field)
|
|
44
|
-
) {
|
|
45
|
-
return (
|
|
46
|
-
<ChoiceGroup
|
|
47
|
-
items={item?.field as any}
|
|
48
|
-
legend={item?.legend as any}
|
|
49
|
-
choicegroupid={item?.choicegroupid as any}
|
|
50
|
-
grouperror={item?.grouperror as any}
|
|
51
|
-
grouphelper={item?.grouphelper as any}
|
|
52
|
-
grouptooltip={item?.grouptooltip as any}
|
|
53
|
-
key={i}
|
|
54
|
-
/>
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
|
-
if (item?.type === "file") {
|
|
58
|
-
return <FileUpload {...(item?.field as any)} key={i} />;
|
|
59
|
-
}
|
|
60
|
-
if (item?.type === "date") {
|
|
61
|
-
return <DatePicker {...(item?.field as any)} key={i} />;
|
|
62
|
-
}
|
|
63
|
-
if (item?.type === "number") {
|
|
64
|
-
return <NumberPicker {...(item?.field as any)} key={i} />;
|
|
65
|
-
}
|
|
66
|
-
if (item?.type === "textarea") {
|
|
67
|
-
return <Textarea {...(item?.field as any)} key={i} />;
|
|
68
|
-
}
|
|
69
|
-
if (item?.type === "formgroup") {
|
|
70
|
-
return <FormGroup {...(item?.field as any)} key={i} />;
|
|
71
|
-
}
|
|
72
|
-
})}
|
|
73
|
-
<Button
|
|
74
|
-
kind={"submit"}
|
|
75
|
-
label={submitlabel}
|
|
76
|
-
size={"large"}
|
|
77
|
-
type={"primary"}
|
|
78
|
-
/>
|
|
79
|
-
</form>
|
|
80
|
-
);
|
|
81
|
-
};
|
|
10
|
+
const baseClass = `${prefix}--form`;
|
|
11
|
+
const themeClass = `${baseClass}__theme__${theme}`;
|
|
12
|
+
|
|
13
|
+
const formClasses = classNames(baseClass, themeClass);
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<form ref={ref} className={formClasses} {...props}>
|
|
17
|
+
{children}
|
|
18
|
+
</form>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
);
|
|
82
22
|
|
|
83
23
|
export default Form;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { ReactElement } from "react";
|
|
2
|
+
import { DropdownProps } from "../Dropdown/Dropdown.props";
|
|
3
|
+
import { InputProps } from "../Input/Input.props";
|
|
4
|
+
import { TextareaProps } from "../Textarea";
|
|
5
|
+
import { ToggleProps } from "../Toggle";
|
|
6
|
+
|
|
7
|
+
export interface FormControlPublicProps {
|
|
8
|
+
/**
|
|
9
|
+
* Optional className to add to the FormControl wrapper
|
|
10
|
+
*/
|
|
11
|
+
className?: string;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Is the input disabled?
|
|
15
|
+
*/
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Does the input have an error?
|
|
20
|
+
*/
|
|
21
|
+
error?: boolean;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The message to display in case of an error
|
|
25
|
+
*/
|
|
26
|
+
errorMessage?: string;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Helper text to display with the label
|
|
30
|
+
*/
|
|
31
|
+
helper?: string;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The FormControl's label
|
|
35
|
+
*/
|
|
36
|
+
label: string;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Where to place the label
|
|
40
|
+
*/
|
|
41
|
+
labelPlacement?: "top" | "start" | "bottom" | "end";
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* The size of your label. Defaults to "medium"
|
|
45
|
+
*/
|
|
46
|
+
labelSize?: "small" | "medium" | "large";
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Inline styles for the input
|
|
50
|
+
*/
|
|
51
|
+
style?: React.CSSProperties;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Optional text to render in a tooltip
|
|
55
|
+
*/
|
|
56
|
+
tooltip?: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface FormControlPrivateProps {
|
|
60
|
+
/**
|
|
61
|
+
* The id of the underlying input element
|
|
62
|
+
*/
|
|
63
|
+
fieldId: string;
|
|
64
|
+
|
|
65
|
+
children:
|
|
66
|
+
| ReactElement<ToggleProps>
|
|
67
|
+
| ReactElement<InputProps>
|
|
68
|
+
| ReactElement<DropdownProps>
|
|
69
|
+
| ReactElement<TextareaProps>;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export type FormControlProps = FormControlPublicProps & FormControlPrivateProps;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import classnames from "classnames";
|
|
2
|
+
import { nanoid } from "nanoid";
|
|
3
|
+
import {
|
|
4
|
+
FC,
|
|
5
|
+
createContext,
|
|
6
|
+
useContext,
|
|
7
|
+
useEffect,
|
|
8
|
+
useMemo,
|
|
9
|
+
useState,
|
|
10
|
+
} from "react";
|
|
11
|
+
import { useGlobalSettings } from "../../hooks";
|
|
12
|
+
import { Tooltip } from "../Tooltip";
|
|
13
|
+
import { FormControlProps } from "./FormControl.props";
|
|
14
|
+
|
|
15
|
+
interface AllyFields {
|
|
16
|
+
tooltip?: string;
|
|
17
|
+
helper?: string;
|
|
18
|
+
errorMessage?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface AllyFieldsIds {
|
|
22
|
+
tooltipId?: string;
|
|
23
|
+
helperId?: string;
|
|
24
|
+
errorId?: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface FormControlContextProps {
|
|
28
|
+
ariaDescribedBy?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Calculates unique IDs for the internal accessibility elements
|
|
32
|
+
// TODO: When we upgrade to React 8, this should use useId instead
|
|
33
|
+
function getA11yFields(
|
|
34
|
+
baseClass = "",
|
|
35
|
+
{ tooltip, helper, errorMessage }: AllyFields = {}
|
|
36
|
+
) {
|
|
37
|
+
return {
|
|
38
|
+
tooltipId: tooltip && `${baseClass}--tooltip--${nanoid()}`,
|
|
39
|
+
helperId: helper && `${baseClass}--helper--${nanoid()}`,
|
|
40
|
+
errorId: errorMessage && `${baseClass}--error--${nanoid()}`,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Calculates the aria-describedby attribute value based on whether or not there's an error
|
|
45
|
+
function getAriaDescribedBy(getAllyFields: AllyFieldsIds, hasError?: boolean) {
|
|
46
|
+
const { tooltipId, helperId, errorId } = getAllyFields;
|
|
47
|
+
|
|
48
|
+
const ariaDescribedBy = classnames(tooltipId, {
|
|
49
|
+
[`${helperId}`]: !hasError,
|
|
50
|
+
[`${errorId}`]: hasError,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// For some reason, classnames seems to return "undefined" as a string sometimes
|
|
54
|
+
if (!ariaDescribedBy || ariaDescribedBy === "undefined") {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
return ariaDescribedBy;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// The context passed down to form elements wrapped by the form control
|
|
61
|
+
export const FormControlContext: React.Context<FormControlContextProps> =
|
|
62
|
+
createContext({});
|
|
63
|
+
|
|
64
|
+
// Hook to get the context value
|
|
65
|
+
export const useFormControl = () => useContext(FormControlContext);
|
|
66
|
+
|
|
67
|
+
const FormControl: FC<FormControlProps> = ({
|
|
68
|
+
children,
|
|
69
|
+
className,
|
|
70
|
+
label,
|
|
71
|
+
helper,
|
|
72
|
+
errorMessage,
|
|
73
|
+
tooltip,
|
|
74
|
+
style,
|
|
75
|
+
error,
|
|
76
|
+
disabled,
|
|
77
|
+
fieldId,
|
|
78
|
+
labelSize = "medium",
|
|
79
|
+
labelPlacement = "top",
|
|
80
|
+
}) => {
|
|
81
|
+
const { prefix } = useGlobalSettings();
|
|
82
|
+
|
|
83
|
+
// Classes applied to the outer container
|
|
84
|
+
const baseClass = `${prefix}--form-control`;
|
|
85
|
+
|
|
86
|
+
// The ids of the tooltip, helper, and error only get calculated on first render
|
|
87
|
+
const a11yFields = useMemo(
|
|
88
|
+
() => getA11yFields(baseClass, { helper, errorMessage, tooltip }),
|
|
89
|
+
[baseClass, helper, errorMessage, tooltip]
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
// The ids of the tooltip, helper, and error
|
|
93
|
+
const { tooltipId, helperId, errorId } = a11yFields;
|
|
94
|
+
|
|
95
|
+
// The aria-describedby attribute value
|
|
96
|
+
const [ariaDescribedBy, setAriaDescribedBy] = useState<string | undefined>(
|
|
97
|
+
undefined
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
// Update the aria-describedby attribute value when the error changes
|
|
101
|
+
useEffect(() => {
|
|
102
|
+
setAriaDescribedBy(
|
|
103
|
+
getAriaDescribedBy({ tooltipId, helperId, errorId }, error)
|
|
104
|
+
);
|
|
105
|
+
}, [tooltipId, helperId, errorId, error]);
|
|
106
|
+
|
|
107
|
+
// The context passed down to form elements wrapped by the form control
|
|
108
|
+
const contextValue: FormControlContextProps = {
|
|
109
|
+
ariaDescribedBy,
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// Classes applied to the outer container
|
|
113
|
+
const errorClass = `${baseClass}__error`;
|
|
114
|
+
const disabledClass = `${baseClass}__disabled`;
|
|
115
|
+
const labelPlacementClass = `${baseClass}__label-placement__${labelPlacement}`;
|
|
116
|
+
|
|
117
|
+
const formControlClass = classnames(
|
|
118
|
+
baseClass,
|
|
119
|
+
className,
|
|
120
|
+
labelPlacementClass,
|
|
121
|
+
[{ [errorClass]: error }, { [disabledClass]: disabled }]
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
// Classes applies to the label
|
|
125
|
+
const labelBaseClass = `${baseClass}--label`;
|
|
126
|
+
const labelSizeClass = `${labelBaseClass}__size__${labelSize}`;
|
|
127
|
+
const labelClass = classnames(labelBaseClass, labelSizeClass);
|
|
128
|
+
|
|
129
|
+
// Helper class
|
|
130
|
+
const helperClass = `${baseClass}--helper`;
|
|
131
|
+
|
|
132
|
+
// Show the error message if there is an error and an error message
|
|
133
|
+
const showError = !!error && !!errorMessage;
|
|
134
|
+
|
|
135
|
+
// Show the helper text if there is no error and a helper text
|
|
136
|
+
const showHelper = !showError && !!helper;
|
|
137
|
+
|
|
138
|
+
return (
|
|
139
|
+
<FormControlContext.Provider value={contextValue}>
|
|
140
|
+
<div className={formControlClass} style={style}>
|
|
141
|
+
<span className={labelClass}>
|
|
142
|
+
<label htmlFor={fieldId}>{label}</label>
|
|
143
|
+
{tooltip && (
|
|
144
|
+
<Tooltip
|
|
145
|
+
id={tooltipId}
|
|
146
|
+
className={`${baseClass}--legend--tooltip`}
|
|
147
|
+
icon={true}
|
|
148
|
+
label={tooltip}
|
|
149
|
+
theme={"dark"}
|
|
150
|
+
/>
|
|
151
|
+
)}
|
|
152
|
+
</span>
|
|
153
|
+
{children}
|
|
154
|
+
{showHelper && (
|
|
155
|
+
<span id={helperId} className={helperClass}>
|
|
156
|
+
{helper}
|
|
157
|
+
</span>
|
|
158
|
+
)}
|
|
159
|
+
{showError && (
|
|
160
|
+
<span id={errorId} className={helperClass} aria-live="assertive">
|
|
161
|
+
{errorMessage}
|
|
162
|
+
</span>
|
|
163
|
+
)}
|
|
164
|
+
</div>
|
|
165
|
+
</FormControlContext.Provider>
|
|
166
|
+
);
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
export default FormControl;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactElement } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { TextInputTypes, FieldTypes } from "../../types";
|
|
3
3
|
import { DropdownProps } from "../Dropdown/Dropdown.props";
|
|
4
4
|
import { InputProps } from "../Input/Input.props";
|
|
5
5
|
import { TextareaProps } from "../Textarea/Textarea.props";
|
|
@@ -56,5 +56,5 @@ export interface FormElementProps {
|
|
|
56
56
|
/**
|
|
57
57
|
* The type of field
|
|
58
58
|
*/
|
|
59
|
-
type?:
|
|
59
|
+
type?: TextInputTypes | FieldTypes;
|
|
60
60
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { TextInputTypes } from "../../types";
|
|
2
2
|
|
|
3
3
|
export interface InputProps {
|
|
4
4
|
/**
|
|
@@ -59,5 +59,5 @@ export interface InputProps {
|
|
|
59
59
|
/**
|
|
60
60
|
* The input's type.
|
|
61
61
|
*/
|
|
62
|
-
type:
|
|
62
|
+
type: TextInputTypes;
|
|
63
63
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { NavigationProps } from "./Navigation.props";
|
|
2
2
|
import ilo_logo_white from "@ilo-org/brand-assets/logo_en_horizontal_white.svg";
|
|
3
|
+
import ilo_logo_blue from "@ilo-org/brand-assets/logo_en_horizontal_blue.svg";
|
|
3
4
|
|
|
4
5
|
const basic: NavigationProps = {
|
|
5
6
|
logo: ilo_logo_white,
|
|
6
|
-
mobilelogo:
|
|
7
|
+
mobilelogo: ilo_logo_blue,
|
|
7
8
|
siteurl: "https://www.ilo.org/",
|
|
8
9
|
tagline: {
|
|
9
10
|
tag: "Advancing social justice, promoting decent work",
|
|
@@ -1,53 +1,45 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { LabelledNumberPickerProps } from "./NumberPicker.props";
|
|
2
2
|
|
|
3
|
-
const basic:
|
|
4
|
-
|
|
3
|
+
const basic: LabelledNumberPickerProps = {
|
|
4
|
+
label: "How many items would you like?",
|
|
5
|
+
id: "numberpicker",
|
|
5
6
|
disabled: false,
|
|
6
7
|
error: false,
|
|
7
|
-
helper: false,
|
|
8
|
-
label: "Number Picker Field Label",
|
|
9
8
|
name: "text",
|
|
10
|
-
placeholder: "
|
|
9
|
+
placeholder: "Select a number",
|
|
11
10
|
required: false,
|
|
12
11
|
};
|
|
13
12
|
|
|
14
|
-
const hashelper:
|
|
15
|
-
|
|
13
|
+
const hashelper: LabelledNumberPickerProps = {
|
|
14
|
+
label: "How many items would you like?",
|
|
15
|
+
id: "numberpicker",
|
|
16
16
|
disabled: false,
|
|
17
17
|
error: false,
|
|
18
|
-
helper: "Here is the helper text",
|
|
19
|
-
label: "Number Picker Field Label",
|
|
20
18
|
name: "text",
|
|
21
|
-
placeholder: "
|
|
19
|
+
placeholder: "Select a number",
|
|
22
20
|
required: false,
|
|
23
21
|
};
|
|
24
22
|
|
|
25
|
-
const haserror:
|
|
26
|
-
|
|
23
|
+
const haserror: LabelledNumberPickerProps = {
|
|
24
|
+
label: "How many items would you like?",
|
|
25
|
+
id: "numberpicker",
|
|
27
26
|
disabled: false,
|
|
28
|
-
error:
|
|
29
|
-
helper: false,
|
|
30
|
-
label: "Number Picker Field Label",
|
|
27
|
+
error: true,
|
|
31
28
|
name: "text",
|
|
32
|
-
placeholder: "
|
|
29
|
+
placeholder: "Select a number",
|
|
33
30
|
required: false,
|
|
34
31
|
};
|
|
35
32
|
|
|
36
|
-
const hastooltip:
|
|
37
|
-
|
|
33
|
+
const hastooltip: LabelledNumberPickerProps = {
|
|
34
|
+
label: "How many items would you like?",
|
|
35
|
+
id: "numberpicker",
|
|
38
36
|
disabled: false,
|
|
39
37
|
error: false,
|
|
40
|
-
helper: false,
|
|
41
|
-
label: "Number Picker Field Label",
|
|
42
38
|
name: "text",
|
|
43
|
-
placeholder: "
|
|
39
|
+
placeholder: "Select a number",
|
|
44
40
|
required: false,
|
|
45
|
-
tooltip: "This is the tooltip",
|
|
46
41
|
};
|
|
47
42
|
|
|
48
|
-
/**
|
|
49
|
-
* Sample prop definitions NumberPicker's enumerable properties (imported in stories and test)
|
|
50
|
-
*/
|
|
51
43
|
const NumberPickerArgs = {
|
|
52
44
|
basic,
|
|
53
45
|
hashelper,
|
|
@@ -1,56 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
import { FormFieldProps } from "../../types";
|
|
2
|
+
import { LabelledFormFieldProps } from "../../types";
|
|
3
|
+
export interface NumberPickerProps extends FormFieldProps<HTMLInputElement> {
|
|
2
4
|
/**
|
|
3
|
-
* The input
|
|
4
|
-
*/
|
|
5
|
-
callback: (e: React.ChangeEvent<HTMLInputElement>) => any;
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Specify an optional className to be added to your input.
|
|
9
|
-
*/
|
|
10
|
-
className?: string;
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Is the input disabled?
|
|
14
|
-
*/
|
|
15
|
-
disabled?: boolean;
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Does the input have an error?
|
|
19
|
-
*/
|
|
20
|
-
error?: string | false;
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* The input's helper text
|
|
24
|
-
*/
|
|
25
|
-
helper: string | false;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* The input's id attribute
|
|
29
|
-
*/
|
|
30
|
-
id?: string;
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Does this input have a label?
|
|
34
|
-
*/
|
|
35
|
-
label: string;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* The input's name attribute
|
|
39
|
-
*/
|
|
40
|
-
name?: Required<string>;
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Specify an optional className to be added to your NumberPicker component.
|
|
5
|
+
* The placeholder text when the input is empty.
|
|
44
6
|
*/
|
|
45
7
|
placeholder?: string;
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Specify whether this input is required
|
|
49
|
-
*/
|
|
50
|
-
required?: boolean;
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Does this NumberPicker have a tooltip?
|
|
54
|
-
*/
|
|
55
|
-
tooltip?: string;
|
|
56
8
|
}
|
|
9
|
+
|
|
10
|
+
export type LabelledNumberPickerProps =
|
|
11
|
+
LabelledFormFieldProps<NumberPickerProps>;
|