@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.
Files changed (156) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/esm/components/Card/Card.d.ts +2 -2
  3. package/dist/esm/components/Card/Card.d.ts.map +1 -1
  4. package/dist/esm/components/DataList/DataList.d.ts +1 -1
  5. package/dist/esm/components/DataList/DataList.d.ts.map +1 -1
  6. package/dist/esm/components/DataList/DataListItem.d.ts +1 -1
  7. package/dist/esm/components/DataList/DataListItem.d.ts.map +1 -1
  8. package/dist/esm/components/MultipleFileUpload/MultipleFileUploadStatusItem.d.ts +2 -0
  9. package/dist/esm/components/MultipleFileUpload/MultipleFileUploadStatusItem.d.ts.map +1 -1
  10. package/dist/esm/components/MultipleFileUpload/MultipleFileUploadStatusItem.js +7 -1
  11. package/dist/esm/components/MultipleFileUpload/MultipleFileUploadStatusItem.js.map +1 -1
  12. package/dist/esm/components/Popover/Popover.d.ts +3 -3
  13. package/dist/esm/components/Popover/Popover.d.ts.map +1 -1
  14. package/dist/esm/components/Wizard/Wizard.d.ts +4 -4
  15. package/dist/esm/components/Wizard/Wizard.d.ts.map +1 -1
  16. package/dist/esm/components/Wizard/WizardToggle.d.ts +2 -2
  17. package/dist/esm/components/Wizard/WizardToggle.d.ts.map +1 -1
  18. package/dist/esm/next/components/Wizard/Wizard.d.ts +1 -3
  19. package/dist/esm/next/components/Wizard/Wizard.d.ts.map +1 -1
  20. package/dist/esm/next/components/Wizard/Wizard.js +36 -45
  21. package/dist/esm/next/components/Wizard/Wizard.js.map +1 -1
  22. package/dist/esm/next/components/Wizard/WizardBody.d.ts +2 -2
  23. package/dist/esm/next/components/Wizard/WizardBody.d.ts.map +1 -1
  24. package/dist/esm/next/components/Wizard/WizardBody.js +2 -2
  25. package/dist/esm/next/components/Wizard/WizardBody.js.map +1 -1
  26. package/dist/esm/next/components/Wizard/WizardContext.d.ts +2 -7
  27. package/dist/esm/next/components/Wizard/WizardContext.d.ts.map +1 -1
  28. package/dist/esm/next/components/Wizard/WizardContext.js +18 -39
  29. package/dist/esm/next/components/Wizard/WizardContext.js.map +1 -1
  30. package/dist/esm/next/components/Wizard/WizardFooter.d.ts +3 -3
  31. package/dist/esm/next/components/Wizard/WizardFooter.d.ts.map +1 -1
  32. package/dist/esm/next/components/Wizard/WizardFooter.js +3 -3
  33. package/dist/esm/next/components/Wizard/WizardFooter.js.map +1 -1
  34. package/dist/esm/next/components/Wizard/WizardNavInternal.d.ts.map +1 -1
  35. package/dist/esm/next/components/Wizard/WizardNavInternal.js +12 -12
  36. package/dist/esm/next/components/Wizard/WizardNavInternal.js.map +1 -1
  37. package/dist/esm/next/components/Wizard/WizardStep.d.ts +1 -3
  38. package/dist/esm/next/components/Wizard/WizardStep.d.ts.map +1 -1
  39. package/dist/esm/next/components/Wizard/WizardStep.js +10 -18
  40. package/dist/esm/next/components/Wizard/WizardStep.js.map +1 -1
  41. package/dist/esm/next/components/Wizard/WizardToggle.d.ts +2 -4
  42. package/dist/esm/next/components/Wizard/WizardToggle.d.ts.map +1 -1
  43. package/dist/esm/next/components/Wizard/WizardToggle.js +19 -16
  44. package/dist/esm/next/components/Wizard/WizardToggle.js.map +1 -1
  45. package/dist/esm/next/components/Wizard/hooks/useWizardFooter.js +3 -3
  46. package/dist/esm/next/components/Wizard/hooks/useWizardFooter.js.map +1 -1
  47. package/dist/esm/next/components/Wizard/types.d.ts +5 -3
  48. package/dist/esm/next/components/Wizard/types.d.ts.map +1 -1
  49. package/dist/esm/next/components/Wizard/types.js.map +1 -1
  50. package/dist/esm/next/components/Wizard/utils.d.ts +3 -3
  51. package/dist/esm/next/components/Wizard/utils.d.ts.map +1 -1
  52. package/dist/esm/next/components/Wizard/utils.js +14 -11
  53. package/dist/esm/next/components/Wizard/utils.js.map +1 -1
  54. package/dist/js/components/Card/Card.d.ts +2 -2
  55. package/dist/js/components/Card/Card.d.ts.map +1 -1
  56. package/dist/js/components/DataList/DataList.d.ts +1 -1
  57. package/dist/js/components/DataList/DataList.d.ts.map +1 -1
  58. package/dist/js/components/DataList/DataListItem.d.ts +1 -1
  59. package/dist/js/components/DataList/DataListItem.d.ts.map +1 -1
  60. package/dist/js/components/MultipleFileUpload/MultipleFileUploadStatusItem.d.ts +2 -0
  61. package/dist/js/components/MultipleFileUpload/MultipleFileUploadStatusItem.d.ts.map +1 -1
  62. package/dist/js/components/MultipleFileUpload/MultipleFileUploadStatusItem.js +7 -1
  63. package/dist/js/components/MultipleFileUpload/MultipleFileUploadStatusItem.js.map +1 -1
  64. package/dist/js/components/Popover/Popover.d.ts +3 -3
  65. package/dist/js/components/Popover/Popover.d.ts.map +1 -1
  66. package/dist/js/components/Wizard/Wizard.d.ts +4 -4
  67. package/dist/js/components/Wizard/Wizard.d.ts.map +1 -1
  68. package/dist/js/components/Wizard/WizardToggle.d.ts +2 -2
  69. package/dist/js/components/Wizard/WizardToggle.d.ts.map +1 -1
  70. package/dist/js/next/components/Wizard/Wizard.d.ts +1 -3
  71. package/dist/js/next/components/Wizard/Wizard.d.ts.map +1 -1
  72. package/dist/js/next/components/Wizard/Wizard.js +36 -45
  73. package/dist/js/next/components/Wizard/Wizard.js.map +1 -1
  74. package/dist/js/next/components/Wizard/WizardBody.d.ts +2 -2
  75. package/dist/js/next/components/Wizard/WizardBody.d.ts.map +1 -1
  76. package/dist/js/next/components/Wizard/WizardBody.js +2 -2
  77. package/dist/js/next/components/Wizard/WizardBody.js.map +1 -1
  78. package/dist/js/next/components/Wizard/WizardContext.d.ts +2 -7
  79. package/dist/js/next/components/Wizard/WizardContext.d.ts.map +1 -1
  80. package/dist/js/next/components/Wizard/WizardContext.js +15 -37
  81. package/dist/js/next/components/Wizard/WizardContext.js.map +1 -1
  82. package/dist/js/next/components/Wizard/WizardFooter.d.ts +3 -3
  83. package/dist/js/next/components/Wizard/WizardFooter.d.ts.map +1 -1
  84. package/dist/js/next/components/Wizard/WizardFooter.js +3 -3
  85. package/dist/js/next/components/Wizard/WizardFooter.js.map +1 -1
  86. package/dist/js/next/components/Wizard/WizardNavInternal.d.ts.map +1 -1
  87. package/dist/js/next/components/Wizard/WizardNavInternal.js +12 -12
  88. package/dist/js/next/components/Wizard/WizardNavInternal.js.map +1 -1
  89. package/dist/js/next/components/Wizard/WizardStep.d.ts +1 -3
  90. package/dist/js/next/components/Wizard/WizardStep.d.ts.map +1 -1
  91. package/dist/js/next/components/Wizard/WizardStep.js +9 -18
  92. package/dist/js/next/components/Wizard/WizardStep.js.map +1 -1
  93. package/dist/js/next/components/Wizard/WizardToggle.d.ts +2 -4
  94. package/dist/js/next/components/Wizard/WizardToggle.d.ts.map +1 -1
  95. package/dist/js/next/components/Wizard/WizardToggle.js +18 -16
  96. package/dist/js/next/components/Wizard/WizardToggle.js.map +1 -1
  97. package/dist/js/next/components/Wizard/hooks/useWizardFooter.js +3 -3
  98. package/dist/js/next/components/Wizard/hooks/useWizardFooter.js.map +1 -1
  99. package/dist/js/next/components/Wizard/types.d.ts +5 -3
  100. package/dist/js/next/components/Wizard/types.d.ts.map +1 -1
  101. package/dist/js/next/components/Wizard/types.js.map +1 -1
  102. package/dist/js/next/components/Wizard/utils.d.ts +3 -3
  103. package/dist/js/next/components/Wizard/utils.d.ts.map +1 -1
  104. package/dist/js/next/components/Wizard/utils.js +16 -13
  105. package/dist/js/next/components/Wizard/utils.js.map +1 -1
  106. package/dist/umd/react-core.min.css +137 -137
  107. package/dist/umd/react-core.min.js +1 -1
  108. package/package.json +2 -2
  109. package/src/components/AlertGroup/examples/AlertGroup.md +2 -2
  110. package/src/components/CalendarMonth/examples/CalendarMonth.md +0 -1
  111. package/src/components/Card/Card.tsx +2 -2
  112. package/src/components/DataList/DataList.tsx +1 -1
  113. package/src/components/DataList/DataListItem.tsx +1 -1
  114. package/src/components/DualListSelector/examples/DualListSelector.md +0 -1
  115. package/src/components/LabelGroup/examples/LabelGroup.md +2 -3
  116. package/src/components/Masthead/examples/Masthead.md +0 -1
  117. package/src/components/Menu/examples/Menu.md +1 -1
  118. package/src/components/MenuToggle/examples/MenuToggle.md +0 -1
  119. package/src/components/MultipleFileUpload/MultipleFileUploadStatusItem.tsx +10 -0
  120. package/src/components/MultipleFileUpload/__tests__/MultipleFileUploadStatusItem.test.tsx +33 -1
  121. package/src/components/MultipleFileUpload/__tests__/__snapshots__/MultipleFileUploadStatusItem.test.tsx.snap +269 -3
  122. package/src/components/MultipleFileUpload/examples/MultipleFileUpload.md +0 -1
  123. package/src/components/NotificationDrawer/examples/NotificationDrawer.md +0 -1
  124. package/src/components/Panel/examples/Panel.md +0 -1
  125. package/src/components/Popover/Popover.tsx +3 -3
  126. package/src/components/Popover/examples/Popover.md +2 -2
  127. package/src/components/Select/examples/Select.md +2 -2
  128. package/src/components/Slider/examples/Slider.md +0 -1
  129. package/src/components/TextArea/examples/TextArea.md +1 -1
  130. package/src/components/TextInput/examples/TextInput.md +1 -1
  131. package/src/components/TreeView/examples/TreeView.md +0 -1
  132. package/src/components/Wizard/Wizard.tsx +4 -4
  133. package/src/components/Wizard/WizardToggle.tsx +2 -2
  134. package/src/components/Wizard/examples/Wizard.md +12 -8
  135. package/src/demos/MultipleFileUploadDemos.md +0 -1
  136. package/src/demos/NotificationDrawer/NotificationDrawer.md +0 -1
  137. package/src/next/components/Wizard/Wizard.tsx +35 -54
  138. package/src/next/components/Wizard/WizardBody.tsx +3 -3
  139. package/src/next/components/Wizard/WizardContext.tsx +29 -61
  140. package/src/next/components/Wizard/WizardFooter.tsx +6 -6
  141. package/src/next/components/Wizard/WizardNavInternal.tsx +18 -17
  142. package/src/next/components/Wizard/WizardStep.tsx +19 -30
  143. package/src/next/components/Wizard/WizardToggle.tsx +22 -24
  144. package/src/next/components/Wizard/__tests__/Wizard.test.tsx +1 -21
  145. package/src/next/components/Wizard/__tests__/WizardBody.test.tsx +2 -2
  146. package/src/next/components/Wizard/__tests__/WizardFooter.test.tsx +5 -5
  147. package/src/next/components/Wizard/__tests__/WizardStep.test.tsx +22 -76
  148. package/src/next/components/Wizard/__tests__/WizardToggle.test.tsx +7 -11
  149. package/src/next/components/Wizard/__tests__/utils.test.tsx +3 -3
  150. package/src/next/components/Wizard/examples/Wizard.md +4 -4
  151. package/src/next/components/Wizard/examples/WizardCustomNav.tsx +4 -4
  152. package/src/next/components/Wizard/examples/WizardKitchenSink.tsx +74 -85
  153. package/src/next/components/Wizard/hooks/__tests__/useWizardFooter.test.tsx +4 -4
  154. package/src/next/components/Wizard/hooks/useWizardFooter.tsx +3 -3
  155. package/src/next/components/Wizard/types.tsx +5 -3
  156. 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
