Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/stutrek/react-multi-page-form

A library to make multi-page forms easier to build and maintain.
https://github.com/stutrek/react-multi-page-form

forms multi-page react workflows

Last synced: 12 days ago
JSON representation

A library to make multi-page forms easier to build and maintain.

Awesome Lists containing this project

README

        

![React Multi Page Form](https://stutrek.github.io/react-multi-page-form/Logo.svg "")

This is a tool for managing the sequence and flow of multi-page workflows. Given a long series of screens, it can put them in the proper order makes it easy to show and hide screens based on previous input.

Workflows can be composed, allowing you to reuse parts of a flow.

This should be used in combination with a component library and validation schema to improve your form management.

An integration with React Hook Form is provided, but the base could be used with any library.

[View the docs](https://stutrek.github.io/react-multi-page-form/)

## Basic Usage

- Create an array of pages and/or sequences. One for each page of the form.
- Set up `react-hook-form`
- Pass the pages and the hook for API into `useMultiPageHookForm` to get the multi-page state and controls.

```typescript
import { useForm } from 'react-hook-form';
import { useMultiPageHookForm } from 'react-multi-page-forms';

// create a list of pages for the form
const pages = [
{
id: 'first',
Component: FirstPage,
},
{
id: 'second',
Component: SecondPage,
},
]
const MyMultiPageForm = () => {
// use react-hook-form's useForm
const hookForm = useForm();

// create multi-page controls
const {
currentPage, // the page object
advance, // goes to the next page, including completed pages
advanceToNextIncomplete, // goes to the next incomplete page
goBack, // goes back one page
isFinal, // if this is the last page
isFirst, // if this is the first page
} = useMultiPageHookForm({
hookForm,
pages,
});

// render the component and controls
return (<>


{!isFirst && Prev}
{!isFinal ? (
Next
) : (
Submit
)}
>);
};
```
[View the docs](https://stutrek.github.io/react-multi-page-form/)

### Pages and Sequences

A **page** represents a single screen that will be shown to the user as part of this multi-step form. It can have as many fields or as few as you'd like. It can even have logic to show and hide fields built in.

A **sequence** is an array of pages and sequences that represent a specific flow. For example, they may be a series of screens specific to a certain country.

```typescript
type FormPage = {
id: string;
// determines whether or not this page is needed
isRequired?: (data: DeepPartial) => boolean | undefined
// determines if the page is already complete
isComplete: (data: DeepPartial) => boolean;
// determines if this should be a final step in the flow
isFinal?: (data: DeepPartial) => boolean;
// if you need to break the flow of the sequence, this makes that possible.
// Undefined will go to the next page in the sequence
selectNextPage?: (data: DeepPartial) => Boolean
// Mounted inputs are automatically validated.
// If you need specific validation logic, put it here.
validate?: (data: DeepPartial) => ErrorList | undefined;
// callback on arrival
onArrive?: (data: DeepPartial) => void;
// callback on departure
onExit?: (data: DeepPartial) => Promise | void;
// the component that will be rendered
Component: (props: ComponentProps) => JSX.Element;
};

export type FormSequence = {
id: string;
// an array of pages or sequences that make up this sequence
pages: SequenceChild[];
// determines if this sequence is needed
isRequired?: isRequiredPredicate;
};

export type DecisionNode = {
id: string,
// determines whether or not this decision is needed
isRequired?: (data: DeepPartial) => boolean | undefined
// where this node should redirect to. Undefined will go to the next page in the sequence
selectNextPage?: (data: DeepPartial) => Boolean
}
```

[View the docs](https://stutrek.github.io/react-multi-page-form/)

## A More Complete Example

```typescript
import { useMultiPageHookForm } from 'react-multi-page-forms'

const pages = [
{
id: 'first',
isComplete: (data) => !!data.name?.length,
Component: FirstPage,
},
{
id: 'second',
isComplete: (data) => !!data.pet?.length,
Component: SecondPage,
},
]

export function MyMultiPageForm() {
// set up React Hook Form
const hookForm = useForm({});
const {
register,
handleSubmit,
formState: { errors },
} = hookForm;

// set up the multi-page controls
const {
currentPage,
advance,
goBack,
isFinal,
isFirst
} = useMultiPageHookForm({
hookForm,
pages: sequence,
});

const onSubmit: SubmitHandler = (data) => {
console.log('submit', data);
};

return (
<>

Multi Page Form Example




{/* render the current page */}



{!isFirst && Prev}
{!isFinal ? (
Next
) : (
Submit
)}


>
);
}
```
[View the docs](https://stutrek.github.io/react-multi-page-form/)