{"id":15295861,"url":"https://github.com/creativetimofficial/react-bootstrap-wizard","last_synced_at":"2025-11-06T08:03:29.237Z","repository":{"id":55869723,"uuid":"111787709","full_name":"creativetimofficial/react-bootstrap-wizard","owner":"creativetimofficial","description":null,"archived":false,"fork":false,"pushed_at":"2020-12-10T12:44:09.000Z","size":68,"stargazers_count":36,"open_issues_count":10,"forks_count":27,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-27T09:12:35.457Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","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/creativetimofficial.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-11-23T09:11:01.000Z","updated_at":"2025-01-21T21:41:08.000Z","dependencies_parsed_at":"2022-08-15T08:10:39.237Z","dependency_job_id":null,"html_url":"https://github.com/creativetimofficial/react-bootstrap-wizard","commit_stats":null,"previous_names":["creativetimofficial/react-wizard"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/creativetimofficial%2Freact-bootstrap-wizard","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/creativetimofficial%2Freact-bootstrap-wizard/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/creativetimofficial%2Freact-bootstrap-wizard/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/creativetimofficial%2Freact-bootstrap-wizard/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/creativetimofficial","download_url":"https://codeload.github.com/creativetimofficial/react-bootstrap-wizard/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248049714,"owners_count":21039265,"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-09-30T18:08:26.786Z","updated_at":"2025-11-06T08:03:29.186Z","avatar_url":"https://github.com/creativetimofficial.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# React Wizard\n\n[![version][version-badge]][CHANGELOG] [![license][license-badge]][LICENSE]\n\n**React Bootstrap Wizard** is a react component package that allows you to split a complicated flow or a complicated form in multiple steps and it's made with [reactstrap components](https://reactstrap.github.io/) and [React](https://reactjs.org/) using [Creative Tim Now UI styles](https://www.creative-tim.com/product/now-ui-kit-pro).\n\n## Installation\n\n```\nnpm install --save react-bootstrap-wizard@latest\n```\n\n## Usage\n\nImport *react-wizard* in your component:\n```\nimport ReactWizard from 'react-bootstrap-wizard';\n```\nAfter that, in your component render method add the following line:\n```\n\u003cReactWizard {...props} /\u003e // where props are the properties you want\n```\n\n## Properties\n```\nReactWizard.defaultProps = {\n  validate: false,\n  previousButtonText: \"Previous\",\n  finishButtonText: \"Finish\",\n  nextButtonText: \"Next\",\n  color: \"primary\",\n  progressbar: false\n};\n\nReactWizard.propTypes = {\n  color: PropTypes.oneOf([\"primary\", \"green\", \"orange\", \"red\", \"blue\"]),\n  previousButtonClasses: PropTypes.string,\n  finishButtonClasses: PropTypes.string,\n  nextButtonClasses: PropTypes.string,\n  headerTextCenter: PropTypes.bool,\n  navSteps: PropTypes.bool,\n  validate: PropTypes.bool,\n  finishButtonClick: PropTypes.func,\n  previousButtonText: PropTypes.node,\n  finishButtonText: PropTypes.node,\n  nextButtonText: PropTypes.node,\n  title: PropTypes.node,\n  description: PropTypes.node,\n  progressbar: PropTypes.bool,\n  steps: PropTypes.arrayOf(\n    PropTypes.shape({\n      stepName: PropTypes.string.isRequired,\n      stepIcon: PropTypes.string,\n      component: PropTypes.func.isRequired,\n      stepProps: PropTypes.object,\n    })\n  ).isRequired\n};\n```\n\n### *color*\nThis prop is used to create the background color of the header and can be one of (***default is the first option***):\n```\n1. 'primary'\n2. 'green'\n3. 'orange'\n4. 'red'\n5. 'blue'\n```\n\n### *previousButtonClasses*\nThis is a string prop that you can use it to add new classes to the previous button that appears in the footer.\n\n### *nextButtonClasses*\nThis is a string prop that you can use it to add new classes to the next button that appears in the footer.\n\n### *finishButtonClasses*\nThis is a string prop that you can use it to add new classes to the finish button that appears in the footer.\n\n### *previousButtonText*\nThis is a prop used to add text/node to the previous button (default is ***Previous***).\n\n### *nextButtonText*\nThis is a prop used to add text/node to the next button (default is ***Next***).\n\n### *finishButtonText*\nThis is a prop used to add text/node to the previous button (default is ***Finish***).\n\n### *headerTextCenter*\nUse this prop to make the title and subtitle of the wizard center aligned.\n\n### *navSteps*\nUse this prop to make the wizard steps clickable.\n\n### *title*\nUse this prop to add a nice title to your wizard.\n\n### *description*\nUse this prop to add a nice description / subtitle to your wizard.\n\n### *progressbar*\nBy setting this prop to true, a progressbar will we rendered instead of a moving tab for the active tab (default is ***false***).\n\n### *steps*\nThis is an array of objects. This objects have two properties:\n1. *stepName* -\u003e used for the name that will appear in the nav (**these have to be unique**)\n2. *stepIcon* -\u003e used to add an icon alongside the name (**these has to be a string**)\n3. *component* -\u003e this is what will be rendered for each *stepName* (**has to be class/function**)\n4. *stepProps* -\u003e this props will be added to the step upon rendering (**has to be an object - like the state object**)\nExample of steps:\n```\nvar steps = [\n  {\n    stepName: \"About\",\n    stepIcon: \"tim-icons icon-single-02\",\n    component: Step1\n  },\n  {\n    stepName: \"Account\",\n    stepIcon: \"tim-icons icon-settings-gear-63\",\n    component: Step2\n  },\n  {\n    stepName: \"Address\",\n    stepIcon: \"tim-icons icon-delivery-fast\",\n    component: Step3,\n    stepProps: {\n      prop1: true,\n      prop2: \"A string\"\n    }\n  }\n];\n```\n\n### *validate*\nThis controls the validation of each step. The user won't be able to pass a step that isn't valid.\nThe validation is done in each step's component class/function.\nYou have to create a function **isValidated** with no parameters that will return one of *true* or *false*.\nIf returned *true*, than the user will be able to go to the next step, else if returned *false*, than the user won't be able to go to the next step.\nIf this prop is set, and the step component doesn't have the **isValidated** function, than the default will be considered **true**, and the user will be able to go to the next step.\n\n### *finishButtonClick*\nThis function is called when the user presses the finish button.\nSee the bellow example to see how to use it.\n```\nfunction finishButtonClick(allStepStates)\n```\n\n## Example code with Class Components\n\n```\nimport React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport ReactWizard from \"react-bootstrap-wizard\";\nimport { Container, Row, Col } from \"reactstrap\";\n\nimport \"bootstrap/dist/css/bootstrap.css\";\n\nclass FirstStep extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      firstStep: \"first step here\"\n    };\n  }\n  render() {\n    return \u003cdiv\u003eHey from First\u003c/div\u003e;\n  }\n}\nclass SecondStep extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      secondStep: \"second step here\"\n    };\n  }\n  isValidated() {\n    // do some validations\n    // decide if you will\n    return true;\n    // or you will\n    // return false;\n  }\n  render() {\n    return \u003cdiv\u003eHey from Second\u003c/div\u003e;\n  }\n}\nclass ThirdStep extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      thirdStep: \"third step here\"\n    };\n  }\n  render() {\n    return \u003cdiv\u003eHey from Third\u003c/div\u003e;\n  }\n}\n\nvar steps = [\n  // this step hasn't got a isValidated() function, so it will be considered to be true\n  { stepName: \"First\", component: FirstStep },\n  // this step will be validated to false\n  { stepName: \"Second\", component: SecondStep },\n  // this step will never be reachable because of the seconds isValidated() steps function that will always return false\n  { stepName: \"Third\", component: ThirdStep }\n];\n\nclass WizardExample extends React.Component {\n  finishButtonClick(allStates) {\n    console.log(allStates);\n  }\n  render() {\n    return (\n      \u003cContainer fluid style={{ marginTop: \"15px\" }}\u003e\n        \u003cRow\u003e\n          \u003cCol xs={12} md={6} className=\"mr-auto ml-auto\"\u003e\n            \u003cReactWizard\n              steps={steps}\n              navSteps\n              title=\"react-wizard\"\n              description=\"This will help you split a complicated flow or a complicated form in multiple steps.\"\n              headerTextCenter\n              validate\n              color=\"primary\"\n              finishButtonClick={this.finishButtonClick}\n            /\u003e\n          \u003c/Col\u003e\n        \u003c/Row\u003e\n      \u003c/Container\u003e\n    );\n  }\n}\n\nReactDOM.render(\u003cWizardExample /\u003e, document.getElementById(\"root\"));\n```\n\n## Example code with Function Components\n\n### React.forwardRef\n\nNote, since this plugin relays on its children (the steps that you pass to it), to have a ref, so that it can access the `isValidated` function, you will need to make sure you forward a ref, thus, you will need the `React.forwardRef`.\n\nCheck the bellow example to understand the issue better.\n\n### React.useImperativeHandle\n\nNote, since this plugin relays on its children (the steps that you pass to it), to have a ref, so that it can access the `isValidated` function, you will need to make sure that the wizard component will be able to access `this.refs.stepName.isValidated` (this is just an example), and that is why, we will need to use the `React.useImperativeHandle` to add a function here, named `isValidated` which will further call the `isValidated` function of the component, or we will set it to undefined. We also use it for retrieving the state of the component.\n\nCheck the bellow example to understand the issue better.\n\n### isValidated inside React.useImperativeHandle\n\nWe use this function, to let the parent component, the wizard, access the `isValidated` prop/function of its children.\n\nCheck the bellow example to understand the issue better.\n\n### state inside React.useImperativeHandle\n\nWe use this property, to let the parent component, the wizard, access the `state` of its children.\n\nCheck the bellow example to understand the issue better.\n\n### Example\n\n```\nimport React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport ReactWizard from \"react-bootstrap-wizard\";\nimport { Container, Row, Col } from \"reactstrap\";\n\nimport \"bootstrap/dist/css/bootstrap.css\";\n\nconst FirstStep = React.forwardRef((props, ref) =\u003e {\n  const [randomState, setRandomState] = React.useState(\n    \"1. This is a random state for first step.\"\n  );\n  React.useImperativeHandle(ref, () =\u003e ({\n    isValidated: undefined,\n    state: {\n      randomState,\n    },\n  }));\n  return \u003cdiv\u003eHey from First\u003c/div\u003e;\n});\n\nconst SecondStep = React.forwardRef((props, ref) =\u003e {\n  const [randomState, setRandomState] = React.useState(\n    \"2. This is a random state for second step.\"\n  );\n  const isValidated = () =\u003e {\n    // do some validations\n    // decide if you will\n    return true;\n    // or you will\n    // return false;\n  };\n  React.useImperativeHandle(ref, () =\u003e ({\n    isValidated: () =\u003e {\n      return isValidated();\n    },\n    state: {\n      randomState,\n    },\n  }));\n  return \u003cdiv\u003eHey from Second\u003c/div\u003e;\n});\n\nconst ThirdStep = React.forwardRef((props, ref) =\u003e {\n  const [randomState, setRandomState] = React.useState(\n    \"3. This is a random state for third step.\"\n  );\n  React.useImperativeHandle(ref, () =\u003e ({\n    isValidated: undefined,\n    state: {\n      randomState,\n    },\n  }));\n  return \u003cdiv\u003eHey from Third\u003c/div\u003e;\n});\n\nvar steps = [\n  // this step hasn't got a isValidated() function, so it will be considered to be true\n  { stepName: \"First\", component: FirstStep },\n  // this step will be validated to false\n  { stepName: \"Second\", component: SecondStep },\n  // this step will never be reachable because of the seconds isValidated() steps function that will always return false\n  { stepName: \"Third\", component: ThirdStep },\n];\n\nfunction WizardExample() {\n  const finishButtonClick = (allStates) =\u003e {\n    console.log(allStates);\n  };\n  return (\n    \u003cContainer fluid style={{ marginTop: \"15px\" }}\u003e\n      \u003cRow\u003e\n        \u003cCol xs={12} md={6} className=\"mr-auto ml-auto\"\u003e\n          \u003cReactWizard\n            steps={steps}\n            navSteps\n            title=\"react-wizard\"\n            description=\"This will help you split a complicated flow or a complicated form in multiple steps.\"\n            headerTextCenter\n            validate\n            color=\"primary\"\n            finishButtonClick={finishButtonClick}\n          /\u003e\n        \u003c/Col\u003e\n      \u003c/Row\u003e\n    \u003c/Container\u003e\n  );\n}\n\nReactDOM.render(\u003cWizardExample /\u003e, document.getElementById(\"root\"));\n\n```\n\n## How to work with NextJS\n\nYou will need to change:\n```\nimport ReactWizard from \"react-bootstrap-wizard\";\n```\nTo:\n```\nimport dynamic from 'next/dynamic'\n\nconst ReactWizard = dynamic(() =\u003e import('react-bootstrap-wizard'))\n\nif (typeof window === \"undefined\") {\n  global.window = {};\n}\nif (typeof document === \"undefined\") {\n  global.document = {};\n}\n```\n\n## Styles\nBe sure to include the styles in your project.\nYou can either include the css:\n```\nimport \"react-bootstrap-wizard/dist/react-wizard.css\"\n```\nOr the scss\n```\nimport \"react-bootstrap-wizard/dist/react-wizard.scss\"\n```\n\n## Dependencies\n\nFor this component to work properly you need to have the following libraries installed in your project:\n\n```\nnpm install --save reactstrap\nnpm install --save bootstrap\n```\n\n\n[CHANGELOG]: ./CHANGELOG.md\n\n[LICENSE]: ./LICENSE.md\n[version-badge]: https://img.shields.io/badge/version-0.0.9-blue.svg\n[license-badge]: https://img.shields.io/badge/license-MIT-blue.svg\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcreativetimofficial%2Freact-bootstrap-wizard","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcreativetimofficial%2Freact-bootstrap-wizard","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcreativetimofficial%2Freact-bootstrap-wizard/lists"}