@patternfly/react-core
Version:
This library provides a set of common React components for use with the PatternFly reference implementation.
395 lines (352 loc) • 10.6 kB
Markdown
---
id: Wizard
section: components
cssPrefix: pf-v6-c-wizard
propComponents:
['Wizard', 'WizardNav', 'WizardNavItem', 'WizardHeader', 'WizardBody', 'WizardFooter', 'WizardToggle', 'WizardStep']
ouia: true
source: react-deprecated
deprecated: true
---
import { Fragment, useEffect, useRef, useState } from 'react';
import { Button, Drawer, DrawerActions, DrawerCloseButton, DrawerColorVariant,
DrawerContent, DrawerContentBody, DrawerHead, DrawerPanelContent, DrawerSection, ModalVariant, Alert, EmptyState, EmptyStateFooter, EmptyStateBody, EmptyStateActions, Title, Progress, Form, FormGroup, TextInput } from '@patternfly/react-core';
import { Wizard as WizardDeprecated, WizardFooter as WizardFooterDeprecated, WizardContextConsumer as WizardContextConsumerDeprecated } from '@patternfly/react-core/deprecated';
import ExternalLinkAltIcon from '@patternfly/react-icons/dist/esm/icons/external-link-alt-icon';
import SlackHashIcon from '@patternfly/react-icons/dist/esm/icons/slack-hash-icon';
import CogsIcon from '@patternfly/react-icons/dist/esm/icons/cogs-icon';
If you seek a wizard solution that allows for more composition, see the [React](/components/wizard) tab.
## Examples
### Basic
```js file="./WizardBasic.tsx"
```
### Basic with disabled steps
```js file="./WizardBasicWithDisabledSteps.tsx"
```
### Anchors for nav items
```js file="./WizardAnchorsForNavItems.tsx"
```
### Incrementally enabled steps
```js file="./WizardIncrementallyEnabledSteps.tsx"
```
### Expandable steps
```js file="./WizardExpandableSteps.tsx"
```
### Finished
```js file="./WizardFinished.tsx"
```
### Enabled on form validation
```js file="./WizardEnabledOnFormValidation.tsx"
```
### Validate on button press
This example demonstrates how to use the `WizardContextConsumer` to consume the `WizardContext`. `WizardContext` can be used to imperatively move to a specific wizard step.
The definition of the `WizardContext` is as follows:
```
interface WizardContext {
goToStepById: (stepId: number | string) => void;
goToStepByName: (stepName: string) => void;
onNext: () => void;
onBack: () => void;
onClose: () => void;
activeStep: WizardStep;
}
```
```js file="./WizardValidateOnButtonPress.tsx"
```
### Progressive steps
```js
import { Button, Radio, Alert } from '@patternfly/react-core';
import {
Wizard as WizardDeprecated,
WizardFooter as WizardFooterDeprecated,
WizardContextConsumer as WizardContextConsumerDeprecated
} from '@patternfly/react-core/deprecated';
class ProgressiveWizard extends React.Component {
constructor(props) {
super(props);
this.state = {
showCreateStep: false,
showUpdateStep: false,
showOptionsStep: false,
showReviewStep: false,
getStartedStepRadio: 'Create',
createStepRadio: 'Quick',
updateStepRadio: 'Quick'
};
this.closeWizard = () => {
console.log('close wizard');
};
this.onGoToStep = ({ id, name }, { prevId, prevName }) => {
// Remove steps after the currently clicked step
if (name === 'Get started') {
this.setState({
showReviewStep: false,
showOptionsStep: false,
showCreateStep: false,
showUpdateStep: false
});
} else if (name === 'Create options' || name === 'Update options') {
this.setState({
showReviewStep: false,
showOptionsStep: false
});
} else if (name.indexOf('Substep') > -1) {
this.setState({
showReviewStep: false
});
}
};
this.getNextStep = (activeStep, callback) => {
if (activeStep.name === 'Get started') {
if (this.state.getStartedStepRadio === 'Create') {
this.setState(
{
showCreateStep: true,
showUpdateStep: false,
showOptionsStep: false,
showReviewStep: false
},
() => {
callback();
}
);
} else {
this.setState(
{
showCreateStep: false,
showUpdateStep: true,
showOptionsStep: false,
showReviewStep: false
},
() => {
callback();
}
);
}
} else if (activeStep.name === 'Create options' || activeStep.name === 'Update options') {
this.setState(
{
showOptionsStep: true,
showReviewStep: false
},
() => {
callback();
}
);
} else if (activeStep.name === 'Substep 3') {
this.setState(
{
showReviewStep: true
},
() => {
callback();
}
);
} else {
callback();
}
};
this.getPreviousStep = (activeStep, callback) => {
if (activeStep.name === 'Review') {
this.setState(
{
showReviewStep: false
},
() => {
callback();
}
);
} else if (activeStep.name === 'Substep 1') {
this.setState(
{
showOptionsStep: false
},
() => {
callback();
}
);
} else if (activeStep.name === 'Create options') {
this.setState(
{
showCreateStep: false
},
() => {
callback();
}
);
} else if (activeStep.name === 'Update options') {
this.setState(
{
showUpdateStep: false
},
() => {
callback();
}
);
} else {
callback();
}
};
}
render() {
const {
stepsValid,
getStartedStepRadio,
createStepRadio,
updateStepRadio,
showCreateStep,
showUpdateStep,
showOptionsStep,
showReviewStep
} = this.state;
const getStartedStep = {
name: 'Get started',
component: (
<div>
<Radio
value="Create"
isChecked={getStartedStepRadio === 'Create'}
onChange={(event) => this.setState({ getStartedStepRadio: event.currentTarget.value })}
label="Create a new thing"
name="radio-step-start"
id="radio-step-start-1"
/>{' '}
<Radio
value="Update"
isChecked={getStartedStepRadio === 'Update'}
onChange={(event) => this.setState({ getStartedStepRadio: event.currentTarget.value })}
label="Update an existing thing"
name="radio-step-start"
id="radio-step-start-2"
/>
</div>
)
};
const createStep = {
name: 'Create options',
component: (
<div>
<Radio
value="Quick"
isChecked={createStepRadio === 'Quick'}
onChange={(event) => this.setState({ createStepRadio: event.currentTarget.value })}
label="Quick create"
name="radio-step-create"
id="radio-step-create-1"
/>{' '}
<Radio
value="Custom"
isChecked={createStepRadio === 'Custom'}
onChange={(event) => this.setState({ createStepRadio: event.currentTarget.value })}
label="Custom create"
name="radio-step-create"
id="radio-step-create-2"
/>
</div>
)
};
const updateStep = {
name: 'Update options',
component: (
<div>
<Radio
value="Quick"
isChecked={updateStepRadio === 'Quick'}
onChange={(event) => this.setState({ updateStepRadio: event.currentTarget.value })}
label="Quick update"
name="radio-step-update"
id="radio-step-update-1"
/>{' '}
<Radio
value="Custom"
isChecked={updateStepRadio === 'Custom'}
onChange={(event) => this.setState({ updateStepRadio: event.currentTarget.value })}
label="Custom update"
name="radio-step-update"
id="radio-step-update-2"
/>
</div>
)
};
const optionsStep = {
name: showCreateStep ? `${createStepRadio} Options` : `${updateStepRadio} Options`,
steps: [
{
name: 'Substep 1',
component: 'Substep 1'
},
{
name: 'Substep 2',
component: 'Substep 2'
},
{
name: 'Substep 3',
component: 'Substep 3'
}
]
};
const reviewStep = {
name: 'Review',
component: (
<div>
<div>First choice: {getStartedStepRadio}</div>
<div>Second choice: {showCreateStep ? createStepRadio : updateStepRadio}</div>
</div>
)
};
const steps = [
getStartedStep,
...(showCreateStep ? [createStep] : []),
...(showUpdateStep ? [updateStep] : []),
...(showOptionsStep ? [optionsStep] : []),
...(showReviewStep ? [reviewStep] : [])
];
const CustomFooter = (
<WizardFooterDeprecated>
<WizardContextConsumerDeprecated>
{({ activeStep, goToStepByName, goToStepById, onNext, onBack, onClose }) => {
return (
<>
<Button
variant="secondary"
onClick={() => this.getPreviousStep(activeStep, onBack)}
className={activeStep.name === 'Get started' ? 'pf-m-disabled' : ''}
>
Back
</Button>
<Button variant="primary" type="submit" onClick={() => this.getNextStep(activeStep, onNext)}>
{activeStep.name === 'Review' ? 'Finish' : 'Next'}
</Button>
<Button variant="link" onClick={onClose}>
Cancel
</Button>
</>
);
}}
</WizardContextConsumerDeprecated>
</WizardFooterDeprecated>
);
const title = 'Progressive wizard';
return (
<WizardDeprecated
navAriaLabel={`${title} steps`}
mainAriaLabel={`${title} content`}
onClose={this.closeWizard}
footer={CustomFooter}
onGoToStep={this.onGoToStep}
steps={steps}
height={400}
/>
);
}
}
```
### Get current step
```js file="./WizardGetCurrentStep.tsx"
```
### Wizard in modal
```js file="./WizardInModal.tsx"
```
### Wizard with drawer
```js file="./WizardWithDrawer.tsx"
```