UNPKG

oui-antd

Version:

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

335 lines (279 loc) 13.6 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _defineProperty2 = require('babel-runtime/helpers/defineProperty'); var _defineProperty3 = _interopRequireDefault(_defineProperty2); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _createClass2 = require('babel-runtime/helpers/createClass'); var _createClass3 = _interopRequireDefault(_createClass2); var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn'); var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); var _inherits2 = require('babel-runtime/helpers/inherits'); var _inherits3 = _interopRequireDefault(_inherits2); var _react = require('react'); var React = _interopRequireWildcard(_react); var _reactDom = require('react-dom'); var ReactDOM = _interopRequireWildcard(_reactDom); var _rcMenu = require('rc-menu'); var _rcMenu2 = _interopRequireDefault(_rcMenu); var _domClosest = require('dom-closest'); var _domClosest2 = _interopRequireDefault(_domClosest); var _classnames = require('classnames'); var _classnames2 = _interopRequireDefault(_classnames); var _shallowequal = require('shallowequal'); var _shallowequal2 = _interopRequireDefault(_shallowequal); var _dropdown = require('../dropdown'); var _dropdown2 = _interopRequireDefault(_dropdown); var _icon = require('../icon'); var _icon2 = _interopRequireDefault(_icon); var _checkbox = require('../checkbox'); var _checkbox2 = _interopRequireDefault(_checkbox); var _radio = require('../radio'); var _radio2 = _interopRequireDefault(_radio); var _FilterDropdownMenuWrapper = require('./FilterDropdownMenuWrapper'); var _FilterDropdownMenuWrapper2 = _interopRequireDefault(_FilterDropdownMenuWrapper); 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)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var FilterMenu = function (_React$Component) { (0, _inherits3['default'])(FilterMenu, _React$Component); function FilterMenu(props) { (0, _classCallCheck3['default'])(this, FilterMenu); var _this = (0, _possibleConstructorReturn3['default'])(this, (FilterMenu.__proto__ || Object.getPrototypeOf(FilterMenu)).call(this, props)); _this.setNeverShown = function (column) { var rootNode = ReactDOM.findDOMNode(_this); var filterBelongToScrollBody = !!(0, _domClosest2['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); _this.confirmFilter(); }; _this.onVisibleChange = function (visible) { _this.setVisible(visible); if (!visible) { _this.confirmFilter(); } }; _this.handleMenuItemClick = function (info) { if (!info.keyPath || info.keyPath.length <= 1) { return; } var keyPathOfSelectedItem = _this.state.keyPathOfSelectedItem; if (_this.state.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 _this$props = _this.props, column = _this$props.column, locale = _this$props.locale, prefixCls = _this$props.prefixCls; var filterd = _this.props.selectedKeys.length > 0; var filterIcon = column.filterIcon; if (typeof filterIcon === 'function') { filterIcon = filterIcon(filterd); } var dropdownSelectedClass = filterd ? prefixCls + '-selected' : ''; return filterIcon ? React.cloneElement(filterIcon, { title: locale.filterTitle, className: (0, _classnames2['default'])(prefixCls + '-icon', filterIcon.props.className) }) : React.createElement(_icon2['default'], { title: locale.filterTitle, type: 'filter', className: dropdownSelectedClass }); }; var visible = 'filterDropdownVisible' in props.column ? props.column.filterDropdownVisible : false; _this.state = { selectedKeys: props.selectedKeys, keyPathOfSelectedItem: {}, visible: visible }; return _this; } (0, _createClass3['default'])(FilterMenu, [{ key: 'componentDidMount', value: function componentDidMount() { var column = this.props.column; this.setNeverShown(column); } }, { key: 'componentWillReceiveProps', value: function componentWillReceiveProps(nextProps) { var column = nextProps.column; this.setNeverShown(column); var newState = {}; /** * 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, _shallowequal2['default'])(this.props.selectedKeys, nextProps.selectedKeys)) { newState.selectedKeys = nextProps.selectedKeys; } if ('filterDropdownVisible' in column) { newState.visible = column.filterDropdownVisible; } if (Object.keys(newState).length > 0) { this.setState(newState); } } }, { 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: 'confirmFilter', value: function confirmFilter() { var selectedKeys = this.state.selectedKeys; if (!(0, _shallowequal2['default'])(selectedKeys, this.props.selectedKeys)) { this.props.confirmFilter(this.props.column, selectedKeys); } } }, { key: 'renderMenuItem', value: function renderMenuItem(item) { var column = this.props.column; var selectedKeys = this.state.selectedKeys; var multiple = 'filterMultiple' in column ? column.filterMultiple : true; var input = multiple ? React.createElement(_checkbox2['default'], { checked: selectedKeys.indexOf(item.value.toString()) >= 0 }) : React.createElement(_radio2['default'], { checked: selectedKeys.indexOf(item.value.toString()) >= 0 }); return React.createElement( _rcMenu.Item, { key: item.value }, input, React.createElement( 'span', null, item.text ) ); } }, { key: 'hasSubMenu', value: function hasSubMenu() { var _props$column$filters = this.props.column.filters, filters = _props$column$filters === undefined ? [] : _props$column$filters; return filters.some(function (item) { return !!(item.children && item.children.length > 0); }); } }, { 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 ? _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: 'render', value: function render() { var _this3 = this; var _props = this.props, column = _props.column, locale = _props.locale, prefixCls = _props.prefixCls, dropdownPrefixCls = _props.dropdownPrefixCls, getPopupContainer = _props.getPopupContainer; // default multiple selection in filter dropdown var multiple = 'filterMultiple' in column ? column.filterMultiple : true; var dropdownMenuClass = (0, _classnames2['default'])((0, _defineProperty3['default'])({}, dropdownPrefixCls + '-menu-without-submenu', !this.hasSubMenu())); var filterDropdown = column.filterDropdown; if (filterDropdown && typeof filterDropdown === 'function') { filterDropdown = filterDropdown({ prefixCls: dropdownPrefixCls + '-custom', setSelectedKeys: function setSelectedKeys(selectedKeys) { return _this3.setSelectedKeys({ selectedKeys: selectedKeys }); }, selectedKeys: this.state.selectedKeys, confirm: this.handleConfirm, clearFilters: this.handleClearFilters, filters: column.filters, getPopupContainer: function getPopupContainer(triggerNode) { return triggerNode.parentNode; } }); } var menus = filterDropdown ? React.createElement( _FilterDropdownMenuWrapper2['default'], null, filterDropdown ) : React.createElement( _FilterDropdownMenuWrapper2['default'], { className: prefixCls + '-dropdown' }, React.createElement( _rcMenu2['default'], { multiple: multiple, onClick: this.handleMenuItemClick, prefixCls: dropdownPrefixCls + '-menu', className: dropdownMenuClass, onSelect: this.setSelectedKeys, onDeselect: this.setSelectedKeys, selectedKeys: this.state.selectedKeys, getPopupContainer: function getPopupContainer(triggerNode) { return triggerNode.parentNode; } }, this.renderMenus(column.filters) ), React.createElement( 'div', { className: prefixCls + '-dropdown-btns' }, React.createElement( 'a', { className: prefixCls + '-dropdown-link confirm', onClick: this.handleConfirm }, locale.filterConfirm ), React.createElement( 'a', { className: prefixCls + '-dropdown-link clear', onClick: this.handleClearFilters }, locale.filterReset ) ) ); return React.createElement( _dropdown2['default'], { trigger: ['click'], overlay: menus, visible: this.neverShown ? false : this.state.visible, onVisibleChange: this.onVisibleChange, getPopupContainer: getPopupContainer, forceRender: true }, this.renderFilterIcon() ); } }]); return FilterMenu; }(React.Component); exports['default'] = FilterMenu; FilterMenu.defaultProps = { handleFilter: function handleFilter() {}, column: {} }; module.exports = exports['default'];