# react-form-stateful

> full featured, extensible form component for react using react hooks

Latest version **0.0.3** (published 2018-12-31) · MIT license · 0 weekly downloads

## Install

```sh
npm install react-form-stateful
pnpm add react-form-stateful
yarn add react-form-stateful
bun add react-form-stateful
```

## Health

**Score 30/100 (F)** — status: abandoned.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.0.3 |
| Published | 2018-12-31 |
| First published | 2018-12-29 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 1 |
| Unpacked size | 291 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | Chris Edwards |
| Maintainers | ckedwards |
| Keywords | react, hooks, react-hooks, form |

## Links

- npm: https://www.npmjs.com/package/react-form-stateful
- Repository: https://github.com/ckedwards/react-form-stateful
- Homepage: https://github.com/ckedwards/react-form-stateful#readme
- Issues: https://github.com/ckedwards/react-form-stateful/issues
- npm.io page: https://npm.io/package/react-form-stateful

## Dependencies (1)

- [tslib](https://npm.io/package/tslib.md) ^1.9.3

## Alternatives

- [mobx-react](https://npm.io/package/mobx-react.md) — 2.8M weekly downloads
- [rc-tree](https://npm.io/package/rc-tree.md) — 2.6M weekly downloads
- [@react-oauth/google](https://npm.io/package/@react-oauth/google.md) — 1.3M weekly downloads
- [@wagmi/connectors](https://npm.io/package/@wagmi/connectors.md) — 877.0K weekly downloads
- [vee-validate](https://npm.io/package/vee-validate.md) — 836.4K weekly downloads

## Recent versions

- 0.0.3 (latest) — 2018-12-31
- 0.0.2 — 2018-12-29
- 0.0.1 — 2018-12-29

## README

# react-form-stateful

react-form-stateful a full featured, extensible form component for react using react hooks

> **NOTE:** this project requires the use of an alpha version of react to use.

## Getting Started

```
npm install --save react-form-stateful
```

## Examples

### Basic Usage

```tsx
import { FC } from 'react';
import { StatefulForm, SFInput, SFSelect, SFTextArea } from 'react-form-stateful';
import * as yup from 'yup';

const ValidationSchemeForm: FC = () => {
  return (
    <StatefulForm
      validationSchema={yup.object().shape({
        email: yup
          .string()
          .required('Email required')
          .email('Invalid email address'),
        desc: yup.string().max(256, 'Please keep your description short!'),
        complaint: yup
          .string()
          .required('Complaint required')
          .max(10000, 'Max complaint size: 10,000 characters.'),
      })}
    >
      <div>Feedback form:</div>
      <label>
        Email:
        <SFInput name="email" />
      </label>
      <label>
        Short Description:
        <SFInput name="desc" />
      </label>
      <label>
        Reason for complaint:
        <SFSelect
          name="reason"
          defaultEntry={'Please select a reason'}
          values={['Bug', 'Typo', 'Feature Request', 'Other']}
        />
      </label>
      <label>
        Complaint:
        <SFTextArea name="complaint" />
      </label>
    </StatefulForm>
  );
};
```

### Other examples

Other examples can be seen in the [examples folder](./examples). `ValidationScheme.tsx` is a simple form and the other two are more complex.

### Customizing Forms

Context is used to expose the state. This allows for helper hooks to be written. Several already exist, but more could easily be written. (Feel free to make a PR).

## Components

One of the components from [components](./src/controls.tsx):

```tsx
type SFControlProps<T = string> = {
  name: string;
  className?: string;
  errorClassName?: string;
  initialValue?: T;
  defaultValue?: T;
};

export const SFInput: FC<SFControlProps> = props => {
  const { touch, value, setValue, error } = useSFControl(props.name, props.initialValue, props.defaultValue);
  return (
    <Fragment>
      <input className={props.className} onBlur={touch} value={value || ''} onChange={e => setValue(e.target.value)} />
      <div className={props.errorClassName}>{error}</div>
    </Fragment>
  );
};
```

Example Usage

```tsx
import { FC, createElement } from 'react';
import { StatefulForm, SFInput } from 'react-form-stateful';

const Form: FC = () => {
  return (
    <StatefulForm>
      <SFInput name="item" />
    </StatefulForm>
  );
};
```

As you can see component that matches your application's look and feel, but basic components do exist for your convenience.

## Extending

While the internal reducer is not exposed, the dispatch and actions are exposed, which allows for extension through side effects.
An example of this can be seen in examples/pages/Pages.tsx.

## NO_DEFAULT and ASYNC_VALIDATION

There are two special constants that help with extending the functionality of react-form-stateful.

#### NO_DEFAULT

`NO_DEFAULT` prevents resets from affecting this value. Useful for hidden from values that are used to control validation.
This us used in the advanced example [examples/pages/Pages](examples/pages/Pages.tsx):

```tsx
const valueState = useSFValue<number[]>(
  '@@pages',
  [0],
  NO_DEFAULT, // Don't get reset
  value => (props.pages.length !== value.length ? 'more pages exist' : null)
);
```

#### ASYNC_VALIDATION

`ASYNC_VALIDATION` Is used to to defer the validation to some external process. This is useful when you want to defer the validation to a separate process. This could also be done with Promises, but there may be cases where `ASYNC_VALIDATION` is more convenient.

```tsx
const { error, setValue, value, touch, touched } = useSFControl<string>(props.name, '', '', () => ASYNC_VALIDATION);
```

Here when a validation is triggered, the error state is set to `{ async:true }`. The form is not submitable until this is resolved. One way to resolve this is to use the `useSFError` hook and set the error state for the component.

```tsx
const [, setError] = useSFError(props.name);
setError('Invalid username');
```

# Prior art

- [Formik](https://github.com/jaredpalmer/formik) (Obviously)

---
_Source: https://npm.io/package/react-form-stateful · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
