Skip to content

Commit

Permalink
Allow disabling back button in Wizard.Pattern. Fixes #527
Browse files Browse the repository at this point in the history
  • Loading branch information
rawagner committed Aug 10, 2018
1 parent 3958558 commit e73a6e3
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,18 @@ class StatefulWizardPattern extends React.Component {
};

render() {
const { shouldDisableNextStep, ...otherProps } = this.props;
const {
shouldDisableNextStep,
shouldDisablePreviousStep,
...otherProps
} = this.props;
const { activeStepIndex } = this.state;
// NOTE: the steps array is passed down with ...otherProps, including any shouldPreventEnter or shouldPreventExit functions inside it.
// These functions are for StatefulWizardPattern only and should not be used in WizardPattern despite being passed down here.
return (
<WizardPattern
nextStepDisabled={shouldDisableNextStep(activeStepIndex)}
previousStepDisabled={shouldDisablePreviousStep(activeStepIndex)}
{...otherProps}
activeStepIndex={activeStepIndex} // Value from state, as set by getDerivedStateFromProps
onStepChanged={this.onStepChanged}
Expand All @@ -54,7 +59,8 @@ class StatefulWizardPattern extends React.Component {
StatefulWizardPattern.propTypes = {
...excludeKeys(WizardPattern.propTypes, [
'activeStepIndex',
'nextStepDisabled'
'nextStepDisabled',
'previousStepDisabled'
]),
steps: PropTypes.arrayOf(
PropTypes.shape({
Expand All @@ -64,15 +70,18 @@ StatefulWizardPattern.propTypes = {
})
),
shouldDisableNextStep: PropTypes.func,
shouldDisablePreviousStep: PropTypes.func,
shouldPreventStepChange: PropTypes.func
};

StatefulWizardPattern.defaultProps = {
...excludeKeys(WizardPattern.defaultProps, [
'activeStepIndex',
'nextStepDisabled'
'nextStepDisabled',
'previousStepDisabled'
]),
shouldDisableNextStep: noop,
shouldDisablePreviousStep: noop,
shouldPreventStepChange: noop
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const WizardPattern = ({
onNext,
onBack,
nextStepDisabled,
previousStepDisabled,
title,
loadingTitle,
loadingMessage,
Expand Down Expand Up @@ -80,19 +81,20 @@ const WizardPattern = ({
const preventEnterTarget =
targetStep.preventEnter ||
(stepBeforeTarget && stepBeforeTarget.isInvalid);
const nextStepClicked = newStepIndex === activeStepIndex + 1;
const nextStepClicked = newStepIndex > activeStepIndex;

return (
preventExitActive ||
preventEnterTarget ||
(nextStepClicked && nextStepDisabled)
);
return preventExitActive || preventEnterTarget || nextStepClicked
? nextStepDisabled
: previousStepDisabled;
};

const activeStepStr = (activeStepIndex + 1).toString();

const prevStepUnreachable =
onFirstStep || activeStep.preventExit || getPrevStep().preventEnter;
previousStepDisabled ||
onFirstStep ||
activeStep.preventExit ||
getPrevStep().preventEnter;
// nextStepUnreachable is still true onFinalStep, because the Next button turns into a Close button
const nextStepUnreachable =
nextStepDisabled ||
Expand Down Expand Up @@ -168,6 +170,7 @@ WizardPattern.propTypes = {
closeText: PropTypes.string,
steps: PropTypes.arrayOf(PropTypes.shape(wizardStepShape)),
nextStepDisabled: PropTypes.bool,
previousStepDisabled: PropTypes.bool,
stepButtonsDisabled: PropTypes.bool,
nextButtonRef: PropTypes.func,
bodyHeader: PropTypes.node,
Expand All @@ -191,6 +194,7 @@ WizardPattern.defaultProps = {
closeText: 'Close',
steps: [],
nextStepDisabled: false,
previousStepDisabled: false,
stepButtonsDisabled: false,
nextButtonRef: noop,
bodyHeader: null,
Expand Down
38 changes: 38 additions & 0 deletions packages/patternfly-react/src/components/Wizard/Wizard.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ const testStatefulWizardPattern = props => {
onExited={onExited}
title="Wizard Pattern Stateful Example"
shouldDisableNextStep={() => false}
shouldDisablePreviousStep={() => false}
shouldPreventStepChange={() => false}
steps={[
{ title: 'General', render: () => <p>General</p> },
Expand Down Expand Up @@ -444,6 +445,28 @@ const testDisableNextStepWizard = props => {
);
};

const testDisablePreviousStepWizard = props => {
const onHide = jest.fn();
const onExited = jest.fn();
const onStepChanged = jest.fn();
return (
<Wizard.Pattern.Stateful
show
onHide={onHide}
onExited={onExited}
onStepChanged={onStepChanged}
title="Wizard Disable Next Step"
shouldDisablePreviousStep={() => true}
steps={[
{ title: '1', render: () => <p>1</p> },
{ title: '2', render: () => <p className=".step2">2</p> },
{ title: '3', render: () => <p>3</p> }
]}
{...props}
/>
);
};

test('Wizard Stateful with shouldDisableNextStep should disable next step', () => {
const component = mount(testDisableNextStepWizard());
expect(
Expand All @@ -453,3 +476,18 @@ test('Wizard Stateful with shouldDisableNextStep should disable next step', () =
.getDOMNode().disabled
).toBe(true);
});

test('Wizard Stateful with shouldDisablePreviousStep should disable previous step', () => {
const component = mount(testDisablePreviousStepWizard());
component
.find('.wizard-pf-footer .btn')
.at(2)
.simulate('click');
expect(component.exists('.step2')).toEqual(true);
expect(
component
.find('.wizard-pf-footer .btn')
.at(1)
.getDOMNode().disabled
).toBe(true);
});
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ exports[`Wizard Stateful Pattern renders properly: Wizard stateful pattern snaps
onHide={[MockFunction]}
onNext={[Function]}
onStepChanged={[Function]}
previousStepDisabled={false}
shouldPreventStepChange={[Function]}
show={true}
stepButtonsDisabled={false}
Expand Down

0 comments on commit e73a6e3

Please sign in to comment.