index.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. Object.defineProperty(exports, "__esModule", {
  4. value: true
  5. });
  6. exports.transferProps = exports.default = void 0;
  7. var _vue = require("vue");
  8. var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
  9. var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
  10. var _vueTypes = _interopRequireDefault(require("../_util/vue-types"));
  11. var _propsUtil = require("../_util/props-util");
  12. var _classNames = _interopRequireDefault(require("../_util/classNames"));
  13. var _list = _interopRequireDefault(require("./list"));
  14. var _operation = _interopRequireDefault(require("./operation"));
  15. var _LocaleReceiver = _interopRequireDefault(require("../locale-provider/LocaleReceiver"));
  16. var _en_US = _interopRequireDefault(require("../locale/en_US"));
  17. var _type = require("../_util/type");
  18. var _useConfigInject = _interopRequireDefault(require("../config-provider/hooks/useConfigInject"));
  19. var _FormItemContext = require("../form/FormItemContext");
  20. var _statusUtils = require("../_util/statusUtils");
  21. var _transKeys = require("../_util/transKeys");
  22. var _style = _interopRequireDefault(require("./style"));
  23. // CSSINJS
  24. const transferProps = () => ({
  25. id: String,
  26. prefixCls: String,
  27. dataSource: (0, _type.arrayType)([]),
  28. disabled: (0, _type.booleanType)(),
  29. targetKeys: (0, _type.arrayType)(),
  30. selectedKeys: (0, _type.arrayType)(),
  31. render: (0, _type.functionType)(),
  32. listStyle: (0, _type.someType)([Function, Object], () => ({})),
  33. operationStyle: (0, _type.objectType)(undefined),
  34. titles: (0, _type.arrayType)(),
  35. operations: (0, _type.arrayType)(),
  36. showSearch: (0, _type.booleanType)(false),
  37. filterOption: (0, _type.functionType)(),
  38. searchPlaceholder: String,
  39. notFoundContent: _vueTypes.default.any,
  40. locale: (0, _type.objectType)(),
  41. rowKey: (0, _type.functionType)(),
  42. showSelectAll: (0, _type.booleanType)(),
  43. selectAllLabels: (0, _type.arrayType)(),
  44. children: (0, _type.functionType)(),
  45. oneWay: (0, _type.booleanType)(),
  46. pagination: (0, _type.someType)([Object, Boolean]),
  47. status: (0, _type.stringType)(),
  48. onChange: (0, _type.functionType)(),
  49. onSelectChange: (0, _type.functionType)(),
  50. onSearch: (0, _type.functionType)(),
  51. onScroll: (0, _type.functionType)(),
  52. 'onUpdate:targetKeys': (0, _type.functionType)(),
  53. 'onUpdate:selectedKeys': (0, _type.functionType)()
  54. });
  55. exports.transferProps = transferProps;
  56. const Transfer = (0, _vue.defineComponent)({
  57. compatConfig: {
  58. MODE: 3
  59. },
  60. name: 'ATransfer',
  61. inheritAttrs: false,
  62. props: transferProps(),
  63. slots: Object,
  64. // emits: ['update:targetKeys', 'update:selectedKeys', 'change', 'search', 'scroll', 'selectChange'],
  65. setup(props, _ref) {
  66. let {
  67. emit,
  68. attrs,
  69. slots,
  70. expose
  71. } = _ref;
  72. const {
  73. configProvider,
  74. prefixCls,
  75. direction
  76. } = (0, _useConfigInject.default)('transfer', props);
  77. // style
  78. const [wrapSSR, hashId] = (0, _style.default)(prefixCls);
  79. const sourceSelectedKeys = (0, _vue.ref)([]);
  80. const targetSelectedKeys = (0, _vue.ref)([]);
  81. const formItemContext = (0, _FormItemContext.useInjectFormItemContext)();
  82. const formItemInputContext = _FormItemContext.FormItemInputContext.useInject();
  83. const mergedStatus = (0, _vue.computed)(() => (0, _statusUtils.getMergedStatus)(formItemInputContext.status, props.status));
  84. (0, _vue.watch)(() => props.selectedKeys, () => {
  85. var _a, _b;
  86. sourceSelectedKeys.value = ((_a = props.selectedKeys) === null || _a === void 0 ? void 0 : _a.filter(key => props.targetKeys.indexOf(key) === -1)) || [];
  87. targetSelectedKeys.value = ((_b = props.selectedKeys) === null || _b === void 0 ? void 0 : _b.filter(key => props.targetKeys.indexOf(key) > -1)) || [];
  88. }, {
  89. immediate: true
  90. });
  91. const getLocale = (transferLocale, renderEmpty) => {
  92. // Keep old locale props still working.
  93. const oldLocale = {
  94. notFoundContent: renderEmpty('Transfer')
  95. };
  96. const notFoundContent = (0, _propsUtil.getPropsSlot)(slots, props, 'notFoundContent');
  97. if (notFoundContent) {
  98. oldLocale.notFoundContent = notFoundContent;
  99. }
  100. if (props.searchPlaceholder !== undefined) {
  101. oldLocale.searchPlaceholder = props.searchPlaceholder;
  102. }
  103. return (0, _extends2.default)((0, _extends2.default)((0, _extends2.default)({}, transferLocale), oldLocale), props.locale);
  104. };
  105. const moveTo = direction => {
  106. const {
  107. targetKeys = [],
  108. dataSource = []
  109. } = props;
  110. const moveKeys = direction === 'right' ? sourceSelectedKeys.value : targetSelectedKeys.value;
  111. const dataSourceDisabledKeysMap = (0, _transKeys.groupDisabledKeysMap)(dataSource);
  112. // filter the disabled options
  113. const newMoveKeys = moveKeys.filter(key => !dataSourceDisabledKeysMap.has(key));
  114. const newMoveKeysMap = (0, _transKeys.groupKeysMap)(newMoveKeys);
  115. // move items to target box
  116. const newTargetKeys = direction === 'right' ? newMoveKeys.concat(targetKeys) : targetKeys.filter(targetKey => !newMoveKeysMap.has(targetKey));
  117. // empty checked keys
  118. const oppositeDirection = direction === 'right' ? 'left' : 'right';
  119. direction === 'right' ? sourceSelectedKeys.value = [] : targetSelectedKeys.value = [];
  120. emit('update:targetKeys', newTargetKeys);
  121. handleSelectChange(oppositeDirection, []);
  122. emit('change', newTargetKeys, direction, newMoveKeys);
  123. formItemContext.onFieldChange();
  124. };
  125. const moveToLeft = () => {
  126. moveTo('left');
  127. };
  128. const moveToRight = () => {
  129. moveTo('right');
  130. };
  131. const onItemSelectAll = (direction, selectedKeys) => {
  132. handleSelectChange(direction, selectedKeys);
  133. };
  134. const onLeftItemSelectAll = selectedKeys => {
  135. return onItemSelectAll('left', selectedKeys);
  136. };
  137. const onRightItemSelectAll = selectedKeys => {
  138. return onItemSelectAll('right', selectedKeys);
  139. };
  140. const handleSelectChange = (direction, holder) => {
  141. if (direction === 'left') {
  142. if (!props.selectedKeys) {
  143. sourceSelectedKeys.value = holder;
  144. }
  145. emit('update:selectedKeys', [...holder, ...targetSelectedKeys.value]);
  146. emit('selectChange', holder, (0, _vue.toRaw)(targetSelectedKeys.value));
  147. } else {
  148. if (!props.selectedKeys) {
  149. targetSelectedKeys.value = holder;
  150. }
  151. emit('update:selectedKeys', [...holder, ...sourceSelectedKeys.value]);
  152. emit('selectChange', (0, _vue.toRaw)(sourceSelectedKeys.value), holder);
  153. }
  154. };
  155. const handleFilter = (direction, e) => {
  156. const value = e.target.value;
  157. emit('search', direction, value);
  158. };
  159. const handleLeftFilter = e => {
  160. handleFilter('left', e);
  161. };
  162. const handleRightFilter = e => {
  163. handleFilter('right', e);
  164. };
  165. const handleClear = direction => {
  166. emit('search', direction, '');
  167. };
  168. const handleLeftClear = () => {
  169. handleClear('left');
  170. };
  171. const handleRightClear = () => {
  172. handleClear('right');
  173. };
  174. const onItemSelect = (direction, selectedKey, checked) => {
  175. const holder = direction === 'left' ? [...sourceSelectedKeys.value] : [...targetSelectedKeys.value];
  176. const index = holder.indexOf(selectedKey);
  177. if (index > -1) {
  178. holder.splice(index, 1);
  179. }
  180. if (checked) {
  181. holder.push(selectedKey);
  182. }
  183. handleSelectChange(direction, holder);
  184. };
  185. const onLeftItemSelect = (selectedKey, checked) => {
  186. return onItemSelect('left', selectedKey, checked);
  187. };
  188. const onRightItemSelect = (selectedKey, checked) => {
  189. return onItemSelect('right', selectedKey, checked);
  190. };
  191. const onRightItemRemove = targetedKeys => {
  192. const {
  193. targetKeys = []
  194. } = props;
  195. const newTargetKeys = targetKeys.filter(key => !targetedKeys.includes(key));
  196. emit('update:targetKeys', newTargetKeys);
  197. emit('change', newTargetKeys, 'left', [...targetedKeys]);
  198. };
  199. const handleScroll = (direction, e) => {
  200. emit('scroll', direction, e);
  201. };
  202. const handleLeftScroll = e => {
  203. handleScroll('left', e);
  204. };
  205. const handleRightScroll = e => {
  206. handleScroll('right', e);
  207. };
  208. const handleListStyle = (listStyle, direction) => {
  209. if (typeof listStyle === 'function') {
  210. return listStyle({
  211. direction
  212. });
  213. }
  214. return listStyle;
  215. };
  216. const leftDataSource = (0, _vue.ref)([]);
  217. const rightDataSource = (0, _vue.ref)([]);
  218. (0, _vue.watchEffect)(() => {
  219. const {
  220. dataSource,
  221. rowKey,
  222. targetKeys = []
  223. } = props;
  224. const ld = [];
  225. const rd = new Array(targetKeys.length);
  226. const targetKeysMap = (0, _transKeys.groupKeysMap)(targetKeys);
  227. dataSource.forEach(record => {
  228. if (rowKey) {
  229. record.key = rowKey(record);
  230. }
  231. // rightData should be ordered by targetKeys
  232. // leftData should be ordered by dataSource
  233. if (targetKeysMap.has(record.key)) {
  234. rd[targetKeysMap.get(record.key)] = record;
  235. } else {
  236. ld.push(record);
  237. }
  238. });
  239. leftDataSource.value = ld;
  240. rightDataSource.value = rd;
  241. });
  242. expose({
  243. handleSelectChange
  244. });
  245. const renderTransfer = transferLocale => {
  246. var _a, _b, _c, _d, _e, _f;
  247. const {
  248. disabled,
  249. operations = [],
  250. showSearch,
  251. listStyle,
  252. operationStyle,
  253. filterOption,
  254. showSelectAll,
  255. selectAllLabels = [],
  256. oneWay,
  257. pagination,
  258. id = formItemContext.id.value
  259. } = props;
  260. const {
  261. class: className,
  262. style
  263. } = attrs;
  264. const children = slots.children;
  265. const mergedPagination = !children && pagination;
  266. const renderEmpty = configProvider.renderEmpty;
  267. const locale = getLocale(transferLocale, renderEmpty);
  268. const {
  269. footer
  270. } = slots;
  271. const renderItem = props.render || slots.render;
  272. const leftActive = targetSelectedKeys.value.length > 0;
  273. const rightActive = sourceSelectedKeys.value.length > 0;
  274. const cls = (0, _classNames.default)(prefixCls.value, className, {
  275. [`${prefixCls.value}-disabled`]: disabled,
  276. [`${prefixCls.value}-customize-list`]: !!children,
  277. [`${prefixCls.value}-rtl`]: direction.value === 'rtl'
  278. }, (0, _statusUtils.getStatusClassNames)(prefixCls.value, mergedStatus.value, formItemInputContext.hasFeedback), hashId.value);
  279. const titles = props.titles;
  280. const leftTitle = (_c = (_a = titles && titles[0]) !== null && _a !== void 0 ? _a : (_b = slots.leftTitle) === null || _b === void 0 ? void 0 : _b.call(slots)) !== null && _c !== void 0 ? _c : (locale.titles || ['', ''])[0];
  281. const rightTitle = (_f = (_d = titles && titles[1]) !== null && _d !== void 0 ? _d : (_e = slots.rightTitle) === null || _e === void 0 ? void 0 : _e.call(slots)) !== null && _f !== void 0 ? _f : (locale.titles || ['', ''])[1];
  282. return (0, _vue.createVNode)("div", (0, _objectSpread2.default)((0, _objectSpread2.default)({}, attrs), {}, {
  283. "class": cls,
  284. "style": style,
  285. "id": id
  286. }), [(0, _vue.createVNode)(_list.default, (0, _objectSpread2.default)({
  287. "key": "leftList",
  288. "prefixCls": `${prefixCls.value}-list`,
  289. "dataSource": leftDataSource.value,
  290. "filterOption": filterOption,
  291. "style": handleListStyle(listStyle, 'left'),
  292. "checkedKeys": sourceSelectedKeys.value,
  293. "handleFilter": handleLeftFilter,
  294. "handleClear": handleLeftClear,
  295. "onItemSelect": onLeftItemSelect,
  296. "onItemSelectAll": onLeftItemSelectAll,
  297. "renderItem": renderItem,
  298. "showSearch": showSearch,
  299. "renderList": children,
  300. "onScroll": handleLeftScroll,
  301. "disabled": disabled,
  302. "direction": direction.value === 'rtl' ? 'right' : 'left',
  303. "showSelectAll": showSelectAll,
  304. "selectAllLabel": selectAllLabels[0] || slots.leftSelectAllLabel,
  305. "pagination": mergedPagination
  306. }, locale), {
  307. titleText: () => leftTitle,
  308. footer
  309. }), (0, _vue.createVNode)(_operation.default, {
  310. "key": "operation",
  311. "class": `${prefixCls.value}-operation`,
  312. "rightActive": rightActive,
  313. "rightArrowText": operations[0],
  314. "moveToRight": moveToRight,
  315. "leftActive": leftActive,
  316. "leftArrowText": operations[1],
  317. "moveToLeft": moveToLeft,
  318. "style": operationStyle,
  319. "disabled": disabled,
  320. "direction": direction.value,
  321. "oneWay": oneWay
  322. }, null), (0, _vue.createVNode)(_list.default, (0, _objectSpread2.default)({
  323. "key": "rightList",
  324. "prefixCls": `${prefixCls.value}-list`,
  325. "dataSource": rightDataSource.value,
  326. "filterOption": filterOption,
  327. "style": handleListStyle(listStyle, 'right'),
  328. "checkedKeys": targetSelectedKeys.value,
  329. "handleFilter": handleRightFilter,
  330. "handleClear": handleRightClear,
  331. "onItemSelect": onRightItemSelect,
  332. "onItemSelectAll": onRightItemSelectAll,
  333. "onItemRemove": onRightItemRemove,
  334. "renderItem": renderItem,
  335. "showSearch": showSearch,
  336. "renderList": children,
  337. "onScroll": handleRightScroll,
  338. "disabled": disabled,
  339. "direction": direction.value === 'rtl' ? 'left' : 'right',
  340. "showSelectAll": showSelectAll,
  341. "selectAllLabel": selectAllLabels[1] || slots.rightSelectAllLabel,
  342. "showRemove": oneWay,
  343. "pagination": mergedPagination
  344. }, locale), {
  345. titleText: () => rightTitle,
  346. footer
  347. })]);
  348. };
  349. return () => wrapSSR((0, _vue.createVNode)(_LocaleReceiver.default, {
  350. "componentName": "Transfer",
  351. "defaultLocale": _en_US.default.Transfer,
  352. "children": renderTransfer
  353. }, null));
  354. }
  355. });
  356. var _default = exports.default = (0, _type.withInstall)(Transfer);