2.1.0 ā€¢ Published 3 months ago

@roqueform/uncontrolled-plugin v2.1.0

Weekly downloads
-
License
MIT
Repository
github
Last release
3 months ago

Uncontrolled plugin for Roqueform

Updates Roqueform fields by listening to change events of associated DOM elements.

šŸ”„ā€‚Try it on CodeSandbox

npm install --save-prod @roqueform/uncontrolled-plugin

Overview

šŸ”Ž API documentation is available here.

This plugin doesn't require any rendering framework. To simplify the usage example, we're going to use the React integration.

import type { SyntheticEvent } from 'react';
import { useField } from '@roqueform/react';
import { uncontrolledPlugin } from '@roqueform/uncontrolled-plugin';

export const App = () => {
  const planetField = useField(
    { name: 'Mars', properties: { color: 'red' } },
    uncontrolledPlugin()
  );

  const handleSubmit = (event: SyntheticEvent) => {
    event.preventDefault();

    // The field value is always in sync with the input element value.
    doSubmit(planetField.value);
  };

  return (
    <form onSubmit={handleSubmit}>
      {'Planet name:'}
      <input
        type="text"
        ref={field.at('name').ref}
      />
      <br/>

      {'Color:'}
      {['red', 'green', 'blue'].map(color =>
        <label>
          <input
            type="radio"
            // šŸŒ• An arbitrary name of a radio group
            name="property-color"
            value={color}
            ref={field.at('properties').at('color').refFor(color)}
          />
          {color}
        </label>
      )}
    </form>
  );
};

Referencing elements

To associate field with an element, pass ref as a ref attribute of an input, textarea, or any other form element:

<input ref={field.ref}/>

The plugin would synchronize the field value with the value of an input element. When the input value is changed and change or input event is dispatched, the field is updated with the corresponding value.

If you have a set of radio buttons, or checkboxes that update a single field, use refFor with a distinct key. refFor always returns the same ref callback for the same key. uncontrolledPlugin would use elements passed to ref callbacks to derive a value.

const namesField = useField(['Mars', 'Pluto'], uncontrolledPlugin());

The plugin derives the field value from the element's value attribute:

<form>
  <input
    type="checkbox"
    value="Mars"
    // šŸŒ• The unique key associated with this is 1.
    ref={namesField.refFor(1)}
  />
  <input
    type="checkbox"
    value="Pluto"
    ref={namesField.refFor(2)}
  />
</form>

Value coercion

By default, uncontrolledPlugin uses the opinionated element value accessor that applies following coercion rules to values of form elements:

  • Single checkbox ā†’ boolean;

  • Multiple checkboxes ā†’ an array of value attributes of checked checkboxes;

  • Radio buttons ā†’ the value attribute of a radio button that is checked or null if no radio buttons are checked;

  • Number input ā†’ number, or null if empty;

  • Range input ā†’ number;

  • Date input ā†’ the value attribute, or null if empty;

  • Time input ā†’ a time string, or null if empty;

  • Image input ā†’ string value of the src attribute;

  • File input ā†’ File or null if no file selected, file inputs are read-only;

  • Multi-file input ā†’ array of File;

  • Others ā†’ value attribute, or null if element doesn't support it;

  • null, undefined, NaN and non-finite numbers are coerced to an empty string and written to value attribute.

This behaviour can be changed by passing a custom ElementsValueAccessor implementation to a plugin. Or you can use a createElementsValueAccessor factory to customise the default behaviour:

import { useField } from '@roqueform/react';
import { uncontrolledPlugin } from '@roqueform/uncontrolled-plugin';

const personField = useField(
  { dateOfBirth: 316310400000 },
  uncontrolledPlugin(
    createElementsValueAccessor({
      dateFormat: 'timestamp'
    })
  )
);

Read more about available options in ElementsValueAccessorOptions.

2.1.0

3 months ago

2.0.0

3 months ago

1.0.1

9 months ago

1.0.0

1 year ago