UNPKG

ant-design-vue

Version:

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

350 lines (309 loc) 12.4 kB
import { isVNode as _isVNode, createVNode as _createVNode } from "vue"; function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } import classNames from '../_util/classNames'; import PropTypes, { withUndefined } from '../_util/vue-types'; import { isValidElement, splitAttrs, findDOMNode, filterEmpty } from '../_util/props-util'; import initDefaultProps from '../_util/props-util/initDefaultProps'; import BaseMixin from '../_util/BaseMixin'; import Checkbox from '../checkbox'; import Search from './search'; import defaultRenderList from './renderListBody'; import triggerEvent from '../_util/triggerEvent'; import { defineComponent, nextTick } from 'vue'; function _isSlot(s) { return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !_isVNode(s); } var defaultRender = function defaultRender() { return null; }; var TransferItem = { key: PropTypes.string.isRequired, title: PropTypes.string.isRequired, description: PropTypes.string, disabled: PropTypes.looseBool }; function isRenderResultPlainObject(result) { return result && !isValidElement(result) && Object.prototype.toString.call(result) === '[object Object]'; } export var TransferListProps = { prefixCls: PropTypes.string, titleText: PropTypes.string, dataSource: PropTypes.arrayOf(PropTypes.shape(TransferItem).loose), filter: PropTypes.string, filterOption: PropTypes.func, checkedKeys: PropTypes.arrayOf(PropTypes.string), handleFilter: PropTypes.func, handleSelect: PropTypes.func, handleSelectAll: PropTypes.func, handleClear: PropTypes.func, renderItem: PropTypes.func, showSearch: PropTypes.looseBool, searchPlaceholder: PropTypes.string, notFoundContent: PropTypes.any, itemUnit: PropTypes.string, itemsUnit: PropTypes.string, body: PropTypes.any, renderList: PropTypes.any, footer: PropTypes.any, lazy: withUndefined(PropTypes.oneOfType([PropTypes.looseBool, PropTypes.object])), disabled: PropTypes.looseBool, direction: PropTypes.string, showSelectAll: PropTypes.looseBool, onItemSelect: PropTypes.func, onItemSelectAll: PropTypes.func, onScroll: PropTypes.func }; function renderListNode(renderList, props) { var bodyContent = renderList ? renderList(props) : null; var customize = !!bodyContent && filterEmpty(bodyContent).length > 0; if (!customize) { bodyContent = defaultRenderList(props); } return { customize: customize, bodyContent: bodyContent }; } export default defineComponent({ name: 'TransferList', mixins: [BaseMixin], inheritAttrs: false, props: initDefaultProps(TransferListProps, { dataSource: [], titleText: '', showSearch: false, lazy: {} }), setup: function setup() { return { timer: null, triggerScrollTimer: null, scrollEvent: null }; }, data: function data() { return { filterValue: '' }; }, beforeUnmount: function beforeUnmount() { clearTimeout(this.triggerScrollTimer); // if (this.scrollEvent) { // this.scrollEvent.remove(); // } }, updated: function updated() { var _this = this; nextTick(function () { if (_this.scrollEvent) { _this.scrollEvent.remove(); } }); }, methods: { handleScroll: function handleScroll(e) { this.$emit('scroll', e); }, getCheckStatus: function getCheckStatus(filteredItems) { var checkedKeys = this.$props.checkedKeys; if (checkedKeys.length === 0) { return 'none'; } if (filteredItems.every(function (item) { return checkedKeys.indexOf(item.key) >= 0 || !!item.disabled; })) { return 'all'; } return 'part'; }, getFilteredItems: function getFilteredItems(dataSource, filterValue) { var _this2 = this; var filteredItems = []; var filteredRenderItems = []; dataSource.forEach(function (item) { var renderedItem = _this2.renderItemHtml(item); var renderedText = renderedItem.renderedText; // Filter skip if (filterValue && filterValue.trim() && !_this2.matchFilter(renderedText, item)) { return null; } filteredItems.push(item); filteredRenderItems.push(renderedItem); }); return { filteredItems: filteredItems, filteredRenderItems: filteredRenderItems }; }, getListBody: function getListBody(prefixCls, searchPlaceholder, filterValue, filteredItems, notFoundContent, bodyDom, filteredRenderItems, checkedKeys, renderList, showSearch, disabled) { var search = showSearch ? _createVNode("div", { "class": "".concat(prefixCls, "-body-search-wrapper") }, [_createVNode(Search, { "prefixCls": "".concat(prefixCls, "-search"), "onChange": this._handleFilter, "handleClear": this._handleClear, "placeholder": searchPlaceholder, "value": filterValue, "disabled": disabled }, null)]) : null; var listBody = bodyDom; if (!listBody) { var bodyNode; var _splitAttrs = splitAttrs(this.$attrs), onEvents = _splitAttrs.onEvents; var _renderListNode = renderListNode(renderList, _extends(_extends(_extends({}, this.$props), { filteredItems: filteredItems, filteredRenderItems: filteredRenderItems, selectedKeys: checkedKeys }), onEvents)), bodyContent = _renderListNode.bodyContent, customize = _renderListNode.customize; // We should wrap customize list body in a classNamed div to use flex layout. if (customize) { bodyNode = _createVNode("div", { "class": "".concat(prefixCls, "-body-customize-wrapper") }, _isSlot(bodyContent) ? bodyContent : { default: function _default() { return [bodyContent]; } }); } else { bodyNode = filteredItems.length ? bodyContent : _createVNode("div", { "class": "".concat(prefixCls, "-body-not-found") }, _isSlot(notFoundContent) ? notFoundContent : { default: function _default() { return [notFoundContent]; } }); } listBody = _createVNode("div", { "class": classNames(showSearch ? "".concat(prefixCls, "-body ").concat(prefixCls, "-body-with-search") : "".concat(prefixCls, "-body")) }, [search, bodyNode]); } return listBody; }, getCheckBox: function getCheckBox(filteredItems, showSelectAll, disabled) { var _this3 = this; var checkStatus = this.getCheckStatus(filteredItems); var checkedAll = checkStatus === 'all'; var checkAllCheckbox = showSelectAll !== false && _createVNode(Checkbox, { "disabled": disabled, "checked": checkedAll, "indeterminate": checkStatus === 'part', "onChange": function onChange() { // Only select enabled items _this3.$emit('itemSelectAll', filteredItems.filter(function (item) { return !item.disabled; }).map(function (_ref) { var key = _ref.key; return key; }), !checkedAll); } }, null); return checkAllCheckbox; }, _handleSelect: function _handleSelect(selectedItem) { var checkedKeys = this.$props.checkedKeys; var result = checkedKeys.some(function (key) { return key === selectedItem.key; }); this.handleSelect(selectedItem, !result); }, _handleFilter: function _handleFilter(e) { var _this4 = this; var handleFilter = this.$props.handleFilter; var filterValue = e.target.value; this.setState({ filterValue: filterValue }); handleFilter(e); if (!filterValue) { return; } // Manually trigger scroll event for lazy search bug // https://github.com/ant-design/ant-design/issues/5631 this.triggerScrollTimer = setTimeout(function () { var transferNode = findDOMNode(_this4); var listNode = transferNode.querySelectorAll('.ant-transfer-list-content')[0]; if (listNode) { triggerEvent(listNode, 'scroll'); } }, 0); }, _handleClear: function _handleClear(e) { this.setState({ filterValue: '' }); this.handleClear(e); }, matchFilter: function matchFilter(text, item) { var filterValue = this.$data.filterValue; var filterOption = this.$props.filterOption; if (filterOption) { return filterOption(filterValue, item); } return text.indexOf(filterValue) >= 0; }, renderItemHtml: function renderItemHtml(item) { var _this$$props$renderIt = this.$props.renderItem, renderItem = _this$$props$renderIt === void 0 ? defaultRender : _this$$props$renderIt; var renderResult = renderItem(item); var isRenderResultPlain = isRenderResultPlainObject(renderResult); return { renderedText: isRenderResultPlain ? renderResult.value : renderResult, renderedEl: isRenderResultPlain ? renderResult.label : renderResult, item: item }; }, filterNull: function filterNull(arr) { return arr.filter(function (item) { return item !== null; }); } }, render: function render() { var filterValue = this.$data.filterValue; var _this$$props = this.$props, prefixCls = _this$$props.prefixCls, dataSource = _this$$props.dataSource, titleText = _this$$props.titleText, checkedKeys = _this$$props.checkedKeys, disabled = _this$$props.disabled, body = _this$$props.body, footer = _this$$props.footer, showSearch = _this$$props.showSearch, searchPlaceholder = _this$$props.searchPlaceholder, notFoundContent = _this$$props.notFoundContent, itemUnit = _this$$props.itemUnit, itemsUnit = _this$$props.itemsUnit, renderList = _this$$props.renderList, showSelectAll = _this$$props.showSelectAll; // Custom Layout var footerDom = footer && footer(_extends({}, this.$props)); var bodyDom = body && body(_extends({}, this.$props)); var listCls = classNames(prefixCls, _defineProperty({}, "".concat(prefixCls, "-with-footer"), !!footerDom)); // ====================== Get filtered, checked item list ====================== var _this$getFilteredItem = this.getFilteredItems(dataSource, filterValue), filteredItems = _this$getFilteredItem.filteredItems, filteredRenderItems = _this$getFilteredItem.filteredRenderItems; // ================================= List Body ================================= var unit = dataSource.length > 1 ? itemsUnit : itemUnit; var listBody = this.getListBody(prefixCls, searchPlaceholder, filterValue, filteredItems, notFoundContent, bodyDom, filteredRenderItems, checkedKeys, renderList, showSearch, disabled); var listFooter = footerDom ? _createVNode("div", { "class": "".concat(prefixCls, "-footer") }, _isSlot(footerDom) ? footerDom : { default: function _default() { return [footerDom]; } }) : null; var checkAllCheckbox = this.getCheckBox(filteredItems, showSelectAll, disabled); return _createVNode("div", { "class": listCls, "style": this.$attrs.style }, [_createVNode("div", { "class": "".concat(prefixCls, "-header") }, [checkAllCheckbox, _createVNode("span", { "class": "".concat(prefixCls, "-header-selected") }, [_createVNode("span", null, [(checkedKeys.length > 0 ? "".concat(checkedKeys.length, "/") : '') + filteredItems.length, ' ', unit]), _createVNode("span", { "class": "".concat(prefixCls, "-header-title") }, _isSlot(titleText) ? titleText : { default: function _default() { return [titleText]; } })])]), listBody, listFooter]); } });