Skip to content

Instantly share code, notes, and snippets.

@nodox
Last active July 1, 2018 21:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nodox/200f13279f7c70b67613cb634eae81be to your computer and use it in GitHub Desktop.
Save nodox/200f13279f7c70b67613cb634eae81be to your computer and use it in GitHub Desktop.
Building a stepper with compound components
import React from "react";
import { render } from "react-dom";
import { StepList } from "./StepList";
import { Step } from "./Step";
const PageTwo = () => (
<h2>We have a second page.</h2>
)
const PageThree = () => (
<h2>Page three is working.</h2>
)
const App = () => (
<StepList>
<Step>
<h1>Hello world on page one!</h1>
</Step>
<Step component={PageTwo} />
<Step component={PageThree} />
</StepList>
);
render(<App />, document.getElementById("root"));
import React from "react";
class Next extends React.Component {
render() {
const { isActive } = this.props;
if (isActive === false) return null;
return (
<button onClick={() => this.props.goToNextStep()}>
Next
</button>
);
}
}
class Previous extends React.Component {
render() {
const { isActive } = this.props;
if (isActive === false) return null;
return (
<button onClick={() => this.props.goToPreviousStep()}>
Previous
</button>
);
}
}
class Submit extends React.Component {
render() {
const { isActive } = this.props;
if (isActive === false) return null;
return (
<button type="submit">
Submit
</button>
);
}
}
export { Previous, Next, Submit };
import React from "react";
import { Previous, Next, Submit } from "./Buttons";
class Step extends React.Component {
render() {
const {
isActive,
displayPrevious,
displayNext,
displaySubmit,
component,
children,
} = this.props;
if(isActive === false) return null;
return (
<React.Fragment>
{component ? React.createElement(component) : children}
<Previous
isActive={displayPrevious}
goToPreviousStep={() => this.props.goToPreviousStep()}
/>
<Next
isActive={displayNext}
goToNextStep={() => this.props.goToNextStep()}
/>
<Submit isActive={displaySubmit} />
</React.Fragment>
);
}
}
export { Step };
import React from "react";
class StepList extends React.Component {
constructor(props) {
super(props);
this.state = {
currentStep: 0,
totalSteps: this.props.children.length - 1,
};
}
goToPreviousStep = () => {
this.setState({ currentStep: this.state.currentStep - 1 });
};
goToNextStep = () => {
this.setState({ currentStep: this.state.currentStep + 1 });
};
render() {
const children = React.Children.map(this.props.children, (child, index) => {
const { currentStep, totalSteps } = this.state;
return React.cloneElement(child, {
isActive: index === currentStep,
displayPrevious: currentStep > 0,
displayNext: currentStep < totalSteps,
displaySubmit: currentStep === totalSteps,
goToPreviousStep: () => this.goToPreviousStep(),
goToNextStep: () => this.goToNextStep(),
});
});
return children;
}
}
export { StepList };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment