diff --git a/packages/react-core/src/components/Wizard/examples/FinishedStep.js b/packages/react-core/src/components/Wizard/examples/FinishedStep.js
deleted file mode 100644
index 6adfd128f09..00000000000
--- a/packages/react-core/src/components/Wizard/examples/FinishedStep.js
+++ /dev/null
@@ -1,70 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import {
- EmptyState,
- EmptyStateIcon,
- EmptyStateBody,
- EmptyStateSecondaryActions,
- Title,
- Progress,
- Button
-} from '@patternfly/react-core';
-// eslint-disable-next-line patternfly-react/import-tokens-icons
-import { CogsIcon } from '@patternfly/react-icons';
-
-const propTypes = {
- onClose: PropTypes.func.isRequired
-};
-
-class FinishedStep extends React.Component {
- constructor(props) {
- super(props);
- this.state = { percent: 0 };
- }
-
- tick() {
- if (this.state.percent < 100) {
- this.setState(prevState => ({
- percent: prevState.percent + 20
- }));
- }
- }
-
- componentDidMount() {
- this.interval = setInterval(() => this.tick(), 1000);
- }
-
- componentWillUnmount() {
- clearInterval(this.interval);
- }
-
- render() {
- const { percent } = this.state;
- return (
-
-
-
-
- {percent === 100 ? 'Validation complete' : 'Validating credentials'}
-
-
-
-
-
- Description can be used to further elaborate on the validation step, or give the user a better idea of how
- long the process will take.
-
-
-
- Log to console
-
-
-
-
- );
- }
-}
-
-FinishedStep.propTypes = propTypes;
-
-export default FinishedStep;
diff --git a/packages/react-core/src/components/Wizard/examples/SampleForm.js b/packages/react-core/src/components/Wizard/examples/SampleForm.js
deleted file mode 100644
index 9992752f404..00000000000
--- a/packages/react-core/src/components/Wizard/examples/SampleForm.js
+++ /dev/null
@@ -1,59 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { Form, FormGroup, TextInput } from '@patternfly/react-core';
-
-const propTypes = {
- formValue: PropTypes.string,
- isFormValid: PropTypes.bool,
- onChange: PropTypes.func
-};
-
-const defaultProps = {
- formValue: '',
- isFormValid: false,
- onChange: () => undefined
-};
-
-class SampleForm extends React.Component {
- static propTypes = propTypes;
- static defaultProps = defaultProps;
-
- state = {
- value: this.props.formValue,
- isValid: this.props.isFormValid
- };
-
- handleTextInputChange = value => {
- const isValid = /^\d+$/.test(value);
- this.setState({ value, isValid });
- this.props.onChange && this.props.onChange(isValid, value);
- };
-
- render() {
- const { value, isValid } = this.state;
- const validated = isValid ? 'default' : 'error';
-
- return (
-
- );
- }
-}
-
-export default SampleForm;
diff --git a/packages/react-core/src/components/Wizard/examples/Wizard.md b/packages/react-core/src/components/Wizard/examples/Wizard.md
index 75ee563df68..56cc069554c 100644
--- a/packages/react-core/src/components/Wizard/examples/Wizard.md
+++ b/packages/react-core/src/components/Wizard/examples/Wizard.md
@@ -8,11 +8,11 @@ ouia: true
---
import { Button, Drawer, DrawerActions, DrawerCloseButton, DrawerColorVariant,
-DrawerContent, DrawerContentBody, DrawerHead, DrawerPanelContent, DrawerSection, Wizard, WizardFooter, WizardContextConsumer, ModalVariant, Alert, EmptyState, EmptyStateIcon, EmptyStateBody, EmptyStateSecondaryActions, Title, Progress } from '@patternfly/react-core';
+DrawerContent, DrawerContentBody, DrawerHead, DrawerPanelContent, DrawerSection, Wizard, WizardFooter, WizardContextConsumer, ModalVariant, Alert, EmptyState, EmptyStateIcon, EmptyStateBody, EmptyStateSecondaryActions, Title, Progress, Form, FormGroup, TextInput } from '@patternfly/react-core';
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 FinishedStep from './FinishedStep';
-import SampleForm from './SampleForm';
+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 next](/components/wizard/react-next) tab.
@@ -20,374 +20,37 @@ If you seek a wizard solution that allows for more composition, see the [React n
### Basic
-```js
-import React from 'react';
-import { Button, Wizard } from '@patternfly/react-core';
-
-class SimpleWizard extends React.Component {
- constructor(props) {
- super(props);
- }
-
- render() {
- const steps = [
- { name: 'First step', component: Step 1 content
},
- { name: 'Second step', component: Step 2 content
},
- { name: 'Third step', component: Step 3 content
},
- { name: 'Fourth step', component: Step 4 content
},
- { name: 'Review', component: Review step content
, nextButtonText: 'Finish' }
- ];
- const title = 'Basic wizard';
- return ;
- }
-}
+```ts file="./WizardBasic.tsx"
```
### Basic with disabled steps
-```js
-import React from 'react';
-import { Button, Wizard } from '@patternfly/react-core';
-
-class SimpleWizard extends React.Component {
- constructor(props) {
- super(props);
- }
-
- render() {
- const steps = [
- { name: 'First step', component: Step 1 content
},
- { name: 'Second step', component: Step 2 content
, isDisabled: true },
- { name: 'Third step', component: Step 3 content
},
- { name: 'Fourth step', component: Step 4 content
, isDisabled: true },
- { name: 'Review', component: Review step content
, nextButtonText: 'Finish' }
- ];
- const title = 'Basic wizard';
- return ;
- }
-}
+```ts file="./WizardBasicWithDisabledSteps.tsx"
```
### Anchors for nav items
-```js
-import React from 'react';
-import { Button, Wizard } from '@patternfly/react-core';
-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';
-
-class WizardWithNavAnchors extends React.Component {
- constructor(props) {
- super(props);
- }
-
- render() {
- const steps = [
- {
- name: (
-
- PF3
-
- ),
- component: Step 1: Read about PF3
,
- stepNavItemProps: { navItemComponent: 'a', href: 'https://www.patternfly.org/v3/', target: '_blank' }
- },
- {
- name: (
-
- PF4
-
- ),
- component: Step 2: Read about PF4
,
- stepNavItemProps: { navItemComponent: 'a', href: 'https://www.patternfly.org/v4/', target: '_blank' }
- },
- {
- name: (
-
- Join us on slack
-
- ),
- component: (
-
- Join the conversation
-
- ),
- stepNavItemProps: { navItemComponent: 'a', href: 'https://patternfly.slack.com/', target: '_blank' }
- }
- ];
- const title = 'Anchor link wizard';
- return ;
- }
-}
+```ts file="./WizardAnchorsForNavItems.tsx"
```
### Incrementally enabled steps
-```js
-import React from 'react';
-import { Button, Wizard } from '@patternfly/react-core';
-
-class IncrementallyEnabledStepsWizard extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- stepIdReached: 1
- };
- this.onNext = ({ id }) => {
- const [, orderIndex] = id.split('-');
-
- this.setState({
- stepIdReached: this.state.stepIdReached < orderIndex ? orderIndex : this.state.stepIdReached
- });
- };
- this.closeWizard = () => {
- console.log('close wizard');
- };
- }
-
- render() {
- const { stepIdReached } = this.state;
-
- const steps = [
- { id: 'incrementallyEnabled-1', name: 'First step', component: Step 1 content
},
- {
- id: 'incrementallyEnabled-2',
- name: 'Second step',
- component: Step 2 content
,
- canJumpTo: stepIdReached >= 2
- },
- {
- id: 'incrementallyEnabled-3',
- name: 'Third step',
- component: Step 3 content
,
- canJumpTo: stepIdReached >= 3
- },
- {
- id: 'incrementallyEnabled-4',
- name: 'Fourth step',
- component: Step 4 content
,
- canJumpTo: stepIdReached >= 4
- },
- {
- id: 'incrementallyEnabled-5',
- name: 'Review',
- component: Review step content
,
- nextButtonText: 'Finish',
- canJumpTo: stepIdReached >= 5
- }
- ];
- const title = 'Incrementally enabled wizard';
- return (
-
- );
- }
-}
+```ts file="./WizardIncrementallyEnabledSteps.tsx"
```
### Expandable steps
-```js
-import React from 'react';
-import { Button, Wizard } from '@patternfly/react-core';
-
-class SimpleWizard extends React.Component {
- constructor(props) {
- super(props);
- }
-
- render() {
- const steps = [
- {
- name: 'First step',
- steps: [
- { name: 'Substep A', component: Substep A content
},
- { name: 'Substep B', component: Substep B content
}
- ]
- },
- { name: 'Second step', component: Step 2 content
},
- {
- name: 'Third step',
- steps: [
- { name: 'Substep C', component: Substep C content
},
- { name: 'Substep D', component: Substep D content
}
- ]
- },
- { name: 'Fourth step', component: Step 4 content
},
- { name: 'Review', component: Review step content
, nextButtonText: 'Finish' }
- ];
- const title = 'Expandable wizard';
- return (
-
- );
- }
-}
+```ts file="./WizardExpandableSteps.tsx"
```
### Finished
-```js
-import React from 'react';
-import { Button, Wizard } from '@patternfly/react-core';
-import FinishedStep from './examples/FinishedStep';
-
-class FinishedStepWizard extends React.Component {
- constructor(props) {
- super(props);
-
- this.closeWizard = () => {
- console.log('close wizard');
- };
- }
-
- render() {
- const steps = [
- { name: 'First step', component: Step 1 content
},
- { name: 'Second step', component: Step 2 content
},
- { name: 'Third step', component: Step 3 content
},
- { name: 'Fourth step', component: Step 4 content
},
- { name: 'Review', component: Review step content
, nextButtonText: 'Finish' },
- { name: 'Finish', component: , isFinishedStep: true }
- ];
- const title = 'Finished wizard';
- return (
-
- );
- }
-}
+```ts file="./WizardFinished.tsx"
```
### Enabled on form validation
-```js
-import React from 'react';
-import { Button, Wizard, Form, FormGroup, TextInput } from '@patternfly/react-core';
-import SampleForm from './examples/SampleForm';
-
-class ValidationWizard extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- isFormValid: false,
- formValue: 'Thirty',
- allStepsValid: false,
- stepIdReached: 1
- };
-
- this.closeWizard = () => {
- console.log('close wizard');
- };
-
- this.onFormChange = (isValid, value) => {
- this.setState(
- {
- isFormValid: isValid,
- formValue: value
- },
- this.areAllStepsValid
- );
- };
-
- this.areAllStepsValid = () => {
- this.setState({
- allStepsValid: this.state.isFormValid
- });
- };
-
- this.onNext = ({ id, name }, { prevId, prevName }) => {
- console.log(`current id: ${id}, current name: ${name}, previous id: ${prevId}, previous name: ${prevName}`);
- const [, orderIndex] = id.split('-');
-
- this.setState({
- stepIdReached: this.state.stepIdReached < orderIndex ? orderIndex : this.state.stepIdReached
- });
- this.areAllStepsValid();
- };
-
- this.onBack = ({ id, name }, { prevId, prevName }) => {
- console.log(`current id: ${id}, current name: ${name}, previous id: ${prevId}, previous name: ${prevName}`);
- this.areAllStepsValid();
- };
-
- this.onGoToStep = ({ id, name }, { prevId, prevName }) => {
- console.log(`current id: ${id}, current name: ${name}, previous id: ${prevId}, previous name: ${prevName}`);
- };
-
- this.onSave = () => {
- console.log('Saved and closed the wizard');
- this.setState({
- isOpen: false
- });
- };
- }
-
- render() {
- const { isFormValid, formValue, allStepsValid, stepIdReached } = this.state;
-
- const steps = [
- { id: 'validated-1', name: 'Information', component: Step 1 content
},
- {
- name: 'Configuration',
- steps: [
- {
- id: 'validated-2',
- name: 'Substep A with validation',
- component: ,
- enableNext: isFormValid,
- canJumpTo: stepIdReached >= 2
- },
- { id: 'validated-3', name: 'Substep B', component: Substep B
, canJumpTo: stepIdReached >= 3 }
- ]
- },
- {
- id: 'validated-4',
- name: 'Additional',
- component: Step 3 content
,
- enableNext: allStepsValid,
- canJumpTo: stepIdReached >= 4
- },
- {
- id: 'validated-5',
- name: 'Review',
- component: Step 4 content
,
- nextButtonText: 'Close',
- canJumpTo: stepIdReached >= 5
- }
- ];
- const title = 'Enabled on form validation wizard';
- return (
-
- );
- }
-}
+```ts file="./WizardEnabledOnFormValidation.tsx"
```
### Validate on button press
@@ -407,104 +70,7 @@ interface WizardContext {
}
```
-```js
-import React from 'react';
-import { Button, Wizard, WizardFooter, WizardContextConsumer, Alert } from '@patternfly/react-core';
-import SampleForm from './examples/SampleForm';
-import FinishedStep from './examples/FinishedStep';
-
-class ValidateButtonPressWizard extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- stepsValid: 0
- };
-
- this.closeWizard = () => {
- console.log('close wizard');
- };
-
- this.validateLastStep = onNext => {
- const { stepsValid } = this.state;
- if (stepsValid !== 1) {
- this.setState({
- stepsValid: 1
- });
- } else {
- onNext();
- }
- };
- }
-
- render() {
- const { stepsValid } = this.state;
-
- const steps = [
- { name: 'First step', component: Step 1 content
},
- { name: 'Second step', component: Step 2 content
},
- {
- name: 'Final Step',
- component: (
- <>
- {stepsValid === 1 && (
-
- )}
-
- >
- )
- },
- { name: 'Finish', component: , isFinishedStep: true }
- ];
-
- const CustomFooter = (
-
-
- {({ activeStep, goToStepByName, goToStepById, onNext, onBack, onClose }) => {
- if (activeStep.name !== 'Final Step') {
- return (
- <>
-
- Forward
-
-
- Backward
-
-
- Cancel
-
- >
- );
- }
- // Final step buttons
- return (
- <>
- this.validateLastStep(onNext)}>Validate
- goToStepByName('Step 1')}>Go to Beginning
- >
- );
- }}
-
-
- );
- const title = 'Validate on button press wizard';
- return (
-
- );
- }
-}
+```ts file="./WizardValidateOnButtonPress.tsx"
```
### Progressive steps
@@ -512,8 +78,6 @@ class ValidateButtonPressWizard extends React.Component {
```js
import React from 'react';
import { Button, Radio, Wizard, WizardFooter, WizardContextConsumer, Alert } from '@patternfly/react-core';
-import SampleForm from './examples/SampleForm';
-import FinishedStep from './examples/FinishedStep';
class ProgressiveWizard extends React.Component {
constructor(props) {
@@ -642,7 +206,6 @@ class ProgressiveWizard extends React.Component {
}
};
}
-
render() {
const {
stepsValid,
@@ -654,7 +217,6 @@ class ProgressiveWizard extends React.Component {
showOptionsStep,
showReviewStep
} = this.state;
-
const getStartedStep = {
name: 'Get started',
component: (
@@ -678,7 +240,6 @@ class ProgressiveWizard extends React.Component {
)
};
-
const createStep = {
name: 'Create options',
component: (
@@ -702,7 +263,6 @@ class ProgressiveWizard extends React.Component {
)
};
-
const updateStep = {
name: 'Update options',
component: (
@@ -726,7 +286,6 @@ class ProgressiveWizard extends React.Component {
)
};
-
const optionsStep = {
name: showCreateStep ? `${createStepRadio} Options` : `${updateStepRadio} Options`,
steps: [
@@ -744,7 +303,6 @@ class ProgressiveWizard extends React.Component {
}
]
};
-
const reviewStep = {
name: 'Review',
component: (
@@ -754,7 +312,6 @@ class ProgressiveWizard extends React.Component {
)
};
-
const steps = [
getStartedStep,
...(showCreateStep ? [createStep] : []),
@@ -762,7 +319,6 @@ class ProgressiveWizard extends React.Component {
...(showOptionsStep ? [optionsStep] : []),
...(showReviewStep ? [reviewStep] : [])
];
-
const CustomFooter = (
@@ -806,248 +362,15 @@ class ProgressiveWizard extends React.Component {
### Get current step
-```js
-import React from 'react';
-import { Button, Wizard } from '@patternfly/react-core';
-
-class GetCurrentStepWizard extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- step: 1
- };
- this.onCurrentStepChanged = ({ id }) => {
- this.setState({
- step: id
- });
- };
- this.closeWizard = () => {
- console.log('close wizard');
- };
- }
-
- render() {
- const steps = [
- { id: 1, name: 'First step', component: Step 1 content
},
- { id: 2, name: 'Second step', component: Step 2 content
},
- { id: 3, name: 'Third step', component: Step 3 content
},
- { id: 4, name: 'Fourth step', component: Step 4 content
},
- { id: 5, name: 'Review', component: Review step content
, nextButtonText: 'Finish' }
- ];
- const title = 'Get current step wizard';
- return (
-
- );
- }
-}
+```ts file="./WizardGetCurrentStep.tsx"
```
### Wizard in modal
-```js
-import React from 'react';
-import { Button, Wizard } from '@patternfly/react-core';
-
-class WizardInModal extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- isOpen: false
- };
- this.handleModalToggle = () => {
- this.setState(({ isOpen }) => ({
- isOpen: !isOpen
- }));
- };
- }
-
- render() {
- const { isOpen } = this.state;
-
- const steps = [
- { name: 'First step', component: Step 1 content
},
- { name: 'Second step', component: Step 2 content
},
- { name: 'Third step', component: Step 3 content
},
- { name: 'Fourth step', component: Step 4 content
},
- { name: 'Review', component: Review step content
, nextButtonText: 'Finish' }
- ];
- const title = 'Wizard in modal';
- return (
-
-
- Show Modal
-
-
-
- );
- }
-}
+```ts file="./WizardInModal.tsx"
```
### Wizard with drawer
-```js
-import React from 'react';
-import {
- Button,
- DrawerActions,
- DrawerCloseButton,
- DrawerHead,
- DrawerPanelContent,
- Text,
- TextContent,
- Wizard
-} from '@patternfly/react-core';
-
-class WizardWithDrawer extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- isOpen: false,
- isDrawerExpanded: false,
- sectionGray: false,
- panelGray: true,
- contentGray: false
- };
-
- this.drawerRef = React.createRef();
-
- this.onExpand = () => {
- this.drawerRef.current && this.drawerRef.current.focus();
- };
-
- this.onOpenClick = () => {
- this.setState({
- isDrawerExpanded: true
- });
- };
-
- this.onCloseClick = () => {
- this.setState({
- isDrawerExpanded: false
- });
- };
- }
-
- render() {
- const { isDrawerExpanded } = this.state;
-
- const panel1Content = (
-
-
-
- drawer-panel-1 content
-
-
-
-
-
-
- );
-
- const panel2Content = (
-
-
-
- drawer-panel-2 content
-
-
-
-
-
-
- );
-
- const panel3Content = (
-
-
-
- drawer-panel-3 content
-
-
-
-
-
-
- );
-
- const drawerToggleButton = (
-
- Open Drawer
-
- );
-
- const steps = [
- {
- name: 'Information',
- component: Information step content
,
- drawerPanelContent: panel1Content,
- drawerToggleButton: drawerToggleButton
- },
- {
- name: 'Configuration',
- steps: [
- {
- name: 'Substep A',
- component: Substep A content
,
- drawerPanelContent: panel2Content,
- drawerToggleButton: drawerToggleButton
- },
- {
- name: 'Substep B',
- component: Substep B content
,
- drawerPanelContent: panel2Content,
- drawerToggleButton: drawerToggleButton
- },
- {
- name: 'Substep C',
- component: Substep C content
,
- drawerPanelContent: panel2Content,
- drawerToggleButton: drawerToggleButton
- }
- ]
- },
- {
- name: 'Additional',
- component: Additional step content
,
- drawerPanelContent: panel3Content,
- drawerToggleButton: drawerToggleButton
- },
- {
- name: 'Review',
- component: Review step content
,
- nextButtonText: 'Finish'
- }
- ];
-
- const title = 'Wizard with drawer';
-
- return (
-
-
-
- );
- }
-}
+```ts file="./WizardWithDrawer.tsx"
```
diff --git a/packages/react-core/src/components/Wizard/examples/WizardAnchorsForNavItems.tsx b/packages/react-core/src/components/Wizard/examples/WizardAnchorsForNavItems.tsx
new file mode 100644
index 00000000000..6c26cd8e937
--- /dev/null
+++ b/packages/react-core/src/components/Wizard/examples/WizardAnchorsForNavItems.tsx
@@ -0,0 +1,42 @@
+import React from 'react';
+import { Button, Wizard } from '@patternfly/react-core';
+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';
+
+export const WizardWithNavAnchors: React.FunctionComponent = () => {
+ const steps = [
+ {
+ name: (
+
+ PF3
+
+ ),
+ component: Step 1: Read about PF3
,
+ stepNavItemProps: { navItemComponent: 'a', href: 'https://www.patternfly.org/v3/', target: '_blank' }
+ },
+ {
+ name: (
+
+ PF4
+
+ ),
+ component: Step 2: Read about PF4
,
+ stepNavItemProps: { navItemComponent: 'a', href: 'https://www.patternfly.org/v4/', target: '_blank' }
+ },
+ {
+ name: (
+
+ Join us on slack
+
+ ),
+ component: (
+
+ Join the conversation
+
+ ),
+ stepNavItemProps: { navItemComponent: 'a', href: 'https://patternfly.slack.com/', target: '_blank' }
+ }
+ ];
+ const title = 'Anchor link wizard example';
+ return ;
+};
diff --git a/packages/react-core/src/components/Wizard/examples/WizardBasic.tsx b/packages/react-core/src/components/Wizard/examples/WizardBasic.tsx
new file mode 100644
index 00000000000..71eca4176f5
--- /dev/null
+++ b/packages/react-core/src/components/Wizard/examples/WizardBasic.tsx
@@ -0,0 +1,14 @@
+import React from 'react';
+import { Wizard } from '@patternfly/react-core';
+
+export const WizardBasic: React.FunctionComponent = () => {
+ const steps = [
+ { name: 'First step', component: Step 1 content
},
+ { name: 'Second step', component: Step 2 content
},
+ { name: 'Third step', component: Step 3 content
},
+ { name: 'Fourth step', component: Step 4 content
},
+ { name: 'Review', component: Review step content
, nextButtonText: 'Finish' }
+ ];
+ const title = 'Basic wizard example';
+ return ;
+};
diff --git a/packages/react-core/src/components/Wizard/examples/WizardBasicWithDisabledSteps.tsx b/packages/react-core/src/components/Wizard/examples/WizardBasicWithDisabledSteps.tsx
new file mode 100644
index 00000000000..46b92e151e9
--- /dev/null
+++ b/packages/react-core/src/components/Wizard/examples/WizardBasicWithDisabledSteps.tsx
@@ -0,0 +1,14 @@
+import React from 'react';
+import { Wizard } from '@patternfly/react-core';
+
+export const WizardBasicWithDisabledSteps: React.FunctionComponent = () => {
+ const steps = [
+ { name: 'First step', component: Step 1 content
},
+ { name: 'Second step', component: Step 2 content
, isDisabled: true },
+ { name: 'Third step', component: Step 3 content
},
+ { name: 'Fourth step', component: Step 4 content
, isDisabled: true },
+ { name: 'Review', component: Review step content
, nextButtonText: 'Finish' }
+ ];
+ const title = 'Basic wizard with disabled steps example';
+ return ;
+};
diff --git a/packages/react-core/src/components/Wizard/examples/WizardEnabledOnFormValidation.tsx b/packages/react-core/src/components/Wizard/examples/WizardEnabledOnFormValidation.tsx
new file mode 100644
index 00000000000..9121779a59e
--- /dev/null
+++ b/packages/react-core/src/components/Wizard/examples/WizardEnabledOnFormValidation.tsx
@@ -0,0 +1,139 @@
+import React from 'react';
+import { Form, FormGroup, TextInput, Wizard, WizardStep } from '@patternfly/react-core';
+interface PrevStepInfo {
+ prevId?: string | number;
+ prevName: React.ReactNode;
+}
+
+interface sampleFormProps {
+ formValue: string;
+ isFormValid: boolean;
+ onChange?: (isValid: boolean, value: string) => void;
+}
+
+const SampleForm: React.FunctionComponent = (props: sampleFormProps) => {
+ const [value, setValue] = React.useState(props.formValue);
+ const [isValid, setIsValid] = React.useState(props.isFormValid);
+
+ const handleTextInputChange = (value: string) => {
+ const valid = /^\d+$/.test(value);
+ setValue(value);
+ setIsValid(valid);
+ props.onChange && props.onChange(valid, value);
+ };
+
+ const validated = isValid ? 'default' : 'error';
+
+ return (
+
+ );
+};
+
+export const WizardFormValidation: React.FunctionComponent = () => {
+ const [isFormValid, setIsFormValid] = React.useState(false);
+ const [formValue, setFormValue] = React.useState('Thirty');
+ const [allStepsValid, setAllStepsValid] = React.useState(false);
+ const [stepIdReached, setStepIdReached] = React.useState(1);
+
+ React.useEffect(() => {
+ setAllStepsValid(isFormValid);
+ }, [isFormValid, stepIdReached]);
+
+ const closeWizard = () => {
+ // eslint-disable-next-line no-console
+ console.log('close wizard');
+ };
+
+ const onFormChange = (isValid: boolean, value: string) => {
+ setIsFormValid(isValid);
+ setFormValue(value);
+ };
+
+ const areAllStepsValid = () => {
+ setAllStepsValid(isFormValid);
+ };
+
+ const onNext = ({ id, name }: WizardStep, { prevId, prevName }: PrevStepInfo) => {
+ // eslint-disable-next-line no-console
+ console.log(`current id: ${id}, current name: ${name}, previous id: ${prevId}, previous name: ${prevName}`);
+ if (id) {
+ if (typeof id === 'string') {
+ const [, orderIndex] = id.split('-');
+ id = parseInt(orderIndex);
+ }
+ setStepIdReached(stepIdReached < id ? id : stepIdReached);
+ }
+ };
+
+ const onBack = ({ id, name }: WizardStep, { prevId, prevName }: PrevStepInfo) => {
+ // eslint-disable-next-line no-console
+ console.log(`current id: ${id}, current name: ${name}, previous id: ${prevId}, previous name: ${prevName}`);
+ areAllStepsValid();
+ };
+
+ const onGoToStep = ({ id, name }: WizardStep, { prevId, prevName }: PrevStepInfo) => {
+ // eslint-disable-next-line no-console
+ console.log(`current id: ${id}, current name: ${name}, previous id: ${prevId}, previous name: ${prevName}`);
+ };
+
+ const steps = [
+ { id: 'validated-1', name: 'Information', component: Step 1 content
},
+ {
+ name: 'Configuration',
+ steps: [
+ {
+ id: 'validated-2',
+ name: 'Substep A with validation',
+ component: ,
+ enableNext: isFormValid,
+ canJumpTo: stepIdReached >= 2
+ },
+ { id: 'validated-3', name: 'Substep B', component: Substep B
, canJumpTo: stepIdReached >= 3 }
+ ]
+ },
+ {
+ id: 'validated-4',
+ name: 'Additional',
+ component: Step 3 content
,
+ enableNext: allStepsValid,
+ canJumpTo: stepIdReached >= 4
+ },
+ {
+ id: 'validated-5',
+ name: 'Review',
+ component: Step 4 content
,
+ nextButtonText: 'Finish',
+ canJumpTo: stepIdReached >= 5
+ }
+ ];
+ const title = 'Wizard enabled on form validation example';
+ return (
+
+ );
+};
diff --git a/packages/react-core/src/components/Wizard/examples/WizardExpandableSteps.tsx b/packages/react-core/src/components/Wizard/examples/WizardExpandableSteps.tsx
new file mode 100644
index 00000000000..5400820f6fe
--- /dev/null
+++ b/packages/react-core/src/components/Wizard/examples/WizardExpandableSteps.tsx
@@ -0,0 +1,34 @@
+import React from 'react';
+import { Wizard } from '@patternfly/react-core';
+
+export const WizardExpandableSteps: React.FunctionComponent = () => {
+ const steps = [
+ {
+ name: 'First step',
+ steps: [
+ { name: 'Substep A', component: Substep A content
},
+ { name: 'Substep B', component: Substep B content
}
+ ]
+ },
+ { name: 'Second step', component: Step 2 content
},
+ {
+ name: 'Third step',
+ steps: [
+ { name: 'Substep C', component: Substep C content
},
+ { name: 'Substep D', component: Substep D content
}
+ ]
+ },
+ { name: 'Fourth step', component: Step 4 content
},
+ { name: 'Review', component: Review step content
, nextButtonText: 'Finish' }
+ ];
+ const title = 'Expandable wizard example';
+ return (
+
+ );
+};
diff --git a/packages/react-core/src/components/Wizard/examples/WizardFinished.tsx b/packages/react-core/src/components/Wizard/examples/WizardFinished.tsx
new file mode 100644
index 00000000000..072d1098f46
--- /dev/null
+++ b/packages/react-core/src/components/Wizard/examples/WizardFinished.tsx
@@ -0,0 +1,90 @@
+import React from 'react';
+import {
+ EmptyState,
+ EmptyStateIcon,
+ EmptyStateBody,
+ EmptyStateSecondaryActions,
+ Title,
+ Progress,
+ Button,
+ Wizard
+} from '@patternfly/react-core';
+// eslint-disable-next-line patternfly-react/import-tokens-icons
+import { CogsIcon } from '@patternfly/react-icons';
+
+interface finishedProps {
+ onClose: () => void;
+}
+
+const FinishedStep: React.FunctionComponent = (props: finishedProps) => {
+ const [percent, setPercent] = React.useState(0);
+
+ const tick = () => {
+ setPercent(prevPercent => {
+ if (prevPercent < 100) {
+ return prevPercent + 20;
+ } else {
+ return prevPercent;
+ }
+ });
+ };
+
+ React.useEffect(() => {
+ const interval = setInterval(() => tick(), 1000);
+
+ if (percent >= 100) {
+ clearInterval(interval);
+ }
+
+ return () => clearInterval(interval);
+ }, [percent]);
+
+ return (
+
+
+
+
+ {percent === 100 ? 'Validation complete' : 'Validating credentials'}
+
+
+
+
+
+ Description can be used to further elaborate on the validation step, or give the user a better idea of how
+ long the process will take.
+
+
+
+ Log to console
+
+
+
+
+ );
+};
+
+export const WizardFinished: React.FunctionComponent = () => {
+ const closeWizard = () => {
+ // eslint-disable-next-line no-console
+ console.log('close wizard');
+ };
+
+ const steps = [
+ { name: 'First step', component: Step 1 content
},
+ { name: 'Second step', component: Step 2 content
},
+ { name: 'Third step', component: Step 3 content
},
+ { name: 'Fourth step', component: Step 4 content
},
+ { name: 'Review', component: Review step content
, nextButtonText: 'Finish' },
+ { name: 'Finish', component: , isFinishedStep: true }
+ ];
+ const title = 'Finished wizard example';
+ return (
+
+ );
+};
diff --git a/packages/react-core/src/components/Wizard/examples/WizardGetCurrentStep.tsx b/packages/react-core/src/components/Wizard/examples/WizardGetCurrentStep.tsx
new file mode 100644
index 00000000000..f41edaa0f34
--- /dev/null
+++ b/packages/react-core/src/components/Wizard/examples/WizardGetCurrentStep.tsx
@@ -0,0 +1,33 @@
+import React from 'react';
+import { Wizard, WizardStep } from '@patternfly/react-core';
+
+export const WizardGetCurrentStep: React.FunctionComponent = () => {
+ const onCurrentStepChanged = ({ id }: WizardStep) => {
+ // eslint-disable-next-line no-console
+ console.log(id);
+ };
+ const closeWizard = () => {
+ // eslint-disable-next-line no-console
+ console.log('close wizard');
+ };
+
+ const steps = [
+ { id: 1, name: 'First step', component: Step 1 content
},
+ { id: 2, name: 'Second step', component: Step 2 content
},
+ { id: 3, name: 'Third step', component: Step 3 content
},
+ { id: 4, name: 'Fourth step', component: Step 4 content
},
+ { id: 5, name: 'Review', component: Review step content
, nextButtonText: 'Finish' }
+ ];
+ const title = 'Get current step wizard example';
+ return (
+
+ );
+};
diff --git a/packages/react-core/src/components/Wizard/examples/WizardInModal.tsx b/packages/react-core/src/components/Wizard/examples/WizardInModal.tsx
new file mode 100644
index 00000000000..98695bf6521
--- /dev/null
+++ b/packages/react-core/src/components/Wizard/examples/WizardInModal.tsx
@@ -0,0 +1,32 @@
+import React from 'react';
+import { Button, Wizard } from '@patternfly/react-core';
+
+export const WizardInModal: React.FunctionComponent = () => {
+ const [isOpen, setIsOpen] = React.useState(false);
+ const handleModalToggle = () => {
+ setIsOpen(!isOpen);
+ };
+ const steps = [
+ { name: 'First step', component: Step 1 content
},
+ { name: 'Second step', component: Step 2 content
},
+ { name: 'Third step', component: Step 3 content
},
+ { name: 'Fourth step', component: Step 4 content
},
+ { name: 'Review', component: Review step content
, nextButtonText: 'Finish' }
+ ];
+ const title = 'Wizard in modal example';
+ return (
+
+
+ Show Modal
+
+
+
+ );
+};
diff --git a/packages/react-core/src/components/Wizard/examples/WizardIncrementallyEnabledSteps.tsx b/packages/react-core/src/components/Wizard/examples/WizardIncrementallyEnabledSteps.tsx
new file mode 100644
index 00000000000..f769c9d7455
--- /dev/null
+++ b/packages/react-core/src/components/Wizard/examples/WizardIncrementallyEnabledSteps.tsx
@@ -0,0 +1,61 @@
+import React from 'react';
+import { Wizard, WizardStep } from '@patternfly/react-core';
+
+export const WizardIncrementallyEnabledSteps: React.FunctionComponent = () => {
+ const [stepIdReached, setStepIdReached] = React.useState(1);
+
+ const onNext = ({ id }: WizardStep) => {
+ if (id) {
+ if (typeof id === 'string') {
+ const [, orderIndex] = id.split('-');
+ id = parseInt(orderIndex);
+ }
+ setStepIdReached(stepIdReached < id ? id : stepIdReached);
+ }
+ };
+
+ const closeWizard = () => {
+ // eslint-disable-next-line no-console
+ console.log('close wizard');
+ };
+
+ const steps = [
+ { id: 'incrementallyEnabled-1', name: 'First step', component: Step 1 content
},
+ {
+ id: 'incrementallyEnabled-2',
+ name: 'Second step',
+ component: Step 2 content
,
+ canJumpTo: stepIdReached >= 2
+ },
+ {
+ id: 'incrementallyEnabled-3',
+ name: 'Third step',
+ component: Step 3 content
,
+ canJumpTo: stepIdReached >= 3
+ },
+ {
+ id: 'incrementallyEnabled-4',
+ name: 'Fourth step',
+ component: Step 4 content
,
+ canJumpTo: stepIdReached >= 4
+ },
+ {
+ id: 'incrementallyEnabled-5',
+ name: 'Review',
+ component: Review step content
,
+ nextButtonText: 'Finish',
+ canJumpTo: stepIdReached >= 5
+ }
+ ];
+ const title = 'Incrementally enabled wizard example';
+ return (
+
+ );
+};
diff --git a/packages/react-core/src/components/Wizard/examples/WizardValidateOnButtonPress.tsx b/packages/react-core/src/components/Wizard/examples/WizardValidateOnButtonPress.tsx
new file mode 100644
index 00000000000..d13172d8f61
--- /dev/null
+++ b/packages/react-core/src/components/Wizard/examples/WizardValidateOnButtonPress.tsx
@@ -0,0 +1,204 @@
+import React from 'react';
+import {
+ EmptyState,
+ EmptyStateIcon,
+ EmptyStateBody,
+ EmptyStateSecondaryActions,
+ Title,
+ Form,
+ FormGroup,
+ TextInput,
+ Progress,
+ Button,
+ Wizard,
+ WizardFooter,
+ WizardContextConsumer,
+ Alert
+} from '@patternfly/react-core';
+// eslint-disable-next-line patternfly-react/import-tokens-icons
+import { CogsIcon } from '@patternfly/react-icons';
+
+interface finishedProps {
+ onClose: () => void;
+}
+
+const FinishedStep: React.FunctionComponent = (props: finishedProps) => {
+ const [percent, setPercent] = React.useState(0);
+
+ const tick = () => {
+ setPercent(prevPercent => {
+ if (prevPercent < 100) {
+ return prevPercent + 20;
+ } else {
+ return prevPercent;
+ }
+ });
+ };
+
+ React.useEffect(() => {
+ const interval = setInterval(() => tick(), 1000);
+
+ if (percent >= 100) {
+ clearInterval(interval);
+ }
+
+ return () => clearInterval(interval);
+ }, [percent]);
+
+ return (
+
+
+
+
+ {percent === 100 ? 'Validation complete' : 'Validating credentials'}
+
+
+
+
+
+ Description can be used to further elaborate on the validation step, or give the user a better idea of how
+ long the process will take.
+
+
+
+ Log to console
+
+
+
+
+ );
+};
+
+interface sampleFormProps {
+ formValue: string;
+ isFormValid: boolean;
+ onChange?: (isValid: boolean, value: string) => void;
+}
+
+const SampleForm: React.FunctionComponent = (props: sampleFormProps) => {
+ const [value, setValue] = React.useState(props.formValue);
+ const [isValid, setIsValid] = React.useState(props.isFormValid);
+
+ const handleTextInputChange = (value: string) => {
+ const valid = /^\d+$/.test(value);
+ setValue(value);
+ setIsValid(valid);
+ props.onChange && props.onChange(valid, value);
+ };
+
+ const validated = isValid ? 'default' : 'error';
+
+ return (
+
+ );
+};
+
+export const WizardValidateButtonPress: React.FunctionComponent = () => {
+ const [isFormValid, setIsFormValid] = React.useState(false);
+ const [formValue, setFormValue] = React.useState('Validating on button press');
+ const [stepsValid, setStepsValid] = React.useState(0);
+ const [errorText, setErrorText] = React.useState(false);
+
+ const closeWizard = () => {
+ // eslint-disable-next-line no-console
+ console.log('close wizard');
+ };
+
+ const onFormChange = (isValid: boolean, value: string) => {
+ setIsFormValid(isValid);
+ setFormValue(value);
+ };
+
+ const validateLastStep: (onNext: () => void) => void = onNext => {
+ if (stepsValid !== 1 && !isFormValid) {
+ setErrorText(true);
+ } else {
+ setStepsValid(1);
+ setErrorText(false);
+ onNext();
+ }
+ };
+
+ const steps = [
+ { name: 'First step', component: Step 1 content
},
+ { name: 'Second step', component: Step 2 content
},
+ {
+ name: 'Final Step',
+ component: (
+ <>
+ {errorText && (
+
+ )}
+
+ >
+ )
+ },
+ { name: 'Finish', component: , isFinishedStep: true }
+ ];
+
+ const CustomFooter = (
+
+
+ {({ activeStep, goToStepByName, onNext, onBack, onClose }) => {
+ if (activeStep.name !== 'Final Step') {
+ return (
+ <>
+
+ Forward
+
+
+ Backward
+
+
+ Cancel
+
+ >
+ );
+ }
+ // Final step buttons
+ return (
+ <>
+ validateLastStep(onNext)}>Validate
+ goToStepByName('First step')}>Go to Beginning
+ >
+ );
+ }}
+
+
+ );
+
+ const title = 'Validate on button press wizard example';
+ return (
+
+ );
+};
diff --git a/packages/react-core/src/components/Wizard/examples/WizardWithDrawer.tsx b/packages/react-core/src/components/Wizard/examples/WizardWithDrawer.tsx
new file mode 100644
index 00000000000..9a1e134fa9b
--- /dev/null
+++ b/packages/react-core/src/components/Wizard/examples/WizardWithDrawer.tsx
@@ -0,0 +1,126 @@
+import React from 'react';
+import {
+ Button,
+ DrawerActions,
+ DrawerCloseButton,
+ DrawerColorVariant,
+ DrawerHead,
+ DrawerPanelContent,
+ Wizard
+} from '@patternfly/react-core';
+
+export const WizardWithDrawer: React.FunctionComponent = () => {
+ const [isDrawerExpanded, setIsDrawerExpanded] = React.useState(false);
+
+ const drawerRef = React.useRef(null);
+
+ const onOpenClick = () => {
+ setIsDrawerExpanded(true);
+ };
+
+ const onCloseClick = () => {
+ setIsDrawerExpanded(false);
+ };
+
+ const panel1Content = (
+
+
+
+ drawer-panel-1 content
+
+
+
+
+
+
+ );
+
+ const panel2Content = (
+
+
+
+ drawer-panel-2 content
+
+
+
+
+
+
+ );
+
+ const panel3Content = (
+
+
+
+ drawer-panel-3 content
+
+
+
+
+
+
+ );
+
+ const drawerToggleButton = (
+
+ Open Drawer
+
+ );
+
+ const steps = [
+ {
+ name: 'Information',
+ component: Information step content
,
+ drawerPanelContent: panel1Content,
+ drawerToggleButton
+ },
+ {
+ name: 'Configuration',
+ steps: [
+ {
+ name: 'Substep A',
+ component: Substep A content
,
+ drawerPanelContent: panel2Content,
+ drawerToggleButton
+ },
+ {
+ name: 'Substep B',
+ component: Substep B content
,
+ drawerPanelContent: panel2Content,
+ drawerToggleButton
+ },
+ {
+ name: 'Substep C',
+ component: Substep C content
,
+ drawerPanelContent: panel2Content,
+ drawerToggleButton
+ }
+ ]
+ },
+ {
+ name: 'Additional',
+ component: Additional step content
,
+ drawerPanelContent: panel3Content,
+ drawerToggleButton
+ },
+ {
+ name: 'Review',
+ component: Review step content
,
+ nextButtonText: 'Finish'
+ }
+ ];
+
+ const title = 'Wizard with drawer example';
+
+ return (
+
+
+
+ );
+};