amis-rpc-design/node_modules/antd/es/transfer/list.js
2023-10-07 19:42:30 +08:00

264 lines
9.4 KiB
JavaScript

"use client";
import DownOutlined from "@ant-design/icons/es/icons/DownOutlined";
import classNames from 'classnames';
import omit from "rc-util/es/omit";
import React, { useMemo, useRef, useState } from 'react';
import { isValidElement } from '../_util/reactNode';
import { groupKeysMap } from '../_util/transKeys';
import Checkbox from '../checkbox';
import Dropdown from '../dropdown';
import DefaultListBody, { OmitProps } from './ListBody';
import Search from './search';
const defaultRender = () => null;
function isRenderResultPlainObject(result) {
return !!(result && !isValidElement(result) && Object.prototype.toString.call(result) === '[object Object]');
}
function getEnabledItemKeys(items) {
return items.filter(data => !data.disabled).map(data => data.key);
}
const isValidIcon = icon => icon !== undefined;
const TransferList = props => {
const {
prefixCls,
dataSource = [],
titleText = '',
checkedKeys,
disabled,
showSearch = false,
style,
searchPlaceholder,
notFoundContent,
selectAll,
selectCurrent,
selectInvert,
removeAll,
removeCurrent,
showSelectAll = true,
showRemove,
pagination,
direction,
itemsUnit,
itemUnit,
selectAllLabel,
selectionsIcon,
footer,
renderList,
onItemSelectAll,
onItemRemove,
handleFilter,
handleClear,
filterOption,
render = defaultRender
} = props;
const [filterValue, setFilterValue] = useState('');
const listBodyRef = useRef({});
const internalHandleFilter = e => {
setFilterValue(e.target.value);
handleFilter(e);
};
const internalHandleClear = () => {
setFilterValue('');
handleClear();
};
const matchFilter = (text, item) => {
if (filterOption) {
return filterOption(filterValue, item, direction);
}
return text.includes(filterValue);
};
const renderListBody = listProps => {
let bodyContent = renderList ? renderList(listProps) : null;
const customize = !!bodyContent;
if (!customize) {
bodyContent = /*#__PURE__*/React.createElement(DefaultListBody, Object.assign({
ref: listBodyRef
}, listProps));
}
return {
customize,
bodyContent
};
};
const renderItem = item => {
const renderResult = render(item);
const isRenderResultPlain = isRenderResultPlainObject(renderResult);
return {
item,
renderedEl: isRenderResultPlain ? renderResult.label : renderResult,
renderedText: isRenderResultPlain ? renderResult.value : renderResult
};
};
const notFoundContentEle = useMemo(() => Array.isArray(notFoundContent) ? notFoundContent[direction === 'left' ? 0 : 1] : notFoundContent, [notFoundContent, direction]);
const [filteredItems, filteredRenderItems] = useMemo(() => {
const filterItems = [];
const filterRenderItems = [];
dataSource.forEach(item => {
const renderedItem = renderItem(item);
if (filterValue && !matchFilter(renderedItem.renderedText, item)) {
return;
}
filterItems.push(item);
filterRenderItems.push(renderedItem);
});
return [filterItems, filterRenderItems];
}, [dataSource, filterValue]);
const checkStatus = useMemo(() => {
if (checkedKeys.length === 0) {
return 'none';
}
const checkedKeysMap = groupKeysMap(checkedKeys);
if (filteredItems.every(item => checkedKeysMap.has(item.key) || !!item.disabled)) {
return 'all';
}
return 'part';
}, [checkedKeys, filteredItems]);
const listBody = useMemo(() => {
const search = showSearch ? /*#__PURE__*/React.createElement("div", {
className: `${prefixCls}-body-search-wrapper`
}, /*#__PURE__*/React.createElement(Search, {
prefixCls: `${prefixCls}-search`,
onChange: internalHandleFilter,
handleClear: internalHandleClear,
placeholder: searchPlaceholder,
value: filterValue,
disabled: disabled
})) : null;
const {
customize,
bodyContent
} = renderListBody(Object.assign(Object.assign({}, omit(props, OmitProps)), {
filteredItems,
filteredRenderItems,
selectedKeys: checkedKeys
}));
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`
}, notFoundContentEle);
}
return /*#__PURE__*/React.createElement("div", {
className: classNames(showSearch ? `${prefixCls}-body ${prefixCls}-body-with-search` : `${prefixCls}-body`)
}, search, bodyNode);
}, [showSearch, prefixCls, searchPlaceholder, filterValue, disabled, checkedKeys, filteredItems, filteredRenderItems, notFoundContentEle]);
const checkBox = /*#__PURE__*/React.createElement(Checkbox, {
disabled: dataSource.length === 0 || disabled,
checked: checkStatus === 'all',
indeterminate: checkStatus === 'part',
className: `${prefixCls}-checkbox`,
onChange: () => {
// Only select enabled items
onItemSelectAll === null || onItemSelectAll === void 0 ? void 0 : onItemSelectAll(filteredItems.filter(item => !item.disabled).map(_ref => {
let {
key
} = _ref;
return key;
}), checkStatus !== 'all');
}
});
const getSelectAllLabel = (selectedCount, totalCount) => {
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);
};
// Custom Layout
const footerDom = footer && (footer.length < 2 ? footer(props) : footer(props, {
direction
}));
const listCls = classNames(prefixCls, {
[`${prefixCls}-with-pagination`]: !!pagination,
[`${prefixCls}-with-footer`]: !!footerDom
});
// ====================== Get filtered, checked item list ======================
const listFooter = footerDom ? /*#__PURE__*/React.createElement("div", {
className: `${prefixCls}-footer`
}, footerDom) : null;
const checkAllCheckbox = !showRemove && !pagination && checkBox;
let items;
if (showRemove) {
items = [/* Remove Current Page */
pagination ? {
key: 'removeCurrent',
label: removeCurrent,
onClick() {
var _a;
const pageKeys = getEnabledItemKeys((((_a = listBodyRef.current) === null || _a === void 0 ? void 0 : _a.items) || []).map(entity => entity.item));
onItemRemove === null || onItemRemove === void 0 ? void 0 : onItemRemove(pageKeys);
}
} : null, /* Remove All */
{
key: 'removeAll',
label: removeAll,
onClick() {
onItemRemove === null || onItemRemove === void 0 ? void 0 : onItemRemove(getEnabledItemKeys(filteredItems));
}
}].filter(Boolean);
} else {
items = [{
key: 'selectAll',
label: selectAll,
onClick() {
const keys = getEnabledItemKeys(filteredItems);
onItemSelectAll === null || onItemSelectAll === void 0 ? void 0 : onItemSelectAll(keys, keys.length !== checkedKeys.length);
}
}, pagination ? {
key: 'selectCurrent',
label: selectCurrent,
onClick() {
var _a;
const pageItems = ((_a = listBodyRef.current) === null || _a === void 0 ? void 0 : _a.items) || [];
onItemSelectAll === null || onItemSelectAll === void 0 ? void 0 : onItemSelectAll(getEnabledItemKeys(pageItems.map(entity => entity.item)), true);
}
} : null, {
key: 'selectInvert',
label: selectInvert,
onClick() {
var _a;
const availableKeys = getEnabledItemKeys(pagination ? (((_a = listBodyRef.current) === null || _a === void 0 ? void 0 : _a.items) || []).map(entity => entity.item) : 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 === null || onItemSelectAll === void 0 ? void 0 : onItemSelectAll(newCheckedKeys, 'replace');
}
}];
}
const dropdown = /*#__PURE__*/React.createElement(Dropdown, {
className: `${prefixCls}-header-dropdown`,
menu: {
items
},
disabled: disabled
}, isValidIcon(selectionsIcon) ? selectionsIcon : /*#__PURE__*/React.createElement(DownOutlined, null));
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`
}, getSelectAllLabel(checkedKeys.length, filteredItems.length)), /*#__PURE__*/React.createElement("span", {
className: `${prefixCls}-header-title`
}, titleText)), listBody, listFooter);
};
if (process.env.NODE_ENV !== 'production') {
TransferList.displayName = 'TransferList';
}
export default TransferList;