1.0.3 • Published 2 months ago

@reactables/react-forms v1.0.3

Weekly downloads
-
License
ISC
Repository
-
Last release
2 months ago

Reactables React

Description

React components for binding @reactables/forms reactables.

Table of Contents

  1. Installation
  2. API
    1. Form
    2. Field
    3. FormArray

Installation

npm i @reactables/react-forms

API

Form

type HookedRxForm = HookedReactable<ControlModels.Form<unknown>, RxFormActions>;

Form is the provider component giving child Field and FormArray child components access to a HookedRxForm.

See full example on StackBlitz

import { build, group, control } from '@reactables/forms';
import { useReactable } from '@reactables/react';
import { Form, Field } from '@reactables/react-forms';
import Input from './Input';

const userConfig = group({
  controls: {
    name: control(['', 'required']),
    email: control(['', ['required', 'email']]),
  },
});

const MyForm = () => {
  const rxForm = useReactable(() => build(userConfig));

  return (
    <Form rxForm={rxForm}>
      <Field name="name" label="Name:" component={Input} />
      <Field name="email" label="Email: " component={Input} />
    </Form>
  );
};

export default MyForm;

Field

A wrapper component that connects a component to the reactable form.

Below is an Input component that will be wrapped by Field and provided the FormControl<T> via the meta prop.

WrappedFieldInputProps are passed in by the input prop which contains the input value and event handlers.

See full example on StackBlitz

import { WrappedFieldProps } from '@reactables/react-forms';

const Input = ({
  input,
  label,
  meta: { touched, errors, pending, valid },
}: { label?: string } & WrappedFieldProps) => {
  return (
    <div className="mb-3">
      {label && (
        <label className={`form-label ${touched && !valid ? 'text-danger' : ''}`}>{label}</label>
      )}
      <input
        {...input}
        type="text"
        className={`form-control ${touched && !valid ? 'is-invalid' : ''}`}
      />
      {touched && errors.required && (
        <div>
          <small className="text-danger">Field is required</small>
        </div>
      )}
      {touched && errors.email && (
        <div>
          <small className="text-danger">Not a valid email address</small>
        </div>
      )}
    </div>
  );
};

export default Input;

Continuing from our Form example we can wrap the Input component above as follows:

import { build, group, control } from '@reactables/forms';
import { useReactable } from '@reactables/react-helpers';
import { Form, Field } from '@reactables/react-forms';
import Input from './Input';

const userConfig = group({
  controls: {
    name: control(['', 'required']),
    email: control(['', ['required', 'email']]),
  },
});

const MyForm = () => {
  const rxForm = useReactable(() => build(userConfig));

  return (
    <Form rxForm={rxForm}>
      <Field name="name" label="Name:" component={Input} />
      <Field name="email" label="Email: " component={Input} />
    </Form>
  );
};

export default MyForm;

FormArray

FormArray uses the function as children pattern and makes available the array items as well as pushControl and removeControl action methods.

See full example on StackBlitz

import { build, group, control, array } from '@reactables/forms';
import { useReactable } from '@reactables/react';
import { Form, Field, FormArray } from '@reactables/react-forms';
import Input from './Input';

const userConfig = group({
  controls: {
    name: control(['', 'required']),
    email: control(['', ['required', 'email']]),
  },
});

const MyForm = () => {
  const rxForm = useReactable(() =>
    build(
      group({
        controls: {
          contacts: array({
            controls: [userConfig],
          }),
        },
      })
    )
  );

  return (
    <Form rxForm={rxForm}>
      <FormArray name="contacts">
        {({ items, pushControl, removeControl }) => {
          return (
            <>
              {items.map((control, index) => {
                return (
                  <div key={control.key}>
                    <Field name={`contacts.${index}.name`} label="Name:" component={Input} />
                    <Field name={`contacts.${index}.email`} label="Email: " component={Input} />
                    <button type="button" onClick={() => removeControl(index)}>
                      Remove contact
                    </button>
                  </div>
                );
              })}
              <button type="button" onClick={() => pushControl(userConfig)}>
                Add User
              </button>
            </>
          );
        }}
      </FormArray>
    </Form>
  );
};

export default MyForm;
1.0.2

3 months ago

1.0.0

3 months ago

1.0.3

2 months ago

1.0.2-beta.0

3 months ago

1.0.0-beta.4

4 months ago

1.0.2-beta.1

3 months ago

1.0.0-beta.5

4 months ago

1.0.0-beta.6

4 months ago

1.0.0-beta.2

6 months ago

1.0.0-beta.3

6 months ago

1.0.0-beta.1

6 months ago

1.0.0-beta.0

6 months ago

0.8.0-alpha.2

6 months ago

0.8.0-alpha.3

6 months ago

0.8.0-alpha.0

6 months ago

0.7.1-alpha.4

6 months ago

0.7.1-alpha.2

6 months ago

0.7.1-alpha.1

6 months ago

0.7.1-alpha.3

6 months ago

0.7.0-alpha.19

6 months ago

0.7.0-alpha.18

6 months ago

0.7.0-alpha.16

7 months ago

0.7.0-alpha.17

7 months ago

0.7.0-alpha.15

7 months ago

0.7.0-alpha.14

7 months ago

0.7.0-alpha.12

7 months ago

0.7.0-alpha.11

7 months ago

0.7.0-alpha.10

8 months ago

0.7.0-alpha.9

8 months ago

0.7.0-alpha.7

8 months ago

0.7.0-alpha.8

8 months ago

0.7.0-alpha.1

8 months ago

0.7.0-alpha.3

8 months ago

0.7.0-alpha.2

8 months ago

0.7.0-alpha.5

8 months ago

0.7.0-alpha.4

8 months ago

0.7.0-alpha.0

8 months ago

0.6.0-alpha.0

9 months ago

0.5.4-alpha.0

9 months ago

0.5.3-alpha.0

9 months ago

0.5.0-alpha.0

9 months ago

0.5.1-alpha.0

9 months ago

0.5.2-alpha.0

9 months ago

0.4.6-alpha.0

9 months ago

0.4.5-alpha.0

9 months ago

0.4.4-alpha.0

9 months ago

0.4.2-alpha.0

9 months ago

0.4.3-alpha.0

9 months ago

0.4.3-alpha.1

9 months ago

0.4.1-alpha.1

10 months ago

0.4.1-alpha.0

10 months ago

0.4.0-alpha.3

10 months ago

0.4.0-alpha.2

10 months ago

0.4.0-alpha.1

10 months ago