@patternfly/react-core 5.2.0-prerelease.20 → 5.2.0-prerelease.21

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 (211) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/components/package.json +1 -1
  3. package/deprecated/package.json +1 -1
  4. package/dist/dynamic/components/AboutModal/package.json +1 -1
  5. package/dist/dynamic/components/Accordion/package.json +1 -1
  6. package/dist/dynamic/components/ActionList/package.json +1 -1
  7. package/dist/dynamic/components/Alert/package.json +1 -1
  8. package/dist/dynamic/components/Avatar/package.json +1 -1
  9. package/dist/dynamic/components/BackToTop/package.json +1 -1
  10. package/dist/dynamic/components/Backdrop/package.json +1 -1
  11. package/dist/dynamic/components/BackgroundImage/package.json +1 -1
  12. package/dist/dynamic/components/Badge/package.json +1 -1
  13. package/dist/dynamic/components/Banner/package.json +1 -1
  14. package/dist/dynamic/components/Brand/package.json +1 -1
  15. package/dist/dynamic/components/Breadcrumb/package.json +1 -1
  16. package/dist/dynamic/components/Button/package.json +1 -1
  17. package/dist/dynamic/components/CalendarMonth/package.json +1 -1
  18. package/dist/dynamic/components/Card/package.json +1 -1
  19. package/dist/dynamic/components/Checkbox/package.json +1 -1
  20. package/dist/dynamic/components/Chip/package.json +1 -1
  21. package/dist/dynamic/components/ClipboardCopy/package.json +1 -1
  22. package/dist/dynamic/components/CodeBlock/package.json +1 -1
  23. package/dist/dynamic/components/DataList/package.json +1 -1
  24. package/dist/dynamic/components/DatePicker/package.json +1 -1
  25. package/dist/dynamic/components/DescriptionList/package.json +1 -1
  26. package/dist/dynamic/components/Divider/package.json +1 -1
  27. package/dist/dynamic/components/DragDrop/package.json +1 -1
  28. package/dist/dynamic/components/Drawer/package.json +1 -1
  29. package/dist/dynamic/components/Dropdown/package.json +1 -1
  30. package/dist/dynamic/components/DualListSelector/package.json +1 -1
  31. package/dist/dynamic/components/EmptyState/package.json +1 -1
  32. package/dist/dynamic/components/ExpandableSection/package.json +1 -1
  33. package/dist/dynamic/components/FileUpload/package.json +1 -1
  34. package/dist/dynamic/components/Form/package.json +1 -1
  35. package/dist/dynamic/components/FormSelect/package.json +1 -1
  36. package/dist/dynamic/components/HelperText/package.json +1 -1
  37. package/dist/dynamic/components/Hint/package.json +1 -1
  38. package/dist/dynamic/components/Icon/package.json +1 -1
  39. package/dist/dynamic/components/InputGroup/package.json +1 -1
  40. package/dist/dynamic/components/JumpLinks/package.json +1 -1
  41. package/dist/dynamic/components/Label/package.json +1 -1
  42. package/dist/dynamic/components/List/package.json +1 -1
  43. package/dist/dynamic/components/LoginPage/package.json +1 -1
  44. package/dist/dynamic/components/Masthead/package.json +1 -1
  45. package/dist/dynamic/components/Menu/package.json +1 -1
  46. package/dist/dynamic/components/MenuToggle/package.json +1 -1
  47. package/dist/dynamic/components/Modal/package.json +1 -1
  48. package/dist/dynamic/components/MultipleFileUpload/package.json +1 -1
  49. package/dist/dynamic/components/Nav/package.json +1 -1
  50. package/dist/dynamic/components/NotificationBadge/package.json +1 -1
  51. package/dist/dynamic/components/NotificationDrawer/package.json +1 -1
  52. package/dist/dynamic/components/NumberInput/package.json +1 -1
  53. package/dist/dynamic/components/OverflowMenu/package.json +1 -1
  54. package/dist/dynamic/components/Page/package.json +1 -1
  55. package/dist/dynamic/components/Pagination/package.json +1 -1
  56. package/dist/dynamic/components/Panel/package.json +1 -1
  57. package/dist/dynamic/components/Popover/package.json +1 -1
  58. package/dist/dynamic/components/Progress/package.json +1 -1
  59. package/dist/dynamic/components/ProgressStepper/package.json +1 -1
  60. package/dist/dynamic/components/Radio/package.json +1 -1
  61. package/dist/dynamic/components/SearchInput/package.json +1 -1
  62. package/dist/dynamic/components/Select/package.json +1 -1
  63. package/dist/dynamic/components/Sidebar/package.json +1 -1
  64. package/dist/dynamic/components/SimpleList/package.json +1 -1
  65. package/dist/dynamic/components/Skeleton/package.json +1 -1
  66. package/dist/dynamic/components/SkipToContent/package.json +1 -1
  67. package/dist/dynamic/components/Slider/package.json +1 -1
  68. package/dist/dynamic/components/Spinner/package.json +1 -1
  69. package/dist/dynamic/components/Switch/package.json +1 -1
  70. package/dist/dynamic/components/Tabs/package.json +1 -1
  71. package/dist/dynamic/components/Text/package.json +1 -1
  72. package/dist/dynamic/components/TextArea/package.json +1 -1
  73. package/dist/dynamic/components/TextInput/package.json +1 -1
  74. package/dist/dynamic/components/TextInputGroup/package.json +1 -1
  75. package/dist/dynamic/components/Tile/package.json +1 -1
  76. package/dist/dynamic/components/TimePicker/package.json +1 -1
  77. package/dist/dynamic/components/Timestamp/package.json +1 -1
  78. package/dist/dynamic/components/Title/package.json +1 -1
  79. package/dist/dynamic/components/ToggleGroup/package.json +1 -1
  80. package/dist/dynamic/components/Toolbar/package.json +1 -1
  81. package/dist/dynamic/components/Tooltip/package.json +1 -1
  82. package/dist/dynamic/components/TreeView/package.json +1 -1
  83. package/dist/dynamic/components/Truncate/package.json +1 -1
  84. package/dist/dynamic/components/Wizard/hooks/package.json +1 -1
  85. package/dist/dynamic/components/Wizard/package.json +1 -1
  86. package/dist/dynamic/deprecated/components/ApplicationLauncher/package.json +1 -1
  87. package/dist/dynamic/deprecated/components/ContextSelector/package.json +1 -1
  88. package/dist/dynamic/deprecated/components/Dropdown/package.json +1 -1
  89. package/dist/dynamic/deprecated/components/OptionsMenu/package.json +1 -1
  90. package/dist/dynamic/deprecated/components/PageHeader/package.json +1 -1
  91. package/dist/dynamic/deprecated/components/Select/package.json +1 -1
  92. package/dist/dynamic/deprecated/components/Wizard/package.json +1 -1
  93. package/dist/dynamic/deprecated/components/package.json +1 -1
  94. package/dist/dynamic/helpers/FocusTrap/FocusTrap/package.json +1 -1
  95. package/dist/dynamic/helpers/GenerateId/GenerateId/package.json +1 -1
  96. package/dist/dynamic/helpers/KeyboardHandler/package.json +1 -1
  97. package/dist/dynamic/helpers/OUIA/ouia/package.json +1 -1
  98. package/dist/dynamic/helpers/Popper/Popper/package.json +1 -1
  99. package/dist/dynamic/helpers/constants/package.json +1 -1
  100. package/dist/dynamic/helpers/datetimeUtils/package.json +1 -1
  101. package/dist/dynamic/helpers/favorites/package.json +1 -1
  102. package/dist/dynamic/helpers/fileUtils/package.json +1 -1
  103. package/dist/dynamic/helpers/htmlConstants/package.json +1 -1
  104. package/dist/dynamic/helpers/package.json +1 -1
  105. package/dist/dynamic/helpers/resizeObserver/package.json +1 -1
  106. package/dist/dynamic/helpers/typeUtils/package.json +1 -1
  107. package/dist/dynamic/helpers/useInterval/package.json +1 -1
  108. package/dist/dynamic/helpers/useIsomorphicLayout/package.json +1 -1
  109. package/dist/dynamic/helpers/useUnmountEffect/package.json +1 -1
  110. package/dist/dynamic/helpers/util/package.json +1 -1
  111. package/dist/dynamic/layouts/Bullseye/package.json +1 -1
  112. package/dist/dynamic/layouts/Flex/package.json +1 -1
  113. package/dist/dynamic/layouts/Gallery/package.json +1 -1
  114. package/dist/dynamic/layouts/Grid/package.json +1 -1
  115. package/dist/dynamic/layouts/Level/package.json +1 -1
  116. package/dist/dynamic/layouts/Split/package.json +1 -1
  117. package/dist/dynamic/layouts/Stack/package.json +1 -1
  118. package/dist/dynamic/next/components/package.json +1 -1
  119. package/dist/esm/components/NotificationDrawer/NotificationDrawerHeader.d.ts.map +1 -1
  120. package/dist/esm/components/NotificationDrawer/NotificationDrawerHeader.js +1 -1
  121. package/dist/esm/components/NotificationDrawer/NotificationDrawerHeader.js.map +1 -1
  122. package/dist/esm/components/NotificationDrawer/NotificationDrawerListItem.d.ts +2 -0
  123. package/dist/esm/components/NotificationDrawer/NotificationDrawerListItem.d.ts.map +1 -1
  124. package/dist/esm/components/NotificationDrawer/NotificationDrawerListItem.js +11 -2
  125. package/dist/esm/components/NotificationDrawer/NotificationDrawerListItem.js.map +1 -1
  126. package/dist/esm/components/TextInput/TextInput.d.ts +9 -1
  127. package/dist/esm/components/TextInput/TextInput.d.ts.map +1 -1
  128. package/dist/esm/components/TextInput/TextInput.js +6 -3
  129. package/dist/esm/components/TextInput/TextInput.js.map +1 -1
  130. package/dist/esm/components/Wizard/Wizard.d.ts +1 -1
  131. package/dist/esm/components/Wizard/Wizard.d.ts.map +1 -1
  132. package/dist/esm/components/Wizard/Wizard.js +5 -11
  133. package/dist/esm/components/Wizard/Wizard.js.map +1 -1
  134. package/dist/esm/components/Wizard/WizardBody.d.ts +1 -1
  135. package/dist/esm/components/Wizard/WizardBody.d.ts.map +1 -1
  136. package/dist/esm/components/Wizard/WizardBody.js +1 -1
  137. package/dist/esm/components/Wizard/WizardBody.js.map +1 -1
  138. package/dist/esm/components/Wizard/WizardFooter.d.ts +7 -1
  139. package/dist/esm/components/Wizard/WizardFooter.d.ts.map +1 -1
  140. package/dist/esm/components/Wizard/WizardFooter.js +4 -4
  141. package/dist/esm/components/Wizard/WizardFooter.js.map +1 -1
  142. package/dist/esm/components/Wizard/WizardNavInternal.js +2 -2
  143. package/dist/esm/components/Wizard/WizardNavInternal.js.map +1 -1
  144. package/dist/esm/components/Wizard/WizardToggle.js +1 -1
  145. package/dist/esm/components/Wizard/WizardToggle.js.map +1 -1
  146. package/dist/esm/components/Wizard/types.d.ts +3 -0
  147. package/dist/esm/components/Wizard/types.d.ts.map +1 -1
  148. package/dist/esm/components/Wizard/types.js.map +1 -1
  149. package/dist/esm/components/Wizard/utils.d.ts +8 -1
  150. package/dist/esm/components/Wizard/utils.d.ts.map +1 -1
  151. package/dist/esm/components/Wizard/utils.js +22 -0
  152. package/dist/esm/components/Wizard/utils.js.map +1 -1
  153. package/dist/js/components/NotificationDrawer/NotificationDrawerHeader.d.ts.map +1 -1
  154. package/dist/js/components/NotificationDrawer/NotificationDrawerHeader.js +1 -1
  155. package/dist/js/components/NotificationDrawer/NotificationDrawerHeader.js.map +1 -1
  156. package/dist/js/components/NotificationDrawer/NotificationDrawerListItem.d.ts +2 -0
  157. package/dist/js/components/NotificationDrawer/NotificationDrawerListItem.d.ts.map +1 -1
  158. package/dist/js/components/NotificationDrawer/NotificationDrawerListItem.js +11 -2
  159. package/dist/js/components/NotificationDrawer/NotificationDrawerListItem.js.map +1 -1
  160. package/dist/js/components/TextInput/TextInput.d.ts +9 -1
  161. package/dist/js/components/TextInput/TextInput.d.ts.map +1 -1
  162. package/dist/js/components/TextInput/TextInput.js +6 -3
  163. package/dist/js/components/TextInput/TextInput.js.map +1 -1
  164. package/dist/js/components/Wizard/Wizard.d.ts +1 -1
  165. package/dist/js/components/Wizard/Wizard.d.ts.map +1 -1
  166. package/dist/js/components/Wizard/Wizard.js +4 -10
  167. package/dist/js/components/Wizard/Wizard.js.map +1 -1
  168. package/dist/js/components/Wizard/WizardBody.d.ts +1 -1
  169. package/dist/js/components/Wizard/WizardBody.d.ts.map +1 -1
  170. package/dist/js/components/Wizard/WizardBody.js +1 -1
  171. package/dist/js/components/Wizard/WizardBody.js.map +1 -1
  172. package/dist/js/components/Wizard/WizardFooter.d.ts +7 -1
  173. package/dist/js/components/Wizard/WizardFooter.d.ts.map +1 -1
  174. package/dist/js/components/Wizard/WizardFooter.js +4 -4
  175. package/dist/js/components/Wizard/WizardFooter.js.map +1 -1
  176. package/dist/js/components/Wizard/WizardNavInternal.js +2 -2
  177. package/dist/js/components/Wizard/WizardNavInternal.js.map +1 -1
  178. package/dist/js/components/Wizard/WizardToggle.js +1 -1
  179. package/dist/js/components/Wizard/WizardToggle.js.map +1 -1
  180. package/dist/js/components/Wizard/types.d.ts +3 -0
  181. package/dist/js/components/Wizard/types.d.ts.map +1 -1
  182. package/dist/js/components/Wizard/types.js.map +1 -1
  183. package/dist/js/components/Wizard/utils.d.ts +8 -1
  184. package/dist/js/components/Wizard/utils.d.ts.map +1 -1
  185. package/dist/js/components/Wizard/utils.js +24 -1
  186. package/dist/js/components/Wizard/utils.js.map +1 -1
  187. package/dist/umd/react-core.min.js +2 -2
  188. package/helpers/package.json +1 -1
  189. package/layouts/package.json +1 -1
  190. package/next/package.json +1 -1
  191. package/package.json +2 -2
  192. package/src/components/Divider/__tests__/Divider.test.tsx +96 -21
  193. package/src/components/Divider/__tests__/__snapshots__/Divider.test.tsx.snap +1 -41
  194. package/src/components/NotificationDrawer/NotificationDrawerHeader.tsx +3 -1
  195. package/src/components/NotificationDrawer/NotificationDrawerListItem.tsx +12 -0
  196. package/src/components/NotificationDrawer/__tests__/NotificationDrawerListItem.test.tsx +14 -1
  197. package/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawerHeader.test.tsx.snap +2 -0
  198. package/src/components/NotificationDrawer/__tests__/__snapshots__/NotificationDrawerListItem.test.tsx.snap +7 -1
  199. package/src/components/TextInput/TextInput.tsx +16 -2
  200. package/src/components/TextInput/__tests__/TextInput.test.tsx +9 -0
  201. package/src/components/TextInput/examples/TextInput.md +1 -1
  202. package/src/components/Wizard/Wizard.tsx +6 -18
  203. package/src/components/Wizard/WizardBody.tsx +2 -2
  204. package/src/components/Wizard/WizardFooter.tsx +20 -5
  205. package/src/components/Wizard/WizardNavInternal.tsx +2 -2
  206. package/src/components/Wizard/WizardToggle.tsx +1 -1
  207. package/src/components/Wizard/__tests__/Wizard.test.tsx +188 -17
  208. package/src/components/Wizard/__tests__/WizardBody.test.tsx +1 -1
  209. package/src/components/Wizard/examples/WizardGetCurrentStep.tsx +38 -4
  210. package/src/components/Wizard/types.tsx +4 -0
  211. package/src/components/Wizard/utils.ts +25 -2
