{"id":13627730,"url":"https://github.com/itamarbareket/whizflow","last_synced_at":"2025-04-17T00:32:26.450Z","repository":{"id":152541919,"uuid":"626378973","full_name":"itamarbareket/whizflow","owner":"itamarbareket","description":"a lightweight, headless and extensible React library for building dynamic multi-step forms or troubleshooting workflows.","archived":false,"fork":false,"pushed_at":"2023-05-07T07:09:46.000Z","size":477,"stargazers_count":9,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-10-07T08:40:59.109Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/itamarbareket.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2023-04-11T10:56:34.000Z","updated_at":"2024-09-02T16:30:24.000Z","dependencies_parsed_at":"2024-01-06T22:54:47.799Z","dependency_job_id":"1a010d8c-68c9-4b89-b842-ab61ea67e197","html_url":"https://github.com/itamarbareket/whizflow","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itamarbareket%2Fwhizflow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itamarbareket%2Fwhizflow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itamarbareket%2Fwhizflow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itamarbareket%2Fwhizflow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/itamarbareket","download_url":"https://codeload.github.com/itamarbareket/whizflow/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223735098,"owners_count":17194045,"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":[],"created_at":"2024-08-01T22:00:37.706Z","updated_at":"2024-11-08T18:30:50.529Z","avatar_url":"https://github.com/itamarbareket.png","language":"TypeScript","funding_links":[],"categories":["Projects by main language","Libraries"],"sub_categories":["react"],"readme":"# WhizFlow\n![npm bundle size](https://img.shields.io/bundlephobia/minzip/whizflow)\n![npm](https://img.shields.io/npm/dm/whizflow)\n![npm](https://img.shields.io/npm/v/whizflow)\n![node-current](https://img.shields.io/node/v/whizflow)\n\nWhizFlow is a lightweight, headless and extensible React library for building dynamic multi-step forms or troubleshooting workflows.\n\n## Features\n\n- Headless: Gives you full control over the UI and styling.\n- Extensible: Allows custom question types and render implementations.\n- Flexible: Easily build complex workflows with conditional branching.\n- Agnostic: Use [Formik](https://formik.org/) or any other form/validation library that you want to handle the input.\n\n## Demo\n\n- [Simple Demo](https://codesandbox.io/s/headless-glitter-9nuvrw?file=/src/App.tsx)\n- [Formik Demo](https://codesandbox.io/s/priceless-browser-74j8dh?file=/src/workflow.ts)\n\n## Installation\n\n```bash\nnpm install whizflow\n```\n\nor\n\n```bash\nyarn add whizflow\n```\n\n## Usage\n\n1. Import WhizFlow and required types:\n\n```jsx\nimport WhizFlow from 'whizflow';\nimport { Step } from 'whizflow/dist/types';\n```\n\n2. Define your workflow:\n\n```jsx\nconst workflow: Step[] = [\n  {\n    id: 'step1',\n    questions: [\n      {\n        id: 'question1',\n        prompt: 'What is your name?',\n        inputType: 'text',\n      },\n    ],\n    next: (answers) =\u003e 'step2',\n  },\n  {\n    id: 'step2',\n    questions: [\n      {\n        id: 'question2',\n        prompt: 'What is your favorite color?',\n        inputType: 'text',\n      },\n    ],\n    next: (answers) =\u003e 'done',\n  },\n];\n```\n\n3. Define your custom question types (optional):\n\n```jsx\nconst questionTypes = {\n  text: (question, answers, setAnswers) =\u003e (\n    \u003cdiv key={question.id}\u003e\n      \u003clabel htmlFor={question.id}\u003e{question.prompt}\u003c/label\u003e\n      \u003cinput\n        id={question.id}\n        type=\"text\"\n        value={answers[question.id] || ''}\n        onChange={(e) =\u003e\n          setAnswers({ ...answers, [question.id]: e.target.value })\n        }\n      /\u003e\n    \u003c/div\u003e\n  ),\n  // Add more question types and their render functions here\n};\n```\n\n4. Use the WhizFlow component in your application:\n\n```jsx\nconst YourComponent = () =\u003e {\n  return (\n    \u003cWhizFlow workflow={workflow} questionTypes={questionTypes}\u003e\n      {({ step, answers, setAnswers, handleNext, renderQuestion }) =\u003e (\n        \u003cdiv\u003e\n          {step.questions.map((question) =\u003e renderQuestion(question.id))}\n          \u003cbutton onClick={handleNext}\u003eNext\u003c/button\u003e\n        \u003c/div\u003e\n      )}\n    \u003c/WhizFlow\u003e\n  );\n};\n\nexport default YourComponent;\n```\n\n## Types\n\n### WhizFlow\n\n`WhizFlow` is the main component for managing the workflow. It accepts the following props:\n\n#### Props\n\n- `workflow` (required): An array of `Step` objects defining the workflow.\n- `onComplete` (optional): A callback function to be called when the workflow reaches the `done` step.\n- `questionTypes` (optional): An object with keys representing the question type and values as the corresponding render functions.\n\n#### Render Props\n\n- `step`: The current step object.\n- `answers`: An object containing the answers for each question in the workflow.\n- `loading`: A boolean to mark when `handleNext` is waiting to resolve.\n- `setAnswers`: A function to update the `answers` object.\n- `handleNext`: A function to handle navigation to the next step in the workflow.\n- `handlePrev`: A function to handle navigation to the previous step.\n- `renderQuestion`: A function to render the correct question type based on the provided dictionary.\n\n### Step\n\nA `Step` object defines a single step in the workflow and includes the following properties:\n\n- `id`: A unique identifier for the step.\n- `questions`: An array of `Question` objects.\n- `next`: A function that determines the next step in the workflow based on the current answers. It should return the next step's ID or `done` if the workflow is complete.\n\n### Question\n\nA `Question` object defines a single question within a step and includes the following properties:\n\n- `id`: A unique identifier for the question.\n- `prompt`: The question's text.\n- `inputType`: The question's input type, which corresponds to the key in the `questionTypes` prop passed to the `WhizFlow` component.\n\n### QuestionTypes\n\nAn object with keys representing the question type and values as render functions. The render functions should take the question, answers, and a `setAnswers` function as arguments and return a React element. You can define custom question types and their implementations in the `questionTypes` object.\n\n```tsx\nconst questionTypes = {\n  text: (question, answers, setAnswers) =\u003e (\n    \u003cdiv key={question.id}\u003e\n      \u003clabel htmlFor={question.id}\u003e{question.prompt}\u003c/label\u003e\n      \u003cinput\n        id={question.id}\n        type=\"text\"\n        value={answers[question.id] || ''}\n        onChange={(e) =\u003e\n          setAnswers({ ...answers, [question.id]: e.target.value })\n        }\n      /\u003e\n    \u003c/div\u003e\n  ),\n  // Add more question types and their render functions here\n};\n```\n\n## API\n\n| Component / Type | Property / Function | Type / Signature | Description |\n| -- | -- | --------- | -------------- |\n| **WhizFlow** | | | Main component for managing the workflow. |\n| | `workflow` | `Step[]` | An array of `Step` objects defining the workflow. (Required) |\n| | `onComplete` | `(answers: Answers) =\u003e void` |A callback function to be called when the workflow reaches the `done` step. (Optional) |\n| | `questionTypes` | `{ [key: string]: QuestionRenderFunction }` | An object with keys representing the question type and values as the corresponding render functions. (Optional) |\n| | `step` | `Step` | The current step object. (Render prop) |\n| | `loading` | `boolean` | Whether `handleNext` is running asyncly. (Render prop) |\n| | `answers` | `Record\u003cstring, any\u003e` | An object containing the answers for each question in the workflow. (Render prop) |\n| | `setAnswers` | `(updatedAnswers: Record\u003cstring, any\u003e) =\u003e void` | A function to update the `answers` object. (Render prop) |\n| | `handleNext` | `(submitterAnswers?: Record\u003cstring, any\u003e) =\u003e void` | A function to handle navigation to the next step in the workflow, allows the submitter to update the answers. (Render prop) |\n| | `handlePrev` | `() =\u003e void` | A function to handle navigation to the previous step in the workflow. (Render prop) |\n| | `renderQuestion` | `(questionId: string) =\u003e React.ReactNode` | A function to render the correct question type based on the provided dictionary. (Render prop) |\n| **Step** | | | An object defining a single step in the workflow. |\n| | `id` | `string` | A unique identifier for the step. |\n| | `questions` | `Question[]` | An array of `Question` objects. |\n| | `next` | `string \\| { nextStepId: string; updatedAnswers?: Answers } ֿֿֿ\\| Promise\u003cstring\u003e \\| Promise\u003c{ nextStepId: string; updatedAnswers?: Answers }\u003e` | A function that determines the next step in the workflow based on the current answers. It should return the next step's ID or 'done' if the workflow is complete. |\n| | `context?` | `any` | An optional context object for the question to pass (to be used later when rendering). |\n| **Question** | | | An object defining a single question within a step. |\n| | `id` | `string` | A unique identifier for the question. |\n| | `prompt` | `string` | The question's text. |\n| | `options` | `Option[]` | An optional option array for multi-select type of questions |\n| | `inputType` | `string` | The question's input type, which corresponds to the key in the `questionTypes` prop passed to the `WhizFlow` component. |\n| | `context?` | `any` | An optional context object for the question to pass (to be used later when rendering). |\n| **Option** | | | Answer option for multi-select type of questions. |\n| | `id` | `string` | A unique identifier for the option. |\n| | `label` | `string` | The option's text. |\n| | `value` | `string` | Value for the option |\n| **QuestionTypes** | - | `{ [key: string]: QuestionRenderFunction }` | An object with keys representing the question type and values as the corresponding render functions. (Optional) |\n| **QuestionRenderFunction** | - | `(question: Question, answers: Record\u003cstring, any\u003e, setAnswers: (updatedAnswers: Record\u003cstring, any\u003e) =\u003e void) =\u003e React.ReactNode` | The render functions should take the question, answers, and a `setAnswers` function as arguments and return a React element. You can define custom question types and their implementations in the `questionTypes` object. |\n\n## License\n\nMIT © [Itamar Bareket](https://github.com/itamarbareket), MobiMatter LTD\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitamarbareket%2Fwhizflow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fitamarbareket%2Fwhizflow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitamarbareket%2Fwhizflow/lists"}