UNPKG

ant-design-vue

Version:

An enterprise-class UI design language and Vue-based implementation

350 lines 13.2 kB
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2"; import _extends from "@babel/runtime/helpers/esm/extends"; import { createVNode as _createVNode, resolveDirective as _resolveDirective } from "vue"; import { computed, watchEffect, defineComponent, ref, watch, toRaw } from 'vue'; import PropTypes from '../_util/vue-types'; import { getPropsSlot } from '../_util/props-util'; import classNames from '../_util/classNames'; import List from './list'; import Operation from './operation'; import LocaleReceiver from '../locale-provider/LocaleReceiver'; import defaultLocale from '../locale/en_US'; import { withInstall, stringType, arrayType, someType, booleanType, objectType, functionType } from '../_util/type'; import useConfigInject from '../config-provider/hooks/useConfigInject'; import { FormItemInputContext, useInjectFormItemContext } from '../form/FormItemContext'; import { getStatusClassNames, getMergedStatus } from '../_util/statusUtils'; import { groupKeysMap, groupDisabledKeysMap } from '../_util/transKeys'; // CSSINJS import useStyle from './style'; export const transferProps = () => ({ id: String, prefixCls: String, dataSource: arrayType([]), disabled: booleanType(), targetKeys: arrayType(), selectedKeys: arrayType(), render: functionType(), listStyle: someType([Function, Object], () => ({})), operationStyle: objectType(undefined), titles: arrayType(), operations: arrayType(), showSearch: booleanType(false), filterOption: functionType(), searchPlaceholder: String, notFoundContent: PropTypes.any, locale: objectType(), rowKey: functionType(), showSelectAll: booleanType(), selectAllLabels: arrayType(), children: functionType(), oneWay: booleanType(), pagination: someType([Object, Boolean]), status: stringType(), onChange: functionType(), onSelectChange: functionType(), onSearch: functionType(), onScroll: functionType(), 'onUpdate:targetKeys': functionType(), 'onUpdate:selectedKeys': functionType() }); const Transfer = defineComponent({ compatConfig: { MODE: 3 }, name: 'ATransfer', inheritAttrs: false, props: transferProps(), slots: Object, // emits: ['update:targetKeys', 'update:selectedKeys', 'change', 'search', 'scroll', 'selectChange'], setup(props, _ref) { let { emit, attrs, slots, expose } = _ref; const { configProvider, prefixCls, direction } = useConfigInject('transfer', props); // style const [wrapSSR, hashId] = useStyle(prefixCls); const sourceSelectedKeys = ref([]); const targetSelectedKeys = ref([]); const formItemContext = useInjectFormItemContext(); const formItemInputContext = FormItemInputContext.useInject(); const mergedStatus = computed(() => getMergedStatus(formItemInputContext.status, props.status)); watch(() => props.selectedKeys, () => { var _a, _b; sourceSelectedKeys.value = ((_a = props.selectedKeys) === null || _a === void 0 ? void 0 : _a.filter(key => props.targetKeys.indexOf(key) === -1)) || []; targetSelectedKeys.value = ((_b = props.selectedKeys) === null || _b === void 0 ? void 0 : _b.filter(key => props.targetKeys.indexOf(key) > -1)) || []; }, { immediate: true }); const getLocale = (transferLocale, renderEmpty) => { // Keep old locale props still working. const oldLocale = { notFoundContent: renderEmpty('Transfer') }; const notFoundContent = getPropsSlot(slots, props, 'notFoundContent'); if (notFoundContent) { oldLocale.notFoundContent = notFoundContent; } if (props.searchPlaceholder !== undefined) { oldLocale.searchPlaceholder = props.searchPlaceholder; } return _extends(_extends(_extends({}, transferLocale), oldLocale), props.locale); }; const moveTo = direction => { const { targetKeys = [], dataSource = [] } = props; const moveKeys = direction === 'right' ? sourceSelectedKeys.value : targetSelectedKeys.value; const dataSourceDisabledKeysMap = groupDisabledKeysMap(dataSource); // filter the disabled options const newMoveKeys = moveKeys.filter(key => !dataSourceDisabledKeysMap.has(key)); const newMoveKeysMap = groupKeysMap(newMoveKeys); // move items to target box const newTargetKeys = direction === 'right' ? newMoveKeys.concat(targetKeys) : targetKeys.filter(targetKey => !newMoveKeysMap.has(targetKey)); // empty checked keys const oppositeDirection = direction === 'right' ? 'left' : 'right'; direction === 'right' ? sourceSelectedKeys.value = [] : targetSelectedKeys.value = []; emit('update:targetKeys', newTargetKeys); handleSelectChange(oppositeDirection, []); emit('change', newTargetKeys, direction, newMoveKeys); formItemContext.onFieldChange(); }; const moveToLeft = () => { moveTo('left'); }; const moveToRight = () => { moveTo('right'); }; const onItemSelectAll = (direction, selectedKeys) => { handleSelectChange(direction, selectedKeys); }; const onLeftItemSelectAll = selectedKeys => { return onItemSelectAll('left', selectedKeys); }; const onRightItemSelectAll = selectedKeys => { return onItemSelectAll('right', selectedKeys); }; const handleSelectChange = (direction, holder) => { if (direction === 'left') { if (!props.selectedKeys) { sourceSelectedKeys.value = holder; } emit('update:selectedKeys', [...holder, ...targetSelectedKeys.value]); emit('selectChange', holder, toRaw(targetSelectedKeys.value)); } else { if (!props.selectedKeys) { targetSelectedKeys.value = holder; } emit('update:selectedKeys', [...holder, ...sourceSelectedKeys.value]); emit('selectChange', toRaw(sourceSelectedKeys.value), holder); } }; const handleFilter = (direction, e) => { const value = e.target.value; emit('search', direction, value); }; const handleLeftFilter = e => { handleFilter('left', e); }; const handleRightFilter = e => { handleFilter('right', e); }; const handleClear = direction => { emit('search', direction, ''); }; const handleLeftClear = () => { handleClear('left'); }; const handleRightClear = () => { handleClear('right'); }; const onItemSelect = (direction, selectedKey, checked) => { const holder = direction === 'left' ? [...sourceSelectedKeys.value] : [...targetSelectedKeys.value]; const index = holder.indexOf(selectedKey); if (index > -1) { holder.splice(index, 1); } if (checked) { holder.push(selectedKey); } handleSelectChange(direction, holder); }; const onLeftItemSelect = (selectedKey, checked) => { return onItemSelect('left', selectedKey, checked); }; const onRightItemSelect = (selectedKey, checked) => { return onItemSelect('right', selectedKey, checked); }; const onRightItemRemove = targetedKeys => { const { targetKeys = [] } = props; const newTargetKeys = targetKeys.filter(key => !targetedKeys.includes(key)); emit('update:targetKeys', newTargetKeys); emit('change', newTargetKeys, 'left', [...targetedKeys]); }; const handleScroll = (direction, e) => { emit('scroll', direction, e); }; const handleLeftScroll = e => { handleScroll('left', e); }; const handleRightScroll = e => { handleScroll('right', e); }; const handleListStyle = (listStyle, direction) => { if (typeof listStyle === 'function') { return listStyle({ direction }); } return listStyle; }; const leftDataSource = ref([]); const rightDataSource = ref([]); watchEffect(() => { const { dataSource, rowKey, targetKeys = [] } = props; const ld = []; const rd = new Array(targetKeys.length); const targetKeysMap = groupKeysMap(targetKeys); dataSource.forEach(record => { if (rowKey) { record.key = rowKey(record); } // rightData should be ordered by targetKeys // leftData should be ordered by dataSource if (targetKeysMap.has(record.key)) { rd[targetKeysMap.get(record.key)] = record; } else { ld.push(record); } }); leftDataSource.value = ld; rightDataSource.value = rd; }); expose({ handleSelectChange }); const renderTransfer = transferLocale => { var _a, _b, _c, _d, _e, _f; const { disabled, operations = [], showSearch, listStyle, operationStyle, filterOption, showSelectAll, selectAllLabels = [], oneWay, pagination, id = formItemContext.id.value } = props; const { class: className, style } = attrs; const children = slots.children; const mergedPagination = !children && pagination; const renderEmpty = configProvider.renderEmpty; const locale = getLocale(transferLocale, renderEmpty); const { footer } = slots; const renderItem = props.render || slots.render; const leftActive = targetSelectedKeys.value.length > 0; const rightActive = sourceSelectedKeys.value.length > 0; const cls = classNames(prefixCls.value, className, { [`${prefixCls.value}-disabled`]: disabled, [`${prefixCls.value}-customize-list`]: !!children, [`${prefixCls.value}-rtl`]: direction.value === 'rtl' }, getStatusClassNames(prefixCls.value, mergedStatus.value, formItemInputContext.hasFeedback), hashId.value); const titles = props.titles; 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]; 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]; return _createVNode("div", _objectSpread(_objectSpread({}, attrs), {}, { "class": cls, "style": style, "id": id }), [_createVNode(List, _objectSpread({ "key": "leftList", "prefixCls": `${prefixCls.value}-list`, "dataSource": leftDataSource.value, "filterOption": filterOption, "style": handleListStyle(listStyle, 'left'), "checkedKeys": sourceSelectedKeys.value, "handleFilter": handleLeftFilter, "handleClear": handleLeftClear, "onItemSelect": onLeftItemSelect, "onItemSelectAll": onLeftItemSelectAll, "renderItem": renderItem, "showSearch": showSearch, "renderList": children, "onScroll": handleLeftScroll, "disabled": disabled, "direction": direction.value === 'rtl' ? 'right' : 'left', "showSelectAll": showSelectAll, "selectAllLabel": selectAllLabels[0] || slots.leftSelectAllLabel, "pagination": mergedPagination }, locale), { titleText: () => leftTitle, footer }), _createVNode(Operation, { "key": "operation", "class": `${prefixCls.value}-operation`, "rightActive": rightActive, "rightArrowText": operations[0], "moveToRight": moveToRight, "leftActive": leftActive, "leftArrowText": operations[1], "moveToLeft": moveToLeft, "style": operationStyle, "disabled": disabled, "direction": direction.value, "oneWay": oneWay }, null), _createVNode(List, _objectSpread({ "key": "rightList", "prefixCls": `${prefixCls.value}-list`, "dataSource": rightDataSource.value, "filterOption": filterOption, "style": handleListStyle(listStyle, 'right'), "checkedKeys": targetSelectedKeys.value, "handleFilter": handleRightFilter, "handleClear": handleRightClear, "onItemSelect": onRightItemSelect, "onItemSelectAll": onRightItemSelectAll, "onItemRemove": onRightItemRemove, "renderItem": renderItem, "showSearch": showSearch, "renderList": children, "onScroll": handleRightScroll, "disabled": disabled, "direction": direction.value === 'rtl' ? 'left' : 'right', "showSelectAll": showSelectAll, "selectAllLabel": selectAllLabels[1] || slots.rightSelectAllLabel, "showRemove": oneWay, "pagination": mergedPagination }, locale), { titleText: () => rightTitle, footer })]); }; return () => wrapSSR(_createVNode(LocaleReceiver, { "componentName": "Transfer", "defaultLocale": defaultLocale.Transfer, "children": renderTransfer }, null)); } }); export default withInstall(Transfer);