list.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. Object.defineProperty(exports, "__esModule", {
  4. value: true
  5. });
  6. exports.transferListProps = exports.default = void 0;
  7. var _vue = require("vue");
  8. var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
  9. var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
  10. var _classNames = _interopRequireDefault(require("../_util/classNames"));
  11. var _vueTypes = _interopRequireDefault(require("../_util/vue-types"));
  12. var _propsUtil = require("../_util/props-util");
  13. var _DownOutlined = _interopRequireDefault(require("@ant-design/icons-vue/lib/icons/DownOutlined"));
  14. var _checkbox = _interopRequireDefault(require("../checkbox"));
  15. var _menu = _interopRequireDefault(require("../menu"));
  16. var _dropdown = _interopRequireDefault(require("../dropdown"));
  17. var _search = _interopRequireDefault(require("./search"));
  18. var _ListBody = _interopRequireDefault(require("./ListBody"));
  19. var _type = require("../_util/type");
  20. var _transKeys = require("../_util/transKeys");
  21. const defaultRender = () => null;
  22. function isRenderResultPlainObject(result) {
  23. return !!(result && !(0, _propsUtil.isValidElement)(result) && Object.prototype.toString.call(result) === '[object Object]');
  24. }
  25. function getEnabledItemKeys(items) {
  26. return items.filter(data => !data.disabled).map(data => data.key);
  27. }
  28. const transferListProps = exports.transferListProps = {
  29. prefixCls: String,
  30. dataSource: (0, _type.arrayType)([]),
  31. filter: String,
  32. filterOption: Function,
  33. checkedKeys: _vueTypes.default.arrayOf(_vueTypes.default.string),
  34. handleFilter: Function,
  35. handleClear: Function,
  36. renderItem: Function,
  37. showSearch: (0, _type.booleanType)(false),
  38. searchPlaceholder: String,
  39. notFoundContent: _vueTypes.default.any,
  40. itemUnit: String,
  41. itemsUnit: String,
  42. renderList: _vueTypes.default.any,
  43. disabled: (0, _type.booleanType)(),
  44. direction: (0, _type.stringType)(),
  45. showSelectAll: (0, _type.booleanType)(),
  46. remove: String,
  47. selectAll: String,
  48. selectCurrent: String,
  49. selectInvert: String,
  50. removeAll: String,
  51. removeCurrent: String,
  52. selectAllLabel: _vueTypes.default.any,
  53. showRemove: (0, _type.booleanType)(),
  54. pagination: _vueTypes.default.any,
  55. onItemSelect: Function,
  56. onItemSelectAll: Function,
  57. onItemRemove: Function,
  58. onScroll: Function
  59. };
  60. var _default = exports.default = (0, _vue.defineComponent)({
  61. compatConfig: {
  62. MODE: 3
  63. },
  64. name: 'TransferList',
  65. inheritAttrs: false,
  66. props: transferListProps,
  67. // emits: ['scroll', 'itemSelectAll', 'itemRemove', 'itemSelect'],
  68. slots: Object,
  69. setup(props, _ref) {
  70. let {
  71. attrs,
  72. slots
  73. } = _ref;
  74. const filterValue = (0, _vue.ref)('');
  75. const transferNode = (0, _vue.ref)();
  76. const defaultListBodyRef = (0, _vue.ref)();
  77. const renderListBody = (renderList, props) => {
  78. let bodyContent = renderList ? renderList(props) : null;
  79. const customize = !!bodyContent && (0, _propsUtil.filterEmpty)(bodyContent).length > 0;
  80. if (!customize) {
  81. bodyContent = (0, _vue.createVNode)(_ListBody.default, (0, _objectSpread2.default)((0, _objectSpread2.default)({}, props), {}, {
  82. "ref": defaultListBodyRef
  83. }), null);
  84. }
  85. return {
  86. customize,
  87. bodyContent
  88. };
  89. };
  90. const renderItemHtml = item => {
  91. const {
  92. renderItem = defaultRender
  93. } = props;
  94. const renderResult = renderItem(item);
  95. const isRenderResultPlain = isRenderResultPlainObject(renderResult);
  96. return {
  97. renderedText: isRenderResultPlain ? renderResult.value : renderResult,
  98. renderedEl: isRenderResultPlain ? renderResult.label : renderResult,
  99. item
  100. };
  101. };
  102. const filteredItems = (0, _vue.ref)([]);
  103. const filteredRenderItems = (0, _vue.ref)([]);
  104. (0, _vue.watchEffect)(() => {
  105. const fItems = [];
  106. const fRenderItems = [];
  107. props.dataSource.forEach(item => {
  108. const renderedItem = renderItemHtml(item);
  109. const {
  110. renderedText
  111. } = renderedItem;
  112. // Filter skip
  113. if (filterValue.value && filterValue.value.trim() && !matchFilter(renderedText, item)) {
  114. return null;
  115. }
  116. fItems.push(item);
  117. fRenderItems.push(renderedItem);
  118. });
  119. filteredItems.value = fItems;
  120. filteredRenderItems.value = fRenderItems;
  121. });
  122. const checkStatus = (0, _vue.computed)(() => {
  123. const {
  124. checkedKeys
  125. } = props;
  126. if (checkedKeys.length === 0) {
  127. return 'none';
  128. }
  129. const checkedKeysMap = (0, _transKeys.groupKeysMap)(checkedKeys);
  130. if (filteredItems.value.every(item => checkedKeysMap.has(item.key) || !!item.disabled)) {
  131. return 'all';
  132. }
  133. return 'part';
  134. });
  135. const enabledItemKeys = (0, _vue.computed)(() => {
  136. return getEnabledItemKeys(filteredItems.value);
  137. });
  138. const getNewSelectKeys = (keys, unCheckedKeys) => {
  139. return Array.from(new Set([...keys, ...props.checkedKeys])).filter(key => unCheckedKeys.indexOf(key) === -1);
  140. };
  141. const getCheckBox = _ref2 => {
  142. let {
  143. disabled,
  144. prefixCls
  145. } = _ref2;
  146. var _a;
  147. const checkedAll = checkStatus.value === 'all';
  148. const checkAllCheckbox = (0, _vue.createVNode)(_checkbox.default, {
  149. "disabled": ((_a = props.dataSource) === null || _a === void 0 ? void 0 : _a.length) === 0 || disabled,
  150. "checked": checkedAll,
  151. "indeterminate": checkStatus.value === 'part',
  152. "class": `${prefixCls}-checkbox`,
  153. "onChange": () => {
  154. // Only select enabled items
  155. const keys = enabledItemKeys.value;
  156. props.onItemSelectAll(getNewSelectKeys(!checkedAll ? keys : [], checkedAll ? props.checkedKeys : []));
  157. }
  158. }, null);
  159. return checkAllCheckbox;
  160. };
  161. const handleFilter = e => {
  162. var _a;
  163. const {
  164. target: {
  165. value: filter
  166. }
  167. } = e;
  168. filterValue.value = filter;
  169. (_a = props.handleFilter) === null || _a === void 0 ? void 0 : _a.call(props, e);
  170. };
  171. const handleClear = e => {
  172. var _a;
  173. filterValue.value = '';
  174. (_a = props.handleClear) === null || _a === void 0 ? void 0 : _a.call(props, e);
  175. };
  176. const matchFilter = (text, item) => {
  177. const {
  178. filterOption
  179. } = props;
  180. if (filterOption) {
  181. return filterOption(filterValue.value, item);
  182. }
  183. return text.includes(filterValue.value);
  184. };
  185. const getSelectAllLabel = (selectedCount, totalCount) => {
  186. const {
  187. itemsUnit,
  188. itemUnit,
  189. selectAllLabel
  190. } = props;
  191. if (selectAllLabel) {
  192. return typeof selectAllLabel === 'function' ? selectAllLabel({
  193. selectedCount,
  194. totalCount
  195. }) : selectAllLabel;
  196. }
  197. const unit = totalCount > 1 ? itemsUnit : itemUnit;
  198. return (0, _vue.createVNode)(_vue.Fragment, null, [(selectedCount > 0 ? `${selectedCount}/` : '') + totalCount, (0, _vue.createTextVNode)(" "), unit]);
  199. };
  200. const notFoundContentEle = (0, _vue.computed)(() => Array.isArray(props.notFoundContent) ? props.notFoundContent[props.direction === 'left' ? 0 : 1] : props.notFoundContent);
  201. const getListBody = (prefixCls, searchPlaceholder, checkedKeys, renderList, showSearch, disabled) => {
  202. const search = showSearch ? (0, _vue.createVNode)("div", {
  203. "class": `${prefixCls}-body-search-wrapper`
  204. }, [(0, _vue.createVNode)(_search.default, {
  205. "prefixCls": `${prefixCls}-search`,
  206. "onChange": handleFilter,
  207. "handleClear": handleClear,
  208. "placeholder": searchPlaceholder,
  209. "value": filterValue.value,
  210. "disabled": disabled
  211. }, null)]) : null;
  212. let bodyNode;
  213. const {
  214. onEvents
  215. } = (0, _propsUtil.splitAttrs)(attrs);
  216. const {
  217. bodyContent,
  218. customize
  219. } = renderListBody(renderList, (0, _extends2.default)((0, _extends2.default)((0, _extends2.default)({}, props), {
  220. filteredItems: filteredItems.value,
  221. filteredRenderItems: filteredRenderItems.value,
  222. selectedKeys: checkedKeys
  223. }), onEvents));
  224. // We should wrap customize list body in a classNamed div to use flex layout.
  225. if (customize) {
  226. bodyNode = (0, _vue.createVNode)("div", {
  227. "class": `${prefixCls}-body-customize-wrapper`
  228. }, [bodyContent]);
  229. } else {
  230. bodyNode = filteredItems.value.length ? bodyContent : (0, _vue.createVNode)("div", {
  231. "class": `${prefixCls}-body-not-found`
  232. }, [notFoundContentEle.value]);
  233. }
  234. return (0, _vue.createVNode)("div", {
  235. "class": showSearch ? `${prefixCls}-body ${prefixCls}-body-with-search` : `${prefixCls}-body`,
  236. "ref": transferNode
  237. }, [search, bodyNode]);
  238. };
  239. return () => {
  240. var _a, _b;
  241. const {
  242. prefixCls,
  243. checkedKeys,
  244. disabled,
  245. showSearch,
  246. searchPlaceholder,
  247. selectAll,
  248. selectCurrent,
  249. selectInvert,
  250. removeAll,
  251. removeCurrent,
  252. renderList,
  253. onItemSelectAll,
  254. onItemRemove,
  255. showSelectAll = true,
  256. showRemove,
  257. pagination
  258. } = props;
  259. // Custom Layout
  260. const footerDom = (_a = slots.footer) === null || _a === void 0 ? void 0 : _a.call(slots, (0, _extends2.default)({}, props));
  261. const listCls = (0, _classNames.default)(prefixCls, {
  262. [`${prefixCls}-with-pagination`]: !!pagination,
  263. [`${prefixCls}-with-footer`]: !!footerDom
  264. });
  265. // ================================= List Body =================================
  266. const listBody = getListBody(prefixCls, searchPlaceholder, checkedKeys, renderList, showSearch, disabled);
  267. const listFooter = footerDom ? (0, _vue.createVNode)("div", {
  268. "class": `${prefixCls}-footer`
  269. }, [footerDom]) : null;
  270. const checkAllCheckbox = !showRemove && !pagination && getCheckBox({
  271. disabled,
  272. prefixCls
  273. });
  274. let menu = null;
  275. if (showRemove) {
  276. menu = (0, _vue.createVNode)(_menu.default, null, {
  277. default: () => [pagination && (0, _vue.createVNode)(_menu.default.Item, {
  278. "key": "removeCurrent",
  279. "onClick": () => {
  280. const pageKeys = getEnabledItemKeys((defaultListBodyRef.value.items || []).map(entity => entity.item));
  281. onItemRemove === null || onItemRemove === void 0 ? void 0 : onItemRemove(pageKeys);
  282. }
  283. }, {
  284. default: () => [removeCurrent]
  285. }), (0, _vue.createVNode)(_menu.default.Item, {
  286. "key": "removeAll",
  287. "onClick": () => {
  288. onItemRemove === null || onItemRemove === void 0 ? void 0 : onItemRemove(enabledItemKeys.value);
  289. }
  290. }, {
  291. default: () => [removeAll]
  292. })]
  293. });
  294. } else {
  295. menu = (0, _vue.createVNode)(_menu.default, null, {
  296. default: () => [(0, _vue.createVNode)(_menu.default.Item, {
  297. "key": "selectAll",
  298. "onClick": () => {
  299. const keys = enabledItemKeys.value;
  300. onItemSelectAll(getNewSelectKeys(keys, []));
  301. }
  302. }, {
  303. default: () => [selectAll]
  304. }), pagination && (0, _vue.createVNode)(_menu.default.Item, {
  305. "onClick": () => {
  306. const pageKeys = getEnabledItemKeys((defaultListBodyRef.value.items || []).map(entity => entity.item));
  307. onItemSelectAll(getNewSelectKeys(pageKeys, []));
  308. }
  309. }, {
  310. default: () => [selectCurrent]
  311. }), (0, _vue.createVNode)(_menu.default.Item, {
  312. "key": "selectInvert",
  313. "onClick": () => {
  314. let availableKeys;
  315. if (pagination) {
  316. availableKeys = getEnabledItemKeys((defaultListBodyRef.value.items || []).map(entity => entity.item));
  317. } else {
  318. availableKeys = enabledItemKeys.value;
  319. }
  320. const checkedKeySet = new Set(checkedKeys);
  321. const newCheckedKeys = [];
  322. const newUnCheckedKeys = [];
  323. availableKeys.forEach(key => {
  324. if (checkedKeySet.has(key)) {
  325. newUnCheckedKeys.push(key);
  326. } else {
  327. newCheckedKeys.push(key);
  328. }
  329. });
  330. onItemSelectAll(getNewSelectKeys(newCheckedKeys, newUnCheckedKeys));
  331. }
  332. }, {
  333. default: () => [selectInvert]
  334. })]
  335. });
  336. }
  337. const dropdown = (0, _vue.createVNode)(_dropdown.default, {
  338. "class": `${prefixCls}-header-dropdown`,
  339. "overlay": menu,
  340. "disabled": disabled
  341. }, {
  342. default: () => [(0, _vue.createVNode)(_DownOutlined.default, null, null)]
  343. });
  344. return (0, _vue.createVNode)("div", {
  345. "class": listCls,
  346. "style": attrs.style
  347. }, [(0, _vue.createVNode)("div", {
  348. "class": `${prefixCls}-header`
  349. }, [showSelectAll ? (0, _vue.createVNode)(_vue.Fragment, null, [checkAllCheckbox, dropdown]) : null, (0, _vue.createVNode)("span", {
  350. "class": `${prefixCls}-header-selected`
  351. }, [(0, _vue.createVNode)("span", null, [getSelectAllLabel(checkedKeys.length, filteredItems.value.length)]), (0, _vue.createVNode)("span", {
  352. "class": `${prefixCls}-header-title`
  353. }, [(_b = slots.titleText) === null || _b === void 0 ? void 0 : _b.call(slots)])])]), listBody, listFooter]);
  354. };
  355. }
  356. });