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
450 lines (371 loc) • 16.2 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Stepper = exports.Step = undefined;
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _styles = require('./styles');
var _lodash = require('lodash');
var _lodash2 = _interopRequireDefault(_lodash);
var _propTypes = require('prop-types');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
/**
* @class{Step} Should be a child of Stepper component
*/
var Step = exports.Step = function (_React$PureComponent) {
_inherits(Step, _React$PureComponent);
function Step() {
_classCallCheck(this, Step);
return _possibleConstructorReturn(this, (Step.__proto__ || Object.getPrototypeOf(Step)).apply(this, arguments));
}
_createClass(Step, [{
key: 'render',
value: function render() {
return _react2.default.isValidElement(this.props.children) ? this.props.children : null;
}
}]);
return Step;
}(_react2.default.PureComponent);
/**
* @class{CustomStepWrapper} Uses this component to render child if we are rendering Custom Step
*/
var CustomStepWrapper = function (_React$Component) {
_inherits(CustomStepWrapper, _React$Component);
function CustomStepWrapper() {
_classCallCheck(this, CustomStepWrapper);
return _possibleConstructorReturn(this, (CustomStepWrapper.__proto__ || Object.getPrototypeOf(CustomStepWrapper)).apply(this, arguments));
}
_createClass(CustomStepWrapper, [{
key: 'clickHandler',
value: function clickHandler() {
this.props.handleClick && this.props.handleClick();
}
}, {
key: 'render',
value: function render() {
return _react2.default.createElement(
'div',
{
style: this.props.styles || {},
onClick: this.clickHandler.bind(this)
},
this.props.children
);
}
}]);
return CustomStepWrapper;
}(_react2.default.Component);
/**
* @class{Stepper} Parent class controlling the logic and rendering of steps
*/
var Stepper = exports.Stepper = function (_React$PureComponent2) {
_inherits(Stepper, _React$PureComponent2);
function Stepper(props) {
_classCallCheck(this, Stepper);
var _this3 = _possibleConstructorReturn(this, (Stepper.__proto__ || Object.getPrototypeOf(Stepper)).call(this, props));
_this3.getIcon = function (childProps, index) {
if (childProps.disabled) {
return childProps.disabledIcon || childProps.icon || _this3.props.disabledIcon || _this3.props.icon || _react2.default.createElement(_styles.InactiveIconContainer, null);
} else if (index === _this3.state.stepIndex) {
return childProps.activeIcon || childProps.icon || _this3.props.activeIcon || _this3.props.icon || _react2.default.createElement(
_styles.ActiveIconContainer,
null,
_react2.default.createElement('i', { className: 'fa fa-chevron-right' })
);
} else if (_this3.state.doneMapping[index]) {
return childProps.doneIcon || childProps.icon || _this3.props.doneIcon || _this3.props.icon || _react2.default.createElement(
_styles.DoneIconContainer,
null,
_react2.default.createElement('i', { className: 'fa fa-check' })
);
}
return childProps.inactiveIcon || childProps.icon || _this3.props.inactiveIcon || _this3.props.icon || _react2.default.createElement(_styles.InactiveIconContainer, null);
};
_this3.handleClick = function (index) {
var childrenArray = _this3.steps;
if (!childrenArray[index].props.disabled && _this3.state.doneMapping[index]) {
if (_this3.props.onChange && typeof _this3.props.stepIndex !== 'undefined') {
_this3.props.onChange(index, 'click');
} else {
_this3.setState({ stepIndex: index });
}
}
};
_this3.next = function () {
var index = _this3.state.stepIndex;
var childrenArray = _this3.steps;
/**
* Mark the current step as done in case of un-controlled component
*/
if (!_this3.props.doneMapping) {
var doneMapping = [].concat(_toConsumableArray(_this3.state.doneMapping));
doneMapping[index] = true;
_this3.setState({ doneMapping: doneMapping });
}
/**
* Call onComplete handler if all steps are complete
*/
if (index === childrenArray.length - 1) {
if (_this3.props.onComplete) {
_this3.props.onComplete();
}
return;
}
/**
* Calculate the next step index
*/
while (index < childrenArray.length && (index === _this3.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 (_this3.props.onChange && _this3.props.stepIndex !== 'undefined') {
_this3.props.onChange(index, 'next');
} else {
_this3.setState({
stepIndex: index
});
}
}
};
_this3.previous = function () {
var index = _this3.state.stepIndex;
var childrenArray = _this3.steps;
/**
* Calculate the previous index
*/
while (index > 0 && (index === _this3.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 (_this3.props.onChange && typeof _this3.props.stepIndex !== 'undefined') {
_this3.props.onChange(index, 'previous');
} else {
_this3.setState({
stepIndex: index
});
}
}
};
_this3.getChildType = function (type) {
return _lodash2.default.filter(_react2.default.Children.toArray(_this3.props.children), function (child) {
return child.type === type;
});
};
_this3.getChildPropType = function (type) {
return _lodash2.default.filter(_react2.default.Children.toArray(_this3.props.children), function (child) {
return child.props.type === type;
});
};
_this3.state = {
stepIndex: props.stepIndex || 0,
doneMapping: props.doneMapping || Array(_react2.default.Children.count(props.children)).fill(false)
};
return _this3;
}
/**
* Update local state when props change
* @param {object} nextProps
*/
_createClass(Stepper, [{
key: 'componentWillReceiveProps',
value: function 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
*/
/**
* Function to get all the children of 'type'
*/
/**
* Function to get all the children with prop 'type'
*/
}, {
key: 'render',
value: function render() {
var _this4 = this;
this.steps = this.props.customStep ? this.getChildPropType('custom-step-item') : this.getChildType(Step);
this.customStepContents = this.getChildPropType('custom-step-content');
return _react2.default.createElement(
_styles.StepperContainer,
{
className: 'stepper',
orientation: this.props.orientation,
styles: this.props.styles.container || {}
},
_react2.default.createElement(
_styles.StepsWrapper,
{
className: 'steps-wrapper',
orientation: this.props.orientation,
styles: this.props.styles.stepper || {}
},
!this.props.customStep && _lodash2.default.map(this.steps, function (step, index) {
return _react2.default.createElement(
_styles.StepItem,
{
orientation: _this4.props.orientation,
styles: _this4.props.styles.step || {},
onClick: function onClick() {
return _this4.handleClick(index);
},
active: index === _this4.state.stepIndex,
done: _this4.state.doneMapping[index],
key: index
},
_this4.getIcon(step.props, index),
step.props.label
);
}),
this.props.customStep && _lodash2.default.map(this.steps, function (customStep, index) {
return _react2.default.createElement(
CustomStepWrapper,
{
key: index,
styles: _this4.props.styles.step || {},
handleClick: _this4.handleClick.bind(_this4, index)
},
_react2.default.cloneElement(customStep, {
active: index === _this4.state.stepIndex
})
);
})
),
!this.props.customStep && _react2.default.createElement(
_styles.ContentWrapper,
{ className: 'content-wrapper' },
this.props.header ? this.props.header : null,
this.steps[this.state.stepIndex],
this.props.footer ? this.props.footer : null
),
this.props.customStep && _lodash2.default.find(this.customStepContents, function (child) {
return child.props.stepChild === _this4.state.stepIndex;
})
);
}
}]);
return Stepper;
}(_react2.default.PureComponent);
Stepper.propTypes = {
/**
* Orientation of the stepper. May be horizontal or vertical
*/
orientation: _propTypes.PropTypes.oneOf(['horizontal', 'vertical']),
/**
* Styles of the stepper.
*/
styles: _propTypes.PropTypes.object,
/**
* Current step index ( to be passes for controlled component)
*/
stepIndex: _propTypes.PropTypes.number,
/**
* Header element
*/
header: _propTypes.PropTypes.element,
/**
* Footer element
*/
footer: _propTypes.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.PropTypes.arrayOf(_propTypes.PropTypes.number),
/**
* Invoked when the step changes
*/
onChange: _propTypes.PropTypes.func,
/**
* Invoked when all the steps are completed
*/
onComplete: _propTypes.PropTypes.func,
/**
* Default icon JSX element
*/
icon: _propTypes.PropTypes.element,
/**
* Inactive icon. Ovverrides icon prop for inactive state
*/
inactiveIcon: _propTypes.PropTypes.element,
/**
* Active icon. Overrides icon prop for active state
*/
activeIcon: _propTypes.PropTypes.element,
/**
* Disabled icon. Overrides icon prop for disabled state
*/
disabledIcon: _propTypes.PropTypes.element,
/**
* Should be true if we are rendering customised step
*/
customStep: _propTypes.PropTypes.bool
};
Step.propTypes = {
/**
* Label for each step
*/
label: _propTypes.PropTypes.string,
/**
* Set disabled to true to disable a step
*/
disabled: _propTypes.PropTypes.bool,
/**
* Icon for a specific step. If provided, it ovverides the icon provided
* in the parent Stepper Component
*/
icon: _propTypes.PropTypes.element,
/**
* Inactive icon. Ovverrides icon prop for inactive state
*/
inactiveIcon: _propTypes.PropTypes.element,
/**
* Active icon. Ovverrides icon prop for inactive state
*/
activeIcon: _propTypes.PropTypes.element,
/**
* Disabled icon. Ovverrides icon prop for inactive state
*/
disabledIcon: _propTypes.PropTypes.element
};
Stepper.defaultProps = {
orientation: 'vertical',
styles: {},
disabled: false,
customStep: false
};