0.6.3 • Published 4 days ago

@burnsred/entity-form v0.6.3

Weekly downloads
1
License
MIT
Repository
github
Last release
4 days ago

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

onChange

In 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

onSubmit

Input

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)
FieldFormInputWidgetComment
Core Widget Params (for basic HTML inputs)
name*
value*
onChange+
onSubmit+Not recommended for use
readOnlyox*
disabledoxx
Extra Widget Params (for React widgets)
field*
errors (1)?*
valueInitial*
typex
Inform the input how to handle the Widget
array*
index*
  1. extra errors for a field can be provided to the Input.