@patternfly/react-core 4.255.1 → 4.256.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dist/esm/components/Card/Card.d.ts +2 -2
- package/dist/esm/components/Card/Card.d.ts.map +1 -1
- package/dist/esm/components/DataList/DataList.d.ts +1 -1
- package/dist/esm/components/DataList/DataList.d.ts.map +1 -1
- package/dist/esm/components/DataList/DataListItem.d.ts +1 -1
- package/dist/esm/components/DataList/DataListItem.d.ts.map +1 -1
- package/dist/esm/components/MultipleFileUpload/MultipleFileUploadStatusItem.d.ts +2 -0
- package/dist/esm/components/MultipleFileUpload/MultipleFileUploadStatusItem.d.ts.map +1 -1
- package/dist/esm/components/MultipleFileUpload/MultipleFileUploadStatusItem.js +7 -1
- package/dist/esm/components/MultipleFileUpload/MultipleFileUploadStatusItem.js.map +1 -1
- package/dist/esm/components/Popover/Popover.d.ts +3 -3
- package/dist/esm/components/Popover/Popover.d.ts.map +1 -1
- package/dist/esm/components/Wizard/Wizard.d.ts +4 -4
- package/dist/esm/components/Wizard/Wizard.d.ts.map +1 -1
- package/dist/esm/components/Wizard/WizardToggle.d.ts +2 -2
- package/dist/esm/components/Wizard/WizardToggle.d.ts.map +1 -1
- package/dist/esm/next/components/Wizard/Wizard.d.ts +1 -3
- package/dist/esm/next/components/Wizard/Wizard.d.ts.map +1 -1
- package/dist/esm/next/components/Wizard/Wizard.js +36 -45
- package/dist/esm/next/components/Wizard/Wizard.js.map +1 -1
- package/dist/esm/next/components/Wizard/WizardBody.d.ts +2 -2
- package/dist/esm/next/components/Wizard/WizardBody.d.ts.map +1 -1
- package/dist/esm/next/components/Wizard/WizardBody.js +2 -2
- package/dist/esm/next/components/Wizard/WizardBody.js.map +1 -1
- package/dist/esm/next/components/Wizard/WizardContext.d.ts +2 -7
- package/dist/esm/next/components/Wizard/WizardContext.d.ts.map +1 -1
- package/dist/esm/next/components/Wizard/WizardContext.js +18 -39
- package/dist/esm/next/components/Wizard/WizardContext.js.map +1 -1
- package/dist/esm/next/components/Wizard/WizardFooter.d.ts +3 -3
- package/dist/esm/next/components/Wizard/WizardFooter.d.ts.map +1 -1
- package/dist/esm/next/components/Wizard/WizardFooter.js +3 -3
- package/dist/esm/next/components/Wizard/WizardFooter.js.map +1 -1
- package/dist/esm/next/components/Wizard/WizardNavInternal.d.ts.map +1 -1
- package/dist/esm/next/components/Wizard/WizardNavInternal.js +12 -12
- package/dist/esm/next/components/Wizard/WizardNavInternal.js.map +1 -1
- package/dist/esm/next/components/Wizard/WizardStep.d.ts +1 -3
- package/dist/esm/next/components/Wizard/WizardStep.d.ts.map +1 -1
- package/dist/esm/next/components/Wizard/WizardStep.js +10 -18
- package/dist/esm/next/components/Wizard/WizardStep.js.map +1 -1
- package/dist/esm/next/components/Wizard/WizardToggle.d.ts +2 -4
- package/dist/esm/next/components/Wizard/WizardToggle.d.ts.map +1 -1
- package/dist/esm/next/components/Wizard/WizardToggle.js +19 -16
- package/dist/esm/next/components/Wizard/WizardToggle.js.map +1 -1
- package/dist/esm/next/components/Wizard/hooks/useWizardFooter.js +3 -3
- package/dist/esm/next/components/Wizard/hooks/useWizardFooter.js.map +1 -1
- package/dist/esm/next/components/Wizard/types.d.ts +5 -3
- package/dist/esm/next/components/Wizard/types.d.ts.map +1 -1
- package/dist/esm/next/components/Wizard/types.js.map +1 -1
- package/dist/esm/next/components/Wizard/utils.d.ts +3 -3
- package/dist/esm/next/components/Wizard/utils.d.ts.map +1 -1
- package/dist/esm/next/components/Wizard/utils.js +14 -11
- package/dist/esm/next/components/Wizard/utils.js.map +1 -1
- package/dist/js/components/Card/Card.d.ts +2 -2
- package/dist/js/components/Card/Card.d.ts.map +1 -1
- package/dist/js/components/DataList/DataList.d.ts +1 -1
- package/dist/js/components/DataList/DataList.d.ts.map +1 -1
- package/dist/js/components/DataList/DataListItem.d.ts +1 -1
- package/dist/js/components/DataList/DataListItem.d.ts.map +1 -1
- package/dist/js/components/MultipleFileUpload/MultipleFileUploadStatusItem.d.ts +2 -0
- package/dist/js/components/MultipleFileUpload/MultipleFileUploadStatusItem.d.ts.map +1 -1
- package/dist/js/components/MultipleFileUpload/MultipleFileUploadStatusItem.js +7 -1
- package/dist/js/components/MultipleFileUpload/MultipleFileUploadStatusItem.js.map +1 -1
- package/dist/js/components/Popover/Popover.d.ts +3 -3
- package/dist/js/components/Popover/Popover.d.ts.map +1 -1
- package/dist/js/components/Wizard/Wizard.d.ts +4 -4
- package/dist/js/components/Wizard/Wizard.d.ts.map +1 -1
- package/dist/js/components/Wizard/WizardToggle.d.ts +2 -2
- package/dist/js/components/Wizard/WizardToggle.d.ts.map +1 -1
- package/dist/js/next/components/Wizard/Wizard.d.ts +1 -3
- package/dist/js/next/components/Wizard/Wizard.d.ts.map +1 -1
- package/dist/js/next/components/Wizard/Wizard.js +36 -45
- package/dist/js/next/components/Wizard/Wizard.js.map +1 -1
- package/dist/js/next/components/Wizard/WizardBody.d.ts +2 -2
- package/dist/js/next/components/Wizard/WizardBody.d.ts.map +1 -1
- package/dist/js/next/components/Wizard/WizardBody.js +2 -2
- package/dist/js/next/components/Wizard/WizardBody.js.map +1 -1
- package/dist/js/next/components/Wizard/WizardContext.d.ts +2 -7
- package/dist/js/next/components/Wizard/WizardContext.d.ts.map +1 -1
- package/dist/js/next/components/Wizard/WizardContext.js +15 -37
- package/dist/js/next/components/Wizard/WizardContext.js.map +1 -1
- package/dist/js/next/components/Wizard/WizardFooter.d.ts +3 -3
- package/dist/js/next/components/Wizard/WizardFooter.d.ts.map +1 -1
- package/dist/js/next/components/Wizard/WizardFooter.js +3 -3
- package/dist/js/next/components/Wizard/WizardFooter.js.map +1 -1
- package/dist/js/next/components/Wizard/WizardNavInternal.d.ts.map +1 -1
- package/dist/js/next/components/Wizard/WizardNavInternal.js +12 -12
- package/dist/js/next/components/Wizard/WizardNavInternal.js.map +1 -1
- package/dist/js/next/components/Wizard/WizardStep.d.ts +1 -3
- package/dist/js/next/components/Wizard/WizardStep.d.ts.map +1 -1
- package/dist/js/next/components/Wizard/WizardStep.js +9 -18
- package/dist/js/next/components/Wizard/WizardStep.js.map +1 -1
- package/dist/js/next/components/Wizard/WizardToggle.d.ts +2 -4
- package/dist/js/next/components/Wizard/WizardToggle.d.ts.map +1 -1
- package/dist/js/next/components/Wizard/WizardToggle.js +18 -16
- package/dist/js/next/components/Wizard/WizardToggle.js.map +1 -1
- package/dist/js/next/components/Wizard/hooks/useWizardFooter.js +3 -3
- package/dist/js/next/components/Wizard/hooks/useWizardFooter.js.map +1 -1
- package/dist/js/next/components/Wizard/types.d.ts +5 -3
- package/dist/js/next/components/Wizard/types.d.ts.map +1 -1
- package/dist/js/next/components/Wizard/types.js.map +1 -1
- package/dist/js/next/components/Wizard/utils.d.ts +3 -3
- package/dist/js/next/components/Wizard/utils.d.ts.map +1 -1
- package/dist/js/next/components/Wizard/utils.js +16 -13
- package/dist/js/next/components/Wizard/utils.js.map +1 -1
- package/dist/umd/react-core.min.css +137 -137
- package/dist/umd/react-core.min.js +1 -1
- package/package.json +2 -2
- package/src/components/AlertGroup/examples/AlertGroup.md +2 -2
- package/src/components/CalendarMonth/examples/CalendarMonth.md +0 -1
- package/src/components/Card/Card.tsx +2 -2
- package/src/components/DataList/DataList.tsx +1 -1
- package/src/components/DataList/DataListItem.tsx +1 -1
- package/src/components/DualListSelector/examples/DualListSelector.md +0 -1
- package/src/components/LabelGroup/examples/LabelGroup.md +2 -3
- package/src/components/Masthead/examples/Masthead.md +0 -1
- package/src/components/Menu/examples/Menu.md +1 -1
- package/src/components/MenuToggle/examples/MenuToggle.md +0 -1
- package/src/components/MultipleFileUpload/MultipleFileUploadStatusItem.tsx +10 -0
- package/src/components/MultipleFileUpload/__tests__/MultipleFileUploadStatusItem.test.tsx +33 -1
- package/src/components/MultipleFileUpload/__tests__/__snapshots__/MultipleFileUploadStatusItem.test.tsx.snap +269 -3
- package/src/components/MultipleFileUpload/examples/MultipleFileUpload.md +0 -1
- package/src/components/NotificationDrawer/examples/NotificationDrawer.md +0 -1
- package/src/components/Panel/examples/Panel.md +0 -1
- package/src/components/Popover/Popover.tsx +3 -3
- package/src/components/Popover/examples/Popover.md +2 -2
- package/src/components/Select/examples/Select.md +2 -2
- package/src/components/Slider/examples/Slider.md +0 -1
- package/src/components/TextArea/examples/TextArea.md +1 -1
- package/src/components/TextInput/examples/TextInput.md +1 -1
- package/src/components/TreeView/examples/TreeView.md +0 -1
- package/src/components/Wizard/Wizard.tsx +4 -4
- package/src/components/Wizard/WizardToggle.tsx +2 -2
- package/src/components/Wizard/examples/Wizard.md +12 -8
- package/src/demos/MultipleFileUploadDemos.md +0 -1
- package/src/demos/NotificationDrawer/NotificationDrawer.md +0 -1
- package/src/next/components/Wizard/Wizard.tsx +35 -54
- package/src/next/components/Wizard/WizardBody.tsx +3 -3
- package/src/next/components/Wizard/WizardContext.tsx +29 -61
- package/src/next/components/Wizard/WizardFooter.tsx +6 -6
- package/src/next/components/Wizard/WizardNavInternal.tsx +18 -17
- package/src/next/components/Wizard/WizardStep.tsx +19 -30
- package/src/next/components/Wizard/WizardToggle.tsx +22 -24
- package/src/next/components/Wizard/__tests__/Wizard.test.tsx +1 -21
- package/src/next/components/Wizard/__tests__/WizardBody.test.tsx +2 -2
- package/src/next/components/Wizard/__tests__/WizardFooter.test.tsx +5 -5
- package/src/next/components/Wizard/__tests__/WizardStep.test.tsx +22 -76
- package/src/next/components/Wizard/__tests__/WizardToggle.test.tsx +7 -11
- package/src/next/components/Wizard/__tests__/utils.test.tsx +3 -3
- package/src/next/components/Wizard/examples/Wizard.md +4 -4
- package/src/next/components/Wizard/examples/WizardCustomNav.tsx +4 -4
- package/src/next/components/Wizard/examples/WizardKitchenSink.tsx +74 -85
- package/src/next/components/Wizard/hooks/__tests__/useWizardFooter.test.tsx +4 -4
- package/src/next/components/Wizard/hooks/useWizardFooter.tsx +3 -3
- package/src/next/components/Wizard/types.tsx +5 -3
- package/src/next/components/Wizard/utils.ts +35 -25
|
@@ -3,7 +3,6 @@ id: Tree view
|
|
|
3
3
|
section: components
|
|
4
4
|
cssPrefix: pf-c-tree-view
|
|
5
5
|
propComponents: ['TreeView', 'TreeViewDataItem', 'TreeViewSearch']
|
|
6
|
-
beta: true
|
|
7
6
|
---
|
|
8
7
|
|
|
9
8
|
import { FolderIcon, FolderOpenIcon, EllipsisVIcon, ClipboardIcon, HamburgerIcon } from '@patternfly/react-icons';
|
|
@@ -18,9 +18,9 @@ export interface WizardStep {
|
|
|
18
18
|
name: React.ReactNode;
|
|
19
19
|
/** The component to render in the main body */
|
|
20
20
|
component?: any;
|
|
21
|
-
/**
|
|
21
|
+
/** The content to render in the drawer panel (use when hasDrawer prop is set on the wizard). */
|
|
22
22
|
drawerPanelContent?: any;
|
|
23
|
-
/**
|
|
23
|
+
/** Custom drawer toggle button that opens the drawer. */
|
|
24
24
|
drawerToggleButton?: React.ReactNode;
|
|
25
25
|
/** Setting to true hides the side nav and footer */
|
|
26
26
|
isFinishedStep?: boolean;
|
|
@@ -108,9 +108,9 @@ export interface WizardProps extends React.HTMLProps<HTMLDivElement> {
|
|
|
108
108
|
isNavExpandable?: boolean;
|
|
109
109
|
/** Callback function to signal the current step in the wizard */
|
|
110
110
|
onCurrentStepChanged?: (step: WizardStep) => void;
|
|
111
|
-
/**
|
|
111
|
+
/** Flag indicating the wizard has a drawer for at least one of the wizard steps */
|
|
112
112
|
hasDrawer?: boolean;
|
|
113
|
-
/**
|
|
113
|
+
/** Flag indicating the wizard drawer is expanded */
|
|
114
114
|
isDrawerExpanded?: boolean;
|
|
115
115
|
}
|
|
116
116
|
|
|
@@ -29,9 +29,9 @@ export interface WizardToggleProps {
|
|
|
29
29
|
mainAriaLabel?: string;
|
|
30
30
|
/** If the wizard is in-page */
|
|
31
31
|
isInPage?: boolean;
|
|
32
|
-
/**
|
|
32
|
+
/** Flag indicating the wizard has a drawer for at least one of the wizard steps */
|
|
33
33
|
hasDrawer?: boolean;
|
|
34
|
-
/**
|
|
34
|
+
/** Flag indicating the wizard drawer is expanded */
|
|
35
35
|
isDrawerExpanded?: boolean;
|
|
36
36
|
}
|
|
37
37
|
|
|
@@ -134,8 +134,10 @@ class IncrementallyEnabledStepsWizard extends React.Component {
|
|
|
134
134
|
stepIdReached: 1
|
|
135
135
|
};
|
|
136
136
|
this.onNext = ({ id }) => {
|
|
137
|
+
const [, orderIndex] = id.split('-');
|
|
138
|
+
|
|
137
139
|
this.setState({
|
|
138
|
-
stepIdReached: this.state.stepIdReached <
|
|
140
|
+
stepIdReached: this.state.stepIdReached < orderIndex ? orderIndex : this.state.stepIdReached
|
|
139
141
|
});
|
|
140
142
|
};
|
|
141
143
|
this.closeWizard = () => {
|
|
@@ -147,27 +149,27 @@ class IncrementallyEnabledStepsWizard extends React.Component {
|
|
|
147
149
|
const { stepIdReached } = this.state;
|
|
148
150
|
|
|
149
151
|
const steps = [
|
|
150
|
-
{ id: '
|
|
152
|
+
{ id: 'incrementallyEnabled-1', name: 'First step', component: <p>Step 1 content</p> },
|
|
151
153
|
{
|
|
152
|
-
id: '
|
|
154
|
+
id: 'incrementallyEnabled-2',
|
|
153
155
|
name: 'Second step',
|
|
154
156
|
component: <p>Step 2 content</p>,
|
|
155
157
|
canJumpTo: stepIdReached >= 2
|
|
156
158
|
},
|
|
157
159
|
{
|
|
158
|
-
id: '
|
|
160
|
+
id: 'incrementallyEnabled-3',
|
|
159
161
|
name: 'Third step',
|
|
160
162
|
component: <p>Step 3 content</p>,
|
|
161
163
|
canJumpTo: stepIdReached >= 3
|
|
162
164
|
},
|
|
163
165
|
{
|
|
164
|
-
id: '
|
|
166
|
+
id: 'incrementallyEnabled-4',
|
|
165
167
|
name: 'Fourth step',
|
|
166
168
|
component: <p>Step 4 content</p>,
|
|
167
169
|
canJumpTo: stepIdReached >= 4
|
|
168
170
|
},
|
|
169
171
|
{
|
|
170
|
-
id: '
|
|
172
|
+
id: 'incrementallyEnabled-5',
|
|
171
173
|
name: 'Review',
|
|
172
174
|
component: <p>Review step content</p>,
|
|
173
175
|
nextButtonText: 'Finish',
|
|
@@ -312,8 +314,10 @@ class ValidationWizard extends React.Component {
|
|
|
312
314
|
|
|
313
315
|
this.onNext = ({ id, name }, { prevId, prevName }) => {
|
|
314
316
|
console.log(`current id: ${id}, current name: ${name}, previous id: ${prevId}, previous name: ${prevName}`);
|
|
317
|
+
const [, orderIndex] = id.split('-');
|
|
318
|
+
|
|
315
319
|
this.setState({
|
|
316
|
-
stepIdReached: this.state.stepIdReached <
|
|
320
|
+
stepIdReached: this.state.stepIdReached < orderIndex ? orderIndex : this.state.stepIdReached
|
|
317
321
|
});
|
|
318
322
|
this.areAllStepsValid();
|
|
319
323
|
};
|
|
@@ -897,7 +901,7 @@ class WizardInModal extends React.Component {
|
|
|
897
901
|
|
|
898
902
|
### Wizard with drawer
|
|
899
903
|
|
|
900
|
-
```js
|
|
904
|
+
```js
|
|
901
905
|
import React from 'react';
|
|
902
906
|
import {
|
|
903
907
|
Button,
|
|
@@ -42,8 +42,6 @@ export interface WizardProps extends React.HTMLProps<HTMLDivElement> {
|
|
|
42
42
|
height?: number | string;
|
|
43
43
|
/** Disables navigation items that haven't been visited. Defaults to false */
|
|
44
44
|
isStepVisitRequired?: boolean;
|
|
45
|
-
/** Flag to unmount inactive steps instead of hiding. Defaults to true */
|
|
46
|
-
hasUnmountedSteps?: boolean;
|
|
47
45
|
/** Callback function when a step in the navigation is clicked */
|
|
48
46
|
onNavByIndex?: WizardNavStepFunction;
|
|
49
47
|
/** Callback function after next button is clicked */
|
|
@@ -66,7 +64,6 @@ export const Wizard = ({
|
|
|
66
64
|
nav,
|
|
67
65
|
startIndex = 1,
|
|
68
66
|
isStepVisitRequired = false,
|
|
69
|
-
hasUnmountedSteps = true,
|
|
70
67
|
onNavByIndex,
|
|
71
68
|
onNext,
|
|
72
69
|
onBack,
|
|
@@ -74,42 +71,37 @@ export const Wizard = ({
|
|
|
74
71
|
onClose,
|
|
75
72
|
...wrapperProps
|
|
76
73
|
}: WizardProps) => {
|
|
77
|
-
const [
|
|
74
|
+
const [activeStepIndex, setActiveStepIndex] = React.useState(startIndex);
|
|
78
75
|
const initialSteps = buildSteps(children);
|
|
79
76
|
|
|
80
77
|
const goToNextStep = (steps: WizardControlStep[] = initialSteps) => {
|
|
81
|
-
const newStepIndex =
|
|
82
|
-
|
|
78
|
+
const newStepIndex = steps.find(step => step.index > activeStepIndex && !step.isHidden && !isWizardParentStep(step))
|
|
79
|
+
?.index;
|
|
83
80
|
|
|
84
|
-
if (
|
|
81
|
+
if (activeStepIndex >= steps.length || !newStepIndex) {
|
|
85
82
|
return onSave ? onSave() : onClose?.();
|
|
86
83
|
}
|
|
87
84
|
|
|
88
|
-
const currStep = isWizardParentStep(steps[
|
|
89
|
-
|
|
90
|
-
: steps[currentStepIndex];
|
|
91
|
-
const prevStep = steps[currentStepIndex - 1];
|
|
92
|
-
|
|
93
|
-
setCurrentStepIndex(newStepIndex);
|
|
85
|
+
const currStep = isWizardParentStep(steps[activeStepIndex]) ? steps[activeStepIndex + 1] : steps[activeStepIndex];
|
|
86
|
+
const prevStep = steps[activeStepIndex - 1];
|
|
94
87
|
|
|
95
|
-
|
|
88
|
+
setActiveStepIndex(newStepIndex);
|
|
89
|
+
return onNext?.(normalizeNavStep(currStep), normalizeNavStep(prevStep));
|
|
96
90
|
};
|
|
97
91
|
|
|
98
92
|
const goToPrevStep = (steps: WizardControlStep[] = initialSteps) => {
|
|
99
93
|
const newStepIndex =
|
|
100
94
|
findLastIndex(
|
|
101
95
|
steps,
|
|
102
|
-
(step: WizardControlStep
|
|
103
|
-
index + 1 < currentStepIndex && !step.isHidden && !isWizardParentStep(step)
|
|
96
|
+
(step: WizardControlStep) => step.index < activeStepIndex && !step.isHidden && !isWizardParentStep(step)
|
|
104
97
|
) + 1;
|
|
105
|
-
const currStep = isWizardParentStep(steps[
|
|
106
|
-
? steps[
|
|
107
|
-
: steps[
|
|
108
|
-
const prevStep = steps[
|
|
109
|
-
|
|
110
|
-
setCurrentStepIndex(newStepIndex);
|
|
98
|
+
const currStep = isWizardParentStep(steps[activeStepIndex - 2])
|
|
99
|
+
? steps[activeStepIndex - 3]
|
|
100
|
+
: steps[activeStepIndex - 2];
|
|
101
|
+
const prevStep = steps[activeStepIndex - 1];
|
|
111
102
|
|
|
112
|
-
|
|
103
|
+
setActiveStepIndex(newStepIndex);
|
|
104
|
+
return onBack?.(normalizeNavStep(currStep), normalizeNavStep(prevStep));
|
|
113
105
|
};
|
|
114
106
|
|
|
115
107
|
const goToStepByIndex = (steps: WizardControlStep[] = initialSteps, index: number) => {
|
|
@@ -120,46 +112,40 @@ export const Wizard = ({
|
|
|
120
112
|
index = 1;
|
|
121
113
|
} else if (index > lastStepIndex) {
|
|
122
114
|
index = lastStepIndex;
|
|
123
|
-
} else if (steps[index - 1].isHidden) {
|
|
124
|
-
// eslint-disable-next-line no-console
|
|
125
|
-
console.error('Wizard: Unable to navigate to hidden step.');
|
|
126
115
|
}
|
|
127
116
|
|
|
128
117
|
const currStep = steps[index - 1];
|
|
129
|
-
const prevStep = steps[
|
|
130
|
-
setCurrentStepIndex(index);
|
|
118
|
+
const prevStep = steps[activeStepIndex - 1];
|
|
131
119
|
|
|
132
|
-
|
|
120
|
+
setActiveStepIndex(index);
|
|
121
|
+
return onNavByIndex?.(normalizeNavStep(currStep), normalizeNavStep(prevStep));
|
|
133
122
|
};
|
|
134
123
|
|
|
135
124
|
const goToStepById = (steps: WizardControlStep[] = initialSteps, id: number | string) => {
|
|
136
|
-
const
|
|
125
|
+
const step = steps.find(step => step.id === id);
|
|
126
|
+
const stepIndex = step?.index;
|
|
127
|
+
const lastStepIndex = steps.length + 1;
|
|
137
128
|
|
|
138
|
-
if (stepIndex > 0 && stepIndex <
|
|
139
|
-
|
|
140
|
-
} else {
|
|
141
|
-
// eslint-disable-next-line no-console
|
|
142
|
-
console.error(`Wizard: Unable to navigate to step with id: ${id}.`);
|
|
129
|
+
if (stepIndex > 0 && stepIndex < lastStepIndex && !step.isHidden) {
|
|
130
|
+
setActiveStepIndex(stepIndex);
|
|
143
131
|
}
|
|
144
132
|
};
|
|
145
133
|
|
|
146
134
|
const goToStepByName = (steps: WizardControlStep[] = initialSteps, name: string) => {
|
|
147
|
-
const
|
|
135
|
+
const step = steps.find(step => step.name === name);
|
|
136
|
+
const stepIndex = step?.index;
|
|
137
|
+
const lastStepIndex = steps.length + 1;
|
|
148
138
|
|
|
149
|
-
if (stepIndex > 0 && stepIndex <
|
|
150
|
-
|
|
151
|
-
} else {
|
|
152
|
-
// eslint-disable-next-line no-console
|
|
153
|
-
console.error(`Wizard: Unable to navigate to step with name: ${name}.`);
|
|
139
|
+
if (stepIndex > 0 && stepIndex < lastStepIndex && !step.isHidden) {
|
|
140
|
+
setActiveStepIndex(stepIndex);
|
|
154
141
|
}
|
|
155
142
|
};
|
|
156
143
|
|
|
157
144
|
return (
|
|
158
145
|
<WizardContextProvider
|
|
159
146
|
steps={initialSteps}
|
|
160
|
-
|
|
147
|
+
activeStepIndex={activeStepIndex}
|
|
161
148
|
footer={footer}
|
|
162
|
-
isStepVisitRequired={isStepVisitRequired}
|
|
163
149
|
onNext={goToNextStep}
|
|
164
150
|
onBack={goToPrevStep}
|
|
165
151
|
onClose={onClose}
|
|
@@ -176,37 +162,32 @@ export const Wizard = ({
|
|
|
176
162
|
{...wrapperProps}
|
|
177
163
|
>
|
|
178
164
|
{header}
|
|
179
|
-
<WizardInternal nav={nav}
|
|
165
|
+
<WizardInternal nav={nav} isStepVisitRequired={isStepVisitRequired} />
|
|
180
166
|
</div>
|
|
181
167
|
</WizardContextProvider>
|
|
182
168
|
);
|
|
183
169
|
};
|
|
184
170
|
|
|
185
|
-
const WizardInternal = ({
|
|
186
|
-
|
|
187
|
-
hasUnmountedSteps,
|
|
188
|
-
isStepVisitRequired
|
|
189
|
-
}: Pick<WizardProps, 'nav' | 'hasUnmountedSteps' | 'isStepVisitRequired'>) => {
|
|
190
|
-
const { currentStep, steps, footer, goToStepByIndex } = useWizardContext();
|
|
171
|
+
const WizardInternal = ({ nav, isStepVisitRequired }: Pick<WizardProps, 'nav' | 'isStepVisitRequired'>) => {
|
|
172
|
+
const { activeStep, steps, footer, goToStepByIndex } = useWizardContext();
|
|
191
173
|
const [isNavExpanded, setIsNavExpanded] = React.useState(false);
|
|
192
174
|
|
|
193
175
|
const wizardNav = React.useMemo(() => {
|
|
194
176
|
if (isCustomWizardNav(nav)) {
|
|
195
|
-
return typeof nav === 'function' ? nav(isNavExpanded, steps,
|
|
177
|
+
return typeof nav === 'function' ? nav(isNavExpanded, steps, activeStep, goToStepByIndex) : nav;
|
|
196
178
|
}
|
|
197
179
|
|
|
198
180
|
return <WizardNavInternal nav={nav} isNavExpanded={isNavExpanded} isStepVisitRequired={isStepVisitRequired} />;
|
|
199
|
-
}, [
|
|
181
|
+
}, [activeStep, isStepVisitRequired, goToStepByIndex, isNavExpanded, nav, steps]);
|
|
200
182
|
|
|
201
183
|
return (
|
|
202
184
|
<WizardToggle
|
|
203
185
|
nav={wizardNav}
|
|
204
186
|
footer={footer}
|
|
205
187
|
steps={steps}
|
|
206
|
-
|
|
188
|
+
activeStep={activeStep}
|
|
207
189
|
isNavExpanded={isNavExpanded}
|
|
208
190
|
toggleNavExpanded={() => setIsNavExpanded(prevIsExpanded => !prevIsExpanded)}
|
|
209
|
-
hasUnmountedSteps={hasUnmountedSteps}
|
|
210
191
|
/>
|
|
211
192
|
);
|
|
212
193
|
};
|
|
@@ -10,7 +10,7 @@ import { css } from '@patternfly/react-styles';
|
|
|
10
10
|
export interface WizardBodyProps {
|
|
11
11
|
children: React.ReactNode | React.ReactNode[];
|
|
12
12
|
/** Set to true to remove the default body padding */
|
|
13
|
-
|
|
13
|
+
hasNoPadding?: boolean;
|
|
14
14
|
/** An aria-label to use for the wrapper element */
|
|
15
15
|
'aria-label'?: string;
|
|
16
16
|
/** Sets the aria-labelledby attribute for the wrapper element */
|
|
@@ -21,13 +21,13 @@ export interface WizardBodyProps {
|
|
|
21
21
|
|
|
22
22
|
export const WizardBody = ({
|
|
23
23
|
children,
|
|
24
|
-
|
|
24
|
+
hasNoPadding = false,
|
|
25
25
|
'aria-label': ariaLabel,
|
|
26
26
|
'aria-labelledby': ariaLabelledBy,
|
|
27
27
|
component: WrapperComponent = 'div'
|
|
28
28
|
}: WizardBodyProps) => (
|
|
29
29
|
<WrapperComponent aria-label={ariaLabel} aria-labelledby={ariaLabelledBy} className={css(styles.wizardMain)}>
|
|
30
|
-
<div className={css(styles.wizardMainBody,
|
|
30
|
+
<div className={css(styles.wizardMainBody, hasNoPadding && styles.modifiers.noPadding)}>{children}</div>
|
|
31
31
|
</WrapperComponent>
|
|
32
32
|
);
|
|
33
33
|
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
-
import { isCustomWizardFooter,
|
|
4
|
-
import {
|
|
3
|
+
import { isCustomWizardFooter, WizardControlStep, WizardFooterType } from './types';
|
|
4
|
+
import { getActiveStep } from './utils';
|
|
5
5
|
import { WizardFooter, WizardFooterProps } from './WizardFooter';
|
|
6
6
|
|
|
7
7
|
export interface WizardContextProps {
|
|
8
8
|
/** List of steps */
|
|
9
9
|
steps: WizardControlStep[];
|
|
10
10
|
/** Current step */
|
|
11
|
-
|
|
12
|
-
/** Current step index */
|
|
13
|
-
currentStepIndex: number;
|
|
11
|
+
activeStep: WizardControlStep;
|
|
14
12
|
/** Footer element */
|
|
15
13
|
footer: React.ReactElement;
|
|
16
14
|
/** Navigate to the next step */
|
|
@@ -31,17 +29,14 @@ export interface WizardContextProps {
|
|
|
31
29
|
getStep: (stepId: number | string) => WizardControlStep;
|
|
32
30
|
/** Set step by ID */
|
|
33
31
|
setStep: (step: Pick<WizardControlStep, 'id'> & Partial<WizardControlStep>) => void;
|
|
34
|
-
/** Toggle step visibility by ID */
|
|
35
|
-
toggleStep: (stepId: number | string, isHidden: boolean) => void;
|
|
36
32
|
}
|
|
37
33
|
|
|
38
34
|
export const WizardContext = React.createContext({} as WizardContextProps);
|
|
39
35
|
|
|
40
36
|
export interface WizardContextProviderProps {
|
|
41
37
|
steps: WizardControlStep[];
|
|
42
|
-
|
|
38
|
+
activeStepIndex: number;
|
|
43
39
|
footer: WizardFooterType;
|
|
44
|
-
isStepVisitRequired: boolean;
|
|
45
40
|
children: React.ReactElement;
|
|
46
41
|
onNext(steps: WizardControlStep[]): void;
|
|
47
42
|
onBack(steps: WizardControlStep[]): void;
|
|
@@ -54,8 +49,7 @@ export interface WizardContextProviderProps {
|
|
|
54
49
|
export const WizardContextProvider: React.FunctionComponent<WizardContextProviderProps> = ({
|
|
55
50
|
steps: initialSteps,
|
|
56
51
|
footer: initialFooter,
|
|
57
|
-
|
|
58
|
-
isStepVisitRequired,
|
|
52
|
+
activeStepIndex,
|
|
59
53
|
children,
|
|
60
54
|
onNext,
|
|
61
55
|
onBack,
|
|
@@ -64,43 +58,58 @@ export const WizardContextProvider: React.FunctionComponent<WizardContextProvide
|
|
|
64
58
|
goToStepByName,
|
|
65
59
|
goToStepByIndex
|
|
66
60
|
}) => {
|
|
67
|
-
const [
|
|
61
|
+
const [currentSteps, setCurrentSteps] = React.useState(initialSteps);
|
|
68
62
|
const [currentFooter, setCurrentFooter] = React.useState(
|
|
69
63
|
typeof initialFooter !== 'function' ? initialFooter : undefined
|
|
70
64
|
);
|
|
71
|
-
|
|
65
|
+
|
|
66
|
+
// Combined initial and current state steps
|
|
67
|
+
const steps = React.useMemo(
|
|
68
|
+
() =>
|
|
69
|
+
currentSteps.map((currentStepProps, index) => {
|
|
70
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
71
|
+
const { isVisited, ...initialStepProps } = initialSteps[index];
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
...currentStepProps,
|
|
75
|
+
...initialStepProps
|
|
76
|
+
};
|
|
77
|
+
}),
|
|
78
|
+
[initialSteps, currentSteps]
|
|
79
|
+
);
|
|
80
|
+
const activeStep = getActiveStep(steps, activeStepIndex);
|
|
72
81
|
|
|
73
82
|
const goToNextStep = React.useCallback(() => onNext(steps), [onNext, steps]);
|
|
74
83
|
const goToPrevStep = React.useCallback(() => onBack(steps), [onBack, steps]);
|
|
75
84
|
|
|
76
85
|
const footer = React.useMemo(() => {
|
|
77
|
-
const wizardFooter = currentFooter || initialFooter;
|
|
86
|
+
const wizardFooter = activeStep?.footer || currentFooter || initialFooter;
|
|
78
87
|
|
|
79
88
|
if (isCustomWizardFooter(wizardFooter)) {
|
|
80
89
|
const customFooter = wizardFooter;
|
|
81
90
|
|
|
82
91
|
return typeof customFooter === 'function'
|
|
83
|
-
? customFooter(
|
|
92
|
+
? customFooter(activeStep, goToNextStep, goToPrevStep, onClose)
|
|
84
93
|
: customFooter;
|
|
85
94
|
}
|
|
86
95
|
|
|
87
96
|
return (
|
|
88
97
|
<WizardFooter
|
|
89
|
-
|
|
98
|
+
activeStep={activeStep}
|
|
90
99
|
onNext={goToNextStep}
|
|
91
100
|
onBack={goToPrevStep}
|
|
92
101
|
onClose={onClose}
|
|
93
|
-
isBackDisabled={
|
|
102
|
+
isBackDisabled={activeStep?.id === steps[0]?.id}
|
|
94
103
|
{...wizardFooter}
|
|
95
104
|
/>
|
|
96
105
|
);
|
|
97
|
-
}, [currentFooter, initialFooter,
|
|
106
|
+
}, [currentFooter, initialFooter, activeStep, goToNextStep, goToPrevStep, onClose, steps]);
|
|
98
107
|
|
|
99
108
|
const getStep = React.useCallback((stepId: string | number) => steps.find(step => step.id === stepId), [steps]);
|
|
100
109
|
|
|
101
110
|
const setStep = React.useCallback(
|
|
102
111
|
(step: Pick<WizardControlStep, 'id'> & Partial<WizardControlStep>) =>
|
|
103
|
-
|
|
112
|
+
setCurrentSteps(prevSteps =>
|
|
104
113
|
prevSteps.map(prevStep => {
|
|
105
114
|
if (prevStep.id === step.id) {
|
|
106
115
|
return { ...prevStep, ...step };
|
|
@@ -112,56 +121,15 @@ export const WizardContextProvider: React.FunctionComponent<WizardContextProvide
|
|
|
112
121
|
[]
|
|
113
122
|
);
|
|
114
123
|
|
|
115
|
-
const toggleStep = React.useCallback(
|
|
116
|
-
(stepId: string | number, isHidden: boolean) =>
|
|
117
|
-
setSteps(prevSteps => {
|
|
118
|
-
let stepToHide: WizardControlStep;
|
|
119
|
-
|
|
120
|
-
return prevSteps.map(prevStep => {
|
|
121
|
-
if (prevStep.id === stepId) {
|
|
122
|
-
// Don't hide the currently active step or its parent (if a sub-step).
|
|
123
|
-
if (
|
|
124
|
-
isHidden &&
|
|
125
|
-
(currentStep.id === prevStep.id ||
|
|
126
|
-
(isWizardParentStep(prevStep) && prevStep.subStepIds.includes(currentStep.id)))
|
|
127
|
-
) {
|
|
128
|
-
// eslint-disable-next-line no-console
|
|
129
|
-
console.error('Wizard: Unable to hide the current step or its parent.');
|
|
130
|
-
return prevStep;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
stepToHide = { ...prevStep, isHidden };
|
|
134
|
-
return stepToHide;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// When isStepVisitRequired is enabled, if the step was previously hidden and not visited yet,
|
|
138
|
-
// when it is shown, all steps beyond it should be disabled to ensure it is visited.
|
|
139
|
-
if (
|
|
140
|
-
isStepVisitRequired &&
|
|
141
|
-
stepToHide?.isHidden === false &&
|
|
142
|
-
!stepToHide?.isVisited &&
|
|
143
|
-
prevSteps.indexOf(stepToHide) < prevSteps.indexOf(prevStep)
|
|
144
|
-
) {
|
|
145
|
-
return { ...prevStep, isVisited: false };
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
return prevStep;
|
|
149
|
-
});
|
|
150
|
-
}),
|
|
151
|
-
[currentStep.id, isStepVisitRequired]
|
|
152
|
-
);
|
|
153
|
-
|
|
154
124
|
return (
|
|
155
125
|
<WizardContext.Provider
|
|
156
126
|
value={{
|
|
157
127
|
steps,
|
|
158
|
-
|
|
159
|
-
currentStepIndex,
|
|
128
|
+
activeStep,
|
|
160
129
|
footer,
|
|
161
130
|
onClose,
|
|
162
131
|
getStep,
|
|
163
132
|
setStep,
|
|
164
|
-
toggleStep,
|
|
165
133
|
setFooter: setCurrentFooter,
|
|
166
134
|
onNext: goToNextStep,
|
|
167
135
|
onBack: goToPrevStep,
|
|
@@ -11,8 +11,8 @@ import { isCustomWizardFooter, WizardControlStep, WizardNavStepFunction } from '
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
export interface WizardFooterProps {
|
|
14
|
-
/** The
|
|
15
|
-
|
|
14
|
+
/** The active step */
|
|
15
|
+
activeStep: WizardControlStep;
|
|
16
16
|
/** Next button callback */
|
|
17
17
|
onNext: () => WizardNavStepFunction | void;
|
|
18
18
|
/** Back button callback */
|
|
@@ -43,9 +43,9 @@ export const WizardFooterWrapper = ({ children }: WizardFooterWrapperProps) => (
|
|
|
43
43
|
<footer className={css(styles.wizardFooter)}>{children}</footer>
|
|
44
44
|
);
|
|
45
45
|
|
|
46
|
-
export const WizardFooter = ({
|
|
47
|
-
const
|
|
48
|
-
return <InternalWizardFooter {...internalProps} {...
|
|
46
|
+
export const WizardFooter = ({ activeStep, ...internalProps }: WizardFooterProps) => {
|
|
47
|
+
const activeStepFooter = !isCustomWizardFooter(activeStep.footer) && activeStep.footer;
|
|
48
|
+
return <InternalWizardFooter {...internalProps} {...activeStepFooter} />;
|
|
49
49
|
};
|
|
50
50
|
|
|
51
51
|
const InternalWizardFooter = ({
|
|
@@ -59,7 +59,7 @@ const InternalWizardFooter = ({
|
|
|
59
59
|
nextButtonText = 'Next',
|
|
60
60
|
backButtonText = 'Back',
|
|
61
61
|
cancelButtonText = 'Cancel'
|
|
62
|
-
}: Omit<WizardFooterProps, '
|
|
62
|
+
}: Omit<WizardFooterProps, 'activeStep'>) => (
|
|
63
63
|
<WizardFooterWrapper>
|
|
64
64
|
<Button variant={ButtonVariant.primary} type="submit" onClick={onNext} isDisabled={isNextDisabled}>
|
|
65
65
|
{nextButtonText}
|
|
@@ -17,7 +17,7 @@ interface WizardNavInternalProps extends Pick<WizardProps, 'isStepVisitRequired'
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export const WizardNavInternal = ({ nav, isStepVisitRequired, isNavExpanded }: WizardNavInternalProps) => {
|
|
20
|
-
const {
|
|
20
|
+
const { activeStep, steps, goToStepByIndex } = useWizardContext();
|
|
21
21
|
|
|
22
22
|
const wizardNavProps: WizardNavProps = {
|
|
23
23
|
isExpanded: isNavExpanded,
|
|
@@ -29,27 +29,28 @@ export const WizardNavInternal = ({ nav, isStepVisitRequired, isNavExpanded }: W
|
|
|
29
29
|
|
|
30
30
|
return (
|
|
31
31
|
<WizardNav {...wizardNavProps}>
|
|
32
|
-
{steps.map((step,
|
|
33
|
-
const
|
|
32
|
+
{steps.map((step, stepIndex) => {
|
|
33
|
+
const hasVisitedNextStep = steps.some(step => step.index > stepIndex + 1 && step.isVisited);
|
|
34
|
+
const isStepDisabled = step.isDisabled || (isStepVisitRequired && !step.isVisited && !hasVisitedNextStep);
|
|
34
35
|
const customStepNavItem = isCustomWizardNavItem(step.navItem) && (
|
|
35
36
|
<React.Fragment key={step.id}>
|
|
36
|
-
{typeof step.navItem === 'function'
|
|
37
|
-
? step.navItem(step, currentStep, steps, goToStepByIndex)
|
|
38
|
-
: step.navItem}
|
|
37
|
+
{typeof step.navItem === 'function' ? step.navItem(step, activeStep, steps, goToStepByIndex) : step.navItem}
|
|
39
38
|
</React.Fragment>
|
|
40
39
|
);
|
|
41
40
|
|
|
42
41
|
if (isWizardParentStep(step) && !step.isHidden) {
|
|
43
|
-
let firstSubStepIndex;
|
|
42
|
+
let firstSubStepIndex: number;
|
|
44
43
|
let hasActiveChild = false;
|
|
45
44
|
|
|
46
45
|
const subNavItems = step.subStepIds?.map((subStepId, subStepIndex) => {
|
|
47
46
|
const subStep = steps.find(step => step.id === subStepId);
|
|
48
|
-
const
|
|
47
|
+
const hasVisitedNextStep = steps.some(step => step.index > subStep.index && step.isVisited);
|
|
48
|
+
const isSubStepDisabled =
|
|
49
|
+
subStep.isDisabled || (isStepVisitRequired && !subStep.isVisited && !hasVisitedNextStep);
|
|
49
50
|
const customSubStepNavItem = isCustomWizardNavItem(subStep.navItem) && (
|
|
50
51
|
<React.Fragment key={subStep.id}>
|
|
51
52
|
{typeof subStep.navItem === 'function'
|
|
52
|
-
? subStep.navItem(subStep,
|
|
53
|
+
? subStep.navItem(subStep, activeStep, steps, goToStepByIndex)
|
|
53
54
|
: subStep.navItem}
|
|
54
55
|
</React.Fragment>
|
|
55
56
|
);
|
|
@@ -61,11 +62,11 @@ export const WizardNavInternal = ({ nav, isStepVisitRequired, isNavExpanded }: W
|
|
|
61
62
|
|
|
62
63
|
// Store the first sub-step index so that when its parent is clicked, the first sub-step is focused
|
|
63
64
|
if (subStepIndex === 0) {
|
|
64
|
-
firstSubStepIndex =
|
|
65
|
+
firstSubStepIndex = subStep.index;
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
// When a sub-step is active, use this flag to set the parent step as active (isCurrent)
|
|
68
|
-
if (
|
|
69
|
+
if (activeStep?.id === subStep.id) {
|
|
69
70
|
hasActiveChild = true;
|
|
70
71
|
}
|
|
71
72
|
|
|
@@ -75,10 +76,10 @@ export const WizardNavInternal = ({ nav, isStepVisitRequired, isNavExpanded }: W
|
|
|
75
76
|
key={subStep.id}
|
|
76
77
|
id={subStep.id}
|
|
77
78
|
content={subStep.name}
|
|
78
|
-
isCurrent={
|
|
79
|
-
isDisabled={
|
|
79
|
+
isCurrent={activeStep?.id === subStep.id}
|
|
80
|
+
isDisabled={isSubStepDisabled}
|
|
80
81
|
isVisited={subStep.isVisited}
|
|
81
|
-
stepIndex={
|
|
82
|
+
stepIndex={subStep.index}
|
|
82
83
|
onNavItemClick={goToStepByIndex}
|
|
83
84
|
status={subStep.status}
|
|
84
85
|
{...subStep.navItem}
|
|
@@ -120,10 +121,10 @@ export const WizardNavInternal = ({ nav, isStepVisitRequired, isNavExpanded }: W
|
|
|
120
121
|
key={step.id}
|
|
121
122
|
id={step.id}
|
|
122
123
|
content={step.name}
|
|
123
|
-
isCurrent={
|
|
124
|
-
isDisabled={
|
|
124
|
+
isCurrent={activeStep?.id === step.id}
|
|
125
|
+
isDisabled={isStepDisabled}
|
|
125
126
|
isVisited={step.isVisited}
|
|
126
|
-
stepIndex={
|
|
127
|
+
stepIndex={step.index}
|
|
127
128
|
onNavItemClick={goToStepByIndex}
|
|
128
129
|
status={step.status}
|
|
129
130
|
{...step.navItem}
|