@alifd/next
Version:
A configurable component library for web built on React.
698 lines (606 loc) • 24.5 kB
JavaScript
'use strict';
exports.__esModule = true;
var _extends2 = require('babel-runtime/helpers/extends');
var _extends3 = _interopRequireDefault(_extends2);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
var _class, _temp;
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _classnames = require('classnames');
var _classnames2 = _interopRequireDefault(_classnames);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _reactLifecyclesCompat = require('react-lifecycles-compat');
var _icon = require('../../icon');
var _icon2 = _interopRequireDefault(_icon);
var _button = require('../../button');
var _button2 = _interopRequireDefault(_button);
var _zhCn = require('../../locale/zh-cn');
var _zhCn2 = _interopRequireDefault(_zhCn);
var _util = require('../../util');
var _configProvider = require('../../config-provider');
var _configProvider2 = _interopRequireDefault(_configProvider);
var _transferPanel = require('../view/transfer-panel');
var _transferPanel2 = _interopRequireDefault(_transferPanel);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var config = _configProvider2.default.config;
var bindCtx = _util.func.bindCtx;
var pickOthers = _util.obj.pickOthers;
var getLeftValue = function getLeftValue(dataSource, rightValue) {
return dataSource.map(function (item) {
return item.value;
}).filter(function (itemValue) {
return rightValue.indexOf(itemValue) === -1;
});
};
var filterCheckedValue = function filterCheckedValue(left, right, dataSource) {
var result = {
left: [],
right: []
};
if (left.length || right.length) {
var value = dataSource.map(function (item) {
return item.value;
});
value.forEach(function (itemValue) {
if (left.indexOf(itemValue) > -1) {
result.left.push(itemValue);
} else if (right.indexOf(itemValue) > -1) {
result.right.push(itemValue);
}
});
}
return result;
};
/**
* Transfer
*/
var Transfer = (_temp = _class = function (_Component) {
(0, _inherits3.default)(Transfer, _Component);
Transfer.normalizeValue = function normalizeValue(value) {
if (value) {
if (Array.isArray(value)) {
return value;
}
/* istanbul ignore next */
return [value];
}
return [];
};
Transfer.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, prevState) {
var innerUpdate = prevState.innerUpdate,
value = prevState.value,
leftValue = prevState.leftValue;
if (innerUpdate) {
return {
innerUpdate: false,
value: value,
leftValue: leftValue
};
}
var st = {};
var newValue = void 0;
if ('value' in nextProps) {
var _value = Transfer.normalizeValue(nextProps.value);
st.value = _value;
newValue = _value;
} else {
/* istanbul ignore next */
newValue = prevState.value;
}
st.leftValue = getLeftValue(nextProps.dataSource, newValue);
var _filterCheckedValue = filterCheckedValue(prevState.leftCheckedValue, prevState.rightCheckedValue, nextProps.dataSource),
left = _filterCheckedValue.left,
right = _filterCheckedValue.right;
st.leftCheckedValue = left;
st.rightCheckedValue = right;
return st;
};
function Transfer(props, context) {
(0, _classCallCheck3.default)(this, Transfer);
var _this = (0, _possibleConstructorReturn3.default)(this, _Component.call(this, props, context));
var value = props.value,
defaultValue = props.defaultValue,
defaultLeftChecked = props.defaultLeftChecked,
defaultRightChecked = props.defaultRightChecked,
dataSource = props.dataSource,
rtl = props.rtl,
operations = props.operations;
if (operations.length === 0) {
operations.push(_react2.default.createElement(_icon2.default, { rtl: rtl, type: 'arrow-right' }));
operations.push(_react2.default.createElement(_icon2.default, { rtl: rtl, type: 'arrow-left' }));
}
var _filterCheckedValue2 = filterCheckedValue(Transfer.normalizeValue(defaultLeftChecked), Transfer.normalizeValue(defaultRightChecked), dataSource),
left = _filterCheckedValue2.left,
right = _filterCheckedValue2.right;
var stValue = Transfer.normalizeValue('value' in props ? value : defaultValue);
_this.state = {
value: stValue,
leftCheckedValue: left,
rightCheckedValue: right,
leftValue: getLeftValue(dataSource, stValue)
};
bindCtx(_this, ['handlePanelChange', 'handlePanelSort', 'handleMoveItem', 'handleSimpleMove', 'handleSimpleMoveAll']);
return _this;
}
Transfer.prototype.groupDatasource = function groupDatasource(value, itemValues, dataSource) {
return value.reduce(function (ret, itemValue) {
var index = itemValues.indexOf(itemValue);
if (index > -1) {
ret.push(dataSource[index]);
}
return ret;
}, []);
};
Transfer.prototype.handlePanelChange = function handlePanelChange(position, value) {
var _setState;
var _state = this.state,
leftCheckedValue = _state.leftCheckedValue,
rightCheckedValue = _state.rightCheckedValue;
var onSelect = this.props.onSelect;
var valuePropName = position === 'left' ? 'leftCheckedValue' : 'rightCheckedValue';
// inner state changed
this.setState((_setState = {
innerUpdate: true
}, _setState[valuePropName] = value, _setState));
onSelect && onSelect(position === 'left' ? value : leftCheckedValue, position === 'left' ? rightCheckedValue : value, position === 'left' ? 'source' : 'target');
};
Transfer.prototype.handlePanelSort = function handlePanelSort(position, dragValue, referenceValue, dragGap) {
var _this2 = this;
var _state2 = this.state,
value = _state2.value,
leftValue = _state2.leftValue;
var newValue = position === 'right' ? value : leftValue;
var currentIndex = newValue.indexOf(dragValue);
var referenceIndex = newValue.indexOf(referenceValue);
var expectIndex = dragGap === 'before' ? referenceIndex : referenceIndex + 1;
if (currentIndex === expectIndex) {
return;
}
newValue.splice(currentIndex, 1);
if (currentIndex < expectIndex) {
expectIndex = expectIndex - 1;
}
newValue.splice(expectIndex, 0, dragValue);
this.setState({
innerUpdate: true,
value: value,
leftValue: leftValue
}, function () {
_this2.props.onSort(newValue, position);
});
};
Transfer.prototype.handleMoveItem = function handleMoveItem(direction) {
var _st;
var rightValue = void 0;
var newLeftValue = void 0;
var movedValue = void 0;
var valuePropName = void 0;
var _state3 = this.state,
value = _state3.value,
leftValue = _state3.leftValue,
leftCheckedValue = _state3.leftCheckedValue,
rightCheckedValue = _state3.rightCheckedValue;
if (direction === 'right') {
rightValue = leftCheckedValue.concat(value);
newLeftValue = leftValue.filter(function (itemValue) {
return leftCheckedValue.indexOf(itemValue) === -1;
});
movedValue = leftCheckedValue;
valuePropName = 'leftCheckedValue';
} else {
rightValue = value.filter(function (itemValue) {
return rightCheckedValue.indexOf(itemValue) === -1;
});
newLeftValue = rightCheckedValue.concat(leftValue);
movedValue = rightCheckedValue;
valuePropName = 'rightCheckedValue';
}
var st = (_st = {}, _st[valuePropName] = [], _st);
this.setValueState(st, rightValue, newLeftValue, movedValue, direction);
};
Transfer.prototype.handleSimpleMove = function handleSimpleMove(direction, v) {
var rightValue = void 0;
var newLeftValue = void 0;
var _state4 = this.state,
value = _state4.value,
leftValue = _state4.leftValue;
if (direction === 'right') {
rightValue = [v].concat(value);
newLeftValue = leftValue.filter(function (itemValue) {
return itemValue !== v;
});
} else {
rightValue = value.filter(function (itemValue) {
return itemValue !== v;
});
newLeftValue = [v].concat(leftValue);
}
this.setValueState({}, rightValue, newLeftValue, [v], direction);
};
Transfer.prototype.handleSimpleMoveAll = function handleSimpleMoveAll(direction) {
var rightValue = void 0;
var newLeftValue = void 0;
var movedValue = void 0;
var dataSource = this.props.dataSource;
var _state5 = this.state,
value = _state5.value,
leftValue = _state5.leftValue;
var disabledValue = dataSource.reduce(function (ret, item) {
if (item.disabled) {
ret.push(item.value);
}
return ret;
}, []);
if (direction === 'right') {
movedValue = leftValue.filter(function (itemValue) {
return disabledValue.indexOf(itemValue) === -1;
});
rightValue = movedValue.concat(value);
newLeftValue = leftValue.filter(function (itemValue) {
return disabledValue.indexOf(itemValue) > -1;
});
} else {
movedValue = value.filter(function (itemValue) {
return disabledValue.indexOf(itemValue) === -1;
});
rightValue = value.filter(function (itemValue) {
return disabledValue.indexOf(itemValue) > -1;
});
newLeftValue = movedValue.concat(leftValue);
}
this.setValueState({}, rightValue, newLeftValue, movedValue, direction);
};
// eslint-disable-next-line max-params
Transfer.prototype.setValueState = function setValueState(st, rightValue, leftValue, movedValue, direction) {
var _this3 = this;
var dataSource = this.props.dataSource;
var callback = function callback() {
if ('onChange' in _this3.props) {
var itemValues = dataSource.map(function (item) {
return item.value;
});
var rightData = _this3.groupDatasource(rightValue, itemValues, dataSource);
var leftData = _this3.groupDatasource(leftValue, itemValues, dataSource);
var movedData = _this3.groupDatasource(movedValue, itemValues, dataSource);
_this3.props.onChange(rightValue, rightData, {
leftValue: leftValue,
leftData: leftData,
movedValue: movedValue,
movedData: movedData,
direction: direction
});
}
};
if (!('value' in this.props)) {
st.value = rightValue;
st.leftValue = leftValue;
}
if (Object.keys(st).length) {
this.setState(st, callback);
} else {
// eslint-disable-next-line callback-return
callback();
}
};
Transfer.prototype.renderCenter = function renderCenter() {
var _props = this.props,
prefix = _props.prefix,
mode = _props.mode,
operations = _props.operations,
disabled = _props.disabled,
leftDisabled = _props.leftDisabled,
rightDisabled = _props.rightDisabled,
locale = _props.locale;
var _state6 = this.state,
leftCheckedValue = _state6.leftCheckedValue,
rightCheckedValue = _state6.rightCheckedValue;
return _react2.default.createElement(
'div',
{ className: prefix + 'transfer-operations' },
mode === 'simple' ? _react2.default.createElement(_icon2.default, { className: prefix + 'transfer-move', size: 'large', type: 'switch' }) : [_react2.default.createElement(
_button2.default,
{
'aria-label': locale.moveToRight,
key: 'l2r',
className: prefix + 'transfer-operation',
type: leftCheckedValue.length ? 'primary' : 'normal',
disabled: leftDisabled || disabled || !leftCheckedValue.length,
onClick: this.handleMoveItem.bind(this, 'right')
},
operations[0]
), _react2.default.createElement(
_button2.default,
{
'aria-label': locale.moveToLeft,
key: 'r2l',
className: prefix + 'transfer-operation',
type: rightCheckedValue.length ? 'primary' : 'normal',
disabled: rightDisabled || disabled || !rightCheckedValue.length,
onClick: this.handleMoveItem.bind(this, 'left')
},
operations[1]
)]
);
};
Transfer.prototype.render = function render() {
var _props2 = this.props,
prefix = _props2.prefix,
mode = _props2.mode,
disabled = _props2.disabled,
className = _props2.className,
dataSource = _props2.dataSource,
locale = _props2.locale,
_props2$showSearch = _props2.showSearch,
showSearch = _props2$showSearch === undefined ? false : _props2$showSearch,
_props2$searchProps = _props2.searchProps,
searchProps = _props2$searchProps === undefined ? {} : _props2$searchProps,
filter = _props2.filter,
onSearch = _props2.onSearch,
leftDisabled = _props2.leftDisabled,
rightDisabled = _props2.rightDisabled,
searchPlaceholder = _props2.searchPlaceholder,
notFoundContent = _props2.notFoundContent,
titles = _props2.titles,
listClassName = _props2.listClassName,
listStyle = _props2.listStyle,
itemRender = _props2.itemRender,
sortable = _props2.sortable,
useVirtual = _props2.useVirtual,
rtl = _props2.rtl,
id = _props2.id,
children = _props2.children,
showCheckAll = _props2.showCheckAll;
var _state7 = this.state,
value = _state7.value,
leftValue = _state7.leftValue,
leftCheckedValue = _state7.leftCheckedValue,
rightCheckedValue = _state7.rightCheckedValue;
var itemValues = dataSource.map(function (item) {
return item.value;
});
var leftDatasource = this.groupDatasource(leftValue, itemValues, dataSource);
var rightDatasource = this.groupDatasource(value, itemValues, dataSource);
var panelProps = {
prefix: prefix,
mode: mode,
locale: locale,
filter: filter,
onSearch: onSearch,
searchPlaceholder: searchPlaceholder,
listClassName: listClassName,
listStyle: listStyle,
itemRender: itemRender,
onMove: this.handleSimpleMove,
onMoveAll: this.handleSimpleMoveAll,
onChange: this.handlePanelChange,
sortable: sortable,
useVirtual: useVirtual,
onSort: this.handlePanelSort,
baseId: id,
customerList: children,
showCheckAll: showCheckAll
};
var others = pickOthers(Object.keys(Transfer.propTypes), this.props);
if (rtl) {
others.dir = 'rtl';
}
var _showSearch = Array.isArray(showSearch) ? showSearch : [showSearch, showSearch];
var _searchProps = Array.isArray(searchProps) ? searchProps : [searchProps, searchProps];
var _notFoundContent = Array.isArray(notFoundContent) ? notFoundContent : [notFoundContent, notFoundContent];
return _react2.default.createElement(
'div',
(0, _extends3.default)({ className: (0, _classnames2.default)(prefix + 'transfer', className), id: id }, others),
_react2.default.createElement(_transferPanel2.default, (0, _extends3.default)({}, panelProps, {
position: 'left',
dataSource: leftDatasource,
disabled: leftDisabled || disabled,
value: leftCheckedValue,
showSearch: _showSearch[0],
searchProps: _searchProps[0],
notFoundContent: _notFoundContent[0],
title: titles[0]
})),
this.renderCenter(),
_react2.default.createElement(_transferPanel2.default, (0, _extends3.default)({}, panelProps, {
position: 'right',
dataSource: rightDatasource,
disabled: rightDisabled || disabled,
value: rightCheckedValue,
showSearch: _showSearch[1],
searchProps: _searchProps[1],
notFoundContent: _notFoundContent[1],
title: titles[1]
}))
);
};
return Transfer;
}(_react.Component), _class.contextTypes = {
prefix: _propTypes2.default.string
}, _class.propTypes = (0, _extends3.default)({}, _configProvider2.default.propTypes, {
prefix: _propTypes2.default.string,
pure: _propTypes2.default.bool,
rtl: _propTypes2.default.bool,
className: _propTypes2.default.string,
/**
* 移动选项模式
*/
mode: _propTypes2.default.oneOf(['normal', 'simple']),
/**
* 数据源
*/
dataSource: _propTypes2.default.arrayOf(_propTypes2.default.object),
/**
* (用于受控)当前值
*/
value: _propTypes2.default.arrayOf(_propTypes2.default.string),
/**
* (用于非受控)初始值
*/
defaultValue: _propTypes2.default.arrayOf(_propTypes2.default.string),
/**
* 值发生改变的时候触发的回调函数
* @param {Array} value 右面板值
* @param {Array} data 右面板数据
* @param {Object} extra 额外参数
* @param {Array} extra.leftValue 左面板值
* @param {Array} extra.leftData 左面板数据
* @param {Array} extra.movedValue 发生移动的值
* @param {Object} extra.movedData 发生移动的数据
* @param {String} extra.direction 移动的方向,值为'left'或'right'
*/
onChange: _propTypes2.default.func,
/**
* Item 被选中的时候触发的回调函数
* @param {Array} sourceSelectedValue 源面板选中的 Item 列表
* @param {Array} targetSelectedValue 目标面板选中的 Item 列表
* @param {String} trigger 触发面板,值为'source'或'target'
*/
onSelect: _propTypes2.default.func,
/**
* 是否禁用
*/
disabled: _propTypes2.default.bool,
/**
* 是否禁用左侧面板
*/
leftDisabled: _propTypes2.default.bool,
/**
* 是否禁用右侧面板
*/
rightDisabled: _propTypes2.default.bool,
/**
* 列表项渲染函数
* @param {Object} data 数据
* @return {ReactNode} 列表项内容
*/
itemRender: _propTypes2.default.func,
/**
* 自定义搜索函数
* @param {String} searchedValue 搜索的内容
* @param {Object} data 数据
* @return {Boolean} 是否匹配到
* @default 根据 label 属性匹配
*/
filter: _propTypes2.default.func,
/**
* 搜索框输入时触发的回调函数
* @param {String} searchedValue 搜索的内容
* @param {String} position 搜索面板的位置
*/
onSearch: _propTypes2.default.func,
/**
* 搜索框占位符
*/
searchPlaceholder: _propTypes2.default.string,
/**
* 左右面板是否显示搜索框
*/
showSearch: _propTypes2.default.oneOfType([_propTypes2.default.bool, _propTypes2.default.arrayOf(_propTypes2.default.bool)]),
/**
* 左右面板搜索框配置项,同 Search 组件 props
*/
searchProps: _propTypes2.default.oneOfType([_propTypes2.default.object, _propTypes2.default.arrayOf(_propTypes2.default.object)]),
/**
* 列表为空显示内容
*/
notFoundContent: _propTypes2.default.oneOfType([_propTypes2.default.node, _propTypes2.default.arrayOf(_propTypes2.default.node)]),
/**
* 左右面板标题
*/
titles: _propTypes2.default.arrayOf(_propTypes2.default.node),
/**
* 向右向左移动按钮显示内容
* @default [<Icon type="arrow-right" />, <Icon type="arrow-left" />]
*/
operations: _propTypes2.default.arrayOf(_propTypes2.default.node),
/**
* 左面板默认选中值
*/
defaultLeftChecked: _propTypes2.default.arrayOf(_propTypes2.default.string),
/**
* 右面板默认选中值
*/
defaultRightChecked: _propTypes2.default.arrayOf(_propTypes2.default.string),
/**
* 左右面板列表自定义样式类名
*/
listClassName: _propTypes2.default.string,
/**
* 左右面板列表自定义样式对象
*/
listStyle: _propTypes2.default.object,
/**
* 是否允许拖拽排序
*/
sortable: _propTypes2.default.bool,
/**
* 拖拽排序时触发的回调函数
* @param {Array} value 排序后的值
* @param {String} position 拖拽的面板位置,值为:left 或 right
*/
onSort: _propTypes2.default.func,
/**
* 自定义国际化文案对象
*/
locale: _propTypes2.default.object,
/**
* 请设置 id 以保证transfer的可访问性
*/
id: _propTypes2.default.string,
/**
* 接收 children 自定义渲染列表
*/
children: _propTypes2.default.func,
/**
* 是否开启虚拟滚动
*/
useVirtual: _propTypes2.default.bool,
/**
* 是否显示底部全选 checkbox
*/
showCheckAll: _propTypes2.default.bool
}), _class.defaultProps = {
prefix: 'next-',
pure: false,
mode: 'normal',
dataSource: [],
defaultValue: [],
disabled: false,
leftDisabled: false,
rightDisabled: false,
showCheckAll: true,
itemRender: function itemRender(data) {
return data.label;
},
showSearch: false,
filter: function filter(searchedValue, data) {
var labelString = '';
var loop = function loop(arg) {
if (_react2.default.isValidElement(arg) && arg.props.children) {
_react2.default.Children.forEach(arg.props.children, loop);
} else if (typeof arg === 'string') {
labelString += arg;
}
};
loop(data.label);
return labelString.length >= searchedValue.length && labelString.indexOf(searchedValue) > -1;
},
onSearch: function onSearch() {},
notFoundContent: 'Not Found',
titles: [],
operations: [],
defaultLeftChecked: [],
defaultRightChecked: [],
sortable: false,
onSort: function onSort() {},
locale: _zhCn2.default.Transfer
}, _temp);
Transfer.displayName = 'Transfer';
exports.default = config((0, _reactLifecyclesCompat.polyfill)(Transfer));
module.exports = exports['default'];