linkmore-design
Version:
π πlmη»δ»ΆεΊγπ
352 lines (340 loc) β’ 11.5 kB
JavaScript
;
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _DownOutlined = _interopRequireDefault(require("@ant-design/icons/DownOutlined"));
var _classnames = _interopRequireDefault(require("classnames"));
var _omit = _interopRequireDefault(require("rc-util/lib/omit"));
var React = _interopRequireWildcard(require("react"));
var _checkbox = _interopRequireDefault(require("../checkbox"));
var _dropdown = _interopRequireDefault(require("../dropdown"));
var _reactNode = require("../_util/reactNode");
var _ListBody = _interopRequireWildcard(require("./ListBody"));
var _search = _interopRequireDefault(require("./search"));
const defaultRender = () => null;
function isRenderResultPlainObject(result) {
return !!(result && !(0, _reactNode.isValidElement)(result) && Object.prototype.toString.call(result) === '[object Object]');
}
function getEnabledItemKeys(items) {
return items.filter(data => !data.disabled).map(data => data.key);
}
class TransferList extends React.PureComponent {
timer;
triggerScrollTimer;
defaultListBodyRef = /*#__PURE__*/React.createRef();
constructor(props) {
super(props);
this.state = {
filterValue: ''
};
}
componentWillUnmount() {
clearTimeout(this.triggerScrollTimer);
}
getCheckStatus(filteredItems) {
const {
checkedKeys
} = this.props;
if (checkedKeys.length === 0) {
return 'none';
}
if (filteredItems.every(item => checkedKeys.includes(item.key) || !!item.disabled)) {
return 'all';
}
return 'part';
}
// ================================ Item ================================
getFilteredItems(dataSource, filterValue) {
const filteredItems = [];
const filteredRenderItems = [];
dataSource.forEach(item => {
const renderedItem = this.renderItem(item);
const {
renderedText
} = renderedItem;
// Filter skip
if (filterValue && !this.matchFilter(renderedText, item)) {
return null;
}
filteredItems.push(item);
filteredRenderItems.push(renderedItem);
});
return {
filteredItems,
filteredRenderItems
};
}
// =============================== Filter ===============================
handleFilter = e => {
const {
handleFilter
} = this.props;
const {
target: {
value: filterValue
}
} = e;
this.setState({
filterValue
});
handleFilter(e);
};
handleClear = () => {
const {
handleClear
} = this.props;
this.setState({
filterValue: ''
});
handleClear();
};
matchFilter = (text, item) => {
const {
filterValue
} = this.state;
const {
filterOption
} = this.props;
if (filterOption) {
return filterOption(filterValue, item);
}
return text.includes(filterValue);
};
// =============================== Render ===============================
renderListBody = (renderList, props) => {
let bodyContent = renderList ? renderList(props) : null;
const customize = !!bodyContent;
if (!customize) {
bodyContent = /*#__PURE__*/React.createElement(_ListBody.default, (0, _extends2.default)({
ref: this.defaultListBodyRef
}, props));
}
return {
customize,
bodyContent
};
};
getListBody(prefixCls, searchPlaceholder, filterValue, filteredItems, notFoundContent, filteredRenderItems, checkedKeys, renderList, showSearch, disabled) {
const search = showSearch ? /*#__PURE__*/React.createElement("div", {
className: `${prefixCls}-body-search-wrapper`
}, /*#__PURE__*/React.createElement(_search.default, {
prefixCls: `${prefixCls}-search`,
onChange: this.handleFilter,
handleClear: this.handleClear,
placeholder: searchPlaceholder,
value: filterValue,
disabled: disabled
})) : null;
const {
bodyContent,
customize
} = this.renderListBody(renderList, {
...(0, _omit.default)(this.props, _ListBody.OmitProps),
filteredItems,
filteredRenderItems,
selectedKeys: checkedKeys
});
const getNotFoundContent = () => {
const contentIndex = this.props.direction === 'left' ? 0 : 1;
return Array.isArray(notFoundContent) ? notFoundContent[contentIndex] : notFoundContent;
};
let bodyNode;
// We should wrap customize list body in a classNamed div to use flex layout.
if (customize) {
bodyNode = /*#__PURE__*/React.createElement("div", {
className: `${prefixCls}-body-customize-wrapper`
}, bodyContent);
} else {
bodyNode = filteredItems.length ? bodyContent : /*#__PURE__*/React.createElement("div", {
className: `${prefixCls}-body-not-found`
}, getNotFoundContent());
}
return /*#__PURE__*/React.createElement("div", {
className: (0, _classnames.default)(showSearch ? `${prefixCls}-body ${prefixCls}-body-with-search` : `${prefixCls}-body`)
}, search, bodyNode);
}
getCheckBox({
filteredItems,
onItemSelectAll,
disabled,
prefixCls
}) {
const checkStatus = this.getCheckStatus(filteredItems);
const checkedAll = checkStatus === 'all';
const checkAllCheckbox = /*#__PURE__*/React.createElement(_checkbox.default, {
disabled: disabled,
checked: checkedAll,
indeterminate: checkStatus === 'part',
className: `${prefixCls}-checkbox`,
onChange: () => {
// Only select enabled items
onItemSelectAll(filteredItems.filter(item => !item.disabled).map(({
key
}) => key), !checkedAll);
}
});
return checkAllCheckbox;
}
renderItem = item => {
const {
render = defaultRender
} = this.props;
const renderResult = render(item);
const isRenderResultPlain = isRenderResultPlainObject(renderResult);
return {
renderedText: isRenderResultPlain ? renderResult.value : renderResult,
renderedEl: isRenderResultPlain ? renderResult.label : renderResult,
item
};
};
getSelectAllLabel = (selectedCount, totalCount) => {
const {
itemsUnit,
itemUnit,
selectAllLabel
} = this.props;
if (selectAllLabel) {
return typeof selectAllLabel === 'function' ? selectAllLabel({
selectedCount,
totalCount
}) : selectAllLabel;
}
const unit = totalCount > 1 ? itemsUnit : itemUnit;
return /*#__PURE__*/React.createElement(React.Fragment, null, (selectedCount > 0 ? `${selectedCount}/` : '') + totalCount, " ", unit);
};
render() {
const {
filterValue
} = this.state;
const {
prefixCls,
dataSource = [],
titleText = '',
checkedKeys,
disabled,
footer,
showSearch = false,
style,
searchPlaceholder,
notFoundContent,
selectAll,
selectCurrent,
selectInvert,
removeAll,
removeCurrent,
renderList,
onItemSelectAll,
onItemRemove,
showSelectAll = true,
showRemove,
pagination,
direction
} = this.props;
// Custom Layout
const footerDom = footer && (footer.length < 2 ? footer(this.props) : footer(this.props, {
direction
}));
const listCls = (0, _classnames.default)(prefixCls, {
[`${prefixCls}-with-pagination`]: !!pagination,
[`${prefixCls}-with-footer`]: !!footerDom
});
// ====================== Get filtered, checked item list ======================
const {
filteredItems,
filteredRenderItems
} = this.getFilteredItems(dataSource, filterValue);
// ================================= List Body =================================
const listBody = this.getListBody(prefixCls, searchPlaceholder, filterValue, filteredItems, notFoundContent, filteredRenderItems, checkedKeys, renderList, showSearch, disabled);
// ================================ List Footer ================================
const listFooter = footerDom ? /*#__PURE__*/React.createElement("div", {
className: `${prefixCls}-footer`
}, footerDom) : null;
const checkAllCheckbox = !showRemove && !pagination && this.getCheckBox({
filteredItems,
onItemSelectAll,
disabled,
prefixCls
});
let items;
if (showRemove) {
items = [/* Remove Current Page */
pagination ? {
key: 'removeCurrent',
onClick: () => {
const pageKeys = getEnabledItemKeys((this.defaultListBodyRef.current?.getItems() || []).map(entity => entity.item));
onItemRemove?.(pageKeys);
},
label: removeCurrent
} : null, /* Remove All */
{
key: 'removeAll',
onClick: () => {
onItemRemove?.(getEnabledItemKeys(filteredItems));
},
label: removeAll
}].filter(item => item);
} else {
items = [{
key: 'selectAll',
onClick: () => {
const keys = getEnabledItemKeys(filteredItems);
onItemSelectAll(keys, keys.length !== checkedKeys.length);
},
label: selectAll
}, pagination ? {
key: 'selectCurrent',
onClick: () => {
const pageItems = this.defaultListBodyRef.current?.getItems() || [];
onItemSelectAll(getEnabledItemKeys(pageItems.map(entity => entity.item)), true);
},
label: selectCurrent
} : null, {
key: 'selectInvert',
onClick: () => {
let availableKeys;
if (pagination) {
availableKeys = getEnabledItemKeys((this.defaultListBodyRef.current?.getItems() || []).map(entity => entity.item));
} else {
availableKeys = getEnabledItemKeys(filteredItems);
}
const checkedKeySet = new Set(checkedKeys);
const newCheckedKeys = [];
const newUnCheckedKeys = [];
availableKeys.forEach(key => {
if (checkedKeySet.has(key)) {
newUnCheckedKeys.push(key);
} else {
newCheckedKeys.push(key);
}
});
onItemSelectAll(newCheckedKeys, true);
onItemSelectAll(newUnCheckedKeys, false);
},
label: selectInvert
}];
}
const dropdown = /*#__PURE__*/React.createElement(_dropdown.default, {
className: `${prefixCls}-header-dropdown`,
menu: {
items
},
disabled: disabled
}, /*#__PURE__*/React.createElement(_DownOutlined.default, null));
// ================================== Render ===================================
return /*#__PURE__*/React.createElement("div", {
className: listCls,
style: style
}, /*#__PURE__*/React.createElement("div", {
className: `${prefixCls}-header`
}, showSelectAll ? /*#__PURE__*/React.createElement(React.Fragment, null, checkAllCheckbox, dropdown) : null, /*#__PURE__*/React.createElement("span", {
className: `${prefixCls}-header-selected`
}, this.getSelectAllLabel(checkedKeys.length, filteredItems.length)), /*#__PURE__*/React.createElement("span", {
className: `${prefixCls}-header-title`
}, titleText)), listBody, listFooter);
}
}
exports.default = TransferList;