"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DataGridTableInternal = exports.DataGridTable = void 0;
const react_1 = __importStar(require("react"));
const DataGridRoot_context_1 = require("../../../data-grid/root/DataGridRoot.context");
const skeleton_1 = require("../../../skeleton");
const utils_external_1 = require("../../../utils-external");
const Slot_1 = require("../../../utils/components/slot/Slot");
const helpers_1 = require("../../../utils/helpers");
const hooks_1 = require("../../../utils/hooks");
const DataTableBaseCell_1 = require("../base-cell/DataTableBaseCell");
const DataTableColumnHeader_1 = require("../column-header/DataTableColumnHeader");
const DataTableDetailsPanelRow_1 = require("../details-panel-row/DataTableDetailsPanelRow");
const DataTableEmptyState_1 = require("../empty-state/DataTableEmptyState");
const useColumnOptions_1 = require("../hooks/useColumnOptions");
const useTableDetailsPanel_1 = require("../hooks/useTableDetailsPanel");
const useTableItems_1 = require("../hooks/useTableItems");
const useTableKeyboardNav_1 = require("../hooks/useTableKeyboardNav");
const useTableSelection_1 = require("../hooks/useTableSelection");
const useTableSort_1 = require("../hooks/useTableSort");
const DataTableLoadingState_1 = require("../loading-state/DataTableLoadingState");
const DataTableSubRowToggle_1 = require("../sub-row-toggle/DataTableSubRowToggle");
const DataTableTbody_1 = require("../tbody/DataTableTbody");
const DataTableThead_1 = require("../thead/DataTableThead");
const DataTableTr_1 = require("../tr/DataTableTr");
const DataTableRoot_context_1 = require("./DataTableRoot.context");
const DataGridTableInternal = (0, react_1.forwardRef)((_a, forwardedRef) => {
    var _b, _c, _d;
    var { className, id, layout = "fixed", stickyHeader = true, onRowAction, emptyContent, loadingContent = {
        variant: "skeleton",
        rows: 5,
        label: "Laster innhold",
    }, // TODO translate label
    detailsPanel, subRows, sorting, selectionTrigger = "row" } = _a, rest = __rest(_a, ["className", "id", "layout", "stickyHeader", "onRowAction", "emptyContent", "loadingContent", "detailsPanel", "subRows", "sorting", "selectionTrigger"]);
    const { columnDefinitions, data, getRowId, selection, isLoading, tableSettings, } = (0, DataGridRoot_context_1.useDataGridContext)();
    const sortingState = (0, useTableSort_1.useTableSort)(sorting);
    const tableItems = (0, useTableItems_1.useTableItems)({
        items: data,
        getRowId,
        subRows,
    });
    const tableSelectionState = (0, useTableSelection_1.useTableSelection)({
        selection,
        selectionTrigger,
        tableItems,
    });
    const { columns, stickyStart, totalColSpan } = (0, useColumnOptions_1.useColumnOptions)(columnDefinitions, {
        stickyColumns: tableSettings === null || tableSettings === void 0 ? void 0 : tableSettings.stickyColumns,
        hasSelection: tableSelectionState.selection.mode !== "none",
        hasDetailsPanel: !!(detailsPanel === null || detailsPanel === void 0 ? void 0 : detailsPanel.getContent),
        layout,
        columnDisplay: tableSettings === null || tableSettings === void 0 ? void 0 : tableSettings.columnDisplay,
    });
    const tableId = (0, utils_external_1.useId)(id);
    /* TODO: Need to figure out how to handle this since settings is provided from root, not table itself */
    const truncateContent = (_b = tableSettings === null || tableSettings === void 0 ? void 0 : tableSettings.truncateContent) !== null && _b !== void 0 ? _b : layout !== "auto";
    return (react_1.default.createElement(DataTableRoot_context_1.DataTableContextProvider, { layout: layout, withKeyboardNav: true, selectionState: tableSelectionState, stickyStart: stickyStart, stickyHeader: stickyHeader, tableId: tableId, loading: loadingContent, onRowAction: onRowAction, columns: columns, totalColSpan: totalColSpan, tableItems: tableItems, sortingState: sortingState },
        react_1.default.createElement(TableElementWrapper, { enabled: true, hasStickyColumns: !!(((_c = tableSettings === null || tableSettings === void 0 ? void 0 : tableSettings.stickyColumns) === null || _c === void 0 ? void 0 : _c.start) ||
                ((_d = tableSettings === null || tableSettings === void 0 ? void 0 : tableSettings.stickyColumns) === null || _d === void 0 ? void 0 : _d.end)) },
            react_1.default.createElement("table", Object.assign({}, rest, { ref: forwardedRef, className: (0, helpers_1.cl)("aksel-data-table", className), "data-zebra-stripes": tableSettings === null || tableSettings === void 0 ? void 0 : tableSettings.zebraStripes, "data-column-dividers": tableSettings === null || tableSettings === void 0 ? void 0 : tableSettings.columnDividers, "data-truncate-content": truncateContent, "data-density": tableSettings === null || tableSettings === void 0 ? void 0 : tableSettings.rowDensity, "data-text-size": tableSettings === null || tableSettings === void 0 ? void 0 : tableSettings.textSize, "data-layout": layout, "data-loading": isLoading || undefined, "aria-busy": isLoading || undefined }),
                react_1.default.createElement(useTableDetailsPanel_1.DataTableDetailsPanelProvider, { detailsPanel: detailsPanel },
                    react_1.default.createElement(DataTableThead_1.DataTableThead, { "data-sticky": stickyHeader || undefined },
                        react_1.default.createElement(DataTableTr_1.DataTableTr, null, columns.map(({ isSticky, isStickyLast, stickyLeftOffset, colDef }) => {
                            var _a, _b;
                            return (react_1.default.createElement(DataTableColumnHeader_1.DataTableColumnHeader, { id: colDef.id, width: colDef.width, align: (_a = colDef.align) !== null && _a !== void 0 ? _a : "left", key: colDef.id, isSticky: isSticky, sortable: colDef.isSortable, label: colDef.header, style: stickyLeftOffset
                                    ? { left: stickyLeftOffset }
                                    : undefined, "data-sticky-last": isStickyLast || undefined }, (_b = colDef.headerCell) !== null && _b !== void 0 ? _b : colDef.header));
                        }))),
                    react_1.default.createElement(DataTableTbody_1.DataTableTbody, null,
                        react_1.default.createElement(DataTableTBodyContent, { emptyContent: emptyContent })))))));
});
exports.DataGridTableInternal = DataGridTableInternal;
/**
 * Temp optimization to avoid re-renders on every keyboard-move, selection change etc
 */