- /** @beta The content to render in the drawer panel (use when hasDrawer prop is set on the wizard). */
21
+ /** The content to render in the drawer panel (use when hasDrawer prop is set on the wizard). */
22
22
  drawerPanelContent?: any;
23
- /** @beta Custom drawer toggle button that opens the drawer. */
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
- /** @beta Flag indicating the wizard has a drawer for at least one of the wizard steps */
111
+ /** Flag indicating the wizard has a drawer for at least one of the wizard steps */
112
112
  hasDrawer?: boolean;
113
- /** @beta Flag indicating the wizard drawer is expanded */
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
- /** @beta Flag indicating the wizard has a drawer for at least one of the wizard steps */
32
+ /** Flag indicating the wizard has a drawer for at least one of the wizard steps */
33
33
  hasDrawer?: boolean;
34
- /** @beta Flag indicating the wizard drawer is expanded */
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 < id ? id : 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: 'incrementally-enabled-1', name: 'First step', component: <p>Step 1 content</p> },
152
+ { id: 'incrementallyEnabled-1', name: 'First step', component: <p>Step 1 content</p> },
151
153
  {
152
- id: 'incrementally-enabled-2',
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: 'incrementally-enabled-3',
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: 'incrementally-enabled-4',
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: 'incrementally-enabled-5',
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 < id ? id : 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 isBeta
904
+ ```js
901
905
  import React from 'react';
902
906
  import {
903
907
  Button,
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  id: File upload - multiple
3
3
  section: components
4
- beta: true
5
4
  ---
6
5
 
7
6
  import UploadIcon from '@patternfly/react-icons/dist/esm/icons/upload-icon';
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  id: Notification drawer
3
3
  section: components
4
- beta: true
5
4
  ---
6
5
 
7
6
  import BellIcon from '@patternfly/react-icons/dist/esm/icons/bell-icon';
@@ -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 [currentStepIndex, setCurrentStepIndex] = React.useState(startIndex);
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
- steps.findIndex((step, index) => index + 1 > currentStepIndex && !step.isHidden && !isWizardParentStep(step)) + 1;
78
+ const newStepIndex = steps.find(step => step.index > activeStepIndex && !step.isHidden && !isWizardParentStep(step))
79
+ ?.index;
83
80
 
84
- if (currentStepIndex >= steps.length || !newStepIndex) {
81
+ if (activeStepIndex >= steps.length || !newStepIndex) {
85
82
  return onSave ? onSave() : onClose?.();
86
83
  }
87
84
 
88
- const currStep = isWizardParentStep(steps[currentStepIndex])
89
- ? steps[currentStepIndex + 1]
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
- return onNext?.(normalizeNavStep(currStep, steps), normalizeNavStep(prevStep, steps));
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, index: number) =>
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[currentStepIndex - 2])
106
- ? steps[currentStepIndex - 3]
107
- : steps[currentStepIndex - 2];
108
- const prevStep = steps[currentStepIndex - 1];
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
- return onBack?.(normalizeNavStep(currStep, steps), normalizeNavStep(prevStep, steps));
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[currentStepIndex - 1];
130
- setCurrentStepIndex(index);
118
+ const prevStep = steps[activeStepIndex - 1];
131
119
 
132
- return onNavByIndex?.(normalizeNavStep(currStep, steps), normalizeNavStep(prevStep, steps));
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 stepIndex = steps.findIndex(step => step.id === id) + 1;
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 < steps.length + 1 && !steps[stepIndex].isHidden) {
139
- setCurrentStepIndex(stepIndex);
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 stepIndex = initialSteps.findIndex(step => step.name === name) + 1;
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 < steps.length + 1 && !steps[stepIndex].isHidden) {
150
- setCurrentStepIndex(stepIndex);
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
- currentStepIndex={currentStepIndex}
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} hasUnmountedSteps={hasUnmountedSteps} isStepVisitRequired={isStepVisitRequired} />
165
+ <WizardInternal nav={nav} isStepVisitRequired={isStepVisitRequired} />
180
166
  </div>
181
167
  </WizardContextProvider>
182
168
  );
183
169
  };
184
170
 
185
- const WizardInternal = ({
186
- nav,
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, currentStep, goToStepByIndex) : nav;
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
- }, [currentStep, isStepVisitRequired, goToStepByIndex, isNavExpanded, nav, steps]);
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
- currentStep={currentStep}
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
- hasNoBodyPadding?: boolean;
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
- hasNoBodyPadding = false,
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, hasNoBodyPadding && styles.modifiers.noPadding)}>{children}</div>
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, isWizardParentStep, WizardControlStep, WizardFooterType } from './types';
4
- import { getCurrentStep } from './utils';
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
- currentStep: WizardControlStep;
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
- currentStepIndex: number;
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
- currentStepIndex,
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 [steps, setSteps] = React.useState(initialSteps);
61
+ const [currentSteps, setCurrentSteps] = React.useState(initialSteps);
68
62
  const [currentFooter, setCurrentFooter] = React.useState(
69
63
  typeof initialFooter !== 'function' ? initialFooter : undefined
70
64
  );
71
- const currentStep = getCurrentStep(steps, currentStepIndex);
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(currentStep, goToNextStep, goToPrevStep, onClose)
92
+ ? customFooter(activeStep, goToNextStep, goToPrevStep, onClose)
84
93
  : customFooter;
85
94
  }
86
95
 
87
96
  return (
88
97
  <WizardFooter
89
- currentStep={currentStep}
98
+ activeStep={activeStep}
90
99
  onNext={goToNextStep}
91
100
  onBack={goToPrevStep}
92
101
  onClose={onClose}
93
- isBackDisabled={currentStep?.id === steps[0]?.id}
102
+ isBackDisabled={activeStep?.id === steps[0]?.id}
94
103
  {...wizardFooter}
95
104
  />
96
105
  );
97
- }, [currentFooter, initialFooter, currentStep, goToNextStep, goToPrevStep, onClose, steps]);
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
- setSteps(prevSteps =>
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
- currentStep,
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 current step */
15
- currentStep: WizardControlStep;
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 = ({ currentStep, ...internalProps }: WizardFooterProps) => {
47
- const currentStepFooter = !isCustomWizardFooter(currentStep.footer) && currentStep.footer;
48
- return <InternalWizardFooter {...internalProps} {...currentStepFooter} />;
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, 'currentStep'>) => (
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 { currentStep, steps, goToStepByIndex } = useWizardContext();
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, index) => {
33
- const stepIndex = index + 1;
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 subStepOrderIndex = steps.indexOf(subStep) + 1;
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, currentStep, steps, goToStepByIndex)
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 = subStepOrderIndex;
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 (currentStep?.id === subStep.id) {
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={currentStep?.id === subStep.id}
79
- isDisabled={subStep.isDisabled || (isStepVisitRequired && !subStep.isVisited)}
79
+ isCurrent={activeStep?.id === subStep.id}
80
+ isDisabled={isSubStepDisabled}
80
81
  isVisited={subStep.isVisited}
81
- stepIndex={subStepOrderIndex}
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={currentStep?.id === step.id}
124
- isDisabled={step.isDisabled || (isStepVisitRequired && !step.isVisited)}
124
+ isCurrent={activeStep?.id === step.id}
125
+ isDisabled={isStepDisabled}
125
126
  isVisited={step.isVisited}
126
- stepIndex={stepIndex}
127
+ stepIndex={step.index}
127
128
  onNavItemClick={goToStepByIndex}
128
129
  status={step.status}
129
130
  {...step.navItem}