{"id":18835530,"url":"https://github.com/stutrek/react-multi-page-form","last_synced_at":"2025-04-14T05:30:34.332Z","repository":{"id":258338007,"uuid":"862959763","full_name":"stutrek/react-multi-page-form","owner":"stutrek","description":"A library to make multi-page forms easier to build and maintain.","archived":false,"fork":false,"pushed_at":"2024-11-05T21:21:09.000Z","size":1425,"stargazers_count":11,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-27T19:15:27.896Z","etag":null,"topics":["forms","multi-page","react","workflows"],"latest_commit_sha":null,"homepage":"https://stutrek.github.io/react-multi-page-form/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stutrek.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-25T13:31:31.000Z","updated_at":"2025-01-12T18:24:32.000Z","dependencies_parsed_at":"2024-10-18T14:34:34.159Z","dependency_job_id":null,"html_url":"https://github.com/stutrek/react-multi-page-form","commit_stats":null,"previous_names":["stutrek/react-multi-page-form"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stutrek%2Freact-multi-page-form","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stutrek%2Freact-multi-page-form/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stutrek%2Freact-multi-page-form/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stutrek%2Freact-multi-page-form/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stutrek","download_url":"https://codeload.github.com/stutrek/react-multi-page-form/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248826451,"owners_count":21167693,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["forms","multi-page","react","workflows"],"created_at":"2024-11-08T02:16:30.058Z","updated_at":"2025-04-14T05:30:33.833Z","avatar_url":"https://github.com/stutrek.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![React Multi Page Form](https://stutrek.github.io/react-multi-page-form/Logo.svg \"\")\n\nThis 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.\n\nWorkflows can be composed, allowing you to reuse parts of a flow.\n\nThis should be used in combination with a component library and validation schema to improve your form management.\n\nAn integration with React Hook Form is provided, but the base could be used with any library.\n\n[View the docs](https://stutrek.github.io/react-multi-page-form/)\n\n## Basic Usage\n\n- Create an array of pages and/or sequences. One for each page of the form.\n- Set up `react-hook-form` \n- Pass the pages and the hook for API into `useMultiPageHookForm` to get the multi-page state and controls.\n\n```typescript\nimport { useForm } from 'react-hook-form';\nimport { useMultiPageHookForm } from 'react-multi-page-forms';\n\n// create a list of pages for the form\nconst pages = [\n    {\n        id: 'first',\n        Component: FirstPage,\n    },\n    {\n        id: 'second',\n        Component: SecondPage,\n    },\n]\nconst MyMultiPageForm = () =\u003e {\n    // use react-hook-form's useForm\n    const hookForm = useForm\u003cFormModel\u003e();\n    \n    // create multi-page controls\n    const { \n        currentPage, // the page object\n        advance, // goes to the next page, including completed pages\n        advanceToNextIncomplete, // goes to the next incomplete page\n        goBack, // goes back one page\n        isFinal, // if this is the last page\n        isFirst, // if this is the first page\n    } = useMultiPageHookForm({\n        hookForm,\n        pages,\n    });\n    \n    // render the component and controls\n    return (\u003c\u003e\n        \u003ccurrentPage.Component\n            errors={errors}\n            register={register}\n        /\u003e\n    \n        {!isFirst \u0026\u0026 \u003cbutton onClick={goBack}\u003ePrev\u003c/button\u003e}\n        {!isFinal ? (\n            \u003cbutton onClick={advance}\u003eNext\u003c/button\u003e\n        ) : (\n            \u003cbutton type=\"submit\"\u003eSubmit\u003c/button\u003e\n        )}\n    \u003c/\u003e);\n};\n```\n[View the docs](https://stutrek.github.io/react-multi-page-form/)\n\n\n### Pages and Sequences\n\nA **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.\n\nA **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.\n\n```typescript\ntype FormPage\u003cDataT, ComponentProps, ErrorList\u003e = {\n    id: string;\n    // determines whether or not this page is needed\n    isRequired?: (data: DeepPartial\u003cDataT\u003e) =\u003e boolean | undefined\n    // determines if the page is already complete\n    isComplete: (data: DeepPartial\u003cDataT\u003e) =\u003e boolean;\n    // determines if this should be a final step in the flow\n    isFinal?: (data: DeepPartial\u003cDataT\u003e) =\u003e boolean;\n    // if you need to break the flow of the sequence, this makes that possible.\n    // Undefined will go to the next page in the sequence\n    selectNextPage?: (data: DeepPartial\u003cDataT\u003e) =\u003e Boolean\n    // Mounted inputs are automatically validated.\n    // If you need specific validation logic, put it here.\n    validate?: (data: DeepPartial\u003cDataT\u003e) =\u003e ErrorList | undefined;\n    // callback on arrival\n    onArrive?: (data: DeepPartial\u003cDataT\u003e) =\u003e void;\n    // callback on departure\n    onExit?: (data: DeepPartial\u003cDataT\u003e) =\u003e Promise\u003cvoid\u003e | void;\n    // the component that will be rendered\n    Component: (props: ComponentProps) =\u003e JSX.Element;\n};\n\nexport type FormSequence\u003cDataT, ComponentProps, ErrorList\u003e = {\n    id: string;\n    // an array of pages or sequences that make up this sequence\n    pages: SequenceChild\u003cDataT, ComponentProps, ErrorList\u003e[];\n    // determines if this sequence is needed\n    isRequired?: isRequiredPredicate\u003cDataT\u003e;\n};\n\nexport type DecisionNode\u003cDataT\u003e = {\n    id: string,\n    // determines whether or not this decision is needed\n    isRequired?: (data: DeepPartial\u003cDataT\u003e) =\u003e boolean | undefined\n    // where this node should redirect to. Undefined will go to the next page in the sequence\n    selectNextPage?: (data: DeepPartial\u003cDataT\u003e) =\u003e Boolean\n}\n```\n\n[View the docs](https://stutrek.github.io/react-multi-page-form/)\n\n\n## A More Complete Example\n\n```typescript\nimport { useMultiPageHookForm } from 'react-multi-page-forms'\n\nconst pages = [\n    {\n        id: 'first',\n        isComplete: (data) =\u003e !!data.name?.length,\n        Component: FirstPage,\n    },\n    {\n        id: 'second',\n        isComplete: (data) =\u003e !!data.pet?.length,\n        Component: SecondPage,\n    },\n]\n\nexport function MyMultiPageForm() {\n    // set up React Hook Form\n    const hookForm = useForm\u003cFormModel\u003e({});\n    const {\n        register,\n        handleSubmit,\n        formState: { errors },\n    } = hookForm;\n    \n    // set up the multi-page controls\n    const { \n        currentPage,\n        advance,\n        goBack,\n        isFinal,\n        isFirst\n    } = useMultiPageHookForm({\n        hookForm,\n        pages: sequence,\n    });\n    \n    const onSubmit: SubmitHandler\u003cFormModel\u003e = (data) =\u003e {\n        console.log('submit', data);\n    };\n    \n    return (\n        \u003c\u003e\n            \u003ch1\u003eMulti Page Form Example\u003c/h1\u003e\n            \u003cform onSubmit={handleSubmit(onSubmit)}\u003e\n                \u003cdiv className=\"card\"\u003e\n                    {/* render the current page */}\n                    \u003ccurrentPage.Component\n                        errors={errors}\n                        register={register}\n                    /\u003e\n                \u003c/div\u003e\n                \u003cdiv className=\"card\"\u003e\n                    {!isFirst \u0026\u0026 \u003cbutton onClick={goBack}\u003ePrev\u003c/button\u003e}\n                    {!isFinal ? (\n                        \u003cbutton onClick={advance}\u003eNext\u003c/button\u003e\n                    ) : (\n                        \u003cbutton type=\"submit\"\u003eSubmit\u003c/button\u003e\n                    )}\n                \u003c/div\u003e\n            \u003c/form\u003e\n        \u003c/\u003e\n    );\n}\n```\n[View the docs](https://stutrek.github.io/react-multi-page-form/)\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstutrek%2Freact-multi-page-form","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstutrek%2Freact-multi-page-form","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstutrek%2Freact-multi-page-form/lists"}