@@ -3,7 +3,7 @@ import React from 'react';
3
3
  import { render, screen } from '@testing-library/react';
4
4
  import userEvent from '@testing-library/user-event';
5
5
 
6
- import { Wizard, WizardFooterProps, WizardStep, WizardNavProps } from '../';
6
+ import { Wizard, WizardFooterProps, WizardStep, WizardNavProps, WizardStepChangeScope } from '../';
7
7
 
8
8
  test('renders step when child is of type WizardStep', () => {
9
9
  render(
@@ -58,6 +58,27 @@ test('renders default footer with custom props', () => {
58
58
  expect(screen.getByRole('button', { name: 'Leave now!' })).toBeVisible();
59
59
  });
60
60
 
61
+ test('can add props to default footer buttons', () => {
62
+ render(
63
+ <Wizard
64
+ footer={{
65
+ nextButtonProps: { id: 'next-button', className: 'custom-class' },
66
+ backButtonProps: { id: 'back-button' },
67
+ cancelButtonProps: { id: 'cancel-button' }
68
+ }}
69
+ >
70
+ <WizardStep id="test-step" name="Test step" />
71
+ </Wizard>
72
+ );
73
+
74
+ const nextButton = screen.getByRole('button', { name: 'Next' });
75
+
76
+ expect(nextButton).toHaveProperty('id', 'next-button');
77
+ expect(nextButton).toHaveClass('custom-class');
78
+ expect(screen.getByRole('button', { name: 'Back' })).toHaveProperty('id', 'back-button');
79
+ expect(screen.getByRole('button', { name: 'Cancel' })).toHaveProperty('id', 'cancel-button');
80
+ });
81
+
61
82
  test('renders custom footer', () => {
62
83
  render(
63
84
  <Wizard footer={<>Some footer</>}>
@@ -100,7 +121,6 @@ test('renders default nav with custom props', () => {
100
121
  });
101
122
 
102
123
  test('renders nav aria label', () => {
103
-
104
124
  render(
105
125
  <Wizard navAriaLabel="custom nav aria-label">
106
126
  <WizardStep id="test-step" name="Test step" />
@@ -174,28 +194,33 @@ test(`can customize the wizard's height and width`, () => {
174
194
  expect(wizard).toHaveStyle('width: 500px');
175
195
  });
176
196
 
177
- test('calls onNavByIndex on nav item click', async () => {
197
+ test('calls onStepChange on nav item click', async () => {
178
198
  const user = userEvent.setup();
179
- const onNavByIndex = jest.fn();
199
+ const onStepChange = jest.fn();
180
200
 
181
201
  render(
182
- <Wizard onStepChange={onNavByIndex}>
202
+ <Wizard onStepChange={onStepChange}>
183
203
  <WizardStep id="step-1" name="Test step 1" />
184
204
  <WizardStep id="step-2" name="Test step 2" />
185
205
  </Wizard>
186
206
  );
187
207
 
188
208
  await user.click(screen.getByRole('button', { name: 'Test step 2' }));
189
- expect(onNavByIndex).toHaveBeenCalled();
209
+ expect(onStepChange).toHaveBeenCalledWith(
210
+ null,
211
+ expect.objectContaining({ id: 'step-2' }),
212
+ expect.objectContaining({ id: 'step-1' }),
213
+ WizardStepChangeScope.Nav
214
+ );
190
215
  });
191
216
 
192
- test('calls onNext and not onSave on next button click when not on the last step', async () => {
217
+ test('calls onStepChange and not onSave on next button click when not on the last step', async () => {
193
218
  const user = userEvent.setup();
194
- const onNext = jest.fn();
219
+ const onStepChange = jest.fn();
195
220
  const onSave = jest.fn();
196
221
 
197
222
  render(
198
- <Wizard onStepChange={onNext} onSave={onSave}>
223
+ <Wizard onStepChange={onStepChange} onSave={onSave}>
199
224
  <WizardStep id="step-1" name="Test step 1" />
200
225
  <WizardStep id="step-2" name="Test step 2" />
201
226
  </Wizard>
@@ -203,16 +228,21 @@ test('calls onNext and not onSave on next button click when not on the last step
203
228
 
204
229
  await user.click(screen.getByRole('button', { name: 'Next' }));
205
230
 
206
- expect(onNext).toHaveBeenCalled();
231
+ expect(onStepChange).toHaveBeenCalledWith(
232
+ null,
233
+ expect.objectContaining({ id: 'step-2' }),
234
+ expect.objectContaining({ id: 'step-1' }),
235
+ WizardStepChangeScope.Next
236
+ );
207
237
  expect(onSave).not.toHaveBeenCalled();
208
238
  });
209
239
 
210
- test('calls onBack on back button click', async () => {
240
+ test('calls onStepChange on back button click', async () => {
211
241
  const user = userEvent.setup();
212
- const onBack = jest.fn();
242
+ const onStepChange = jest.fn();
213
243
 
214
244
  render(
215
- <Wizard onStepChange={onBack}>
245
+ <Wizard onStepChange={onStepChange}>
216
246
  <WizardStep id="step-1" name="Test step 1" />
217
247
  <WizardStep id="step-2" name="Test step 2" />
218
248
  </Wizard>
@@ -221,7 +251,12 @@ test('calls onBack on back button click', async () => {
221
251
  await user.click(screen.getByRole('button', { name: 'Test step 2' }));
222
252
  await user.click(screen.getByRole('button', { name: 'Back' }));
223
253
 
224
- expect(onBack).toHaveBeenCalled();
254
+ expect(onStepChange).toHaveBeenCalledWith(
255
+ null,
256
+ expect.objectContaining({ id: 'step-1' }),
257
+ expect.objectContaining({ id: 'step-2' }),
258
+ WizardStepChangeScope.Back
259
+ );
225
260
  });
226
261
 
227
262
  test('calls onSave and not onClose on next button click when on the last step', async () => {
@@ -445,17 +480,153 @@ test('incrementally shows/hides steps based on the activeStep when isProgressive
445
480
  ).toBeNull();
446
481
  });
447
482
 
448
- test('parent step can be non-collapsible by setting isCollapsible to false', () => {
483
+ test('parent step can be expandable by setting isExpandable to true', () => {
484
+ render(
485
+ <Wizard>
486
+ <WizardStep
487
+ id="step-1"
488
+ name="Test step 1"
489
+ isExpandable
490
+ steps={[<WizardStep id="sub-step-1" name="Sub step 1" />]}
491
+ />
492
+ </Wizard>
493
+ );
494
+
495
+ expect(screen.getByLabelText('step icon', { exact: false })).toBeVisible();
496
+ });
497
+
498
+ test('child steps are disabled when parent is disabled', () => {
449
499
  render(
450
500
  <Wizard>
451
501
  <WizardStep
452
502
  id="step-1"
453
503
  name="Test step 1"
454
- isCollapsible={false}
504
+ isDisabled
455
505
  steps={[<WizardStep id="sub-step-1" name="Sub step 1" />]}
456
506
  />
457
507
  </Wizard>
458
508
  );
459
509
 
460
- expect(screen.queryByLabelText('step icon', { exact: false })).toBeNull();
510
+ expect(
511
+ screen.getByRole('button', {
512
+ name: 'Test step 1'
513
+ })
514
+ ).toBeDisabled();
515
+ expect(
516
+ screen.getByRole('button', {
517
+ name: 'Sub step 1'
518
+ })
519
+ ).toBeDisabled();
520
+ });
521
+
522
+ test('child steps are hidden when parent is hidden', () => {
523
+ render(
524
+ <Wizard>
525
+ <WizardStep id="step-1" name="Test step 1" isHidden steps={[<WizardStep id="sub-step-1" name="Sub step 1" />]} />
526
+ </Wizard>
527
+ );
528
+
529
+ expect(
530
+ screen.queryByRole('button', {
531
+ name: 'Test step 1'
532
+ })
533
+ ).toBeNull();
534
+ expect(
535
+ screen.queryByRole('button', {
536
+ name: 'Sub step 1'
537
+ })
538
+ ).toBeNull();
539
+ });
540
+
541
+ test('onStepChange skips over disabled or hidden steps and substeps', async () => {
542
+ const user = userEvent.setup();
543
+ const onStepChange = jest.fn();
544
+
545
+ render(
546
+ <Wizard onStepChange={onStepChange}>
547
+ <WizardStep id="step-1" name="Test step 1" />
548
+ <WizardStep id="step-2" name="Test step 2" steps={[<WizardStep id="step2-sub1" name="Test Substep 1" />]} />
549
+ <WizardStep id="step-3" name="Test step 3" isDisabled />
550
+ <WizardStep
551
+ id="step-4"
552
+ name="Test step 4"
553
+ isDisabled
554
+ steps={[<WizardStep id="step4-sub1" name="Test Substep 1" />]}
555
+ />
556
+ <WizardStep
557
+ id="step-5"
558
+ name="Test step 4"
559
+ steps={[
560
+ <WizardStep id="step5-sub1" name="Test Substep 1" isDisabled />,
561
+ <WizardStep id="step5-sub2" name="Test Substep 2" />
562
+ ]}
563
+ />
564
+ <WizardStep id="step-6" name="Test step 6" isHidden />
565
+ <WizardStep
566
+ id="step-7"
567
+ name="Test step 7"
568
+ isHidden
569
+ steps={[<WizardStep id="step7-sub1" name="Test Substep 1" />]}
570
+ />
571
+ <WizardStep
572
+ id="step-8"
573
+ name="Test step 8"
574
+ steps={[
575
+ <WizardStep id="step8-sub1" name="Test Substep 1" isHidden />,
576
+ <WizardStep id="step8-sub2" name="Test Substep 2" />
577
+ ]}
578
+ />
579
+ </Wizard>
580
+ );
581
+
582
+ const nextButton = screen.getByRole('button', { name: 'Next' });
583
+ const backButton = screen.getByRole('button', { name: 'Back' });
584
+
585
+ await user.click(nextButton);
586
+ expect(onStepChange).toHaveBeenCalledWith(
587
+ null,
588
+ expect.objectContaining({ id: 'step2-sub1' }),
589
+ expect.objectContaining({ id: 'step-1' }),
590
+ WizardStepChangeScope.Next
591
+ );
592
+
593
+ await user.click(nextButton);
594
+ expect(onStepChange).toHaveBeenCalledWith(
595
+ null,
596
+ expect.objectContaining({ id: 'step5-sub2' }),
597
+ expect.objectContaining({ id: 'step2-sub1' }),
598
+ WizardStepChangeScope.Next
599
+ );
600
+
601
+ await user.click(nextButton);
602
+ expect(onStepChange).toHaveBeenCalledWith(
603
+ null,
604
+ expect.objectContaining({ id: 'step8-sub2' }),
605
+ expect.objectContaining({ id: 'step5-sub2' }),
606
+ WizardStepChangeScope.Next
607
+ );
608
+
609
+ await user.click(backButton);
610
+ expect(onStepChange).toHaveBeenCalledWith(
611
+ null,
612
+ expect.objectContaining({ id: 'step5-sub2' }),
613
+ expect.objectContaining({ id: 'step8-sub2' }),
614
+ WizardStepChangeScope.Back
615
+ );
616
+
617
+ await user.click(backButton);
618
+ expect(onStepChange).toHaveBeenCalledWith(
619
+ null,
620
+ expect.objectContaining({ id: 'step2-sub1' }),
621
+ expect.objectContaining({ id: 'step5-sub2' }),
622
+ WizardStepChangeScope.Back
623
+ );
624
+
625
+ await user.click(backButton);
626
+ expect(onStepChange).toHaveBeenCalledWith(
627
+ null,
628
+ expect.objectContaining({ id: 'step-1' }),
629
+ expect.objectContaining({ id: 'step2-sub1' }),
630
+ WizardStepChangeScope.Back
631
+ );
461
632
  });
@@ -10,7 +10,7 @@ test('renders children without additional props', () => {
10
10
  expect(container).not.toHaveAttribute('aria-labelledby');
11
11
  });
12
12
 
13
- test('has no padding className when hasNoBodyPadding is not specified', () => {
13
+ test('has no padding className when hasNoPadding is not specified', () => {
14
14
  render(<WizardBody>content</WizardBody>);
15
15
  expect(screen.getByText('content')).not.toHaveClass('pf-m-no-padding');
16
16
  });
@@ -36,7 +36,7 @@ const CurrentStepDescriptionList = ({ currentStep }: { currentStep: WizardStepTy
36
36
  export const GetCurrentStepWizard: React.FunctionComponent = () => {
37
37
  const [currentStep, setCurrentStep] = React.useState<WizardStepType>();
38
38
 
39
- const onStepChange = (event: React.MouseEvent<HTMLButtonElement>, currentStep: WizardStepType) =>
39
+ const onStepChange = (_event: React.MouseEvent<HTMLButtonElement>, currentStep: WizardStepType) =>
40
40
  setCurrentStep(currentStep);
41
41
 
42
42
  return (
@@ -44,9 +44,43 @@ export const GetCurrentStepWizard: React.FunctionComponent = () => {
44
44
  <WizardStep name="Step 1" id="get-current-step-1">
45
45
  {currentStep ? <CurrentStepDescriptionList currentStep={currentStep} /> : 'Step 1 content'}
46
46
  </WizardStep>
47
- <WizardStep name="Step 2" id="get-current-step-2">
48
- <CurrentStepDescriptionList currentStep={currentStep} />
49
- </WizardStep>
47
+ <WizardStep
48
+ name="Step 2"
49
+ id="get-current-step-2"
50
+ isDisabled
51
+ steps={[
52
+ <WizardStep name="Substep 1" id="get-current-substep-1" key="get-current-substep-1">
53
+ <CurrentStepDescriptionList currentStep={currentStep} />
54
+ </WizardStep>,
55
+ <WizardStep name="Substep 2" id="get-current-substep-2" key="get-current-substep-2">
56
+ <CurrentStepDescriptionList currentStep={currentStep} />
57
+ </WizardStep>
58
+ ]}
59
+ />
60
+ <WizardStep
61
+ name="Step 3"
62
+ id="get-current-step-3"
63
+ steps={[
64
+ <WizardStep name="Substep 3" id="get-current-substep-3" key="get-current-substep-3">
65
+ <CurrentStepDescriptionList currentStep={currentStep} />
66
+ </WizardStep>,
67
+ <WizardStep name="Substep 4" id="get-current-substep-4" key="get-current-substep-4">
68
+ <CurrentStepDescriptionList currentStep={currentStep} />
69
+ </WizardStep>
70
+ ]}
71
+ />
72
+ <WizardStep
73
+ name="Step 4"
74
+ id="get-current-step-4"
75
+ steps={[
76
+ <WizardStep name="Substep 5" id="get-current-substep-5" key="get-current-substep-5" isHidden>
77
+ <CurrentStepDescriptionList currentStep={currentStep} />
78
+ </WizardStep>,
79
+ <WizardStep name="Substep 6" id="get-current-substep-6" key="get-current-substep-6">
80
+ <CurrentStepDescriptionList currentStep={currentStep} />
81
+ </WizardStep>
82
+ ]}
83
+ />
50
84
  <WizardStep name="Review" id="get-current-review-step" footer={{ nextButtonText: 'Finish' }}>
51
85
  <CurrentStepDescriptionList currentStep={currentStep} />
52
86
  </WizardStep>
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { WizardNavProps, WizardNavItemProps, WizardFooterProps } from '.';
3
+ import { ButtonProps } from '../Button';
3
4
 
4
5
  /** Type used to define 'basic' steps, or in other words, steps that are neither parents or children of parents. */
5
6
  export interface WizardBasicStep {
@@ -30,6 +31,9 @@ export enum WizardNavItemStatus {
30
31
  Error = 'error'
31
32
  }
32
33
 
34
+ /** Type for customizing a button (next, back or cancel) in a Wizard footer. It omits some props which either have a default value or are passed directly via WizardFooterProps. */
35
+ export type WizardFooterButtonProps = Omit<ButtonProps, 'children' | 'variant' | 'onClick'>;
36
+
33
37
  /** Type used to define parent steps. */
34
38
  export interface WizardParentStep extends WizardBasicStep {
35
39
  /** Nested step IDs */
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
 
3
- import { WizardStepType } from './types';
3
+ import { isWizardParentStep, isWizardSubStep, WizardStepType } from './types';
4
4
  import { WizardStep, WizardStepProps } from './WizardStep';
5
5
 
6
6
  /**
@@ -8,7 +8,7 @@ import { WizardStep, WizardStepProps } from './WizardStep';
8
8
  * @param children
9
9
  * @returns WizardStepType[]
10
10
  */
11
- export const buildSteps = (children: React.ReactNode | React.ReactNode[]) =>
11
+ export const buildSteps = (children: React.ReactNode) =>
12
12
  React.Children.toArray(children).reduce((acc: WizardStepType[], child: React.ReactNode, index: number) => {
13
13
  if (isWizardStep(child)) {
14
14
  const { props: childProps } = child;
@@ -57,3 +57,26 @@ export const normalizeStepProps = ({
57
57
  steps: _steps,
58
58
  ...controlStep
59
59
  }: WizardStepProps): Omit<WizardStepType, 'index'> => controlStep;
60
+
61
+ /**
62
+ * Determines whether a step is navigable based on disabled/hidden properties
63
+ * @param steps All steps
64
+ * @param step
65
+ * @returns boolean
66
+ */
67
+ export const isStepEnabled = (steps: WizardStepType[], step: WizardStepType): boolean => {
68
+ // Skip over parent steps since they are merely containers of sub-steps
69
+ if (!isWizardParentStep(step) && !step.isHidden && !step.isDisabled) {
70
+ if (isWizardSubStep(step)) {
71
+ const parentStep = steps.find((otherStep) => otherStep.id === step.parentId);
72
+
73
+ if (!parentStep.isHidden && !parentStep.isDisabled) {
74
+ return true;
75
+ }
76
+ } else {
77
+ return true;
78
+ }
79
+ }
80
+
81
+ return false;
82
+ };