UNPKG

antd

Version:

An enterprise-class UI design language and React components implementation

396 lines (325 loc) 15.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var React = _interopRequireWildcard(require("react")); var ReactDOM = _interopRequireWildcard(require("react-dom")); var _reactLifecyclesCompat = require("react-lifecycles-compat"); var _rcMenu = _interopRequireWildcard(require("rc-menu")); var _domClosest = _interopRequireDefault(require("dom-closest")); var _classnames = _interopRequireDefault(require("classnames")); var _shallowequal = _interopRequireDefault(require("shallowequal")); var _dropdown = _interopRequireDefault(require("../dropdown")); var _icon = _interopRequireDefault(require("../icon")); var _checkbox = _interopRequireDefault(require("../checkbox")); var _radio = _interopRequireDefault(require("../radio")); var _FilterDropdownMenuWrapper = _interopRequireDefault(require("./FilterDropdownMenuWrapper")); var _util = require("./util"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj["default"] = obj; return newObj; } } function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } 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 _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function stopPropagation(e) { e.stopPropagation(); if (e.nativeEvent.stopImmediatePropagation) { e.nativeEvent.stopImmediatePropagation(); } } var FilterMenu = /*#__PURE__*/ function (_React$Component) { _inherits(FilterMenu, _React$Component); function FilterMenu(props) { var _this; _classCallCheck(this, FilterMenu); _this = _possibleConstructorReturn(this, _getPrototypeOf(FilterMenu).call(this, props)); _this.setNeverShown = function (column) { var rootNode = ReactDOM.findDOMNode(_assertThisInitialized(_this)); var filterBelongToScrollBody = !!(0, _domClosest["default"])(rootNode, ".ant-table-scroll"); if (filterBelongToScrollBody) { // When fixed column have filters, there will be two dropdown menus // Filter dropdown menu inside scroll body should never be shown // To fix https://github.com/ant-design/ant-design/issues/5010 and // https://github.com/ant-design/ant-design/issues/7909 _this.neverShown = !!column.fixed; } }; _this.setSelectedKeys = function (_ref) { var selectedKeys = _ref.selectedKeys; _this.setState({ selectedKeys: selectedKeys }); }; _this.handleClearFilters = function () { _this.setState({ selectedKeys: [] }, _this.handleConfirm); }; _this.handleConfirm = function () { _this.setVisible(false); // Call `setSelectedKeys` & `confirm` in the same time will make filter data not up to date // https://github.com/ant-design/ant-design/issues/12284 _this.setState({}, _this.confirmFilter); }; _this.onVisibleChange = function (visible) { _this.setVisible(visible); var column = _this.props.column; // https://github.com/ant-design/ant-design/issues/17833 if (!visible && !(column.filterDropdown instanceof Function)) { _this.confirmFilter(); } }; _this.handleMenuItemClick = function (info) { var selectedKeys = _this.state.selectedKeys; if (!info.keyPath || info.keyPath.length <= 1) { return; } var keyPathOfSelectedItem = _this.state.keyPathOfSelectedItem; if (selectedKeys && selectedKeys.indexOf(info.key) >= 0) { // deselect SubMenu child delete keyPathOfSelectedItem[info.key]; } else { // select SubMenu child keyPathOfSelectedItem[info.key] = info.keyPath; } _this.setState({ keyPathOfSelectedItem: keyPathOfSelectedItem }); }; _this.renderFilterIcon = function () { var _classNames; var _this$props = _this.props, column = _this$props.column, locale = _this$props.locale, prefixCls = _this$props.prefixCls, selectedKeys = _this$props.selectedKeys; var filtered = selectedKeys && selectedKeys.length > 0; var filterIcon = column.filterIcon; if (typeof filterIcon === 'function') { filterIcon = filterIcon(filtered); } var dropdownIconClass = (0, _classnames["default"])((_classNames = {}, _defineProperty(_classNames, "".concat(prefixCls, "-selected"), filtered), _defineProperty(_classNames, "".concat(prefixCls, "-open"), _this.getDropdownVisible()), _classNames)); return filterIcon ? React.cloneElement(filterIcon, { title: locale.filterTitle, className: (0, _classnames["default"])("".concat(prefixCls, "-icon"), dropdownIconClass, filterIcon.props.className), onClick: stopPropagation }) : React.createElement(_icon["default"], { title: locale.filterTitle, type: "filter", theme: "filled", className: dropdownIconClass, onClick: stopPropagation }); }; var visible = 'filterDropdownVisible' in props.column ? props.column.filterDropdownVisible : false; _this.state = { selectedKeys: props.selectedKeys, valueKeys: (0, _util.generateValueMaps)(props.column.filters), keyPathOfSelectedItem: {}, visible: visible, prevProps: props }; return _this; } _createClass(FilterMenu, [{ key: "componentDidMount", value: function componentDidMount() { var column = this.props.column; this.setNeverShown(column); } }, { key: "componentDidUpdate", value: function componentDidUpdate() { var column = this.props.column; this.setNeverShown(column); } }, { key: "getDropdownVisible", value: function getDropdownVisible() { return this.neverShown ? false : this.state.visible; } }, { key: "setVisible", value: function setVisible(visible) { var column = this.props.column; if (!('filterDropdownVisible' in column)) { this.setState({ visible: visible }); } if (column.onFilterDropdownVisibleChange) { column.onFilterDropdownVisibleChange(visible); } } }, { key: "hasSubMenu", value: function hasSubMenu() { var _this$props$column$fi = this.props.column.filters, filters = _this$props$column$fi === void 0 ? [] : _this$props$column$fi; return filters.some(function (item) { return !!(item.children && item.children.length > 0); }); } }, { key: "confirmFilter", value: function confirmFilter() { var _this$props2 = this.props, column = _this$props2.column, propSelectedKeys = _this$props2.selectedKeys, confirmFilter = _this$props2.confirmFilter; var _this$state = this.state, selectedKeys = _this$state.selectedKeys, valueKeys = _this$state.valueKeys; var filterDropdown = column.filterDropdown; if (!(0, _shallowequal["default"])(selectedKeys, propSelectedKeys)) { confirmFilter(column, filterDropdown ? selectedKeys : selectedKeys.map(function (key) { return valueKeys[key]; }).filter(function (key) { return key !== undefined; })); } } }, { key: "renderMenus", value: function renderMenus(items) { var _this2 = this; return items.map(function (item) { if (item.children && item.children.length > 0) { var keyPathOfSelectedItem = _this2.state.keyPathOfSelectedItem; var containSelected = Object.keys(keyPathOfSelectedItem).some(function (key) { return keyPathOfSelectedItem[key].indexOf(item.value) >= 0; }); var subMenuCls = containSelected ? "".concat(_this2.props.dropdownPrefixCls, "-submenu-contain-selected") : ''; return React.createElement(_rcMenu.SubMenu, { title: item.text, className: subMenuCls, key: item.value.toString() }, _this2.renderMenus(item.children)); } return _this2.renderMenuItem(item); }); } }, { key: "renderMenuItem", value: function renderMenuItem(item) { var column = this.props.column; var selectedKeys = this.state.selectedKeys; var multiple = 'filterMultiple' in column ? column.filterMultiple : true; // We still need trade key as string since Menu render need string var internalSelectedKeys = (selectedKeys || []).map(function (key) { return key.toString(); }); var input = multiple ? React.createElement(_checkbox["default"], { checked: internalSelectedKeys.indexOf(item.value.toString()) >= 0 }) : React.createElement(_radio["default"], { checked: internalSelectedKeys.indexOf(item.value.toString()) >= 0 }); return React.createElement(_rcMenu.Item, { key: item.value }, input, React.createElement("span", null, item.text)); } }, { key: "render", value: function render() { var _this3 = this; var originSelectedKeys = this.state.selectedKeys; var _this$props3 = this.props, column = _this$props3.column, locale = _this$props3.locale, prefixCls = _this$props3.prefixCls, dropdownPrefixCls = _this$props3.dropdownPrefixCls, getPopupContainer = _this$props3.getPopupContainer; // default multiple selection in filter dropdown var multiple = 'filterMultiple' in column ? column.filterMultiple : true; var dropdownMenuClass = (0, _classnames["default"])(_defineProperty({}, "".concat(dropdownPrefixCls, "-menu-without-submenu"), !this.hasSubMenu())); var filterDropdown = column.filterDropdown; if (filterDropdown instanceof Function) { filterDropdown = filterDropdown({ prefixCls: "".concat(dropdownPrefixCls, "-custom"), setSelectedKeys: function setSelectedKeys(selectedKeys) { return _this3.setSelectedKeys({ selectedKeys: selectedKeys }); }, selectedKeys: originSelectedKeys, confirm: this.handleConfirm, clearFilters: this.handleClearFilters, filters: column.filters }); } var menus = filterDropdown ? React.createElement(_FilterDropdownMenuWrapper["default"], { className: "".concat(prefixCls, "-dropdown") }, filterDropdown) : React.createElement(_FilterDropdownMenuWrapper["default"], { className: "".concat(prefixCls, "-dropdown") }, React.createElement(_rcMenu["default"], { multiple: multiple, onClick: this.handleMenuItemClick, prefixCls: "".concat(dropdownPrefixCls, "-menu"), className: dropdownMenuClass, onSelect: this.setSelectedKeys, onDeselect: this.setSelectedKeys, selectedKeys: originSelectedKeys && originSelectedKeys.map(function (val) { return val.toString(); }), getPopupContainer: getPopupContainer }, this.renderMenus(column.filters)), React.createElement("div", { className: "".concat(prefixCls, "-dropdown-btns") }, React.createElement("a", { className: "".concat(prefixCls, "-dropdown-link confirm"), onClick: this.handleConfirm }, locale.filterConfirm), React.createElement("a", { className: "".concat(prefixCls, "-dropdown-link clear"), onClick: this.handleClearFilters }, locale.filterReset))); return React.createElement(_dropdown["default"], { trigger: ['click'], placement: "bottomRight", overlay: menus, visible: this.getDropdownVisible(), onVisibleChange: this.onVisibleChange, getPopupContainer: getPopupContainer, forceRender: true }, this.renderFilterIcon()); } }], [{ key: "getDerivedStateFromProps", value: function getDerivedStateFromProps(nextProps, prevState) { var column = nextProps.column; var prevProps = prevState.prevProps; var newState = { prevProps: nextProps }; /** * if the state is visible the component should ignore updates on selectedKeys prop to avoid * that the user selection is lost * this happens frequently when a table is connected on some sort of realtime data * Fixes https://github.com/ant-design/ant-design/issues/10289 and * https://github.com/ant-design/ant-design/issues/10209 */ if ('selectedKeys' in nextProps && !(0, _shallowequal["default"])(prevProps.selectedKeys, nextProps.selectedKeys)) { newState.selectedKeys = nextProps.selectedKeys; } if (!(0, _shallowequal["default"])((prevProps.column || {}).filters, (nextProps.column || {}).filters)) { newState.valueKeys = (0, _util.generateValueMaps)(nextProps.column.filters); } if ('filterDropdownVisible' in column) { newState.visible = column.filterDropdownVisible; } return newState; } }]); return FilterMenu; }(React.Component); FilterMenu.defaultProps = { handleFilter: function handleFilter() {}, column: {} }; (0, _reactLifecyclesCompat.polyfill)(FilterMenu); var _default = FilterMenu; exports["default"] = _default; //# sourceMappingURL=filterDropdown.js.map