· 6 years ago · Oct 12, 2019, 11:02 PM
1# Composed inputs in React, key insights
2
3Composed input = making an input that's composed of more than one input, but considered as being one input in the form.
4
5Objective: Creating groups of input that behave like they are a single input (eg. date with 3 inputs for M, D, Y)
6
7- tries to replicate native APIs as much as possible
8- hidden `input[type=hidden]` is the actual used input (ref on it, has the name & the value)
9- proxy validity & validationMessage on `input[type=hidden]` to make it return the validity of other fields as well
10- clone events of other inputs and dispatch it on hidden input.
11- `focus` focuses the first focusable input in the group
12
13# Error Handling: Key insights
14
15- replacing native error popup with custom one
16- masking the error of a sub-input to display it yourself
17- determine the best time to display an error message
18- i18n native validity: do we sync custom formatting for native errors with setCustomValidity?
19- i18n setCustomValidity for custom validation: setCustomValidity should contain actual message, how to pass custom message IDs + metadata for formatting? Symbol? Parents should be able to format based on it. Context?
20
21## API exemple
22
23- useMaybeControlledValue
24- ComposedField
25- MaskValidity
26- FormatValidity
27- useInputValidity()
28- useDelayedInputValidity()
29- `const [bind, values, errors] = useFormFields(defaultValues)`
30
31```jsx
32# composed field:
33
34const MyComposedDate = React.forwardRef((props, ref) => {
35
36 const [value, setValue] = useMaybeControlledValue(props);
37
38 const onChange = e => {
39 setValue(computeNewValue(e));
40 };
41
42 const validity = useDelayedInputValidity(ref);
43
44 return (
45 <ComposedField value={value} {...props} ref={ref}>
46 <input type="number" min="1" max="31" name={'_' + props.name + '_day'} value={getDay(value)} />
47 <input type="number" min="1" max="12" name={'_' + props.name + '_month'} value={getMonth(value)} />
48 <input type="number" name={'_' + props.name + '_year'} value={getYear(value)} />
49 {validity.shouldReport && <p role="alert">{validity.msg}</p>}
50 </ComposedField>
51 );
52});
53```