zent
Version:
一套前端设计语言和基于React的实现
486 lines (401 loc) • 14.2 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _defineProperty2 = require('babel-runtime/helpers/defineProperty');
var _defineProperty3 = _interopRequireDefault(_defineProperty2);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _classnames4 = require('classnames');
var _classnames5 = _interopRequireDefault(_classnames4);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _popover = require('../popover');
var _popover2 = _interopRequireDefault(_popover);
var _tabs = require('../tabs');
var _tabs2 = _interopRequireDefault(_tabs);
var _icon = require('../icon');
var _icon2 = _interopRequireDefault(_icon);
var _forEach = require('lodash/forEach');
var _forEach2 = _interopRequireDefault(_forEach);
var _find = require('lodash/find');
var _find2 = _interopRequireDefault(_find);
var _noop = require('lodash/noop');
var _noop2 = _interopRequireDefault(_noop);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var PopoverContent = _popover2['default'].Content;
var withPopover = _popover2['default'].withPopover;
var TabPanel = _tabs2['default'].TabPanel;
var PopoverClickTrigger = function (_Popover$Trigger$Clic) {
(0, _inherits3['default'])(PopoverClickTrigger, _Popover$Trigger$Clic);
function PopoverClickTrigger() {
(0, _classCallCheck3['default'])(this, PopoverClickTrigger);
return (0, _possibleConstructorReturn3['default'])(this, (PopoverClickTrigger.__proto__ || Object.getPrototypeOf(PopoverClickTrigger)).apply(this, arguments));
}
(0, _createClass3['default'])(PopoverClickTrigger, [{
key: 'getTriggerProps',
value: function getTriggerProps(child) {
var _this2 = this;
return {
onClick: function onClick(evt) {
if (_this2.props.contentVisible) {
_this2.props.close();
} else {
_this2.props.open();
}
_this2.triggerEvent(child, 'onClick', evt);
}
};
}
}]);
return PopoverClickTrigger;
}(_popover2['default'].Trigger.Click);
var _ref3 = _react2['default'].createElement(_icon2['default'], { type: 'caret-down' });
var Cascader = function (_ref) {
(0, _inherits3['default'])(Cascader, _ref);
function Cascader(props) {
(0, _classCallCheck3['default'])(this, Cascader);
var _this3 = (0, _possibleConstructorReturn3['default'])(this, (Cascader.__proto__ || Object.getPrototypeOf(Cascader)).call(this, props));
_this3.onShow = function () {
_this3.setState({
open: true
});
};
_this3.onClose = function () {
_this3.setState({
open: false
});
};
_this3.onTabChange = function (id) {
_this3.setState({
activeId: id
});
};
_this3.clickHandler = function (item, stage, popover) {
var loadMore = _this3.props.loadMore;
var options = _this3.state.options;
if (!item.isLeaf && loadMore && (!item.children || item.children.length === 0)) {
_this3.setState({
isLoading: true,
loadingStage: stage
});
loadMore(item, stage).then(function (children) {
item.children = children;
_this3.expandHandler(item, stage, popover);
_this3.setState({
options: options,
isLoading: false
});
});
} else {
_this3.expandHandler(item, stage, popover);
}
};
_this3.expandHandler = function (item, stage, popover) {
var value = _this3.state.value;
var changeOnSelect = _this3.props.changeOnSelect;
var hasClose = false;
value = value.slice(0, stage - 1);
value.push(item.id);
var obj = {
value: value
};
if (item.children) {
obj.activeId = ++stage;
} else {
hasClose = true;
popover.close();
}
if (hasClose || changeOnSelect) {
_this3.resetCascaderValue(value);
}
_this3.setState(obj);
};
_this3.state = {
value: props.value,
options: props.options,
onChangeValue: [],
activeId: 1,
open: false
};
return _this3;
}
(0, _createClass3['default'])(Cascader, [{
key: 'componentWillMount',
value: function componentWillMount() {
this.resetCascaderValue(null, null, false);
}
}, {
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
var loadMore = this.props.loadMore;
if (nextProps.hasOwnProperty('value')) {
var nextValue = nextProps.value || [];
if (!loadMore) {
this.setState({
value: nextValue
});
}
this.resetCascaderValue(nextValue, nextProps.options, false);
}
if (this.props.options !== nextProps.options) {
this.setState({
options: nextProps.options
});
}
}
}, {
key: 'resetCascaderValue',
value: function resetCascaderValue(value, options) {
var isTriggerChange = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
var onChangeValue = [];
var activeId = 1;
var onChange = this.props.onChange;
var state = this.state;
value = value || state.value;
options = options || state.options;
if (options && options.length > 0 && value && value.length > 0) {
activeId = 0;
(0, _forEach2['default'])(value, function (id) {
var nextOption = (0, _find2['default'])(options, { id: id });
activeId++;
options = nextOption.children;
onChangeValue.push({
id: nextOption.id,
title: nextOption.title
});
});
}
if (isTriggerChange) {
onChange(onChangeValue);
}
this.setState({
onChangeValue: onChangeValue,
activeId: activeId
});
}
}, {
key: 'recursiveNextOptions',
value: function recursiveNextOptions(options, id) {
if (options && options.length > 0) {
var currOptions = (0, _find2['default'])(options, { id: id });
if (currOptions && currOptions.children) {
return currOptions.children;
}
}
}
}, {
key: 'renderPanels',
value: function renderPanels(popover) {
var PanelEls = [];
var tabIndex = 1;
var title = this.props.title;
var _state = this.state,
options = _state.options,
value = _state.value;
var tabTitle = '标题';
title = title || [];
if (title.length > 0) {
tabTitle = title[0];
}
PanelEls.push(_react2['default'].createElement(
TabPanel,
{
tab: this.renderTabTitle(tabTitle, tabIndex),
id: tabIndex,
key: tabIndex
},
this.renderCascaderItems(options, tabIndex, popover)
));
if (value && value.length > 0) {
for (var i = 0; i < value.length; i++) {
tabIndex++;
options = this.recursiveNextOptions(options, value[i]);
if (title.length >= tabIndex) {
tabTitle = title[tabIndex - 1];
} else {
tabTitle = '标题';
}
if (options) {
PanelEls.push(_react2['default'].createElement(
TabPanel,
{
tab: this.renderTabTitle(tabTitle, tabIndex),
id: tabIndex,
key: tabIndex
},
this.renderCascaderItems(options, tabIndex, popover)
));
}
}
}
return PanelEls;
}
}, {
key: 'renderCascaderItems',
value: function renderCascaderItems(items, stage, popover) {
var _this4 = this;
var prefix = this.props.prefix;
var value = this.state.value;
var cascaderItems = items.map(function (item) {
var _classnames;
var cascaderItemCls = (0, _classnames5['default'])((_classnames = {}, (0, _defineProperty3['default'])(_classnames, prefix + '-cascader__list-link', true), (0, _defineProperty3['default'])(_classnames, 'active', item.id === value[stage - 1]), _classnames));
return _react2['default'].createElement(
'div',
{ className: prefix + '-cascader__list-item', key: item.id },
_react2['default'].createElement(
'span',
{
className: cascaderItemCls,
title: item.title,
onClick: function onClick() {
return _this4.clickHandler(item, stage, popover);
}
},
item.title
)
);
});
return _react2['default'].createElement(
'div',
{ className: prefix + '-cascader__list' },
cascaderItems
);
}
}, {
key: 'renderTabTitle',
value: function renderTabTitle(title, stage) {
var prefix = this.props.prefix;
var _state2 = this.state,
isLoading = _state2.isLoading,
loadingStage = _state2.loadingStage;
if (isLoading && stage === loadingStage) {
return _react2['default'].createElement(
'div',
{ className: prefix + '-cascader__loading' },
_react2['default'].createElement(
'div',
{ className: prefix + '-cascader__loading-label' },
title
),
_react2['default'].createElement('div', { className: prefix + '-cascader__loading-icon' })
);
}
return title;
}
}, {
key: 'render',
value: function render() {
var _this5 = this,
_classnames2,
_classnames3;
var _props = this.props,
prefix = _props.prefix,
className = _props.className,
popClassName = _props.popClassName,
placeholder = _props.placeholder;
var _state3 = this.state,
onChangeValue = _state3.onChangeValue,
open = _state3.open,
activeId = _state3.activeId;
var CascaderPopoverContent = withPopover(function (_ref2) {
var popover = _ref2.popover;
return _react2['default'].createElement(
'div',
{ className: prefix + '-cascader__popup-inner' },
_react2['default'].createElement(
_tabs2['default'],
{
activeId: activeId,
onTabChange: _this5.onTabChange,
className: prefix + '-cascader__tabs'
},
_this5.renderPanels(popover)
)
);
});
var cascaderValue = placeholder;
var hasValue = false;
if (onChangeValue && onChangeValue.length > 0) {
hasValue = true;
cascaderValue = onChangeValue.map(function (valueItem) {
return valueItem.title;
});
cascaderValue = cascaderValue.join(' / ');
}
var cascaderCls = (0, _classnames5['default'])((_classnames2 = {}, (0, _defineProperty3['default'])(_classnames2, prefix + '-cascader', true), (0, _defineProperty3['default'])(_classnames2, className, true), (0, _defineProperty3['default'])(_classnames2, 'open', open), _classnames2));
var selectTextCls = (0, _classnames5['default'])((_classnames3 = {}, (0, _defineProperty3['default'])(_classnames3, prefix + '-cascader__select-text', true), (0, _defineProperty3['default'])(_classnames3, 'is-placeholder', !hasValue), _classnames3));
return _react2['default'].createElement(
'div',
{ className: cascaderCls },
_react2['default'].createElement(
_popover2['default'],
{
className: popClassName,
position: _popover2['default'].Position.BottomLeft,
onShow: this.onShow,
onClose: this.onClose
},
_react2['default'].createElement(
PopoverClickTrigger,
null,
_react2['default'].createElement(
'div',
{ className: prefix + '-cascader__select' },
_react2['default'].createElement(
'div',
{ className: selectTextCls },
_react2['default'].createElement(
'span',
{ className: prefix + '-cascader__select-text-content' },
cascaderValue
),
_ref3
)
)
),
_react2['default'].createElement(
PopoverContent,
null,
_react2['default'].createElement(CascaderPopoverContent, { ref: function ref(_ref4) {
return _this5.cascader = _ref4;
} })
)
)
);
}
}]);
return Cascader;
}(_react.PureComponent || _react.Component);
Cascader.propTypes = {
prefix: _propTypes2['default'].string,
className: _propTypes2['default'].string,
popClassName: _propTypes2['default'].string,
onChange: _propTypes2['default'].func,
loadMore: _propTypes2['default'].func,
value: _propTypes2['default'].array,
options: _propTypes2['default'].array,
placeholder: _propTypes2['default'].string,
changeOnSelect: _propTypes2['default'].bool,
title: _propTypes2['default'].array
};
Cascader.defaultProps = {
prefix: 'zent',
className: '',
popClassName: 'zent-cascader__popup',
onChange: _noop2['default'],
value: [],
options: [],
placeholder: '请选择',
changeOnSelect: false,
title: ['省份', '城市', '县区']
};
exports['default'] = Cascader;