/*!
 * Copyright (c) 2026 Vertex Software LLC. All rights reserved.
 */
import { h, Host, } from "@stencil/core";
import { Point } from "@vertexvis/geometry";
import { ElementPool, generateInstanceFromTemplate, } from "@vertexvis/html-templates";
import { readDOM } from "../../lib/stencil";
import { getSceneTreeViewportHeight } from "../scene-tree/lib/dom";
import { isLoadedRow } from "../scene-tree/lib/row";
import { getSceneTreeTableOffsetTop, getSceneTreeTableViewportWidth, scrollToTop, } from "./lib/dom";
import { SceneTreeCellHoverController } from "./lib/hover-controller";
import { restartTimeout } from "./lib/window";
export class SceneTreeTableLayout {
    constructor() {
        /**
         * @internal
         */
        this.rows = [];
        /**
         * @internal
         */
        this.totalRows = 0;
        /**
         * @internal
         */
        this.rowHeight = 24;
        /**
         * The number of offscreen rows above and below the viewport to render. Having
         * a higher number reduces the chance of the browser not displaying a row
         * while scrolling.
         *
         * This prop will be automatically populated based on the `overScanCount` prop
         * specified in the parent `<vertex-scene-tree />` element.
         */
        this.overScanCount = 25;
        /**
         * @internal
         */
        this.layoutOffset = 0;
        /**
         * @internal
         */
        this.scrollOffset = 0;
        /**
         * @internal
         */
        this.viewportStartIndex = 0;
        /**
         * @internal
         */
        this.viewportEndIndex = 0;
        this.columnGridLayout = '1fr';
        this.columnGridFixedLayout = '';
        this.isComputingCellHeight = true;
        this.isScrolling = false;
        /**
         * This stores internal state that you want to preserve across live-reloads,
         * but shouldn't trigger a refresh if the data changes. Marking this with
         * @State to allow to preserve state across live-reloads.
         */
        this.stateMap = {
            viewportRows: [],
            columnWidths: [],
            columnWidthPercentages: [],
        };
        this.lastStartIndex = 0;
        this.columnElements = [];
        this.cellHoverController = new SceneTreeCellHoverController();
        this.layoutColumns = () => {
            const visibleRowCount = this.viewportEndIndex - this.viewportStartIndex + 1;
            const diff = this.viewportStartIndex - this.lastStartIndex;
            this.lastStartIndex = this.viewportStartIndex;
            this.iterateColumns((col, pool, colIndex) => {
                pool.updateElements(visibleRowCount);
                if (diff > 0) {
                    pool.swapHeadToTail(diff);
                }
                else {
                    pool.swapTailToHead(-diff);
                }
                col.style.minHeight = `${this.rowHeight * this.totalRows}px`;
                const cellPaddingLeft = colIndex === 0
                    ? (depth) => `calc(${depth} * 0.5rem)`
                    : () => `0`;
                pool.iterateElements((el, binding, rowIndex) => {
                    const row = this.stateMap.viewportRows[rowIndex];
                    if (isLoadedRow(row)) {
                        this.updateCell(row, el, binding, rowIndex, cellPaddingLeft);
                    }
                });
            });
        };
        this.updateCell = (row, cell, binding, rowIndex, cellPaddingLeft) => {
            cell.style.position = 'absolute';
            cell.style.top = `${(this.viewportStartIndex + rowIndex) * this.rowHeight}px`;
            cell.style.boxSizing = 'border-box';
            cell.style.height = `${this.rowHeight}px`;
            cell.style.width = '100%';
            cell.style.paddingLeft = cellPaddingLeft(row.node.depth);
            /* eslint-disable @typescript-eslint/no-explicit-any */
            cell.tree = this.tree;
            cell.node = row.node;
            cell.hoverController = this.cellHoverController;
            cell.isScrolling = this.isScrolling;
            /* eslint-enable @typescript-eslint/no-explicit-any */
            binding.bind(row);
        };
        this.updateLayoutPosition = () => {
            readDOM(() => {
                if (this.tableElement != null) {
                    this.layoutOffset = getSceneTreeTableOffsetTop(this.tableElement);
                }
            });
        };
        this.recomputeColumnWidths = () => {
            const layoutWidth = this.getLayoutWidth();
            if (layoutWidth != null &&
                this.stateMap.columnWidths.length ===
                    this.stateMap.columnWidthPercentages.length) {
                this.stateMap.columnWidths = this.stateMap.columnWidthPercentages.map((w) => w * layoutWidth);
                this.columnsResized.emit(this.stateMap.columnWidths);
            }
        };
        this.recomputeColumnPercentages = () => {
            const layoutWidth = this.getLayoutWidth();
            if (layoutWidth != null &&
                this.stateMap.columnWidths.length ===
                    this.stateMap.columnWidthPercentages.length) {
                this.stateMap.columnWidthPercentages = this.stateMap.columnWidths.map((w) => w / layoutWidth);
            }
        };
        this.computeInitialColumnWidths = () => {
            this.stateMap.columnWidths = this.columnElements.map((c) => { var _a; return (_a = c.initialWidth) !== null && _a !== void 0 ? _a : 100; });
            const layoutWidth = this.getLayoutWidth();
            if (layoutWidth != null) {
                const columnWidthSum = this.stateMap.columnWidths.reduce((result, w) => result + w, 0);
                const scaledColumnWidths = this.stateMap.columnWidths.map((w) => w * (layoutWidth / columnWidthSum));
                this.stateMap.columnWidthPercentages = scaledColumnWidths.map((w) => w / layoutWidth);
                this.stateMap.columnWidths = scaledColumnWidths;
            }
        };
        this.updateColumnElements = () => {
            this.columnElements = Array.from(this.hostEl.querySelectorAll('vertex-scene-tree-table-column'));
        };
        this.computeCellHeight = async () => {
            var _a;
            if (this.isComputingCellHeight && this.columnElements.length > 0) {
                const dummyData = {
                    index: 0,
                    node: {
                        id: { hex: '' },
                        name: 'Dummy row',
                        expanded: false,
                        selected: false,
                        visible: false,
                        partiallyVisible: false,
                        isLeaf: false,
                        depth: 0,
                        columnsList: [],
                        filterHit: false,
                        hasGeometry: false,
                        phantom: false,
                        endItem: false,
                    },
                    metadata: {},
                    data: {},
                };
                const { bindings, element } = this.createColumnCellInstance(this.columnElements[0]);
                bindings.bind(dummyData);
                element.style.visibility = 'hidden';
                (_a = this.columnElements[0]) === null || _a === void 0 ? void 0 : _a.appendChild(element);
                /* eslint-disable @typescript-eslint/no-explicit-any */
                if (typeof element.componentOnReady === 'function') {
                    await element.componentOnReady();
                }
                /* eslint-enable @typescript-eslint/no-explicit-any */
                let height = element.clientHeight;
                if (height === 0) {
                    height = await new Promise((resolve) => {
                        setTimeout(() => resolve(element.getBoundingClientRect().height), 5);
                    });
                }
                this.rowHeight = height !== null && height !== void 0 ? height : this.rowHeight;
                element.remove();
                this.isComputingCellHeight = this.rowHeight === 0;
            }
        };
        this.computeHeaderHeight = () => {
            var _a;
            if (this.stateMap.headerHeight == null) {
                this.stateMap.headerHeight =
                    (_a = this.headerElement) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().height;
                this.hostEl.style.setProperty('--header-height', `${this.stateMap.headerHeight}px`);
            }
        };
        this.computeColumnGridLayout = () => {
            if (this.stateMap.columnWidths.length === 0) {
                this.stateMap.columnWidths = this.columnElements.map((c) => { var _a; return (_a = c.initialWidth) !== null && _a !== void 0 ? _a : 100; });
            }
            const layoutWidth = this.getLayoutWidth();
            if (layoutWidth != null) {
                if (this.stateMap.columnWidthPercentages.length === 0) {
                    this.stateMap.columnWidthPercentages = this.columnElements.map((c) => { var _a; return ((_a = c.initialWidth) !== null && _a !== void 0 ? _a : 100) / layoutWidth; });
                }
            }
            /**
             * This layout uses `1fr` instead of the final column width to
             * allow the final column to shrink when a scrollbar appears.
             *
             * This flex behavior is not desired for the header and divider
             * elements since they are not scrollable, and `columnGridFixedLayout`
             * should be used instead.
             */
            this.columnGridLayout = `${this.stateMap.columnWidths
                .slice(0, -1)
                .reduce((res, w) => `${res} ${w}px`, '')} 1fr`;
            this.columnGridFixedLayout = `${this.stateMap.columnWidths.reduce((res, w) => `${res} ${w}px`, '')}`;
        };
        this.bindHeaderData = () => {
            if (this.stateMap.headerInstances == null) {
                this.stateMap.headerInstances = this.columnElements
                    .map((c, i) => {
                    var _a;
                    const instance = this.createHeaderInstance(c);
                    if (instance != null) {
                        instance.element.style.paddingRight =
                            i === this.columnElements.length - 1
                                ? `0`
                                : `var(--scene-tree-table-column-gap)`;
                        instance.element.slot = 'header';
                        instance.element.style.gridColumnStart = `${i + 1}`;
                        instance.element.style.gridColumnEnd = `${i + 2}`;
                        (_a = this.hostEl) === null || _a === void 0 ? void 0 : _a.appendChild(instance.element);
                    }
                    return instance;
                })
                    .filter((i) => i != null);
            }
            if (this.stateMap.headerDividerInstances == null) {
                this.stateMap.headerDividerInstances = this.columnElements
                    .slice(0, -1)
                    .map((_, i) => {
                    var _a;
                    const instance = this.createDividerInstance();
                    instance.element.slot = 'divider';
                    instance.element.style.position = 'absolute';
                    instance.element.style.right = '0';
                    instance.element.style.pointerEvents = 'auto';
                    instance.element.style.gridColumnStart = `${i + 1}`;
                    instance.element.style.gridColumnEnd = `${i + 2}`;
                    (_a = this.hostEl) === null || _a === void 0 ? void 0 : _a.appendChild(instance.element);
                    return instance;
                });
            }
        };
        this.rebindHeaderData = () => {
            var _a, _b;
            this.removeDividerDragListeners();
            (_a = this.stateMap.headerInstances) === null || _a === void 0 ? void 0 : _a.forEach((i) => i.element.remove());
            (_b = this.stateMap.headerDividerInstances) === null || _b === void 0 ? void 0 : _b.forEach((i) => i.element.remove());
            this.stateMap.headerInstances = undefined;
            this.stateMap.headerDividerInstances = undefined;
            this.bindHeaderData();
            this.addDividerDragListeners();
        };
        this.createDividerPointerDownHandler = (index) => {
            return (event) => {
                var _a, _b;
                event.preventDefault();
                event.stopPropagation();
                this.lastDividerPointerPosition = Point.create(Math.floor(event.clientX), Math.floor(event.clientY));
                this.resizingColumnIndex = index;
                (_b = (_a = this.stateMap.headerDividerInstances) === null || _a === void 0 ? void 0 : _a[index]) === null || _b === void 0 ? void 0 : _b.element.classList.add('dragging');
                window.addEventListener('pointermove', this.handleDividerPointerMove);
                window.addEventListener('pointerup', this.handleDividerPointerUp);
            };
        };
        this.handleDividerPointerMove = (event) => {
            const current = Point.create(Math.floor(event.clientX), Math.floor(event.clientY));
            if (this.lastDividerPointerPosition != null &&
                this.resizingColumnIndex != null) {
                const resizingIndex = this.resizingColumnIndex;
                const diff = Point.subtract(this.lastDividerPointerPosition, current);
                if (Math.abs(diff.x) >= 1 && this.isValidResize(diff, resizingIndex)) {
                    this.stateMap.columnWidths = this.stateMap.columnWidths.map((w, i) => i === resizingIndex ? w - diff.x : w);
                    if (resizingIndex + 1 < this.stateMap.columnWidths.length) {
                        this.stateMap.columnWidths = this.stateMap.columnWidths.map((w, i) => i === resizingIndex + 1 ? w + diff.x : w);
                    }
                    this.lastDividerPointerPosition = current;
                    this.computeColumnGridLayout();
                }
            }
        };
        this.handleDividerPointerUp = () => {
            var _a, _b;
            if (this.resizingColumnIndex != null) {
                (_b = (_a = this.stateMap.headerDividerInstances) === null || _a === void 0 ? void 0 : _a[this.resizingColumnIndex]) === null || _b === void 0 ? void 0 : _b.element.classList.remove('dragging');
            }
            this.lastDividerPointerPosition = undefined;
            this.resizingColumnIndex = undefined;
            this.recomputeColumnPercentages();
            this.recomputeColumnWidths();
            window.removeEventListener('pointermove', this.handleDividerPointerMove);
            window.removeEventListener('pointerup', this.handleDividerPointerUp);
        };
        this.isValidResize = (diff, index) => {
            var _a, _b, _c, _d;
            const currentColumn = this.columnElements[index];
            const nextColumn = this.columnElements[index + 1];
            const currentWidth = this.stateMap.columnWidths[index];
            const nextWidth = this.stateMap.columnWidths[index + 1];
            const currentMinWidth = (_a = currentColumn.minWidth) !== null && _a !== void 0 ? _a : 0;
            const currentMaxWidth = (_b = currentColumn.maxWidth) !== null && _b !== void 0 ? _b : Number.MAX_SAFE_INTEGER;
            const nextMinWidth = (_c = nextColumn.minWidth) !== null && _c !== void 0 ? _c : 0;
            const nextMaxWidth = (_d = nextColumn.maxWidth) !== null && _d !== void 0 ? _d : Number.MAX_SAFE_INTEGER;
            const currentIsValid = currentWidth - diff.x > currentMinWidth &&
                currentWidth - diff.x < currentMaxWidth;
            const nextIsValid = nextColumn != null
                ? nextWidth + diff.x > nextMinWidth && nextWidth + diff.x < nextMaxWidth
                : true;
            return currentIsValid && nextIsValid;
        };
        this.handleScrollChanged = async (event) => {
            this.isScrolling = true;
            this.scrollTimer = restartTimeout(() => {
                this.isScrolling = false;
            }, this.scrollTimer);
            this.scrollOffset = event.target.scrollTop;
            await this.computeAndUpdateViewportRows();
        };
    }
    componentWillLoad() {
        this.updateColumnElements();
        this.createPools();
        this.headerResizeObserver = new ResizeObserver(() => {
            this.stateMap.headerHeight = undefined;
            this.computeHeaderHeight();
            this.updateLayoutPosition();
        });
        this.resizeObserver = new ResizeObserver(() => {
            this.updateLayoutPosition();
            this.clearLayoutHeight();
            this.clearLayoutWidth();
            this.recomputeColumnWidths();
            this.computeColumnGridLayout();
        });
    }
    async componentDidLoad() {
        var _a, _b, _c;
        this.computeInitialColumnWidths();
        this.computeColumnGridLayout();
        this.ensureDividerTemplateDefined();
        this.computeCellHeight();
        this.computeHeaderHeight();
        this.rebindHeaderData();
        (_a = this.tableElement) === null || _a === void 0 ? void 0 : _a.addEventListener('scroll', this.handleScrollChanged, {
            passive: true,
        });
        if (this.headerElement != null) {
            (_b = this.headerResizeObserver) === null || _b === void 0 ? void 0 : _b.observe(this.headerElement);
        }
        (_c = this.resizeObserver) === null || _c === void 0 ? void 0 : _c.observe(this.hostEl);
    }
    async componentWillRender() {
        await this.computeAndUpdateViewportRows();
    }
    componentDidRender() {
        this.layoutColumns();
        this.layoutRendered.emit();
    }
    async componentDidUpdate() {
        if (this.isComputingCellHeight) {
            await this.computeCellHeight();
        }
    }
    disconnectedCallback() {
        var _a, _b, _c;
        (_a = this.tableElement) === null || _a === void 0 ? void 0 : _a.removeEventListener('scroll', this.handleScrollChanged);
        this.removeDividerDragListeners();
        (_b = this.headerResizeObserver) === null || _b === void 0 ? void 0 : _b.disconnect();
        (_c = this.resizeObserver) === null || _c === void 0 ? void 0 : _c.disconnect();
        this.stateMap.columnWidths = [];
        this.stateMap.columnWidthPercentages = [];
    }
    async handleViewportRowsPropsChanged() {
        await this.computeAndUpdateViewportRows();
    }
    /**
     * Scrolls the table to the provided top value.
     *
     * @param top The position to scroll to.
     * @param options A set of options to configure the scrolling behavior.
     */
    async scrollToPosition(top, options) {
        if (this.tableElement != null) {
            scrollToTop(this.tableElement, top, options);
        }
    }
    /**
     * Attempts to compute the height of templated cells. Used for internals
     * or testing.
     *
     * @internal
     * @ignore
     */
    async attemptComputeCellHeight() {
        this.computeCellHeight();
    }
    render() {
        return (h(Host, { key: 'b2968ba20c38a9e9ddda5b5af54c8ffef30d7682' }, h("div", { key: 'd17866ac3ac7f26ba76b46ff5682a0ec910faff5', class: "header", ref: (ref) => (this.headerElement = ref), style: {
                gridTemplateColumns: this.columnGridFixedLayout,
                display: this.columnElements.length <= 1 ? 'none' : 'grid',
            } }, h("slot", { key: '6bd84a11c21b399b848b8e18875117c9bf549278', name: "header" })), h("div", { key: '619f01616e0903d35d806116fb3f0f549ba9e388', class: "table", ref: (ref) => (this.tableElement = ref), style: {
                gridTemplateColumns: this.columnGridLayout,
            } }, h("slot", { key: 'b0de28b116b31023d2988d5dc13dbd0838b2317d', onSlotchange: () => {
                this.ensureDividerTemplateDefined();
                this.updateColumnElements();
                this.recreateColumnPools();
                this.computeInitialColumnWidths();
                this.rebindHeaderData();
                this.computeColumnGridLayout();
            } })), h("div", { key: '7260968b016ab69858dcd96ec2f053654772d432', class: "divider-overlay", style: {
                gridTemplateColumns: this.columnGridFixedLayout,
            } }, h("slot", { key: '9066d169f49953069710e0a20899f4dd5c9c69c9', name: "divider" })), this.resizingColumnIndex != null && h("div", { key: '54c202cc30717398d42eb80db613f9288334cd3a', class: "resize-overlay" })));
    }
    computeViewportRows() {
        const viewportHeight = this.getLayoutHeight();
        const canComputeIndices = viewportHeight != null &&
            viewportHeight > 0 &&
            !this.isComputingCellHeight;
        if (canComputeIndices) {
            const viewportCount = Math.ceil(viewportHeight / this.rowHeight);
            const viewportStartIndex = Math.floor(this.scrollOffset / this.rowHeight);
            const viewportEndIndex = viewportStartIndex + viewportCount;
            const startIndex = Math.max(0, viewportStartIndex - this.overScanCount);
            const endIndex = Math.min(this.totalRows - 1, viewportEndIndex + this.overScanCount);
            const rows = this.getViewportRows(startIndex, endIndex);
            this.viewportStartIndex = startIndex;
            this.viewportEndIndex = endIndex;
            this.stateMap.viewportRows = rows;
        }
    }
    async computeAndUpdateViewportRows() {
        var _a;
        this.computeViewportRows();
        if (((_a = this.controller) === null || _a === void 0 ? void 0 : _a.isConnected) && this.totalRows > 0) {
            await this.controller.updateActiveRowRange(this.viewportStartIndex, this.viewportEndIndex);
        }
    }
    createPools() {
        if (this.stateMap.columnElementPools == null) {
            this.stateMap.columnElementPools = this.columnElements.reduce((map, c) => map.set(c, new ElementPool(c, () => this.createColumnCellInstance(c))), new WeakMap());
        }
    }
    recreateColumnPools() {
        this.columnElements.forEach((c) => {
            var _a, _b, _c;
            if (((_a = this.stateMap.columnElementPools) === null || _a === void 0 ? void 0 : _a.get(c)) == null) {
                (_b = this.stateMap.columnElementPools) === null || _b === void 0 ? void 0 : _b.set(c, new ElementPool(c, () => this.createColumnCellInstance(c)));
            }
            else {
                (_c = this.stateMap.columnElementPools
                    .get(c)) === null || _c === void 0 ? void 0 : _c.updateElementFactory(() => this.createColumnCellInstance(c));
            }
        });
    }
    iterateColumns(f) {
        this.columnElements.forEach((column, i) => {
            var _a;
            const pool = (_a = this.stateMap.columnElementPools) === null || _a === void 0 ? void 0 : _a.get(column);
            if (pool != null) {
                f(column, pool, i);
            }
            else {
                throw new Error('Cannot find pool for column');
            }
        });
    }
    ensureDividerTemplateDefined() {
        const template = this.hostEl.querySelector('template[slot="divider"]');
        if (template == null) {
            const defaultDividerTemplate = document.createElement('template');
            defaultDividerTemplate.slot = 'divider';
            defaultDividerTemplate.innerHTML = `
        <vertex-scene-tree-table-resize-divider slot="divider">
        </vertex-scene-tree-table-resize-divider>
      `;
            this.hostEl.appendChild(defaultDividerTemplate);
        }
    }
    createHeaderInstance(column) {
        const template = column.querySelector('template[slot="header"]');
        if (template != null) {
            return generateInstanceFromTemplate(template);
        }
    }
    createDividerInstance() {
        const template = this.hostEl.querySelector('template[slot="divider"]');
        if (template != null) {
            return generateInstanceFromTemplate(template);
        }
        else {
            throw new Error('Table is missing divider template element');
        }
    }
    createColumnCellInstance(column) {
        const template = column.querySelector('template:not([slot="header"])');
        if (template != null) {
            return generateInstanceFromTemplate(template);
        }
        else {
            throw new Error('Column is missing cell template element');
        }
    }
    addDividerDragListeners() {
        var _a;
        this.stateMap.headerDividerListeners =
            (_a = this.stateMap.headerDividerInstances) === null || _a === void 0 ? void 0 : _a.map((d, i) => {
                const listener = this.createDividerPointerDownHandler(i);
                d.element.addEventListener('pointerdown', listener);
                return listener;
            });
    }
    removeDividerDragListeners() {
        var _a;
        if (this.stateMap.headerDividerListeners != null) {
            const listeners = this.stateMap.headerDividerListeners;
            (_a = this.stateMap.headerDividerInstances) === null || _a === void 0 ? void 0 : _a.forEach((d, i) => {
                const listener = listeners[i];
                if (listener != null) {
                    d.element.removeEventListener('pointerdown', listener);
                }
            });
            this.stateMap.headerDividerListeners = undefined;
        }
    }
    getViewportRows(startIndex, endIndex) {
        const rows = this.rows.slice(startIndex, endIndex + 1);
        return rows.map((row) => (row != null ? this.populateRowData(row) : row));
    }
    populateRowData(row) {
        var _a;
        if (this.rowData != null && row != null) {
            const data = ((_a = this.rowData) === null || _a === void 0 ? void 0 : _a.call(this, row)) || {};
            return { ...row, data };
        }
        else {
            return row;
        }
    }
    getLayoutHeight() {
        if (this.layoutHeight == null && this.tableElement != null) {
            this.layoutHeight = getSceneTreeViewportHeight(this.tableElement);
        }
        return this.layoutHeight;
    }
    getLayoutWidth() {
        if (this.layoutWidth == null) {
            const computedWidth = getSceneTreeTableViewportWidth(this.hostEl);
            if (computedWidth > 0) {
                this.layoutWidth = computedWidth;
            }
        }
        return this.layoutWidth;
    }
    clearLayoutHeight() {
        this.layoutHeight = undefined;
    }
    clearLayoutWidth() {
        this.layoutWidth = undefined;
    }
    static get is() { return "vertex-scene-tree-table-layout"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["scene-tree-table-layout.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["scene-tree-table-layout.css"]
        };
    }
    static get properties() {
        return {
            "tree": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "HTMLVertexSceneTreeElement",
                    "resolved": "HTMLVertexSceneTreeElement | undefined",
                    "references": {
                        "HTMLVertexSceneTreeElement": {
                            "location": "global",
                            "id": "global::HTMLVertexSceneTreeElement"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "A reference to the scene tree to perform operations for interactions. Such\nas expansion, visibility and selection."
                },
                "getter": false,
                "setter": false
            },
            "controller": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "SceneTreeController",
                    "resolved": "SceneTreeController | undefined",
                    "references": {
                        "SceneTreeController": {
                            "location": "import",
                            "path": "../scene-tree/lib/controller",
                            "id": "src/components/scene-tree/lib/controller.ts::SceneTreeController",
                            "referenceLocation": "SceneTreeController"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": undefined
                        }],
                    "text": ""
                },
                "getter": false,
                "setter": false
            },
            "rows": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "Row[]",
                    "resolved": "Row[]",
                    "references": {
                        "Row": {
                            "location": "import",
                            "path": "../scene-tree/lib/row",
                            "id": "src/components/scene-tree/lib/row.ts::Row",
                            "referenceLocation": "Row"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": undefined
                        }],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "defaultValue": "[]"
            },
            "totalRows": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": undefined
                        }],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "total-rows",
                "defaultValue": "0"
            },
            "rowHeight": {
                "type": "number",
                "mutable": true,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": undefined
                        }],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "row-height",
                "defaultValue": "24"
            },
            "overScanCount": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The number of offscreen rows above and below the viewport to render. Having\na higher number reduces the chance of the browser not displaying a row\nwhile scrolling.\n\nThis prop will be automatically populated based on the `overScanCount` prop\nspecified in the parent `<vertex-scene-tree />` element."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "over-scan-count",
                "defaultValue": "25"
            },
            "rowData": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "RowDataProvider",
                    "resolved": "((row: Row) => Record<string, unknown>) | undefined",
                    "references": {
                        "RowDataProvider": {
                            "location": "import",
                            "path": "../scene-tree/types",
                            "id": "src/components/scene-tree/types.ts::RowDataProvider",
                            "referenceLocation": "RowDataProvider"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [{
                            "name": "example",
                            "text": "```html\n<script>\n  const table = document.querySelector('vertex-scene-tree-table');\n  table.rowData = (row) => {\n    return { func: () => console.log('row', row.node.name) };\n  }\n</script>\n\n<vertex-scene-tree>\n <vertex-scene-tree-table>\n   <vertex-scene-tree-table-column>\n     <template>\n       <button event:click=\"{{row.data.func}}\">Hi</button>\n     </template>\n   </vertex-scene-tree-table-column>\n </vertex-scene-tree-table>\n</vertex-scene-tree>\n```"
                        }],
                    "text": "A callback that is invoked immediately before a row is about to be rendered.\nThis callback can return additional data that can be bound to in a\ntemplate.\n\nThis prop will be automatically populated based on the `rowData` prop\nspecified in the parent `<vertex-scene-tree />` element."
                },
                "getter": false,
                "setter": false
            },
            "layoutOffset": {
                "type": "number",
                "mutable": true,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": undefined
                        }],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "layout-offset",
                "defaultValue": "0"
            },
            "scrollOffset": {
                "type": "number",
                "mutable": true,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": undefined
                        }],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "scroll-offset",
                "defaultValue": "0"
            },
            "layoutHeight": {
                "type": "number",
                "mutable": true,
                "complexType": {
                    "original": "number",
                    "resolved": "number | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": undefined
                        }],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "layout-height"
            },
            "layoutWidth": {
                "type": "number",
                "mutable": true,
                "complexType": {
                    "original": "number",
                    "resolved": "number | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": undefined
                        }],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "layout-width"
            },
            "viewportStartIndex": {
                "type": "number",
                "mutable": true,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": undefined
                        }],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "viewport-start-index",
                "defaultValue": "0"
            },
            "viewportEndIndex": {
                "type": "number",
                "mutable": true,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": undefined
                        }],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "viewport-end-index",
                "defaultValue": "0"
            }
        };
    }
    static get states() {
        return {
            "columnGridLayout": {},
            "columnGridFixedLayout": {},
            "isComputingCellHeight": {},
            "lastDividerPointerPosition": {},
            "resizingColumnIndex": {},
            "isScrolling": {},
            "scrollTimer": {},
            "stateMap": {}
        };
    }
    static get events() {
        return [{
                "method": "layoutRendered",
                "name": "layoutRendered",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": undefined
                        }],
                    "text": ""
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }, {
                "method": "columnsResized",
                "name": "columnsResized",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "An event that is emitted when the columns of this `<vertex-scene-tree-table-layout>`\nare resized with an array containing the widths of the columns in pixels."
                },
                "complexType": {
                    "original": "number[]",
                    "resolved": "number[]",
                    "references": {}
                }
            }];
    }
    static get methods() {
        return {
            "scrollToPosition": {
                "complexType": {
                    "signature": "(top: number, options: Pick<DomScrollToOptions, \"behavior\">) => Promise<void>",
                    "parameters": [{
                            "name": "top",
                            "type": "number",
                            "docs": "The position to scroll to."
                        }, {
                            "name": "options",
                            "type": "{ behavior?: ScrollBehavior | undefined; }",
                            "docs": "A set of options to configure the scrolling behavior."
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "Pick": {
                            "location": "global",
                            "id": "global::Pick"
                        },
                        "DomScrollToOptions": {
                            "location": "import",
                            "path": "./lib/dom",
                            "id": "src/components/scene-tree-table-layout/lib/dom.ts::DomScrollToOptions",
                            "referenceLocation": "DomScrollToOptions"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Scrolls the table to the provided top value.",
                    "tags": [{
                            "name": "param",
                            "text": "top The position to scroll to."
                        }, {
                            "name": "param",
                            "text": "options A set of options to configure the scrolling behavior."
                        }]
                }
            },
            "attemptComputeCellHeight": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Attempts to compute the height of templated cells. Used for internals\nor testing.",
                    "tags": [{
                            "name": "internal",
                            "text": undefined
                        }, {
                            "name": "ignore",
                            "text": undefined
                        }]
                }
            }
        };
    }
    static get elementRef() { return "hostEl"; }
    static get watchers() {
        return [{
                "propName": "rows",
                "methodName": "handleViewportRowsPropsChanged"
            }, {
                "propName": "totalRows",
                "methodName": "handleViewportRowsPropsChanged"
            }, {
                "propName": "rowHeight",
                "methodName": "handleViewportRowsPropsChanged"
            }];
    }
}
//# sourceMappingURL=scene-tree-table-layout.js.map
