diff --git a/src/components/base/Stepper/index.js b/src/components/base/Stepper/index.js new file mode 100644 index 00000000..038aef23 --- /dev/null +++ b/src/components/base/Stepper/index.js @@ -0,0 +1,81 @@ +// @flow + +import React, { PureComponent } from 'react' +import invariant from 'invariant' +import { translate } from 'react-i18next' + +import type { T } from 'types/common' + +import { ModalContent, ModalTitle, ModalFooter, ModalBody } from 'components/base/Modal' +import Breadcrumb from 'components/Breadcrumb' + +type Props = { + t: T, + title: string, + initialStepId: string, + onClose: void => void, + steps: Step[], + children: any, +} + +export type Step = { + id: string, + label: string, + component: StepProps => React$Node, + footer: StepProps => React$Node, + preventClose?: boolean, + onBack?: StepProps => void, +} + +type State = { + stepId: string, +} + +export type StepProps = { + t: T, + transitionTo: string => void, +} + +class Stepper extends PureComponent { + state = { + stepId: this.props.initialStepId, + } + + transitionTo = stepId => this.setState({ stepId }) + + render() { + const { t, steps, title, onClose, children, ...props } = this.props + const { stepId } = this.state + + const stepIndex = steps.findIndex(s => s.id === stepId) + const step = steps[stepIndex] + + invariant(step, `Stepper: step ${stepId} doesn't exists`) + + const { component: StepComponent, footer: StepFooter, onBack, preventClose } = step + + const stepProps: StepProps = { + t, + transitionTo: this.transitionTo, + ...props, + } + + return ( + + onBack(stepProps) : undefined}>{title} + + + + {children} + + {StepFooter && ( + + + + )} + + ) + } +} + +export default translate()(Stepper) diff --git a/src/components/base/Stepper/stories.js b/src/components/base/Stepper/stories.js new file mode 100644 index 00000000..4cb41487 --- /dev/null +++ b/src/components/base/Stepper/stories.js @@ -0,0 +1,50 @@ +// @flow + +import React from 'react' +import { storiesOf } from '@storybook/react' +import { action } from '@storybook/addon-actions' + +import Stepper from 'components/base/Stepper' +import Button from 'components/base/Button' + +import type { StepProps, Step } from 'components/base/Stepper' + +const stories = storiesOf('Components/base', module) + +const steps: Step[] = [ + { + id: 'first', + label: 'first step', + component: () =>
first step
, + footer: ({ transitionTo }: StepProps) => ( +
+ +
+ ), + }, + { + id: 'second', + label: 'second step', + preventClose: true, + onBack: ({ transitionTo }: StepProps) => transitionTo('first'), + component: () =>
second step (you cant close on this one)
, + footer: ({ transitionTo }: StepProps) => ( +
+ +
+ ), + }, +] + +stories.add('Stepper', () => ( + +))