@burnsred/entity-form v0.6.5
Form bindings for Entities
<Form field={myEntityField} value={myEntityRecord}>
<div>
<Input name="foo"> // infers Widget type from entity field
<Input name="foo" type="other"> // overrides Widget type
<Input name="foo" widget={WidgetComponent}> // direct control
</div>
</Form>Form
The form is primarily to set up a FormContext for the Input components to
extract information from.
Its interface specifically matches that of Widget so it's possible to create
forms which process nested records by nesting a Form as the Widget to an
Input in another Form.
Widgets
Widgets are expected to affect the actual user interface component.
Any plain HTML element will be passed:
name
value
readOnly
disabled
onChangeIn addition to the above, any React component will be passed:
errors: Entity validations errors
field: the Entity Field associated with this Input
choices: value choices if specified on the Field
valueInitial: the initial (non-draft) value for this field
index: if this is a multi-value field, our index position in the values list
onSubmitInput
The Input extracts details from the FormContext appropriate for its
Widget, based on its name.
Wrapper
Optionally, you can pass a Wrapper, along with wrapperProps, to the Input.
This component will be rendered with the selected Widget as its child, and all
of the field properties passed to it.
If not passed, a useDefault will be called for widgets.Wrapper, falling back
to a plain React Fragment.
useFormField
This hook does most of the work of resolving the properties to pass into the Widget.
It takes all the properties of an Input, and returns:
{
name
field
value
valueInitial
disabled
readOnly
errors
onChange
onSubmit
}This can be used in cases where you need more control over the overall widget rendering. For example:
export function NumberWidget({ label, name, type = 'number' }) {
const { value, disabled, readOnly, errors, onChange } = useFormField({
name,
type,
});
return (
<FormControl
isInvalid={errors.length}
isDisabled={disabled}
isReadOnly={readOnly}
>
<FormLabel>{label}</FormLabel>
<Input type={type} onChange={onChange} value={value} />
{errors &&
errors.map(({ code, message }) => (
<FormErrorMessage key={code}>{message}</FormErrorMessage>
))}
</FormControl>
);
}Sources of data
Widget either sources props from Input, or resolves from the Form Context
- = Input produces a wrapper over the Form Context value x - Input can override context o - Original default comes from here (not Query)
| Field | Form | Input | Widget | Comment |
|---|---|---|---|---|
| Core Widget Params (for basic HTML inputs) | ||||
| name | * | |||
| value | * | |||
| onChange | + | |||
| onSubmit | + | Not recommended for use | ||
| readOnly | o | x | * | |
| disabled | o | x | x | |
| Extra Widget Params (for React widgets) | ||||
| field | * | |||
| errors (1) | ? | * | ||
| valueInitial | * | |||
| type | x | |||
| Inform the input how to handle the Widget | ||||
| array | * | |||
| index | * |
- extra errors for a field can be provided to the Input.