import { h } from "@stencil/core";
import { hasValue } from '../../utils/utils';
import { LocalDataSource } from '../../utils/data-source/local.data-source';
import { SimpleDataSource } from '../../utils/data-source/simple.data-source';
import Tunnel from '../locale/i18n.provider';
import { TableClasses, calculateOffsets, calculatePinBoundaries, colCellsFromCell, implicitColumnFactory, persistColumn } from './table.utils';
import { NativeRenderer } from './table.renderer';
import { MetaColumn } from './column/meta-column';
import { Colgroup } from './fn-html/colgroup';
import { Tbody } from './fn-html/tbody';
import { Thead } from './fn-html/thead';
import { DefaultCellRenderer } from './cell/default-cell.renderer';
import { DefaultRowRenderer } from './row/default-row.renderer';
import { ColumnRenderer } from './column/column.renderer';
let tableId = 0;
export class Table {
    constructor() {
        this.cellMouseOverListener = (e) => this.highlightColumn(e);
        this.cellMouseOutListener = (e) => this.clearColumnHighlight(e);
        this.cellRenderers = [DefaultCellRenderer];
        this.id = `anj-table-${tableId++}`;
        this.inited = false;
        this.rowRenderers = [DefaultRowRenderer];
        /**
         * Sets the width of all columns.
         * Options are `"auto"`, `"auto-fix"`, or a number representing the number of pixels. Default is auto.
         */
        this.columnWidth = 'auto';
        /**
         * Height of the table
         */
        this.height = 'auto';
        /**
         * Highlight on hover
         * Possible values are: `"rows"`, `"columns"`, and `"none"`. Default is "rows"
         */
        this.highlight = 'rows';
        /**
         * Implicitly set the columns based on the records
         */
        this.implicitColumns = false;
        /**
         * A unique identifier for the table
         */
        this.name = this.id;
        /**
         * Is the table re-orderable by users
         */
        this.orderable = false;
        /** @internal */
        this.renderer = new NativeRenderer();
        /**
         * Columns that have been selected by field name
         */
        this.selectedColumnFields = [];
        /**
         * Row keys that have been selected
         */
        this.selectedRowKeys = [];
        /**
         * Is the table re-sizable by users
         */
        this.sizable = false;
    }
    get pagerOptions() {
        return this.pager ? {
            page: this.pager.page,
            range: this.pager.range,
            size: this.pager.size
        } : {};
    }
    set pagerOptions(options) {
        if (this.pager) {
            this.pager.page = options.page;
            this.pager.size = options.size;
            this.pager.range = options.range;
        }
    }
    async onColumnsChange() {
        if (!this.inited)
            return;
        return this.loadColumns();
    }
    async onDataSourceChange() {
        if (this.colDefs && Array.isArray(this.dataSource)) {
            if (this.source) {
                return this.updateData(this.dataSource);
            }
            else {
                return this.connectDataSource();
            }
        }
    }
    async componentDidLoad() {
        await this.loadColumns();
        await this.connectDataSource();
        this.inited = true;
    }
    componentWillUpdate() {
        if (this.highlight === 'columns') {
            Array.from(this.element.querySelectorAll('td, th')).forEach((el) => {
                el.removeEventListener('mouseenter', this.cellMouseOverListener);
                el.removeEventListener('mouseleave', this.cellMouseOutListener);
            });
        }
        this.anjTableWillUpdate.emit();
    }
    componentDidUpdate() {
        if (this.highlight === 'columns') {
            Array.from(this.element.querySelectorAll('td, th')).forEach((el) => {
                el.addEventListener('mouseenter', this.cellMouseOverListener);
                el.addEventListener('mouseleave', this.cellMouseOutListener);
            });
        }
        if (this.colDefs && this.columnWidth === 'auto-fix') {
            this.colDefs.filter(c => c.visible && c.width === 'auto').forEach(c => {
                const colClass = ColumnRenderer.classFromColumnName(c.name);
                const firstCell = this.element.querySelector(`td.${colClass}`);
                c.width = firstCell ? `${firstCell.offsetWidth}px` : 'auto';
            });
        }
        this.anjTableDidUpdate.emit();
    }
    componentDidUnload() {
        this.componentWillUpdate();
    }
    /* Loading of various controls */
    onControlLoaded(event) {
        event.stopPropagation();
        const target = event.target;
        switch (target.tagName) {
            case 'ANJ-FILTER':
                this.filter = event.detail;
                break;
            case 'ANJ-COLUMN-FILTERING':
                this.filtering = event.target;
                break;
            case 'ANJ-STATE-STORE':
                this.store = event.target;
                break;
            default:
                this.pager = target;
                break;
        }
    }
    /* Row Render Controls */
    onRowControlLoaded(event) {
        event.stopPropagation();
        const target = event.target;
        this.rowRenderers.unshift(target);
        if (target.tagName === 'ANJ-ROW-GROUPING') {
            this.rowGroupControl = target;
        }
    }
    /* Cell Render Controls */
    onCellControlLoaded(event) {
        event.stopPropagation();
        const target = event.target;
        this.cellRenderers.unshift(target);
    }
    /* Column Events */
    async onColumnToggle({ detail }) {
        const column = this.colDefs.find(c => c.name === detail);
        column.visible = !column.visible;
        this.colDefs = this.groupColumns(this.colDefs);
        return this.scroller.doResize();
    }
    onOrderChange({ detail }) {
        const columns = this.colDefs.slice(0);
        const column = columns.splice(detail.currentIndex, 1)[0];
        column.pinned = columns[detail.targetIndex].pinned;
        columns.splice(detail.targetIndex, 0, column);
        this.colDefs = this.groupColumns(columns);
    }
    onPinChange({ detail }) {
        this.colDefs[detail.index].pinned = detail.pin;
        this.colDefs = this.groupColumns(this.colDefs);
    }
    async persistState() {
        if (!this.store)
            return;
        const options = await this.dataOptions(false);
        if (options && this.colDefs) {
            options.columns = this.colDefs.map(persistColumn);
            return this.store.set(options);
        }
    }
    /* End Column Events */
    /* Data Events */
    /**
     * Eat any load events from child tables
     */
    async onRowChange(event) {
        if (event.target !== this.element) {
            event.stopPropagation();
        }
        if (event.type === 'anjColumnsDidUpdate' || event.type === 'anjRowsDidLoad') {
            return this.persistState();
        }
    }
    async onPage() {
        return this.setRows(this.spinner.spinWhile(this.source.paginate(await this.dataOptions())));
    }
    async onColumnGroupChange() {
        this.anjRowsWillLoad.emit();
        return this.setRows(this.spinner.spinWhile(this.source.sort(await this.dataOptions())));
    }
    async onSort(event) {
        // ignore events from child tables
        if (!this.isChild(event.target)) {
            return;
        }
        this.anjRowsWillLoad.emit();
        // TODO: handle multisort
        if (event.detail.field) {
            this.colDefs = this.colDefs.map((col) => {
                if (event.detail.type) {
                    if (col.field === event.detail.field) {
                        col.filter = hasValue(event.detail.query) ? event.detail : undefined;
                    }
                }
                else {
                    col.sortIndex = col.field === event.detail.field ? 0 : undefined;
                    col.sortOrder = col.field === event.detail.field ? event.detail.order : 'asc';
                }
                return col;
            });
        }
        if (this.pager) {
            this.pager.page = 1;
        }
        return this.setRows(this.spinner.spinWhile(this.source.sort(await this.dataOptions())));
    }
    addRow({ detail, target }) {
        if (target.mode === 'noop') {
            return;
        }
        if (detail.index) {
            const rows = this.rows.slice(0);
            rows.splice(detail.index, 0, detail.data);
            this.rows = rows;
        }
        else {
            this.rows = [detail.data].concat(this.rows);
        }
    }
    onDelete({ detail, target }) {
        if (target.mode === 'noop') {
            return;
        }
        const rows = this.rows.slice(0);
        rows.splice(detail.index, 1);
        this.rows = rows;
    }
    async updateRow({ detail }) {
        const rows = this.rows.slice(0);
        rows[detail.index] = detail.data;
        this.rows = rows;
    }
    /**
     * Send changes made to the rows to the data source to become persistent.
     */
    async patchData({ detail }) {
        const opts = await this.dataOptions();
        return this.setRows(this.spinner.spinWhile(this.source.patch(Object.assign(opts, { patch: detail }))));
    }
    /* End Data Events */
    /**
     * Finds all anj-context-menu items within the table and returns their nodes
     */
    async columnMenu() {
        return Array.from(this.element.querySelectorAll('anj-context-menu-item'))
            .map(i => i.cloneNode(true));
    }
    /**
     * Returns the current instantiated column definitions
     */
    async getColumns() {
        return this.colDefs;
    }
    /**
     * Returns the current rows displayed (not the whole data set)
     */
    async getRows() {
        return this.rows;
    }
    /**
     * Refresh the underlying data source with a new array of data
     */
    async updateData(data) {
        this.source.data = data;
        return this.loadRowData();
    }
    /**
     * Scroll the table to a given set of coordinates by column field and/or row key.
     */
    async scrollByKey(columnField, rowKey) {
        const rowIndex = rowKey ? this.rows.findIndex(r => r[this.rowKey] === rowKey) : 0;
        const columnIndex = columnField ? this.colDefs.findIndex(c => c.field === columnField) : 0;
        return this.scrollByIndex(columnIndex, rowIndex);
    }
    /**
     * Scroll the table to a given set of coordinates by column and/or row index.
     */
    async scrollByIndex(columnIndex, rowIndex) {
        // In the event we need scroll by index, everything below can be moved there, then call that here -r
        const rowEl = this.element.querySelectorAll('tr')[rowIndex];
        const colEl = this.element.querySelectorAll('th')[columnIndex];
        const rowOffset = rowEl.offsetTop + rowEl.clientHeight;
        const colOffex = colEl.offsetWidth + colEl.offsetLeft;
        let rowCoords;
        let colCoords;
        if (rowOffset > this.scroller.clientHeight + this.scroller.scrollTop) {
            rowCoords = rowOffset - this.scroller.clientHeight;
        }
        else if (rowOffset < this.element.scrollTop + this.element.clientHeight) {
            rowCoords = this.scroller.scrollTop - rowEl.clientHeight > -1 ? this.scroller.scrollTop - rowEl.clientHeight : 0;
        }
        if (colOffex > this.scroller.scrollLeft + this.scroller.offsetWidth) {
            colCoords = colOffex - this.scroller.offsetWidth;
        }
        else if (colOffex < this.scroller.scrollLeft + this.scroller.offsetWidth) {
            colCoords = this.scroller.scrollLeft - colEl.offsetWidth > -1 ? this.scroller.scrollLeft - colEl.offsetWidth : 0;
        }
        return this.scroller.debouncedScrollTo(colCoords, rowCoords);
    }
    connectDataSource() {
        if (!this.dataSource)
            return;
        this.source = Array.isArray(this.dataSource) && this.dataSource.length < 1000
            ? new SimpleDataSource(this.dataSource) : new LocalDataSource(this.dataSource);
        return this.loadRowData();
    }
    async loadRowData() {
        return this.setRows(this.spinner.spinWhile(this.source.fetchData(await this.dataOptions(true))));
    }
    async loadColumns() {
        const columns = await Promise.all(Array.from(this.element.querySelectorAll('anj-column'))
            .filter(col => this.isChild(col))
            .map((col) => col.componentOnReady()));
        const storedCols = this.store && !this.colDefs ? await this.loadColumnsFromStore() : undefined;
        this.colDefs = this.groupColumns(columns.concat(this.loadMetaColumns()), storedCols);
    }
    loadMetaColumns() {
        if (!this.columns)
            return [];
        return this.columns.map(col => new MetaColumn(this.element, col, this.translator));
    }
    groupColumns(loaded, stored) {
        const columns = stored ? this.initColumnsFromStore(loaded, stored) : loaded;
        // this is kinda dumb, but it gets around Safari not having a stable sort -r
        const visible = columns.filter(visibleColumnFilter);
        const left = visible.filter(col => col.pinned === 'left');
        const right = visible.filter(col => col.pinned === 'right');
        const scrolling = visible.filter(col => !col.pinned);
        const allVisible = left.concat(scrolling, right);
        const allColumns = allVisible.concat(columns.filter(col => !col.visible || col.groupIndex !== undefined)).map((c, i) => {
            c.index = i;
            return c;
        });
        this.pinBoundaries = calculatePinBoundaries(left.length, right.length, scrolling.length);
        this.offsets = calculateOffsets(allVisible);
        if (this.colDefs) {
            this.anjColumnsDidUpdate.emit(allColumns);
        }
        else {
            this.anjColumnsDidLoad.emit(allColumns);
        }
        return allColumns;
    }
    async loadColumnsFromStore() {
        const store = await this.store.get();
        return store && store.columns ? store.columns : undefined;
    }
    initColumnsFromStore(columns, stored) {
        return columns.map(col => {
            const s = stored.find(c => c.name === col.name);
            return s ? Object.assign(col, s) : col;
        }).sort((a, b) => a.index - b.index);
    }
    isChild(el) {
        const table = el.closest(this.element.tagName);
        return table.name === this.name;
    }
    async setRows(pending) {
        try {
            const data = await pending;
            if (this.implicitColumns && this.colDefs.filter(c => !c.internal).length === 0 && data.data && data.data.length > 0) {
                this.columns = implicitColumnFactory(Object.keys(data.data[0]), data.data);
                await this.loadColumns();
            }
            this.rows = data.data || [];
            if (this.pager) {
                this.pager.total = data.total || 0;
            }
            this.anjRowsDidLoad.emit();
        }
        catch (e) {
            throw e;
        }
    }
    // TODO these should probably move to the data source itself
    async dataOptions(fromStore = false) {
        if (fromStore && this.store) {
            return this.initOptionsFromStore();
        }
        const baseOpts = { key: this.rowKey };
        const sorts = this.colDefs.filter(c => c.sortIndex > -1).sort((a, b) => a.sortIndex - b.sortIndex).map(c => {
            return {
                key: c.field,
                order: c.sortOrder,
                index: c.sortIndex
            };
        });
        const groups = this.colDefs.filter(c => c.groupIndex > -1).sort((a, b) => a.groupIndex - b.groupIndex).map(c => {
            return {
                groupKeys: c.groupKeys,
                key: c.field,
                groupKey: c.groupKey,
                index: c.groupIndex,
                autoExpand: this.rowGroupControl.autoExpand
            };
        });
        const filters = this.colDefs.filter(c => c.filter).map(c => {
            return {
                key: c.field,
                query: c.filter.query,
                type: c.filter.type
            };
        });
        if (this.filter && this.filter.value) {
            filters.unshift({ type: 'contains', query: this.filter.value || '', key: undefined });
        }
        return Object.assign({
            filter: filters.length > 0 ? filters : undefined,
            group: groups.length > 0 ? groups : undefined,
            sort: sorts.length > 0 ? sorts : undefined
        }, this.pagerOptions, baseOpts);
    }
    async initOptionsFromStore() {
        const options = await this.store.get();
        if (!options) {
            return this.dataOptions();
        }
        if (this.filter && options.filter && !options.filter[0].key) {
            this.filter.value = options.filter[0].query;
        }
        if (this.pager) {
            this.pagerOptions = options;
        }
        if (options.sort) {
            options.sort.forEach((sort) => {
                const col = this.colDefs.find((c) => c.field === sort.key);
                col.sortIndex = sort.index;
                col.sortOrder = sort.order;
            });
        }
        return options;
    }
    highlightColumn({ target }) {
        colCellsFromCell(target).forEach(el => el.classList.add('anj-highlight'));
    }
    clearColumnHighlight({ target }) {
        colCellsFromCell(target).forEach(el => el.classList.remove('anj-highlight'));
    }
    getRowRenderer(row, rowIndex, columns) {
        const props = {
            cellRenderers: this.cellRenderers,
            columns,
            offsets: this.offsets,
            pinBoundaries: this.pinBoundaries,
            renderer: this.renderer,
            row,
            rowIndex
        };
        return this.rowRenderers.find(r => r.when(row)).row(props);
    }
    render() {
        const columns = this.colDefs ? this.colDefs.filter(visibleColumnFilter) : undefined;
        return [
            h("div", { class: "anj-table-header" },
                h("div", { class: "anj-table-filter" },
                    h("slot", { name: "filter" })),
                h("div", { class: "anj-table-controls" },
                    h("slot", null))),
            columns && this.rows ?
                h("anj-scroller", { style: { maxHeight: this.height }, ref: (r) => this.scroller = r },
                    h("table", { class: TableClasses.table },
                        h(Colgroup, { columns: columns }),
                        h(Thead, { columns: columns, filtering: !!this.filtering, offsets: this.offsets, pinBoundaries: this.pinBoundaries, translator: this.translator }),
                        h(Tbody, { classList: TableClasses.body }, this.rows.map((row, index) => this.getRowRenderer(row, index, columns)))))
                : undefined,
            h("div", { style: { display: this.rows && this.rows.length === 0 ? 'block' : 'none' } },
                h("slot", { name: "footer-message" })),
            h("div", { style: { display: this.rows && this.rows.length > 0 ? 'block' : 'none' } },
                h("slot", { name: "footer" })),
            h("anj-spinner-controller", { ref: (r) => this.spinner = r })
        ];
    }
    static get is() { return "anj-table"; }
    static get originalStyleUrls() { return {
        "$": ["table.scss"]
    }; }
    static get styleUrls() { return {
        "$": ["table.css"]
    }; }
    static get properties() { return {
        "activeRowIndex": {
            "type": "number",
            "mutable": false,
            "complexType": {
                "original": "number",
                "resolved": "number",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "Row the user is engaged with"
            },
            "attribute": "active-row-index",
            "reflect": false
        },
        "columns": {
            "type": "unknown",
            "mutable": true,
            "complexType": {
                "original": "ColumnConfiguration[]",
                "resolved": "ColumnConfiguration[]",
                "references": {
                    "ColumnConfiguration": {
                        "location": "import",
                        "path": "./table.types"
                    }
                }
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "Array of data objects to render"
            }
        },
        "columnWidth": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "'auto' | 'auto-fix' | string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "Sets the width of all columns.\nOptions are `\"auto\"`, `\"auto-fix\"`, or a number representing the number of pixels. Default is auto."
            },
            "attribute": "column-width",
            "reflect": true,
            "defaultValue": "'auto'"
        },
        "dataSource": {
            "type": "any",
            "mutable": false,
            "complexType": {
                "original": "any",
                "resolved": "any",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "The data source for row data"
            },
            "attribute": "data-source",
            "reflect": false
        },
        "dateFormatter": {
            "type": "unknown",
            "mutable": false,
            "complexType": {
                "original": "IntlFormatFn",
                "resolved": "(value: any, variables?: any) => string",
                "references": {
                    "IntlFormatFn": {
                        "location": "import",
                        "path": "../locale/i18n.provider"
                    }
                }
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "Default formatter to use for dates"
            }
        },
        "datetimeFormatter": {
            "type": "unknown",
            "mutable": false,
            "complexType": {
                "original": "IntlFormatFn",
                "resolved": "(value: any, variables?: any) => string",
                "references": {
                    "IntlFormatFn": {
                        "location": "import",
                        "path": "../locale/i18n.provider"
                    }
                }
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "Default formatter to use for dates"
            }
        },
        "height": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "Height of the table"
            },
            "attribute": "height",
            "reflect": false,
            "defaultValue": "'auto'"
        },
        "highlight": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "'cells' | 'columns' | 'none' | 'rows'",
                "resolved": "\"cells\" | \"columns\" | \"none\" | \"rows\"",
                "references": {}
            },
            "required": false,
            "optional": true,
            "docs": {
                "tags": [],
                "text": "Highlight on hover\nPossible values are: `\"rows\"`, `\"columns\"`, and `\"none\"`. Default is \"rows\""
            },
            "attribute": "highlight",
            "reflect": true,
            "defaultValue": "'rows'"
        },
        "implicitColumns": {
            "type": "boolean",
            "mutable": false,
            "complexType": {
                "original": "boolean",
                "resolved": "boolean",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "Implicitly set the columns based on the records"
            },
            "attribute": "implicit-columns",
            "reflect": false,
            "defaultValue": "false"
        },
        "name": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "A unique identifier for the table"
            },
            "attribute": "name",
            "reflect": false,
            "defaultValue": "this.id"
        },
        "numberFormatter": {
            "type": "unknown",
            "mutable": false,
            "complexType": {
                "original": "IntlFormatFn",
                "resolved": "(value: any, variables?: any) => string",
                "references": {
                    "IntlFormatFn": {
                        "location": "import",
                        "path": "../locale/i18n.provider"
                    }
                }
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "Default formatter to use for numbers"
            }
        },
        "orderable": {
            "type": "boolean",
            "mutable": false,
            "complexType": {
                "original": "boolean",
                "resolved": "boolean",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "Is the table re-orderable by users"
            },
            "attribute": "orderable",
            "reflect": true,
            "defaultValue": "false"
        },
        "renderer": {
            "type": "unknown",
            "mutable": false,
            "complexType": {
                "original": "TableRenderer",
                "resolved": "TableRenderer",
                "references": {
                    "TableRenderer": {
                        "location": "import",
                        "path": "./table.types"
                    }
                }
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [{
                        "text": undefined,
                        "name": "internal"
                    }],
                "text": ""
            },
            "defaultValue": "new NativeRenderer()"
        },
        "rowKey": {
            "type": "any",
            "mutable": false,
            "complexType": {
                "original": "number | string",
                "resolved": "number | string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "The property for row objects to be treated as a unique key"
            },
            "attribute": "row-key",
            "reflect": false
        },
        "selectedColumnFields": {
            "type": "unknown",
            "mutable": false,
            "complexType": {
                "original": "string[]",
                "resolved": "string[]",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "Columns that have been selected by field name"
            },
            "defaultValue": "[]"
        },
        "selectedRowKeys": {
            "type": "unknown",
            "mutable": false,
            "complexType": {
                "original": "(number | string)[]",
                "resolved": "(string | number)[]",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "Row keys that have been selected"
            },
            "defaultValue": "[]"
        },
        "sizable": {
            "type": "boolean",
            "mutable": false,
            "complexType": {
                "original": "boolean",
                "resolved": "boolean",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": "Is the table re-sizable by users"
            },
            "attribute": "sizable",
            "reflect": true,
            "defaultValue": "false"
        },
        "translator": {
            "type": "unknown",
            "mutable": false,
            "complexType": {
                "original": "IntlFormatFn",
                "resolved": "(value: any, variables?: any) => string",
                "references": {
                    "IntlFormatFn": {
                        "location": "import",
                        "path": "../locale/i18n.provider"
                    }
                }
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [{
                        "text": undefined,
                        "name": "internal"
                    }],
                "text": ""
            }
        }
    }; }
    static get states() { return {
        "colDefs": {},
        "rows": {}
    }; }
    static get events() { return [{
            "method": "anjColumnsDidLoad",
            "name": "anjColumnsDidLoad",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": "Emitted when the columns have loaded."
            },
            "complexType": {
                "original": "ColumnDefinition[]",
                "resolved": "ColumnDefinition[]",
                "references": {
                    "ColumnDefinition": {
                        "location": "import",
                        "path": "./table.types"
                    }
                }
            }
        }, {
            "method": "anjColumnsDidUpdate",
            "name": "anjColumnsDidUpdate",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": "Emitted when the columns have updated."
            },
            "complexType": {
                "original": "ColumnDefinition[]",
                "resolved": "ColumnDefinition[]",
                "references": {
                    "ColumnDefinition": {
                        "location": "import",
                        "path": "./table.types"
                    }
                }
            }
        }, {
            "method": "anjRowsWillLoad",
            "name": "anjRowsWillLoad",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": "Emitted when before kicking off a load from the data source."
            },
            "complexType": {
                "original": "void",
                "resolved": "void",
                "references": {}
            }
        }, {
            "method": "anjRowsDidLoad",
            "name": "anjRowsDidLoad",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": "Emitted after the data source completes a load."
            },
            "complexType": {
                "original": "void",
                "resolved": "void",
                "references": {}
            }
        }, {
            "method": "anjTableWillUpdate",
            "name": "anjTableWillUpdate",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": "Emitted when the table will update."
            },
            "complexType": {
                "original": "void",
                "resolved": "void",
                "references": {}
            }
        }, {
            "method": "anjTableDidUpdate",
            "name": "anjTableDidUpdate",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": "Emitted when the table has updated."
            },
            "complexType": {
                "original": "void",
                "resolved": "void",
                "references": {}
            }
        }]; }
    static get methods() { return {
        "patchData": {
            "complexType": {
                "signature": "({ detail }: CustomEvent<any>) => Promise<void>",
                "parameters": [{
                        "tags": [],
                        "text": ""
                    }],
                "references": {
                    "Promise": {
                        "location": "global"
                    },
                    "CustomEvent": {
                        "location": "global"
                    }
                },
                "return": "Promise<void>"
            },
            "docs": {
                "text": "Send changes made to the rows to the data source to become persistent.",
                "tags": []
            }
        },
        "columnMenu": {
            "complexType": {
                "signature": "() => Promise<HTMLAnjContextMenuItemElement[]>",
                "parameters": [],
                "references": {
                    "Promise": {
                        "location": "global"
                    },
                    "HTMLAnjContextMenuItemElement": {
                        "location": "global"
                    }
                },
                "return": "Promise<HTMLAnjContextMenuItemElement[]>"
            },
            "docs": {
                "text": "Finds all anj-context-menu items within the table and returns their nodes",
                "tags": []
            }
        },
        "getColumns": {
            "complexType": {
                "signature": "() => Promise<ColumnDefinition[]>",
                "parameters": [],
                "references": {
                    "Promise": {
                        "location": "global"
                    },
                    "ColumnDefinition": {
                        "location": "import",
                        "path": "./table.types"
                    }
                },
                "return": "Promise<ColumnDefinition[]>"
            },
            "docs": {
                "text": "Returns the current instantiated column definitions",
                "tags": []
            }
        },
        "getRows": {
            "complexType": {
                "signature": "() => Promise<RowData[]>",
                "parameters": [],
                "references": {
                    "Promise": {
                        "location": "global"
                    },
                    "RowData": {
                        "location": "import",
                        "path": "./table.types"
                    }
                },
                "return": "Promise<RowData[]>"
            },
            "docs": {
                "text": "Returns the current rows displayed (not the whole data set)",
                "tags": []
            }
        },
        "updateData": {
            "complexType": {
                "signature": "(data: RowData[]) => Promise<void>",
                "parameters": [{
                        "tags": [],
                        "text": ""
                    }],
                "references": {
                    "Promise": {
                        "location": "global"
                    },
                    "RowData": {
                        "location": "import",
                        "path": "./table.types"
                    }
                },
                "return": "Promise<void>"
            },
            "docs": {
                "text": "Refresh the underlying data source with a new array of data",
                "tags": []
            }
        },
        "scrollByKey": {
            "complexType": {
                "signature": "(columnField?: string, rowKey?: string | number) => Promise<void>",
                "parameters": [{
                        "tags": [],
                        "text": ""
                    }, {
                        "tags": [],
                        "text": ""
                    }],
                "references": {
                    "Promise": {
                        "location": "global"
                    }
                },
                "return": "Promise<void>"
            },
            "docs": {
                "text": "Scroll the table to a given set of coordinates by column field and/or row key.",
                "tags": []
            }
        },
        "scrollByIndex": {
            "complexType": {
                "signature": "(columnIndex: number, rowIndex: number) => Promise<void>",
                "parameters": [{
                        "tags": [],
                        "text": ""
                    }, {
                        "tags": [],
                        "text": ""
                    }],
                "references": {
                    "Promise": {
                        "location": "global"
                    }
                },
                "return": "Promise<void>"
            },
            "docs": {
                "text": "Scroll the table to a given set of coordinates by column and/or row index.",
                "tags": []
            }
        }
    }; }
    static get elementRef() { return "element"; }
    static get watchers() { return [{
            "propName": "columns",
            "methodName": "onColumnsChange"
        }, {
            "propName": "dataSource",
            "methodName": "onDataSourceChange"
        }]; }
    static get listeners() { return [{
            "name": "anjFilterDidLoad",
            "method": "onControlLoaded",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "anjColumnFilteringDidLoad",
            "method": "onControlLoaded",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "anjPagerDidLoad",
            "method": "onControlLoaded",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "anjStateStoreDidLoad",
            "method": "onControlLoaded",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "anjRowControlDidLoad",
            "method": "onRowControlLoaded",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "anjCellControlDidLoad",
            "method": "onCellControlLoaded",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "anjColumnToggle",
            "method": "onColumnToggle",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "anjReorder",
            "method": "onOrderChange",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "anjPin",
            "method": "onPinChange",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "anjResizeEnd",
            "method": "persistState",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "anjColumnsDidLoad",
            "method": "onRowChange",
            "target": undefined,
            "capture": true,
            "passive": false
        }, {
            "name": "anjColumnsDidUpdate",
            "method": "onRowChange",
            "target": undefined,
            "capture": true,
            "passive": false
        }, {
            "name": "anjRowsWillLoad",
            "method": "onRowChange",
            "target": undefined,
            "capture": true,
            "passive": false
        }, {
            "name": "anjRowsDidLoad",
            "method": "onRowChange",
            "target": undefined,
            "capture": true,
            "passive": false
        }, {
            "name": "anjPage",
            "method": "onPage",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "anjColumnGroupChange",
            "method": "onColumnGroupChange",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "anjFilter",
            "method": "onSort",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "anjSort",
            "method": "onSort",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "anjCreateStart",
            "method": "addRow",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "anjDelete",
            "method": "onDelete",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "anjUpdateEnd",
            "method": "updateRow",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "anjEditWillSave",
            "method": "patchData",
            "target": undefined,
            "capture": false,
            "passive": false
        }]; }
}
Tunnel.injectProps(Table, ['dateFormatter', 'datetimeFormatter', 'numberFormatter', 'translator']);
const visibleColumnFilter = (c) => {
    return (c.visible && c.groupIndex === undefined);
};
