UNPKG

fk-react-ui-components

Version:

Step 1 : Create a file in [ Seeds / Plants / Trees ] <br> Step 2 : It should export an Object with component name and story Component [Refer other components] <br> Step 3 : Story Component should return a react component <br> Step 3 : Created file should

310 lines (267 loc) 9.54 kB
import React from 'react'; import { StepperContainer, StepsWrapper, ContentWrapper, StepItem, DoneIconContainer, ActiveIconContainer, InactiveIconContainer } from './styles'; import { PropTypes } from 'prop-types'; /** * @class{Step} Should be a child of Stepper component */ export class Step extends React.PureComponent { render() { return React.isValidElement(this.props.children) ? this.props.children : null; } } /** * @class{Stepper} Parent class controlling the logic and rendering of steps */ export class Stepper extends React.PureComponent { constructor(props) { super(props); this.getIcon = (childProps, index) => { if (childProps.disabled) { return childProps.disabledIcon || childProps.icon || this.props.disabledIcon || this.props.icon || React.createElement(InactiveIconContainer, null); } else if (index === this.state.stepIndex) { return childProps.activeIcon || childProps.icon || this.props.activeIcon || this.props.icon || React.createElement( ActiveIconContainer, null, React.createElement('i', { className: 'fa fa-chevron-right' }) ); } else if (this.state.doneMapping[index]) { return childProps.doneIcon || childProps.icon || this.props.doneIcon || this.props.icon || React.createElement( DoneIconContainer, null, React.createElement('i', { className: 'fa fa-check' }) ); } else { return childProps.inactiveIcon || childProps.icon || this.props.inactiveIcon || this.props.icon || React.createElement(InactiveIconContainer, null); } }; this.handleClick = index => { const childrenArray = React.Children.toArray(this.props.children); if (!childrenArray[index].props.disabled && this.state.doneMapping[index]) { if (this.props.onChange && typeof this.props.stepIndex !== 'undefined') { this.props.onChange(index, 'click'); } else { this.setState({ stepIndex: index }); } } }; this.next = () => { let index = this.state.stepIndex; const childrenArray = React.Children.toArray(this.props.children); /** * Mark the current step as done in case of un-controlled component */ if (!this.props.doneMapping) { const doneMapping = [...this.state.doneMapping]; doneMapping[index] = true; this.setState({ doneMapping }); } /** * Call onComplete handler if all steps are complete */ if (index === childrenArray.length - 1) { if (this.props.onComplete) { this.props.onComplete(); } return; } /** * Calculate the next step index */ while (index < childrenArray.length && (index === this.state.stepIndex || childrenArray[index].props.disabled)) { index += 1; } /** * Update the step index in the local state in case of un-controlled component. * For controlled component simply call the onChange handler */ if (!childrenArray[index].props.disabled) { if (this.props.onChange && this.props.stepIndex !== 'undefined') { this.props.onChange(index, 'next'); } else { this.setState({ stepIndex: index }); } } }; this.previous = () => { let index = this.state.stepIndex; const childrenArray = React.Children.toArray(this.props.children); /** * Calculate the previous index */ while (index > 0 && (index === this.state.stepIndex || childrenArray[index].props.disabled)) { index -= 1; } /** * Update the step index in the local state in case of un-controlled component. * For controlled component simply call the onChange handler */ if (!childrenArray[index].props.disabled) { if (this.props.onChange && typeof this.props.stepIndex !== 'undefined') { this.props.onChange(index, 'previous'); } else { this.setState({ stepIndex: index }); } } }; this.state = { stepIndex: props.stepIndex || 0, doneMapping: props.doneMapping || Array(React.Children.count(props.children)).fill(false) }; } /** * Update local state when props change * @param {object} nextProps */ componentWillReceiveProps(nextProps) { if (this.props.stepIndex !== nextProps.stepIndex) { this.setState({ stepIndex: nextProps.stepIndex }); } if (this.props.doneMapping !== nextProps.doneMapping) { this.setState({ doneMapping: nextProps.doneMapping }); } } /** * Returns the icon to be rendered for any step * @param {object} childProps * @param {number} index * @return {element} */ /** * Handles click on any step. * Calls onClick prop if provided else goes to that step if current * stepIndex is greater than index and step is not disabled * @param {number} index */ /** * Function to move to the next step */ /** * Function to move to the previous step */ render() { return React.createElement( StepperContainer, { orientation: this.props.orientation, styles: this.props.styles.container || {} }, React.createElement( StepsWrapper, { orientation: this.props.orientation, styles: this.props.styles.stepper || {} }, React.Children.map(this.props.children, (step, index) => { return React.createElement( StepItem, { orientation: this.props.orientation, styles: this.props.styles.step || {}, onClick: () => this.handleClick(index), active: index === this.state.stepIndex, done: this.state.doneMapping[index] }, this.getIcon(step.props, index), step.props.label ); }) ), React.createElement( ContentWrapper, null, this.props.header ? this.props.header : null, React.Children.toArray(this.props.children)[this.state.stepIndex], this.props.footer ? this.props.footer : null ) ); } } Stepper.propTypes = { /** * Orientation of the stepper. May be horizontal or vertical */ orientation: PropTypes.oneOf(['horizontal', 'vertical']), /** * Styles of the stepper. */ styles: PropTypes.object, /** * Current step index ( to be passes for controlled component) */ stepIndex: PropTypes.number, /** * Header element */ header: PropTypes.element, /** * Footer element */ footer: PropTypes.element, /** * Mapping of steps vs there done state (true / false) * e.g. [true, false, false, false] (First step is done, rest are not) * To be passed for controlled component */ doneMapping: PropTypes.arrayOf(PropTypes.number), /** * Invoked when the step changes */ onChange: PropTypes.func, /** * Invoked when all the steps are completed */ onComplete: PropTypes.func, /** * Default icon JSX element */ icon: PropTypes.element, /** * Inactive icon. Ovverrides icon prop for inactive state */ inactiveIcon: PropTypes.element, /** * Active icon. Overrides icon prop for active state */ activeIcon: PropTypes.element, /** * Disabled icon. Overrides icon prop for disabled state */ disabledIcon: PropTypes.element }; Step.propTypes = { /** * Label for each step */ label: PropTypes.string, /** * Set disabled to true to disable a step */ disabled: PropTypes.bool, /** * Icon for a specific step. If provided, it ovverides the icon provided * in the parent Stepper Component */ icon: PropTypes.element, /** * Inactive icon. Ovverrides icon prop for inactive state */ inactiveIcon: PropTypes.element, /** * Active icon. Ovverrides icon prop for inactive state */ activeIcon: PropTypes.element, /** * Disabled icon. Ovverrides icon prop for inactive state */ disabledIcon: PropTypes.element }; Stepper.defaultProps = { orientation: 'vertical', styles: {}, disabled: false }; //# sourceMappingURL=index.js.map