Wizard
Examples
Wizard example
This example shows a simple Wizard component with the following features:
- Three different tabs
- Navigation using Next and Previous buttons
- Validation of data before navigating away from the first page
- A cancel option that redirects the user to the second page
- A simple progress bar
First page
The following sections explain the different steps to define a basic Wizard using the components from the @jutro/wizard-next
package.
The Wizard implementation requires:
- Definition of the different Wizard pages that can be displayed
- Definition of the Wizard layout: how the wizard is displayed, including breakpoint alternatives
- Definition of the custom elements like the action bar and progress indicator
- Definition of the Wizard steps: routes and alternatives, for example where the user is directed after completing a step
- The composition of the Wizard by using all the previously defined elements
1. Define the wizard pages
Defining a wrapper component is the recommended approach for the Wizard pages definition. Each Wizard step must reference a component that either wraps or extends WizardPage
.
The following example shows how to create the page components for the above Wizard.
import { useState } from 'react';
import { WizardPage } from '@jutro/wizard-next';
import { Checkbox } from '@jutro/components';
import { useLocation } from 'react-router-dom';
const TheFirstPage = ({ id, wizardPageProps }) => {
const location = useLocation();
const [valid, setValid] = useState(false);
const [stateMessages, setStateMessages] = useState(null);
const firstStepCheckboxChanged = (e, value) => {
setValid(value);
};
const wizardPageOnNext = () => {
if (!valid) {
setStateMessages({
error: ['Select this checkbox to go to the next page'],
});
}
// if false is returned, the default next event does not continue
return valid;
};
return (
<WizardPage
id={id}
{...wizardPageProps}
onNext={wizardPageOnNext}
location={location}
title="First page">
<span>Here you can add your content</span>
<Checkbox
label="This is mandatory to continue"
required={true}
stateMessages={stateMessages}
onChange={firstStepCheckboxChanged}
/>
</WizardPage>
);
};
const AnotherWizardPage = ({ id, wizardPageProps }) => {
const location = useLocation();
return (
<WizardPage
id={id}
{...wizardPageProps}
location={location}
title="Second page">
<span>Another wizard page</span>
</WizardPage>
);
};
const LastWizardPage = ({ id, wizardPageProps }) => {
const location = useLocation();
return (
<WizardPage
id={id}
{...wizardPageProps}
location={location}
title="The last page">
<span>The last wizard page</span>
</WizardPage>
);
};
Apart from the page definition, the example has a validation mechanism implemented for the first page which, in case of invalid data, prevents the transition to the next page.
2. Define the layout
Define the Wizard page structure for the different breakpoints.
const layout = {
desktop: { colStart: 1, colSpan: 12 },
tablet: { colStart: 1, colSpan: 10 },
phone: { colStart: 1, colSpan: 6 },
};
3. Define any custom elements
In this example, we are using components from the base configuration. See the Customizing the progress bar and Customizing the action bar sections for custom implementation references.
4. Define the wizard steps
You must specify the corresponding route and the assigned WizardPage
component for each step.
const steps = [
{
id: 'wizard.firstpage',
route: 'firstpage',
title: 'First page',
component: TheFirstPage,
},
{
id: 'wizard.secondpage',
route: 'secondpage',
title: 'Second page',
component: AnotherWizardPage,
},
{
id: 'wizard.lastpage',
route: 'lastpage',
title: 'Last page',
component: LastWizardPage,
},
];
5. Compose the wizard
Bring all the elements defined so far together to compose the wizard.
The Cancel option is added by defining a cancelPath
property, while the Next and Previous buttons use the steps definition order by default.
import { Wizard } from '@jutro/wizard-next';
import { useLocation } from 'react-router-dom';
<Wizard
layout={layout}
baseRoute={'/'}
basePath={'/'}
location={useLocation}
cancelPath="secondpage"
steps={steps}
/>;
Customizing the progress bar
Use renderProgressBar
to turn off the progress bar, or render a custom progress bar.
- To turn off the progress bar, set
renderProgressBar
tonull
orfalse
. - To customize the progress bar, set
renderProgressBar
to a render prop.
This render prop expects a function that receives one parameter, an object with the basePath
prop and an array of the steps
which are both passed to the Wizard.
The following is an example of a custom progress bar made using the layout and steps defined in the previous examples:
First page
import { useLocation } from 'react-router-dom';
import { Wizard } from '@jutro/wizard-next';
import { StepProgressBar } from '@jutro/components';
const customProgressBar = ({ basePath, steps }) => {
const { pathname } = useLocation(); // calc if the subroute a match
const stepRoutes = steps.map((step) => step?.route);
const currentStep = stepRoutes.indexOf(pathname.replace(`${basePath}/`, ''));
const barSteps = steps.map((step) => {
step.active = false;
return step;
});
if (currentStep >= 0) barSteps[currentStep].active = true;
return <StepProgressBar steps={barSteps} />;
};
<Wizard
layout={layout}
baseRoute={'/'}
basePath={'/'}
location={useLocation}
cancelPath="firstpage"
steps={steps}
renderProgressBar={customProgressBar}
/>;
For more information about render props, see the React docs.
Customizing the action bar
Use renderActionBar
to disable the action bar, or render a custom action bar.
- To disable the action bar, set
renderActionBar
tonull
orfalse
. - To customize the action bar, set
renderActionBar
to a render prop.
The render prop is a function that receives two parameters:
resolvedPropsForButtons
- this includes route paths which are calculated by the Wizard based on the flow and the current step.actionBarLayout
- the same prop passed into Wizard to set the layout of the action bar. If you are using a custom action bar, you can use this prop in any way you want, as it is passed directly through the Wizard to the render prop function.
An example of a custom action bar, using the steps and layout from previous examples would be:
First page
export const WizardWithCustomActionBar = () => {
const location = useLocation();
const history = useHistory();
const customActionBar = (resolvedPropsForButtons, actionBarLayout) => {
const selectedFlexDirection =
actionBarLayout === 'column' ? 'column' : 'row';
return (
<div
style={{
border: 'solid 1px yellow',
display: 'flex',
flexDirection: selectedFlexDirection,
}}>
{resolvedPropsForButtons.map((propForButton) =>
('next' == propForButton.name || 'previous' == propForButton.name) &&
propForButton.to != undefined ? (
<Button
label={propForButton.name}
fullWidth={true}
onClick={(e, to: propForButton.to) => handleNavigation(e, to)}
/>
) : (
''
)
)}
</div>
);
};
const handleNavigation = (event, to) => {
history.replace(`//${to}`);
};
return (
<Wizard
layout={layout}
baseRoute={'/'}
basePath={'/'}
location={location}
steps={steps}
renderActionBar={customActionBar}
/>
);
};
We have removed the validation from this example, but you can add it in the handleNavigation
function.
Usage
See Wizard Usage specifications in the patterns section.
Code
Import statement
import { * } from '@jutro/wizard-next';
Jutro provides the Wizard related features through the @jutro/wizard-next
package. It contains the following components:
Wizard
WizardPage
WizardProgress
WizardActionBar
WizardPrompt
The Wizard
is the main component that puts all the pieces together - the progress bar, the buttons and actions associated with them, and the wizard content in the wizard pages. When using WizardProgress
and WizardActionBar
, you can customize their look and feel, use your own components in them, or remove them completely.
Wizard features
The main features of the Wizard are:
Progress indicator
Apart from the default progress indicator provided, it is possible to use a custom one. This enables you to create your own progress indicator to meet your project requirements, while fully utilizing the other Jutro Wizard features.
Action bar
The action bar manages the wizard actions. It supports onCancel
, onFinish
, onNext
, and onPrevious
events and the associated callbacks can be customized using JSX. Additionally, you can customize a knockout page for each action. Within each action, you can customize a different knockout page depending on the response.
Page transitions
Manages the page transitions, normally triggered by the user through the action bar buttons interaction. Supports next
, previous
, and jump
(for example, a user is on step 5 and the jump action takes them to step 3).
Wizard component
Use this component to render a wizard. This component is the main wizard container. It renders routes for the specified steps. Each step must reference a component that either wraps or extends <WizardPage
. Each step component will receive information from the wizard and navigation paths to be used in page rendering.
import { Wizard } from '@jutro/wizard-next';
const steps = [
{
key: 'one',
route: 'step1',
component: PageOne,
},
{
key: 'two',
route: 'step2',
component: PageTwo,
},
{
key: 'three',
route: 'step3',
component: PageThree,
},
];
<Wizard
baseRoute="/wizard/:zipCode"
basePath="/wizard/90210"
steps={steps}
cancelPath="/home"
finishPath="/home"
/>;
Wizard props
This is the list of properties of the Wizard
component. In the next subsections you can find additional information of the layout
and buttonProps
properties and their expected types.
basePath
required- Type
string
DescriptionBase path for the wizard; used when building step links
baseRoute
required- Type
string
DescriptionBase route for the wizard; used when building step routes
location
required- Type
{}
DescriptionCurrent path location, provided by react-router. See react-router props
actionBarLayout
- Type
'default' | 'spaceEvenly'
DescriptionThe type of layout applied to action bar items:
default
- keeps items with visual separation,spaceEvenly
- distributes items evenly in available grid space bodyClassName
- Type
string
DescriptionCSS class name for the body of this component
buttonProps
- Type
{ cancel:{}, previous: {}, next: {}, finish: {} }
DescriptionOverrides for action buttons
callbackMap
- Type
{onStartWizard: func, onFinishWizard: func, onCancelWizard: func,}
DescriptionCallback map for the resolver
cancelPath
- Type
string
DescriptionPath to navigate on 'cancel'; if none provided, the 'cancel' button will not be displayed
className
- Type
string
DescriptionCSS class name for this component
componentMap
- Type
{}
DescriptionComponent map for page component resolver
finishPath
- Type
string
DescriptionPath to navigate on 'finish'; if none provided, the 'finish' button will not be displayed
history
- Type
{}
DescriptionReact-Router history object. See react-router props
initialStepPath
- Type
string
DescriptionPath to the initial step (will be appended to 'basePath'); if not provided, the first step will be displayed
knockoutPath
- Type
string
DescriptionPath to navigate on fail of 'next'; if none provided, no default failTo will be added to the 'next' button
layout
- Type
{desktop: layoutShape, tablet: layoutShape, phoneWide: layoutShape, phone: layoutShape}
DescriptionObject to override page layout
match
- Type
{}
DescriptionReact-Router match object. See react-router props
onCancel
- Type
string | func
DescriptionCallback to invoke when the 'cancel' button is clicked; returns true, false or a promise
onFinish
- Type
string | func
DescriptionCallback to invoke when the 'finish' button is clicked; returns true, false or a promise
onStart
- Type
string | func
DescriptionCallback to trigger when the Wizard mounts
onWizardEvent
- Type
func(info, eventName)
DescriptionThe function(info, eventName) called when a page loads (invoked by WizardPage)
renderActionBar
- Type
func | boolean
DescriptionCallback to render the action bar, or hide/show it
renderNotFound
- Type
func
DescriptionCallback to render 'not found' content; if not provided, nothing will be rendered if a path is not found
renderProgressBar
- Type
func
DescriptionCallback to render a progress bar, or hide/show it
staticContext
- Type
{}
DescriptionReact-Router static context
steps
- Type
{ id: string, route: string, title: string, , component: React.Node }[]
DescriptionArray of steps of the wizard
subRoutes
- Type
{ id: string, route: string, title: string, , component: React.Node }[]
DescriptionArray of routes for subwizards. If a subroute matches the current location a subwizard is active otherwise the outer wizard is active
Wizard layouts
The wizard uses a grid structure derived from the Layout
component. You can also pass custom layout objects for desktops, tablets, and phones to customize the wizard layout.
return (
<WizardExampleContext.Provider value={exampleContext}>
<Wizard
baseRoute={route}
layout={{
desktop: {
columns: ['1fr'],
repeat: '4',
gap: 'large',
colStart: '2',
colSpan: '1',
},
tablet: {
repeat: '4',
...
},
phone: {
repeat: '4',
...
},
}}
basePath={path}
steps={steps}
.......
/>
</WizardExampleContext.Provider>
);
Layout prop
children
- Type
ReactNode (preferably `GridItem`)
DescriptionThe content to be displayed in the page
className
- Type
string
DescriptionCSS class passed to grid tag
id
- Type
string
DescriptionId to identify the layout component
layout
- Type
{desktop?: LayoutShape, tablet?: LayoutShape, phoneWide?: LayoutShape, phone?: LayoutShape,}
colSpan
- Type
number | string
DescriptionSpecifies how many columns an element should span across.
colStart
- Type
number | string
DescriptionDefine column to start
columns
- Type
any[]
DescriptionDefine explicit columns.
gap
- Type
'auto-none' | 'small' | 'medium' | 'large'
DescriptionThe gap size between rows and columns.'
repeat
- Type
'auto-fit' | 'auto-fill' | number
DescriptionAmount of columns to repeat.
DescriptionOverride the default device layout:
desktop
,tablet
,phoneWide
andphone
, all of typeLayoutShape
LayoutShape
props
The LayoutShape
object is used in the layout
property to define the layout of the wizard for each of the possible breakpoints.
colSpan
- Type
string | number
Descriptionspecifies how many columns an element should span across
colStart
- Type
string | number
Descriptiondefine column to start from
columns
- Type
string[] | number[]
Descriptiondefine explicit columns
gap
- Type
'none', 'small', 'medium', 'large'
DescriptionGap between rows and columns
repeat
- Type
'auto-fit' | 'auto-fill' | number | string
DescriptionRepeat columns patterns
buttonProps
property
buttonProps
are passed to the action bar buttons. This includes cancel
, previous
, next
, and finish
. They can be used to customize the look and feel or the behavior of the default Wizard
(or WizardPage
) buttons.
You can pass button props to both Wizard
and WizardPage
.
If you set buttonProps
in the Wizard component, you override the default values of the action bar buttons for the whole wizard flow.
For example, the wizard will have a next
button with fullWidth
set to true
:
<Wizard
buttonProps={{
next: {
fullWidth: true,
},
}}
/>
If you set buttonProps
in a Wizard step, you override the values of the action bar buttons for that step.
Continuing the previous example, this step of the wizard flow would then have a next
button with fullWidth
set to false
, overwriting the value set at the wizard level for this particular step.
<WizardPage
buttonProps={{
// overrides of default button props, these props will have priority over the buttonProps override from the wizard.
next: {
fullWidth: false,
},
}}
/>
buttonProps
props
children
- Type
React.Node | IntlMessageShape | { pathname?: IntlMessageShape; hash?: IntlMessageShape }
DescriptionThe children elements to render inside of the Button
className
- Type
string
DescriptionCSS class name for this button
disabled
- Type
boolean
DescriptionIf
true
this button is disabled failToMessage
- Type
string
DescriptionThe message shown when the promise is rejected; shown if 'failTo' is not provided
fullWidth
- Type
boolean
DescriptionIf
true
, the button expands to the available width icon
- Type
string
DescriptionIcon name
iconClassName
- Type
string
DescriptionCSS class name for the icon
iconPosition
- Type
left | right
DescriptionWhere the icon is placed relative to the text
id
- Type
string
DescriptionID to be assigned to the button
message
- TypeDescription
The message shown when executing the trigger/promise
size
- Type
small | medium
DescriptionAllows you to select the smaller or larger variant
to
- Type
IntlMessageShape | IntlRouterLocation
DescriptionThe destination path when the promise is resolved; can be an object like
<Link to>
toMessage
- Type
string
DescriptionThe message shown when the promise is resolved; shown if 'to' is not provided
Wizard page component
The WizardPage
component defines the content and events for a specific Wizard step.
import { WizardPage } from '@jutro/wizard-next';
import { useLocation } from 'react-router-dom';
const myWizardPage = () => {
const location = useLocation();
return (
<WizardPage
{
cancelPath="/"
finishPath="/offer"
knockoutPath="/knockoutPage"
} location={location}>
<span>Account wizard page</span>
</WizardPage>
);
};
WizardPage props
children
required- Type
node
DescriptionThe content to be displayed in the page
id
required- Type
string
DescriptionId passed to the page panel
location
required- Type
object
DescriptionThe location object with pathname of current url. Usually provided from the location.pathname prop passed from the router.
buttonProps
- Type
object
DescriptionOverrides for action buttons
className
- Type
string
DescriptionCSS class passed to root element of the component
headerClass
- Type
string
DescriptionCSS class passed to wizard page header
knockoutPath
- Type
string
DescriptionPath to navigate on fail of 'next'; if none is provided, no default failTo will be added to the 'next' button
onLoad
- Type
function
DescriptionThe callback to invoke when page is loaded; returns true, false or a promise
onNext
- Type
function
DescriptionThe callback to invoke when the 'next' button is clicked; returns true, false or a promise
onPageEventInfo
- Type
function
DescriptionThe callback to get page event info to send with a wizard event
onPrevious
- Type
function
DescriptionCallback to invoke when the 'back' button is clicked; returns true, false or a promise
pageEventInfo
- Type
function | object
DescriptionObject or callback to get page event info to send with a wizard event
panelClassName
- Type
string
DescriptionAdditional class name for the panel
renderHeader
- Type
function
DescriptionFunction which renders a custom panel header element
renderPanel
- Type
function
DescriptionThe callback to the render panel method; if null then renders without a panel
renderSubTitle
- Type
function
DescriptionFunction to render a custom subTitle
renderTitle
- Type
function
DescriptionFunction to render a custom title
resolveCallbackMap
- Type
object
DescriptionCallback map for the resolver
subTitle
- Description
Default panel subtitle expression
title
- Description
Default panel title expression
WizardPage considerations and references
-
Wizard page callbacks:
onNext
,onLoad
, andonPrevious
. You can also show prompts when the user tries to go back to a previous page or wants to cancel the wizard. -
See the Button props section for details on the
buttonProps
placementOptions. -
For more details about render props, see the Customizing the action bar and Customizing the progress bar sections.
Wizard progress bar component
There is a default progress indicator that you can customize or you can provide a custom component through the render function property.
The default progress indicator is managed through the WizardProgress
component. It relies on the SimpleProgressBar
component.
All the WizardProgress
component logic is based on the information provided by the Wizard
where it is embedded. For example, the list of steps is extracted from the Wizard Context.
See the Customizing the progress bar section for further details.
WizardProgress props
basePath
- Type
string
DescriptionPath to be used when composing the steps urls
location
- Type
'none' | 'small' | 'medium' | 'large'
DescriptionTo look for matching subroutes
progressBarClassName
deprecated- Type
string
DescriptionClass to override progress bar step styles
Wizard action bar
The WizardActionBar
component provides the default functionality to display and handle the different options available in the Wizard. It generates and renders the WizardButton
from actions passed using props. It combines the action with default properties for each button; the default properties are overwritten when provided in actions.
Below is an example defining what happens when the user clicks the Cancel or Next button:
import { WizardActionBar } from '@jutro/wizard-next';
const actions = [
{name: 'cancel', to: '/'},
{name: 'next', to: '/wizard/test/step2'}
]
<WizardActionBar actions={actions}/>
WizardActionBar props
actions
required- Type
[]
DescriptionThe list of actions to be rendered in the <WizardActionBar>
className
- Type
string
DescriptionCSS class name for this component
layout
- Type
'default' | 'spaceEvenly' | 'center'
DescriptionType of layout applied to action bar items:
default
- keeps items with visual separation,spaceEvenly
- distributes items evenly in available grid space,center
- center button horizontally, will vertically stack multiple buttons
Wizard prompt
Provides a convenient prompting mechanism for the context of a wizard. It allows separate conditions and prompts for 'previous' and 'cancel' windows.
import { <WizardPrompt } from '@jutro/wizard-next';
<WizardPrompt
cancelPrompt={{when: wizardChanged, message: 'Want to cancel?'}}
previousPrompt={{when: dataChanged, message: 'Want to go back?'}}
/>
WizardPrompt props
basePath
- Type
string
DescriptionPath to be used when composing the steps urls
previousPrompt
- Type
{when: boolean, title: string, message: string }
DescriptionProperties for the 'previous' prompt; contains 'when', 'title' and 'message'
cancelPrompt
deprecated- Type
{when: boolean, title: string, message: string }
DescriptionProperties for the 'cancel' prompt; contains 'when', 'title' and 'message'
Wizard custom behaviors
Prevent navigation
If the function passed to the onCancel
, onNext
, or onPrevious
properties returns false
, the action is stopped, and the user is not redirected to the corresponding path, staying on the current step.
Changelog
10.9.0
-
A new opt-in feature was introduced that disables automatic event publishing for the Wizard component. You can enable this feature by adding
JUTRO_DISABLE_AUTO_EVENTS_PUBLISHING=true
to the.env
file in the root of your Jutro application. When this is enabled, legacy components no longer publish events by default. For more information on events and how to set up new events, see the Events documentation.
10.2.0
- Deprecated the
progressBarClassName
property from theWizardProgress
component.
10.0.0
- Decommissioned
ScrollToError
component that was exposed through the@jutro/wizard-next
package. - Deprecated the usage of metadata to define the
Wizard
composition and set up.