import { __assign, __extends } from "tslib";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import * as ReactDom from 'react-dom';
import { createRef, PureComponent } from 'react';
import classnames from 'classnames';
import isEqual from '../utils/isEqual';
import noop from '../utils/noop';
import measureScrollbar from '../utils/dom/measureScrollbar';
import { runOnceInNextFrame } from '../utils/nextFrame';
import { WindowResizeHandler } from '../utils/component/WindowResizeHandler';
import { WindowScrollHandler } from '../utils/component/WindowScrollHandler';
import BatchComponents from './BatchComponents';
import { groupedColumns, getLeafColumns, needFixBatchComps, isElementInView, mapDOMNodes, getCompatSelectionPropsFn, getSelectAllCheckboxState, } from './utils';
import { I18nReceiver as Receiver } from '../i18n';
import BlockLoading from '../loading/BlockLoading';
import Store from './Store';
import ColGroup from './ColGroup';
import Header from './Header';
import Body from './Body';
import Footer from './Footer';
import SelectionCheckbox from './SelectionCheckbox';
import SelectionRadio from './SelectionRadio';
import Affix from '../affix';
import SelectionCheckboxAll from './SelectionCheckboxAll';
import isBrowser from '../utils/isBrowser';
import { hasOwnProperty } from '../utils/hasOwn';
import isNil from '../utils/isNil';
import { Icon } from '../icon';
function stopPropagation(e) {
    e.stopPropagation();
    if (e.nativeEvent.stopImmediatePropagation) {
        e.nativeEvent.stopImmediatePropagation();
    }
}
var prefix = 'zent';
var BTN_WIDTH = 28;
var DEFAULT_SIZE = 'large';
var Grid = (function (_super) {
    __extends(Grid, _super);
    function Grid(props) {
        var _a;
        var _this = _super.call(this, props) || this;
        _this.mounted = false;
        _this.selectionPropsCache = {};
        _this.store = new Store();
        _this.gridNode = createRef();
        _this.footNode = createRef();
        _this.headerNode = createRef();
        _this.bodyTable = createRef();
        _this.leftBody = createRef();
        _this.rightBody = createRef();
        _this.scrollBody = createRef();
        _this.scrollHeader = createRef();
        _this.stickyHead = createRef();
        _this.syncFixedTableRowHeight = function () {
            var _a, _b, _c, _d, _e, _f, _g, _h, _j;
            if (!_this.mounted || !_this.gridNode.current) {
                return;
            }
            var tableRect = _this.gridNode.current.getBoundingClientRect();
            if (tableRect.height !== undefined && tableRect.height <= 0) {
                return;
            }
            var bodyRows = (_b = (_a = _this.bodyTable) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.querySelectorAll("tbody ." + prefix + "-grid-tr");
            var expandRows = (_d = (_c = _this.bodyTable) === null || _c === void 0 ? void 0 : _c.current) === null || _d === void 0 ? void 0 : _d.querySelectorAll("tbody ." + prefix + "-grid-tr__expanded");
            var headRows = ((_e = _this.scrollHeader) === null || _e === void 0 ? void 0 : _e.current)
                ? (_g = (_f = _this.scrollHeader) === null || _f === void 0 ? void 0 : _f.current) === null || _g === void 0 ? void 0 : _g.querySelectorAll('thead')
                : (_j = (_h = _this.bodyTable) === null || _h === void 0 ? void 0 : _h.current) === null || _j === void 0 ? void 0 : _j.querySelectorAll('thead');
            var fixedColumnsBodyRowsHeight = mapDOMNodes(bodyRows, function (row) { return row.getBoundingClientRect().height || 'auto'; });
            var fixedColumnsHeadRowsHeight = mapDOMNodes(headRows, function (row) { return row.getBoundingClientRect().height || 'auto'; });
            var fixedColumnsBodyExpandRowsHeight = mapDOMNodes(expandRows, function (row) { return row.getBoundingClientRect().height || 'auto'; });
            if (isEqual(_this.state.fixedColumnsBodyRowsHeight, fixedColumnsBodyRowsHeight) &&
                isEqual(_this.state.fixedColumnsHeadRowsHeight, fixedColumnsHeadRowsHeight) &&
                isEqual(_this.state.fixedColumnsBodyExpandRowsHeight, fixedColumnsBodyExpandRowsHeight)) {
                return;
            }
            _this.setState({
                fixedColumnsBodyRowsHeight: fixedColumnsBodyRowsHeight,
                fixedColumnsHeadRowsHeight: fixedColumnsHeadRowsHeight,
                fixedColumnsBodyExpandRowsHeight: fixedColumnsBodyExpandRowsHeight,
            });
        };
        _this.onChange = function (conf) {
            var params = Object.assign({}, _this.store.getState('conf'), conf);
            _this.store.setState('conf');
            _this.props.onChange && _this.props.onChange(params);
        };
        _this.onPaginationChange = function (pageSize, current) {
            _this.props.onChange &&
                _this.props.onChange({
                    pageSize: pageSize,
                    current: current,
                });
        };
        _this.getDataKey = function (data, rowIndex) {
            var rowKey = _this.props.rowKey;
            return rowKey ? data === null || data === void 0 ? void 0 : data[rowKey] : rowIndex;
        };
        _this.isAnyColumnsFixed = function () {
            return _this.store.getState('isAnyColumnsFixed', function () { var _a; return ((_a = _this.store.getState('columns')) !== null && _a !== void 0 ? _a : []).some(function (column) { return !!column.fixed; }); });
        };
        _this.isAnyColumnsLeftFixed = function () {
            return _this.store.getState('isAnyColumnsLeftFixed', function () {
                var _a;
                return ((_a = _this.store.getState('columns')) !== null && _a !== void 0 ? _a : []).some(function (column) { return column.fixed === 'left' || column.fixed === true; });
            });
        };
        _this.isAnyColumnsRightFixed = function () {
            return _this.store.getState('isAnyColumnsRightFixed', function () {
                var _a;
                return ((_a = _this.store.getState('columns')) !== null && _a !== void 0 ? _a : []).some(function (column) { return column.fixed === 'right'; });
            });
        };
        _this.getLeftColumns = function () {
            var columns = _this.store.getState('columns') || [];
            return columns.filter(function (column) { return column.fixed === 'left' || column.fixed === true; });
        };
        _this.getRightColumns = function () {
            var columns = _this.store.getState('columns') || [];
            return columns.filter(function (column) { return column.fixed === 'right'; });
        };
        _this.handleExpandRow = function (clickRow, rowData) {
            return function (e) {
                var _a;
                var onExpand = _this.props.onExpand;
                var expandRowKeys = ((_a = _this.state.expandRowKeys) !== null && _a !== void 0 ? _a : []).map(function (row, index) {
                    return index === clickRow ? !row : row;
                });
                _this.store.setState({
                    columns: _this.getColumns(_this.props, _this.props.columns, expandRowKeys),
                });
                _this.setState({
                    expandRowKeys: expandRowKeys,
                });
                if (typeof onExpand === 'function') {
                    onExpand({
                        expanded: expandRowKeys[clickRow],
                        data: rowData,
                        event: e,
                        index: clickRow,
                    });
                }
            };
        };
        _this.getExpandBodyRender = function (expandRowKeys, expandation) {
            return function (rowData, pos) {
                var row = pos.row;
                var _a = expandation.isExpandable, isExpandable = _a === void 0 ? function () { return true; } : _a;
                return isExpandable(rowData, row) ? (_jsx(Icon, { type: expandRowKeys[row] ? 'up' : 'down', className: prefix + "-grid-expandable-btn", onClick: _this.handleExpandRow(row, rowData) }, void 0)) : null;
            };
        };
        _this.getColumns = function (props, columnsArg, expandRowKeysArg) {
            var _a = props || _this.props, selection = _a.selection, expandation = _a.expandation;
            var isStoreColumns = !columnsArg;
            var columns = (columnsArg || _this.store.getState('columns')).slice();
            var expandRowKeys = expandRowKeysArg || _this.state.expandRowKeys;
            var hasLeft = columns.some(function (column) { return column.fixed === 'left' || column.fixed === true; });
            if (selection) {
                var selectionColumn = _this.getSelectionColumn(props, columnsArg);
                if (selectionColumn) {
                    var maySelectionColumn = columns[0];
                    if (maySelectionColumn &&
                        ['selection-column', 'selection-column-single'].indexOf(maySelectionColumn.key) !== -1) {
                        columns[0] = __assign(__assign({}, columns[0]), selectionColumn);
                    }
                    else {
                        columns.unshift(selectionColumn);
                    }
                }
            }
            if (expandation) {
                var expandColumn = {
                    title: '',
                    key: 'expand-column',
                    width: BTN_WIDTH,
                    bodyRender: _this.getExpandBodyRender(expandRowKeys, expandation),
                };
                if (hasLeft) {
                    expandColumn.fixed = 'left';
                }
                columns.unshift(expandColumn);
            }
            if (!isStoreColumns) {
                columns = groupedColumns(columns);
            }
            return columns;
        };
        _this.getBatchComponents = function (position) {
            var _a = _this.props, datasets = _a.datasets, batchRender = _a.batchRender, selection = _a.selection, rowKey = _a.rowKey;
            return (_jsx(BatchComponents, { position: position, store: _this.store, onSelect: _this.handleBatchSelect, datasets: datasets, getDataKey: _this.getDataKey, prefix: prefix, batchRender: batchRender, selection: selection, selectionPropsCache: _this.selectionPropsCache, rowKey: rowKey }, "batch"));
        };
        _this.getLeftFixedTable = function () {
            return _this.getTable({
                columns: _this.getLeftColumns(),
                fixed: 'left',
                bodyRef: _this.leftBody,
            });
        };
        _this.getRightFixedTable = function () {
            return _this.getTable({
                columns: _this.getRightColumns(),
                fixed: 'right',
                bodyRef: _this.rightBody,
            });
        };
        _this.forceScroll = function (target, distance, direction) {
            var scrollDirection = "scroll" + direction;
            if (target && target[scrollDirection] !== distance) {
                target[scrollDirection] = distance;
            }
        };
        _this.handleBodyScrollRunOnceNextFrame = runOnceInNextFrame(function (e) {
            var _a, _b, _c, _d, _e;
            if (!_this.mounted) {
                return;
            }
            if (!_this.isAnyColumnsFixed()) {
                return;
            }
            var target = e.target;
            var autoStick = _this.props.autoStick;
            var scrollTop = target.scrollTop, scrollLeft = target.scrollLeft;
            var leftBody = (_a = _this.leftBody) === null || _a === void 0 ? void 0 : _a.current;
            var rightBody = (_b = _this.rightBody) === null || _b === void 0 ? void 0 : _b.current;
            var scrollHeader = (_c = _this.scrollHeader) === null || _c === void 0 ? void 0 : _c.current;
            var stickyHead = (_d = _this.stickyHead) === null || _d === void 0 ? void 0 : _d.current;
            var bodyTable = (_e = _this.bodyTable) === null || _e === void 0 ? void 0 : _e.current;
            if (_this.lastScrollLeft !== target.scrollLeft) {
                if (scrollHeader && target === scrollHeader) {
                    _this.forceScroll(bodyTable, scrollLeft, 'Left');
                    autoStick && _this.forceScroll(stickyHead, scrollLeft, 'Left');
                }
                if (bodyTable && target === bodyTable) {
                    _this.forceScroll(scrollHeader, scrollLeft, 'Left');
                    autoStick && _this.forceScroll(stickyHead, scrollLeft, 'Left');
                }
                if (autoStick && target === stickyHead) {
                    _this.forceScroll(bodyTable, scrollLeft, 'Left');
                    _this.forceScroll(scrollHeader, scrollLeft, 'Left');
                }
                _this.lastScrollLeft = scrollLeft;
                _this.setScrollPositionClassName();
            }
            if (_this.lastScrollTop !== target.scrollTop) {
                if (leftBody && target === leftBody) {
                    _this.forceScroll(rightBody, scrollTop, 'Top');
                    _this.forceScroll(bodyTable, scrollTop, 'Top');
                }
                if (rightBody && target === rightBody) {
                    _this.forceScroll(leftBody, scrollTop, 'Top');
                    _this.forceScroll(bodyTable, scrollTop, 'Top');
                }
                if (bodyTable && target === bodyTable) {
                    _this.forceScroll(rightBody, scrollTop, 'Top');
                    _this.forceScroll(leftBody, scrollTop, 'Top');
                }
                _this.lastScrollTop = target.scrollTop;
            }
        });
        _this.handleBodyScroll = function (e) {
            e.persist();
            _this.handleBodyScrollRunOnceNextFrame(e);
        };
        _this.onResize = function () {
            _this.syncFixedTableRowHeight();
            _this.setScrollPositionClassName();
            _this.toggleBatchComponents();
            _this.setStickyHeadWidth();
        };
        _this.onRowMouseEnter = function (mouseOverRowIndex) {
            _this.setState({
                mouseOverRowIndex: mouseOverRowIndex,
            });
        };
        _this.getTable = function (options) {
            var _a, _b;
            if (options === void 0) { options = {}; }
            var _c = _this.props, _d = _c.size, size = _d === void 0 ? DEFAULT_SIZE : _d, datasets = _c.datasets, scroll = _c.scroll, sortType = _c.sortType, sortBy = _c.sortBy, defaultSortType = _c.defaultSortType, rowClassName = _c.rowClassName, onRowClick = _c.onRowClick, ellipsis = _c.ellipsis, expandation = _c.expandation, rowKey = _c.rowKey, components = _c.components, rowProps = _c.rowProps, disableHoverHighlight = _c.disableHoverHighlight;
            var fixed = options.fixed, isStickyHead = options.isStickyHead;
            var columns = options.columns || _this.store.getState('columns');
            var expandRowKeys = _this.state.expandRowKeys;
            var tableClassName = '';
            var bodyStyle = {};
            var tableStyle = {};
            if (fixed || !isNil(scroll.x)) {
                tableClassName = prefix + "-grid-fixed";
                bodyStyle.overflowX = isStickyHead ? 'hidden' : 'auto';
            }
            if (!fixed && !isNil(scroll.x)) {
                tableStyle.width = scroll.x;
            }
            var header = (_jsx(Header, { size: size, prefix: prefix, columns: columns, fixed: fixed, store: _this.store, onChange: _this.onChange, sortType: sortType, scroll: scroll, sortBy: sortBy, defaultSortType: defaultSortType, fixedColumnsHeadRowsHeight: _this.state.fixedColumnsHeadRowsHeight, ref: _this.headerNode }, void 0));
            var leafColumns = getLeafColumns(columns);
            var body = (_jsx(Body, { size: size, prefix: prefix, rowKey: rowKey, columns: leafColumns, datasets: datasets, expandRowKeys: expandRowKeys, mouseOverRowIndex: _this.state.mouseOverRowIndex, onRowMouseEnter: _this.onRowMouseEnter, rowClassName: rowClassName, onRowClick: onRowClick, fixed: fixed, hasFixedColumn: _this.isAnyColumnsFixed(), scroll: scroll, expandRender: expandation && expandation.expandRender, fixedColumnsBodyRowsHeight: _this.state.fixedColumnsBodyRowsHeight, fixedColumnsBodyExpandRowsHeight: _this.state.fixedColumnsBodyExpandRowsHeight, components: components, rowProps: rowProps, disableHoverHighlight: disableHoverHighlight }, void 0));
            var y = scroll.y, x = scroll.x;
            if (y) {
                var scrollbarWidth = measureScrollbar();
                var headStyle = {};
                var scrollBodyStyle = {
                    maxHeight: y,
                    overflowY: 'auto',
                };
                if (scrollbarWidth > 0) {
                    headStyle.paddingBottom = 0;
                    if (!fixed && _this.isAnyColumnsFixed() && x) {
                        headStyle.marginBottom = -scrollbarWidth;
                        headStyle.marginRight = scrollbarWidth;
                    }
                }
                else {
                    scrollBodyStyle.marginBottom = 0;
                }
                var table = [
                    _jsx("div", __assign({ className: classnames(prefix + "-grid-header", (_a = {},
                            _a[prefix + "-grid-sticky-header"] = options.isStickyHead,
                            _a)), style: headStyle, ref: options.headRef, onScroll: _this.handleBodyScroll, "data-zv": 'v10.0.11' }, { children: header }), "header"),
                ];
                if (!options.isStickyHead) {
                    table.push(_jsx("div", __assign({ className: prefix + "-grid-body-outer", "data-zv": 'v10.0.11' }, { children: _jsx("div", __assign({ className: prefix + "-grid-body", style: scrollBodyStyle, ref: options.bodyRef, onScroll: _this.handleBodyScroll, "data-zv": 'v10.0.11' }, { children: body }), "body") }), "body-outer"));
                }
                return table;
            }
            return [
                _jsx("div", __assign({ style: bodyStyle, ref: options.bodyRef, onScroll: _this.handleBodyScroll, "data-zv": 'v10.0.11' }, { children: _jsxs("table", __assign({ className: classnames(prefix + "-grid-table " + prefix + "-grid-table-" + size, tableClassName, (_b = {},
                            _b[prefix + "-grid-table-ellipsis"] = ellipsis,
                            _b)), style: tableStyle, "data-zv": 'v10.0.11' }, { children: [_jsx(ColGroup, { columns: columns }, void 0), header, options.isStickyHead ? null : body] }), void 0) }), "table"),
            ];
        };
        _this.getEmpty = function (i18n) {
            var _a = _this.props, datasets = _a.datasets, emptyLabel = _a.emptyLabel;
            if (!datasets || datasets.length === 0) {
                return (_jsx("div", __assign({ className: prefix + "-grid-empty", "data-zv": 'v10.0.11' }, { children: emptyLabel || i18n.emptyLabel }), "empty"));
            }
            return null;
        };
        _this.getSelectionPropsByItem = function (data, rowIndex, nextSelection) {
            var selection = nextSelection || _this.props.selection;
            var getSelectionProps = getCompatSelectionPropsFn(selection);
            if (!getSelectionProps) {
                return {};
            }
            if (!_this.selectionPropsCache[rowIndex]) {
                _this.selectionPropsCache[rowIndex] = getSelectionProps(data);
            }
            return _this.selectionPropsCache[rowIndex];
        };
        _this.isFixedLayout = function () {
            var _a = _this.props, tableLayout = _a.tableLayout, _b = _a.columns, columns = _b === void 0 ? [] : _b, _c = _a.scroll, scroll = _c === void 0 ? {} : _c, ellipsis = _a.ellipsis;
            if (typeof tableLayout !== 'undefined') {
                return tableLayout === 'fixed';
            }
            if (columns.some(function (_a) {
                var noWrap = _a.noWrap;
                return !!noWrap;
            }) && ellipsis) {
                return true;
            }
            if (typeof scroll.x !== 'undefined' || typeof scroll.y !== 'undefined') {
                return true;
            }
            return false;
        };
        _this.onSelectChange = function (selectedRowKeys, data) {
            var _a = _this.props, datasets = _a.datasets, selection = _a.selection;
            var onSelect = selection === null || selection === void 0 ? void 0 : selection.onSelect;
            if (typeof onSelect === 'function') {
                var selectedRows = (datasets || []).filter(function (row, i) {
                    return (selectedRowKeys !== null && selectedRowKeys !== void 0 ? selectedRowKeys : []).indexOf(_this.getDataKey(row, i)) !== -1;
                });
                onSelect(selectedRowKeys, selectedRows, data);
            }
        };
        _this.handleSelect = function (data, rowIndex, e) {
            var selection = _this.props.selection;
            var isSingleSelection = selection.isSingleSelection;
            var checked = e.target.checked;
            var selectedRowKeys = _this.store.getState('selectedRowKeys') || [];
            if (isSingleSelection) {
                selectedRowKeys = [rowIndex];
            }
            else {
                if (checked) {
                    selectedRowKeys = selectedRowKeys.concat(rowIndex);
                }
                else {
                    selectedRowKeys = selectedRowKeys.filter(function (i) { return rowIndex !== i; });
                }
            }
            _this.store.setState({ selectedRowKeys: selectedRowKeys });
            _this.onSelectChange(selectedRowKeys, data);
        };
        _this.handleBatchSelect = function (type, data) {
            var _a;
            var selectedRowKeys = ((_a = _this.store.getState('selectedRowKeys')) !== null && _a !== void 0 ? _a : []).slice();
            var changeRowKeys = [];
            switch (type) {
                case 'selectAll':
                    (data || []).forEach(function (key, index) {
                        var rowIndex = _this.getDataKey(key, index);
                        if (selectedRowKeys.indexOf(rowIndex) === -1) {
                            selectedRowKeys = selectedRowKeys.concat(rowIndex);
                            changeRowKeys.push(rowIndex);
                        }
                    });
                    break;
                case 'removeAll':
                    selectedRowKeys = (selectedRowKeys || []).filter(function (selectedRowKey) {
                        return (data || []).every(function (key, index) {
                            var rowIndex = _this.getDataKey(key, index);
                            var match = selectedRowKey === rowIndex;
                            if (match) {
                                changeRowKeys.push(key);
                            }
                            return !match;
                        });
                    });
                    break;
                default:
                    break;
            }
            _this.store.setState({ selectedRowKeys: selectedRowKeys });
            var changeRow = (data || []).filter(function (row, i) { return changeRowKeys.indexOf(_this.getDataKey(row, i)) !== -1; });
            _this.onSelectChange(selectedRowKeys, changeRow);
        };
        _this.renderSelectionCheckbox = function () {
            return function (data, _a) {
                var row = _a.row;
                var rowIndex = _this.getDataKey(data, row);
                var props = _this.getSelectionPropsByItem(data, rowIndex);
                return (_jsx("span", __assign({ onClick: stopPropagation, className: "zent-grid-selection-checkbox", "data-zv": 'v10.0.11' }, { children: _jsx(SelectionCheckbox, __assign({}, props, { rowIndex: rowIndex, store: _this.store, onChange: function (e) {
                            return _this.handleSelect(data, _this.getDataKey(data, row), e);
                        } }), void 0) }), void 0));
            };
        };
        _this.renderSelectionRadio = function () {
            return function (data, _a) {
                var row = _a.row;
                var rowIndex = _this.getDataKey(data, row);
                var props = _this.getSelectionPropsByItem(data, rowIndex);
                return (_jsx("span", __assign({ onClick: stopPropagation, className: "zent-grid-selection-radio", "data-zv": 'v10.0.11' }, { children: _jsx(SelectionRadio, __assign({}, props, { rowIndex: rowIndex, store: _this.store, onChange: function (e) {
                            return _this.handleSelect(data, _this.getDataKey(data, row), e);
                        } }), void 0) }), void 0));
            };
        };
        _this.toggleBatchComponents = function () {
            var isSupportFixed = _this.props.stickyBatch && _this.props.batchRender;
            if (!_this.mounted || !isSupportFixed) {
                return;
            }
            if (!_this.footEl) {
                _this.footEl = ReactDom.findDOMNode(_this.footNode.current);
            }
            if (!_this.headerEl) {
                _this.headerEl = ReactDom.findDOMNode(_this.headerNode.current);
            }
            var isTableInView = isElementInView(_this.gridNode.current);
            var isHeaderInView = isElementInView(_this.headerEl);
            var isFootInView = isElementInView(_this.footEl);
            var batchNeedRenderFixed = needFixBatchComps(isTableInView, isHeaderInView, isFootInView);
            var batchRenderFixed = _this.store.getState('batchRenderFixed');
            if (batchRenderFixed !== batchNeedRenderFixed) {
                _this.store.setState({
                    batchRenderFixed: batchNeedRenderFixed,
                    batchRenderFixedStyles: _this.getBatchFixedStyle(),
                });
            }
        };
        _this.onScroll = function () {
            _this.toggleBatchComponents();
            var scrollLeft = document.body.scrollLeft ||
                document.documentElement.scrollLeft ||
                window.pageXOffset;
            if (_this.props.autoStick) {
                var isTableInView = isElementInView(_this.gridNode.current);
                var tableHeaderEl = ReactDom.findDOMNode(_this.headerNode.current);
                var offset = 0;
                if (tableHeaderEl && !offset) {
                    var height = tableHeaderEl.getBoundingClientRect().height;
                    offset = height;
                }
                var isHeaderInView = isElementInView(tableHeaderEl, offset);
                _this.setState({
                    showStickHead: !isHeaderInView && isTableInView,
                    marginLeft: "-" + scrollLeft + "px",
                });
            }
        };
        _this.getStickyHead = function () {
            var content = [
                _this.getTable({
                    isStickyHead: true,
                    headRef: _this.stickyHead,
                    bodyRef: _this.stickyHead,
                }),
                _this.isAnyColumnsLeftFixed() && (_jsx("div", __assign({ className: prefix + "-grid-fixed-left", "data-zv": 'v10.0.11' }, { children: _this.getTable({
                        columns: _this.getLeftColumns(),
                        fixed: 'left',
                        isStickyHead: true,
                    }) }), "left-sticky-head")),
                _this.isAnyColumnsRightFixed() && (_jsx("div", __assign({ className: prefix + "-grid-fixed-right", "data-zv": 'v10.0.11' }, { children: _this.getTable({
                        columns: _this.getRightColumns(),
                        fixed: 'right',
                        isStickyHead: true,
                    }) }), "right-sticky-head")),
            ];
            var style = {
                visibility: _this.state.showStickHead ? 'visible' : 'hidden',
                height: _this.state.showStickHead ? 'auto' : 0,
            };
            return _this.isAnyColumnsFixed() ? (_jsx("div", __assign({ className: prefix + "-grid-scroll", style: style, "data-zv": 'v10.0.11' }, { children: content }), void 0)) : (_jsx("div", __assign({ style: style, "data-zv": 'v10.0.11' }, { children: content }), void 0));
        };
        _this.setStickyHeadWidth = function () {
            if (_this.props.autoStick && _this.gridNode && _this.gridNode.current) {
                var scroll_1 = _this.props.scroll;
                var width = _this.gridNode.current.getBoundingClientRect().width;
                if (scroll_1 && !isNil(scroll_1.x) && !isNil(scroll_1.y)) {
                    width -= measureScrollbar();
                }
                _this.setState({
                    tableWidth: width,
                });
            }
        };
        var expandRowKeys = _this.getExpandRowKeys(props);
        _this.store.setState({
            columns: _this.getColumns(props, props.columns, expandRowKeys),
            selectedRowKeys: (_a = props === null || props === void 0 ? void 0 : props.selection) === null || _a === void 0 ? void 0 : _a.selectedRowKeys,
        });
        _this.setScrollPosition('both');
        _this.state = {
            mouseOverRowIndex: -1,
            fixedColumnsBodyRowsHeight: [],
            fixedColumnsHeadRowsHeight: [],
            fixedColumnsBodyExpandRowsHeight: [],
            expandRowKeys: expandRowKeys,
            showStickHead: false,
            tableWidth: undefined,
            marginLeft: undefined,
        };
        return _this;
    }
    Grid.prototype.getExpandRowKeys = function (props) {
        var expandation = props.expandation, datasets = props.datasets;
        if (expandation) {
            var isExpanded_1 = expandation.isExpanded;
            var expandRowKeys = datasets.reduce(function (items, rowData, rowIndex) {
                if (typeof isExpanded_1 === 'function') {
                    items[rowIndex] = isExpanded_1(rowData, rowIndex);
                }
                else {
                    items[rowIndex] = false;
                }
                return items;
            }, []);
            return expandRowKeys;
        }
        return [];
    };
    Grid.prototype.getSelectionColumn = function (props, columnsArg) {
        var _this = this;
        var columns = (columnsArg || this.store.getState('columns')).slice();
        var hasLeft = columns.some(function (column) { return column.fixed === 'left' || column.fixed === true; });
        var _a = props || this.props, datasets = _a.datasets, selection = _a.selection;
        if (!selection) {
            return null;
        }
        var selectionColumn = null;
        if (selection.isSingleSelection) {
            selectionColumn = {
                title: '',
                key: 'selection-column-single',
                width: BTN_WIDTH,
                bodyRender: this.renderSelectionRadio(),
            };
        }
        else {
            var selectAllState = getSelectAllCheckboxState(datasets !== null && datasets !== void 0 ? datasets : [], this.getDataKey, function (row, idx) { return _this.getSelectionPropsByItem(row, idx, selection); });
            selectionColumn = {
                title: (_jsx(SelectionCheckboxAll, { store: this.store, datasets: selectAllState.enabledRows, disabledDatasets: selectAllState.disabledRows, getDataKey: this.getDataKey, onSelect: this.handleBatchSelect, disabled: selectAllState.allDisabled }, void 0)),
                key: 'selection-column',
                width: BTN_WIDTH,
                bodyRender: this.renderSelectionCheckbox(),
            };
        }
        if (hasLeft) {
            selectionColumn.fixed = 'left';
        }
        return selectionColumn;
    };
    Grid.prototype.getBatchFixedStyle = function () {
        if (!isBrowser) {
            return {};
        }
        var el = ReactDom.findDOMNode(this.footNode.current);
        if (el && this.props.stickyBatch) {
            return {
                width: el.getBoundingClientRect().width,
            };
        }
        return {};
    };
    Grid.prototype.setScrollPosition = function (position) {
        this.scrollPosition = position;
        if (this.gridNode.current) {
            var el = this.gridNode.current;
            if (position === 'both') {
                el.className = el.className.replace(new RegExp(prefix + "-grid-scroll-position-.+$", 'gi'), ' ');
                el.classList.add(prefix + "-grid-scroll-position-left");
                el.classList.add(prefix + "-grid-scroll-position-right");
            }
            else {
                el.className = el.className.replace(new RegExp(prefix + "-grid-scroll-position-.+$", 'gi'), ' ');
                el.classList.add(prefix + "-grid-scroll-position-" + position);
            }
        }
    };
    Grid.prototype.setScrollPositionClassName = function () {
        var _a;
        var node = (_a = this.bodyTable) === null || _a === void 0 ? void 0 : _a.current;
        var scrollToLeft = node.scrollLeft === 0;
        var scrollToRight = node.scrollLeft + 1 >=
            node.children[0].getBoundingClientRect().width -
                node.getBoundingClientRect().width;
        if (scrollToLeft && scrollToRight) {
            this.setScrollPosition('both');
        }
        else if (scrollToLeft) {
            this.setScrollPosition('left');
        }
        else if (scrollToRight) {
            this.setScrollPosition('right');
        }
        else if (this.scrollPosition !== 'middle') {
            this.setScrollPosition('middle');
        }
    };
    Grid.prototype.componentDidMount = function () {
        this.mounted = true;
        this.setScrollPositionClassName();
        if (this.isAnyColumnsFixed()) {
            this.syncFixedTableRowHeight();
        }
        this.setStickyHeadWidth();
    };
    Grid.prototype.componentWillUnmount = function () {
        this.mounted = false;
    };
    Grid.prototype.componentWillReceiveProps = function (nextProps) {
        var _a, _b;
        if (nextProps.selection !== this.props.selection) {
            if (!nextProps.selection) {
                this.store.setState({
                    columns: this.getColumns(nextProps, nextProps.columns),
                });
            }
        }
        if (nextProps.selection &&
            hasOwnProperty(nextProps.selection, 'selectedRowKeys')) {
            this.store.setState({
                selectedRowKeys: nextProps.selection.selectedRowKeys || [],
                columns: this.getColumns(nextProps),
            });
            var selection = this.props.selection;
            if (selection &&
                getCompatSelectionPropsFn(nextProps.selection) !==
                    getCompatSelectionPropsFn(selection)) {
                this.selectionPropsCache = {};
            }
        }
        else if (((_a = nextProps.selection) === null || _a === void 0 ? void 0 : _a.isSingleSelection) !==
            ((_b = this.props.selection) === null || _b === void 0 ? void 0 : _b.isSingleSelection)) {
            this.store.setState({
                columns: this.getColumns(nextProps),
            });
        }
        if (nextProps.columns && nextProps.columns !== this.props.columns) {
            this.store.setState({
                columns: this.getColumns(nextProps, nextProps.columns),
            });
        }
        if (hasOwnProperty(nextProps, 'datasets') &&
            nextProps.datasets !== this.props.datasets) {
            this.selectionPropsCache = {};
            var expandRowKeys = this.getExpandRowKeys(nextProps);
            this.store.setState({
                columns: this.getColumns(nextProps, nextProps.columns, expandRowKeys),
            });
            this.setState({
                expandRowKeys: expandRowKeys,
            });
        }
    };
    Grid.prototype.componentDidUpdate = function (prevProps) {
        var _a, _b;
        if (this.isAnyColumnsFixed()) {
            if (((_a = this.props.scroll) === null || _a === void 0 ? void 0 : _a.x) !== ((_b = prevProps.scroll) === null || _b === void 0 ? void 0 : _b.x)) {
                this.setScrollPositionClassName();
            }
            this.syncFixedTableRowHeight();
        }
    };
    Grid.prototype.render = function () {
        var _a;
        var _this = this;
        var _b = this.props, loading = _b.loading, _c = _b.pageInfo, pageInfo = _c === void 0 ? {} : _c, paginationType = _b.paginationType, bordered = _b.bordered, autoStick = _b.autoStick, autoStickOffsetTop = _b.autoStickOffsetTop, _d = _b.loadingProps, loadingProps = _d === void 0 ? {} : _d, size = _b.size;
        var _e = this.state, marginLeft = _e.marginLeft, tableWidth = _e.tableWidth, showStickHead = _e.showStickHead;
        var stickHeadWarpStyle = {};
        if (autoStick) {
            stickHeadWarpStyle.width = tableWidth;
            stickHeadWarpStyle.marginLeft = marginLeft;
            stickHeadWarpStyle.visibility = showStickHead ? 'visible' : 'hidden';
        }
        var className = prefix + "-grid";
        var borderedClassName = bordered ? prefix + "-grid-bordered" : '';
        className = classnames(className, this.props.className, borderedClassName, (_a = {},
            _a[prefix + "-grid-without-size"] = size === undefined,
            _a[prefix + "-grid-fixed-layout"] = this.isFixedLayout(),
            _a));
        if (this.scrollPosition === 'both') {
            className = classnames(className, prefix + "-grid-scroll-position-left", prefix + "-grid-scroll-position-right");
        }
        else {
            className = classnames(className, prefix + "-grid-scroll-position-" + this.scrollPosition);
        }
        return (_jsx(Receiver, __assign({ componentName: "Grid" }, { children: function (i18n) {
                var content = [
                    _this.getTable({
                        headRef: _this.scrollHeader,
                        bodyRef: _this.bodyTable,
                    }),
                    _this.getEmpty(i18n),
                    _jsx(Footer, { ref: _this.footNode, prefix: prefix, pageInfo: pageInfo, paginationType: paginationType, onChange: _this.onChange, onPaginationChange: _this.onPaginationChange, batchComponents: _this.getBatchComponents('foot') }, "footer"),
                ];
                var scrollTable = _this.isAnyColumnsFixed() ? (_jsx("div", __assign({ className: prefix + "-grid-scroll", "data-zv": 'v10.0.11' }, { children: content }), void 0)) : (content);
                return (_jsxs("div", __assign({ className: className, ref: _this.gridNode, "data-zv": 'v10.0.11' }, { children: [_this.getBatchComponents('header'), _jsxs(BlockLoading, __assign({}, loadingProps, { loading: loading }, { children: [autoStick && (_jsx("div", __assign({ style: stickHeadWarpStyle, className: "zent-grid-sticky-header-warp", "data-zv": 'v10.0.11' }, { children: _jsx(Affix, __assign({ offsetTop: autoStickOffsetTop }, { children: _this.getStickyHead() }), void 0) }), void 0)), scrollTable, _this.isAnyColumnsLeftFixed() && (_jsx("div", __assign({ className: prefix + "-grid-fixed-left", "data-zv": 'v10.0.11' }, { children: _this.getLeftFixedTable() }), void 0)), _this.isAnyColumnsRightFixed() && (_jsx("div", __assign({ className: prefix + "-grid-fixed-right", "data-zv": 'v10.0.11' }, { children: _this.getRightFixedTable() }), void 0))] }), void 0), _jsx(WindowResizeHandler, { onResize: _this.onResize }, void 0), _jsx(WindowScrollHandler, { onScroll: _this.onScroll, options: { capture: true } }, void 0)] }), void 0));
            } }), void 0));
    };
    Grid.defaultProps = {
        className: '',
        bordered: false,
        datasets: [],
        columns: [],
        loading: false,
        paginationType: 'default',
        onChange: noop,
        rowKey: 'id',
        emptyLabel: '',
        scroll: {},
        onRowClick: noop,
        ellipsis: false,
        onExpand: noop,
        stickyBatch: false,
        autoStick: false,
        autoStickOffsetTop: 0,
        disableHoverHighlight: false,
    };
    return Grid;
}(PureComponent));
export { Grid };
export default Grid;