function TableElementWrapper({ children, enabled, hasStickyColumns, }) {
    const [applyStickyStyles, setApplyStickyStyles] = (0, react_1.useState)(false);
    const tableWrapperRef = (0, react_1.useRef)(null);
    const tableRef = (0, react_1.useRef)(null);
    const rafRef = (0, react_1.useRef)(null);
    const { tabIndex, setTableRef } = (0, useTableKeyboardNav_1.useTableKeyboardNav)({
        enabled,
    });
    const mergedTableRefs = (0, hooks_1.useMergeRefs)(tableRef, setTableRef);
    const updateStickyStyles = (0, react_1.useCallback)(() => {
        if (!tableWrapperRef.current) {
            return;
        }
        const doesWrapperHasScroll = tableWrapperRef.current.scrollWidth > tableWrapperRef.current.clientWidth;
        setApplyStickyStyles(doesWrapperHasScroll);
    }, []);
    const scheduleStickyStylesUpdate = (0, react_1.useCallback)(() => {
        if (rafRef.current !== null) {
            return;
        }
        rafRef.current = requestAnimationFrame(() => {
            rafRef.current = null;
            updateStickyStyles();
        });
    }, [updateStickyStyles]);
    (0, react_1.useEffect)(function observeAndUpdateStickyStyles() {
        if (!hasStickyColumns) {
            return;
        }
        const tableWrapperElement = tableWrapperRef.current;
        if (!tableWrapperElement) {
            return;
        }
        const handleResize = () => scheduleStickyStylesUpdate();
        window.addEventListener("resize", handleResize);
        let resizeObserver;
        if (typeof ResizeObserver !== "undefined") {
            resizeObserver = new ResizeObserver(handleResize);
            resizeObserver.observe(tableWrapperElement);
            if (tableRef.current) {
                resizeObserver.observe(tableRef.current);
            }
        }
        scheduleStickyStylesUpdate();
        return () => {
            window.removeEventListener("resize", handleResize);
            resizeObserver === null || resizeObserver === void 0 ? void 0 : resizeObserver.disconnect();
            if (rafRef.current !== null) {
                cancelAnimationFrame(rafRef.current);
                rafRef.current = null;
            }
        };
    }, [scheduleStickyStylesUpdate, hasStickyColumns]);
    return (react_1.default.createElement("div", { className: "aksel-data-table__border-wrapper" },
        react_1.default.createElement("div", { ref: tableWrapperRef, className: "aksel-data-table__scroll-wrapper" },
            react_1.default.createElement(Slot_1.Slot, { tabIndex: tabIndex, 
                /* @ts-expect-error Ref is not typed correctly to handle this case */
                ref: mergedTableRefs, "data-scroll": applyStickyStyles ? "true" : undefined }, children))));
}
function DataTableTBodyContent({ emptyContent }) {
    var _a, _b, _c;
    const { columns, loading, totalColSpan, tableItems } = (0, DataTableRoot_context_1.useDataTableContext)();
    const { isLoading } = (0, DataGridRoot_context_1.useDataGridContext)();
    if (isLoading && (loading === null || loading === void 0 ? void 0 : loading.variant) === "content") {
        return (react_1.default.createElement(DataTableLoadingState_1.DataTableLoadingState, { colSpan: totalColSpan }, loading.content));
    }
    if (isLoading && (loading === null || loading === void 0 ? void 0 : loading.variant) === "skeleton") {
        const rows = (_a = loading.rows) !== null && _a !== void 0 ? _a : 5;
        const label = (_b = loading.label) !== null && _b !== void 0 ? _b : "Laster innhold"; // TODO translate
        return (react_1.default.createElement(react_1.default.Fragment, null,
            react_1.default.createElement("tr", null,
                react_1.default.createElement("td", { colSpan: totalColSpan, className: "aksel-sr-only" }, label)),
            Array.from({ length: rows }, (_, rowIndex) => (react_1.default.createElement(DataTableTr_1.DataTableTr, { key: `skeleton-row-${rowIndex}`, "aria-hidden": true }, columns.map(({ isSticky, isStickyLast, stickyLeftOffset, colDef }, colDefIndex) => {
                var _a;
                return (react_1.default.createElement(DataTableBaseCell_1.DataTableBaseCell, { align: (_a = colDef.align) !== null && _a !== void 0 ? _a : "left", key: colDef.id || colDefIndex, as: colDef.isRowHeader ? "th" : "td", isSticky: isSticky, style: stickyLeftOffset ? { left: stickyLeftOffset } : undefined, "data-sticky-last": isStickyLast || undefined },
                    react_1.default.createElement(skeleton_1.Skeleton, { variant: "text" })));
            }))))));
    }
    if (tableItems.items.length === 0 && emptyContent !== undefined) {
        return (react_1.default.createElement(DataTableEmptyState_1.DataTableEmptyState, { colSpan: totalColSpan }, emptyContent));
    }
    const renderLoadingAnnouncement = isLoading && (loading === null || loading === void 0 ? void 0 : loading.variant) === "overlay";
    const overlayLabel = (loading === null || loading === void 0 ? void 0 : loading.variant) === "overlay"
        ? ((_c = loading.label) !== null && _c !== void 0 ? _c : "Laster innhold") // TODO translate
        : "Laster innhold";
    return (react_1.default.createElement(react_1.default.Fragment, null,
        renderLoadingAnnouncement && (react_1.default.createElement("tr", null,
            react_1.default.createElement("td", { colSpan: totalColSpan, className: "aksel-sr-only" }, overlayLabel))),
        tableItems.items.map((rowData, rowIndex) => {
            const rowId = tableItems.visibleRowIds[rowIndex];
            const details = rowId != null ? tableItems.itemDetails.get(rowId) : undefined;
            /* Should in theory be impossible. Look about typing this? */
            if (!details) {
                return null;
            }
            return (react_1.default.createElement(DataTableDataRow, { key: details.id, rowData: rowData, details: details, columns: columns }));
        })));
}
const DataTableDataRow = (0, react_1.memo)(function DataTableDataRow({ rowData, details, columns, }) {
    const hasSubRows = details.children.length > 0;
    return (react_1.default.createElement(react_1.default.Fragment, null,
        react_1.default.createElement(DataTableTr_1.DataTableTr, { rowId: details.id }, columns.map(({ isSticky, isStickyLast, stickyLeftOffset, colDef }, colDefIndex) => {
            var _a;
            const renderNestedToggle = colDefIndex === 0 && hasSubRows;
            const renderNestedIndent = colDefIndex === 0 && (details.level > 0 || hasSubRows);
            const style = Object.assign({ "--__axc-data-table-nested-depth": details.level }, (stickyLeftOffset ? { left: stickyLeftOffset } : {}));
            return (react_1.default.createElement(DataTableBaseCell_1.DataTableBaseCell, { align: (_a = colDef.align) !== null && _a !== void 0 ? _a : "left", key: colDef.id || colDefIndex, as: colDef.isRowHeader ? "th" : "td", isSticky: isSticky, "data-nested": renderNestedIndent || undefined, "data-sticky-last": isStickyLast || undefined, style: style, beforeContent: renderNestedToggle ? (react_1.default.createElement(DataTableSubRowToggle_1.DataTableSubRowToggle, { details: details })) : undefined }, colDef.bodyCell(rowData)));
        })),
        react_1.default.createElement(DataTableDetailsPanelRow_1.DataTableDetailsPanelRow, { rowId: details.id, rowData: rowData })));
}, 
/* TODO: Might be some better metrics we could use to optimize this */
(prev, next) => prev.rowData === next.rowData &&
    prev.columns === next.columns &&
    prev.details.id === next.details.id &&
    prev.details.level === next.details.level &&
    prev.details.children.length === next.details.children.length);
const DataGridTable = DataGridTableInternal;
exports.DataGridTable = DataGridTable;
exports.default = DataGridTable;
//# sourceMappingURL=DataGridTableRoot.js.map