UNPKG

react-data-grid

Version:

Feature-rich and customizable data grid React component

1,408 lines • 104 kB
import { createContext, memo, use, useCallback, useEffectEvent, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react"; import { flushSync } from "react-dom"; import { Fragment, jsx, jsxs } from "react/jsx-runtime"; //#region src/utils/frozenColumnUtils.ts function isStartFrozen(frozen) { return frozen === true || frozen === "start"; } //#endregion //#region src/utils/colSpanUtils.ts function getColSpan(column, lastStartFrozenColumnIndex, firstEndFrozenColumnIndex, args) { if (typeof column.colSpan !== "function") return void 0; const colSpan = column.colSpan(args); if (!Number.isInteger(colSpan) || colSpan <= 1) return void 0; const spanEnd = column.idx + colSpan - 1; if (isStartFrozen(column.frozen) && spanEnd > lastStartFrozenColumnIndex) return void 0; if (column.frozen === false && firstEndFrozenColumnIndex !== -1 && spanEnd >= firstEndFrozenColumnIndex) return; return colSpan; } //#endregion //#region src/utils/activePositionUtils.ts function isCellEditableUtil(column, row) { return column.renderEditCell != null && (typeof column.editable === "function" ? column.editable(row) : column.editable) !== false; } function getCellColSpan({ rows, topSummaryRows, bottomSummaryRows, rowIdx, mainHeaderRowIdx, lastStartFrozenColumnIndex, firstEndFrozenColumnIndex, column }) { const topSummaryRowsCount = topSummaryRows?.length ?? 0; if (rowIdx === mainHeaderRowIdx) return getColSpan(column, lastStartFrozenColumnIndex, firstEndFrozenColumnIndex, { type: "HEADER" }); if (topSummaryRows && rowIdx > mainHeaderRowIdx && rowIdx <= topSummaryRowsCount + mainHeaderRowIdx) return getColSpan(column, lastStartFrozenColumnIndex, firstEndFrozenColumnIndex, { type: "SUMMARY", row: topSummaryRows[rowIdx + topSummaryRowsCount] }); if (rowIdx >= 0 && rowIdx < rows.length) { const row = rows[rowIdx]; return getColSpan(column, lastStartFrozenColumnIndex, firstEndFrozenColumnIndex, { type: "ROW", row }); } if (bottomSummaryRows) return getColSpan(column, lastStartFrozenColumnIndex, firstEndFrozenColumnIndex, { type: "SUMMARY", row: bottomSummaryRows[rowIdx - rows.length] }); } function getNextActivePosition({ moveUp, moveNext, cellNavigationMode, columns, colSpanColumns, rows, topSummaryRows, bottomSummaryRows, minRowIdx, mainHeaderRowIdx, maxRowIdx, activePosition: { idx: activeIdx, rowIdx: activeRowIdx }, nextPosition, nextPositionIsCellInActiveBounds, lastStartFrozenColumnIndex, firstEndFrozenColumnIndex }) { let { idx: nextIdx, rowIdx: nextRowIdx } = nextPosition; const columnsCount = columns.length; const setColSpan = (moveNext) => { for (const column of colSpanColumns) { const colIdx = column.idx; if (colIdx > nextIdx) break; const colSpan = getCellColSpan({ rows, topSummaryRows, bottomSummaryRows, rowIdx: nextRowIdx, mainHeaderRowIdx, lastStartFrozenColumnIndex, firstEndFrozenColumnIndex, column }); if (colSpan && nextIdx > colIdx && nextIdx < colSpan + colIdx) { nextIdx = colIdx + (moveNext ? colSpan : 0); break; } } }; const getParentRowIdx = (parent) => { return parent.level + mainHeaderRowIdx; }; const setHeaderGroupColAndRowSpan = () => { if (moveNext) { let { parent } = columns[nextIdx]; while (parent !== void 0) { const parentRowIdx = getParentRowIdx(parent); if (nextRowIdx === parentRowIdx) { nextIdx = parent.idx + parent.colSpan; break; } ({parent} = parent); } } else if (moveUp) { let { parent } = columns[nextIdx]; let found = false; while (parent !== void 0) { const parentRowIdx = getParentRowIdx(parent); if (nextRowIdx >= parentRowIdx) { nextIdx = parent.idx; nextRowIdx = parentRowIdx; found = true; break; } ({parent} = parent); } if (!found) { nextIdx = activeIdx; nextRowIdx = activeRowIdx; } } }; if (nextPositionIsCellInActiveBounds) { setColSpan(moveNext); if (nextRowIdx < mainHeaderRowIdx) setHeaderGroupColAndRowSpan(); } if (cellNavigationMode === "CHANGE_ROW") { const isAfterLastColumn = nextIdx === columnsCount; const isBeforeFirstColumn = nextIdx === -1; if (isAfterLastColumn) { if (!(nextRowIdx === maxRowIdx)) { nextIdx = 0; nextRowIdx += 1; } } else if (isBeforeFirstColumn) { if (!(nextRowIdx === minRowIdx)) { nextRowIdx -= 1; nextIdx = columnsCount - 1; } setColSpan(false); } } if (nextRowIdx < mainHeaderRowIdx && nextIdx > -1 && nextIdx < columnsCount) { let { parent } = columns[nextIdx]; const nextParentRowIdx = nextRowIdx; nextRowIdx = mainHeaderRowIdx; while (parent !== void 0) { const parentRowIdx = getParentRowIdx(parent); if (parentRowIdx >= nextParentRowIdx) { nextRowIdx = parentRowIdx; nextIdx = parent.idx; } ({parent} = parent); } } return { idx: nextIdx, rowIdx: nextRowIdx }; } function canExitGrid({ maxColIdx, minRowIdx, maxRowIdx, activePosition: { rowIdx, idx }, shiftKey }) { return shiftKey ? idx === 0 && rowIdx === minRowIdx : idx === maxColIdx && rowIdx === maxRowIdx; } //#endregion //#region src/utils/domUtils.ts function stopPropagation(event) { event.stopPropagation(); } function scrollIntoView(element, behavior = "instant") { element?.scrollIntoView({ inline: "nearest", block: "nearest", behavior }); } function getRowToScroll(gridEl) { return gridEl.querySelector("& > [role=\"row\"][tabindex=\"0\"]"); } function getCellToScroll(gridEl) { return gridEl.querySelector("& > [role=\"row\"] > [tabindex=\"0\"]"); } function focusElement(element, shouldScroll) { if (element === null) return; if (shouldScroll) scrollIntoView(element); element.focus({ preventScroll: true }); } function focusRow(gridEl) { focusElement(getRowToScroll(gridEl), true); } function focusCell(gridEl, shouldScroll = true) { focusElement(getCellToScroll(gridEl), shouldScroll); } //#endregion //#region src/utils/eventUtils.ts function createCellEvent(event) { let defaultPrevented = false; const cellEvent = { ...event, preventGridDefault() { defaultPrevented = true; }, isGridDefaultPrevented() { return defaultPrevented; } }; Object.setPrototypeOf(cellEvent, Object.getPrototypeOf(event)); return cellEvent; } //#endregion //#region src/utils/keyboardUtils.ts const nonInputKeys = /* @__PURE__ */ new Set([ "Unidentified", "Alt", "AltGraph", "CapsLock", "Control", "Fn", "FnLock", "Meta", "NumLock", "ScrollLock", "Shift", "Tab", "ArrowDown", "ArrowLeft", "ArrowRight", "ArrowUp", "End", "Home", "PageDown", "PageUp", "Insert", "ContextMenu", "Escape", "Pause", "Play", "PrintScreen", "F1", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12" ]); function isCtrlKeyHeldDown(e) { return (e.ctrlKey || e.metaKey) && e.key !== "Control"; } const vKey = 86; function isDefaultCellInput(event, isUserHandlingPaste) { if (isCtrlKeyHeldDown(event) && (event.keyCode !== vKey || isUserHandlingPaste)) return false; return !nonInputKeys.has(event.key); } /** * By default, the following navigation keys are enabled while an editor is open, under specific conditions: * - Tab: * - The editor must be an <input>, a <textarea>, or a <select> element. * - The editor element must be the only immediate child of the editor container/a label. */ function onEditorNavigation({ key, target }) { if (key === "Tab" && (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement || target instanceof HTMLSelectElement)) return target.closest(".rdg-editor-container")?.querySelectorAll("input, textarea, select").length === 1; return false; } function getLeftRightKey(direction) { const isRtl = direction === "rtl"; return { leftKey: isRtl ? "ArrowRight" : "ArrowLeft", rightKey: isRtl ? "ArrowLeft" : "ArrowRight" }; } //#endregion //#region src/utils/renderMeasuringCells.tsx const measuringCellClassname = "rdg-7-0-0-beta-60-fa71d63e"; function renderMeasuringCells(viewportColumns) { return viewportColumns.map(({ key, idx, minWidth, maxWidth }) => /* @__PURE__ */ jsx("div", { className: measuringCellClassname, style: { gridColumnStart: idx + 1, minWidth, maxWidth }, "data-measuring-cell-key": key }, key)); } const cellClassname = `rdg-cell rdg-7-0-0-beta-60-85c48527`; const cellFrozenBase = "rdg-7-0-0-beta-60-203d9925"; const cellFrozenStartClassname = `rdg-cell-frozen-start ${cellFrozenBase}`; const cellFrozenEndClassname = `rdg-cell-frozen-end ${cellFrozenBase}`; const cellDragHandleClassname = `rdg-cell-drag-handle rdg-7-0-0-beta-60-bfba19bc`; //#endregion //#region src/utils/styleUtils.ts function getHeaderCellStyle(column, rowIdx, rowSpan) { const gridRowEnd = rowIdx + 1; const paddingBlockStart = `calc(${rowSpan - 1} * var(--rdg-header-row-height))`; if (column.parent === void 0) return { insetBlockStart: 0, gridRowStart: 1, gridRowEnd, paddingBlockStart }; return { insetBlockStart: `calc(${rowIdx - rowSpan} * var(--rdg-header-row-height))`, gridRowStart: gridRowEnd - rowSpan, gridRowEnd, paddingBlockStart }; } function getCellStyle(column, colSpan = 1) { const index = column.idx + 1; return { gridColumnStart: index, gridColumnEnd: index + colSpan, insetInlineStart: isStartFrozen(column.frozen) ? `var(--rdg-frozen-start-${column.idx})` : void 0, insetInlineEnd: column.frozen === "end" ? `var(--rdg-frozen-end-${column.idx + colSpan - 1})` : void 0 }; } function classnames(...args) { let classname = ""; for (const arg of args) if (typeof arg === "string") classname += ` ${arg}`; return classname.slice(1); } function getCellClassname(column, ...extraClasses) { return classnames(cellClassname, isStartFrozen(column.frozen) && cellFrozenStartClassname, column.frozen === "end" && cellFrozenEndClassname, ...extraClasses); } //#endregion //#region src/utils/index.ts const { min, max, floor, abs } = Math; function assertIsValidKeyGetter(keyGetter) { if (typeof keyGetter !== "function") throw new Error("Please specify the rowKeyGetter prop to use selection"); } function clampColumnWidth(width, { minWidth, maxWidth }) { width = max(width, minWidth); if (typeof maxWidth === "number" && maxWidth >= minWidth) return min(width, maxWidth); return width; } function getHeaderCellRowSpan(column, rowIdx) { return column.parent === void 0 ? rowIdx : column.level - column.parent.level; } //#endregion //#region src/hooks/useActivePosition.ts const initialActivePosition = { idx: -1, rowIdx: Number.NEGATIVE_INFINITY, mode: "ACTIVE" }; function useActivePosition({ gridRef, columns, rows, isTreeGrid, maxColIdx, minRowIdx, maxRowIdx, setDraggedOverRowIdx }) { const [activePosition, setActivePosition] = useState(initialActivePosition); const [positionToFocus, setPositionToFocus] = useState(null); const positionToFocusRef = useRef(null); /** * Returns whether the given position represents a valid cell or row position in the grid. * Active bounds: any valid position in the grid * Viewport: any valid position in the grid outside of header rows and summary rows * Row selection is only allowed in TreeDataGrid */ function validatePosition({ idx, rowIdx }) { const isColumnPositionAllColumns = isTreeGrid && idx === -1; const isColumnPositionInActiveBounds = idx >= 0 && idx <= maxColIdx; const isRowPositionInActiveBounds = rowIdx >= minRowIdx && rowIdx <= maxRowIdx; const isRowPositionInViewport = rowIdx >= 0 && rowIdx < rows.length; const isRowInActiveBounds = isColumnPositionAllColumns && isRowPositionInActiveBounds; const isRowInViewport = isColumnPositionAllColumns && isRowPositionInViewport; const isCellInActiveBounds = isColumnPositionInActiveBounds && isRowPositionInActiveBounds; const isCellInViewport = isColumnPositionInActiveBounds && isRowPositionInViewport; return { isPositionInActiveBounds: isRowInActiveBounds || isCellInActiveBounds, isPositionInViewport: isRowInViewport || isCellInViewport, isRowInActiveBounds, isRowInViewport, isCellInActiveBounds, isCellInViewport }; } function getResolvedValues(position) { return { resolvedActivePosition: position, validatedPosition: validatePosition(position) }; } function getActiveColumn() { if (!validatedPosition.isCellInActiveBounds) throw new Error("No column for active position"); return columns[resolvedActivePosition.idx]; } function getActiveRow() { if (!validatedPosition.isPositionInViewport) throw new Error("No row for active position"); return rows[resolvedActivePosition.rowIdx]; } let { resolvedActivePosition, validatedPosition } = getResolvedValues(activePosition); if (!validatedPosition.isPositionInActiveBounds && resolvedActivePosition !== initialActivePosition) { setActivePosition(initialActivePosition); setDraggedOverRowIdx(void 0); ({resolvedActivePosition, validatedPosition} = getResolvedValues(initialActivePosition)); } else if (resolvedActivePosition.mode === "EDIT") { if ((getActiveColumn().editorOptions?.closeOnExternalRowChange ?? true) && getActiveRow() !== resolvedActivePosition.originalRow) { const newPosition = { idx: resolvedActivePosition.idx, rowIdx: resolvedActivePosition.rowIdx, mode: "ACTIVE" }; setActivePosition(newPosition); setPositionToFocus(null); ({resolvedActivePosition, validatedPosition} = getResolvedValues(newPosition)); } } useLayoutEffect(() => { if (positionToFocus !== null && positionToFocus !== positionToFocusRef.current) { positionToFocusRef.current = positionToFocus; if (positionToFocus.idx === -1) focusRow(gridRef.current); else focusCell(gridRef.current); } }, [positionToFocus, gridRef]); return { activePosition: resolvedActivePosition, setActivePosition, setPositionToFocus, activePositionIsInActiveBounds: validatedPosition.isPositionInActiveBounds, activePositionIsInViewport: validatedPosition.isPositionInViewport, activePositionIsRow: validatedPosition.isRowInActiveBounds, activePositionIsCellInViewport: validatedPosition.isCellInViewport, validatePosition, getActiveColumn, getActiveRow }; } //#endregion //#region src/cellRenderers/renderCheckbox.tsx const checkboxClassname = `rdg-checkbox-input rdg-7-0-0-beta-60-3b807ead`; function renderCheckbox({ onChange, indeterminate, ...props }) { function handleChange(e) { onChange(e.target.checked, e.nativeEvent.shiftKey); } return /* @__PURE__ */ jsx("input", { ref: (el) => { if (el) el.indeterminate = indeterminate === true; }, type: "checkbox", className: checkboxClassname, onChange: handleChange, ...props }); } //#endregion //#region src/cellRenderers/renderToggleGroup.tsx const groupCellContentClassname = `rdg-group-cell-content rdg-7-0-0-beta-60-07919382`; const caretClassname = `rdg-caret rdg-7-0-0-beta-60-02a50147`; function renderToggleGroup(props) { return /* @__PURE__ */ jsx(ToggleGroup, { ...props }); } function ToggleGroup({ groupKey, isExpanded, tabIndex, toggleGroup }) { function handleKeyDown({ key }) { if (key === "Enter") toggleGroup(); } return /* @__PURE__ */ jsxs("span", { className: groupCellContentClassname, tabIndex, onKeyDown: handleKeyDown, children: [groupKey, /* @__PURE__ */ jsx("svg", { viewBox: "0 0 14 8", width: "14", height: "8", className: caretClassname, "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: isExpanded ? "M1 1 L 7 7 L 13 1" : "M1 7 L 7 1 L 13 7" }) })] }); } //#endregion //#region src/cellRenderers/renderValue.tsx function renderValue(props) { return props.row?.[props.column.key]; } //#endregion //#region src/DataGridDefaultRenderersContext.ts const DataGridDefaultRenderersContext = createContext(void 0); DataGridDefaultRenderersContext.displayName = "DataGridDefaultRenderersContext"; function useDefaultRenderers() { return use(DataGridDefaultRenderersContext); } //#endregion //#region src/cellRenderers/SelectCellFormatter.tsx function SelectCellFormatter({ value, tabIndex, indeterminate, disabled, onChange, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy }) { const renderCheckbox = useDefaultRenderers().renderCheckbox; return renderCheckbox({ "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, tabIndex, indeterminate, disabled, checked: value, onChange }); } //#endregion //#region src/Columns.tsx const SELECT_COLUMN_KEY = "rdg-select-column"; function HeaderRenderer({ tabIndex }) { const { isIndeterminate, isRowSelected, onRowSelectionChange } = useHeaderRowSelection(); return /* @__PURE__ */ jsx(SelectCellFormatter, { "aria-label": "Select All", tabIndex, indeterminate: isIndeterminate, value: isRowSelected, onChange: (checked) => { onRowSelectionChange({ checked: isIndeterminate ? false : checked }); } }); } function SelectFormatter({ row, tabIndex }) { const { isRowSelectionDisabled, isRowSelected, onRowSelectionChange } = useRowSelection(); return /* @__PURE__ */ jsx(SelectCellFormatter, { "aria-label": "Select", tabIndex, disabled: isRowSelectionDisabled, value: isRowSelected, onChange: (checked, isShiftClick) => { onRowSelectionChange({ row, checked, isShiftClick }); } }); } function SelectGroupFormatter({ row, tabIndex }) { const { isRowSelected, onRowSelectionChange } = useRowSelection(); return /* @__PURE__ */ jsx(SelectCellFormatter, { "aria-label": "Select Group", tabIndex, value: isRowSelected, onChange: (checked) => { onRowSelectionChange({ row, checked, isShiftClick: false }); } }); } const SelectColumn = { key: SELECT_COLUMN_KEY, name: "", width: 35, minWidth: 35, maxWidth: 35, resizable: false, sortable: false, frozen: true, renderHeaderCell(props) { return /* @__PURE__ */ jsx(HeaderRenderer, { ...props }); }, renderCell(props) { return /* @__PURE__ */ jsx(SelectFormatter, { ...props }); }, renderGroupCell(props) { return /* @__PURE__ */ jsx(SelectGroupFormatter, { ...props }); } }; //#endregion //#region src/renderHeaderCell.tsx const headerSortCellClassname = "rdg-7-0-0-beta-60-56a248e4"; const headerSortNameClassname = `rdg-header-sort-name rdg-7-0-0-beta-60-7fad8c83`; function renderHeaderCell({ column, sortDirection, priority }) { if (!column.sortable) return column.name; return /* @__PURE__ */ jsx(SortableHeaderCell, { sortDirection, priority, children: column.name }); } function SortableHeaderCell({ sortDirection, priority, children }) { const renderSortStatus = useDefaultRenderers().renderSortStatus; return /* @__PURE__ */ jsxs("span", { className: headerSortCellClassname, children: [/* @__PURE__ */ jsx("span", { className: headerSortNameClassname, children }), /* @__PURE__ */ jsx("span", { children: renderSortStatus({ sortDirection, priority }) })] }); } //#endregion //#region src/hooks/useCalculatedColumns.ts const DEFAULT_COLUMN_WIDTH = "auto"; const DEFAULT_COLUMN_MIN_WIDTH = 50; function useCalculatedColumns({ rawColumns, defaultColumnOptions, getColumnWidth, viewportWidth, scrollLeft, enableVirtualization }) { const defaultWidth = defaultColumnOptions?.width ?? DEFAULT_COLUMN_WIDTH; const defaultMinWidth = defaultColumnOptions?.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH; const defaultMaxWidth = defaultColumnOptions?.maxWidth ?? void 0; const defaultRenderCell = defaultColumnOptions?.renderCell ?? renderValue; const defaultRenderHeaderCell = defaultColumnOptions?.renderHeaderCell ?? renderHeaderCell; const defaultSortable = defaultColumnOptions?.sortable ?? false; const defaultResizable = defaultColumnOptions?.resizable ?? false; const defaultDraggable = defaultColumnOptions?.draggable ?? false; const { columns, colSpanColumns, lastStartFrozenColumnIndex, firstEndFrozenColumnIndex, headerRowsCount } = useMemo(() => { let lastStartFrozenColumnIndex = -1; let firstEndFrozenColumnIndex = -1; let headerRowsCount = 1; const columns = []; collectColumns(rawColumns, 1); function collectColumns(rawColumns, level, parent) { for (const rawColumn of rawColumns) { if ("children" in rawColumn) { const calculatedColumnParent = { name: rawColumn.name, parent, idx: -1, colSpan: 0, level: 0, headerCellClass: rawColumn.headerCellClass }; collectColumns(rawColumn.children, level + 1, calculatedColumnParent); continue; } const frozen = rawColumn.frozen ?? false; columns.push({ ...rawColumn, parent, idx: 0, level: 0, frozen, width: rawColumn.width ?? defaultWidth, minWidth: rawColumn.minWidth ?? defaultMinWidth, maxWidth: rawColumn.maxWidth ?? defaultMaxWidth, sortable: rawColumn.sortable ?? defaultSortable, resizable: rawColumn.resizable ?? defaultResizable, draggable: rawColumn.draggable ?? defaultDraggable, renderCell: rawColumn.renderCell ?? defaultRenderCell, renderHeaderCell: rawColumn.renderHeaderCell ?? defaultRenderHeaderCell }); if (isStartFrozen(frozen)) lastStartFrozenColumnIndex++; if (level > headerRowsCount) headerRowsCount = level; } } columns.sort((a, b) => { if (a.key === "rdg-select-column") return -1; if (b.key === "rdg-select-column") return 1; return (a.frozen === "end" ? 2 : a.frozen === false ? 1 : 0) - (b.frozen === "end" ? 2 : b.frozen === false ? 1 : 0); }); const colSpanColumns = []; columns.forEach((column, idx) => { column.idx = idx; updateColumnParent(column, idx, 0); if (column.colSpan != null) colSpanColumns.push(column); if (column.frozen === "end" && firstEndFrozenColumnIndex === -1) firstEndFrozenColumnIndex = idx; }); return { columns, colSpanColumns, lastStartFrozenColumnIndex, firstEndFrozenColumnIndex, headerRowsCount }; }, [ rawColumns, defaultWidth, defaultMinWidth, defaultMaxWidth, defaultRenderCell, defaultRenderHeaderCell, defaultResizable, defaultSortable, defaultDraggable ]); const { templateColumns, layoutCssVars, totalStartFrozenColumnWidth, totalEndFrozenColumnWidth, columnMetrics } = useMemo(() => { const columnMetrics = /* @__PURE__ */ new Map(); let left = 0; let totalStartFrozenColumnWidth = 0; let totalEndFrozenColumnWidth = 0; const templateColumns = []; for (const column of columns) { let width = getColumnWidth(column); if (typeof width === "number") width = clampColumnWidth(width, column); else width = column.minWidth; templateColumns.push(`${width}px`); columnMetrics.set(column, { width, left }); left += width; } if (lastStartFrozenColumnIndex !== -1) { const lastStartFrozenColumnMetric = columnMetrics.get(columns[lastStartFrozenColumnIndex]); totalStartFrozenColumnWidth = lastStartFrozenColumnMetric.left + lastStartFrozenColumnMetric.width; } const layoutCssVars = {}; for (let i = 0; i <= lastStartFrozenColumnIndex; i++) { const column = columns[i]; layoutCssVars[`--rdg-frozen-start-${column.idx}`] = `${columnMetrics.get(column).left}px`; } if (firstEndFrozenColumnIndex !== -1) { const lastColumn = columns[columns.length - 1]; const lastColumnMetric = columnMetrics.get(lastColumn); const gridEnd = lastColumnMetric.left + lastColumnMetric.width; totalEndFrozenColumnWidth = gridEnd - columnMetrics.get(columns[firstEndFrozenColumnIndex]).left; for (let i = firstEndFrozenColumnIndex; i < columns.length; i++) { const column = columns[i]; const metric = columnMetrics.get(column); layoutCssVars[`--rdg-frozen-end-${column.idx}`] = `${gridEnd - (metric.left + metric.width)}px`; } } return { templateColumns, layoutCssVars, totalStartFrozenColumnWidth, totalEndFrozenColumnWidth, columnMetrics }; }, [ getColumnWidth, columns, lastStartFrozenColumnIndex, firstEndFrozenColumnIndex ]); const [colOverscanStartIdx, colOverscanEndIdx] = useMemo(() => { if (!enableVirtualization) return [0, columns.length - 1]; const viewportLeft = scrollLeft + totalStartFrozenColumnWidth; const viewportRight = scrollLeft + viewportWidth - totalEndFrozenColumnWidth; const lastColIdx = columns.length - 1; const firstUnfrozenColumnIdx = min(lastStartFrozenColumnIndex + 1, lastColIdx); if (viewportLeft >= viewportRight) return [firstUnfrozenColumnIdx, firstUnfrozenColumnIdx]; let colVisibleStartIdx = firstUnfrozenColumnIdx; while (colVisibleStartIdx < lastColIdx) { const { left, width } = columnMetrics.get(columns[colVisibleStartIdx]); if (left + width > viewportLeft) break; colVisibleStartIdx++; } let colVisibleEndIdx = colVisibleStartIdx; while (colVisibleEndIdx < lastColIdx) { const { left, width } = columnMetrics.get(columns[colVisibleEndIdx]); if (left + width >= viewportRight) break; colVisibleEndIdx++; } return [max(firstUnfrozenColumnIdx, colVisibleStartIdx - 1), min(lastColIdx, colVisibleEndIdx + 1)]; }, [ columnMetrics, columns, lastStartFrozenColumnIndex, scrollLeft, totalStartFrozenColumnWidth, totalEndFrozenColumnWidth, viewportWidth, enableVirtualization ]); return { columns, colSpanColumns, colOverscanStartIdx, colOverscanEndIdx, templateColumns, layoutCssVars, headerRowsCount, lastStartFrozenColumnIndex, firstEndFrozenColumnIndex, totalStartFrozenColumnWidth, totalEndFrozenColumnWidth }; } function updateColumnParent(column, index, level) { if (level < column.level) column.level = level; if (column.parent !== void 0) { const { parent } = column; if (parent.idx === -1) parent.idx = index; parent.colSpan += 1; updateColumnParent(parent, index, level - 1); } } //#endregion //#region src/hooks/useColumnWidths.ts function useColumnWidths(columns, viewportColumns, templateColumns, gridRef, gridWidth, columnWidths, onColumnWidthsChange, onColumnResize, setColumnResizing) { const [columnToAutoResize, setColumnToAutoResize] = useState(null); const [columnsToMeasureOnResize, setColumnsToMeasureOnResize] = useState(null); const [prevGridWidth, setPrevGridWidth] = useState(gridWidth); const columnsCanFlex = columns.length === viewportColumns.length; const ignorePreviouslyMeasuredColumnsOnGridWidthChange = columnsCanFlex && gridWidth !== prevGridWidth; const newTemplateColumns = [...templateColumns]; const columnsToMeasure = []; for (const { key, idx, width } of viewportColumns) { const columnWidth = columnWidths.get(key); if (key === columnToAutoResize?.key) { newTemplateColumns[idx] = columnToAutoResize.width === "max-content" ? columnToAutoResize.width : `${columnToAutoResize.width}px`; columnsToMeasure.push(key); } else if (typeof width === "string" && columnWidth?.type !== "resized" && (ignorePreviouslyMeasuredColumnsOnGridWidthChange || columnsToMeasureOnResize?.has(key) === true || columnWidth === void 0)) { newTemplateColumns[idx] = width; columnsToMeasure.push(key); } } const gridTemplateColumns = newTemplateColumns.join(" "); useLayoutEffect(updateMeasuredAndResizedWidths); function updateMeasuredAndResizedWidths() { setPrevGridWidth(gridWidth); if (columnsToMeasure.length === 0) return; const newColumnWidths = new Map(columnWidths); let hasChanges = false; for (const key of columnsToMeasure) { const measuredWidth = measureColumnWidth(gridRef, key); hasChanges ||= measuredWidth !== columnWidths.get(key)?.width; if (measuredWidth === void 0) newColumnWidths.delete(key); else newColumnWidths.set(key, { type: "measured", width: measuredWidth }); } if (columnToAutoResize !== null) { const resizingKey = columnToAutoResize.key; const oldWidth = columnWidths.get(resizingKey)?.width; const newWidth = measureColumnWidth(gridRef, resizingKey); if (newWidth !== void 0 && oldWidth !== newWidth) { hasChanges = true; newColumnWidths.set(resizingKey, { type: "resized", width: newWidth }); } setColumnToAutoResize(null); } if (hasChanges) onColumnWidthsChange(newColumnWidths); } function handleColumnResize(column, nextWidth) { const { key: resizingKey } = column; flushSync(() => { if (columnsCanFlex) { const columnsToRemeasure = /* @__PURE__ */ new Set(); for (const { key, width } of viewportColumns) if (resizingKey !== key && typeof width === "string" && columnWidths.get(key)?.type !== "resized") columnsToRemeasure.add(key); setColumnsToMeasureOnResize(columnsToRemeasure); } setColumnToAutoResize({ key: resizingKey, width: nextWidth }); setColumnResizing(typeof nextWidth === "number"); }); setColumnsToMeasureOnResize(null); if (onColumnResize) { const previousWidth = columnWidths.get(resizingKey)?.width; const newWidth = typeof nextWidth === "number" ? nextWidth : measureColumnWidth(gridRef, resizingKey); if (newWidth !== void 0 && newWidth !== previousWidth) onColumnResize(column, newWidth); } } return { gridTemplateColumns, handleColumnResize }; } function measureColumnWidth(gridRef, key) { const selector = `[data-measuring-cell-key="${CSS.escape(key)}"]`; return (gridRef.current?.querySelector(selector))?.getBoundingClientRect().width; } //#endregion //#region src/hooks/useGridDimensions.ts const initialSize = { inlineSize: 1, blockSize: 1 }; const sizeMap = /* @__PURE__ */ new WeakMap(); const targetToRefMap = /* @__PURE__ */ new WeakMap(); const subscribers = /* @__PURE__ */ new Map(); const resizeObserver = globalThis.ResizeObserver == null ? null : new ResizeObserver(resizeObserverCallback); function resizeObserverCallback(entries) { for (const entry of entries) { const target = entry.target; if (targetToRefMap.has(target)) updateSize(targetToRefMap.get(target), entry.contentBoxSize[0]); } } function updateSize(ref, size) { if (sizeMap.has(ref)) { const prevSize = sizeMap.get(ref); if (prevSize.inlineSize === size.inlineSize && prevSize.blockSize === size.blockSize) return; } sizeMap.set(ref, size); subscribers.get(ref)?.(); } function getServerSnapshot$1() { return initialSize; } function useGridDimensions(gridRef) { const { inlineSize, blockSize } = useSyncExternalStore(useCallback((onStoreChange) => { subscribers.set(gridRef, onStoreChange); return () => { subscribers.delete(gridRef); }; }, [gridRef]), useCallback(() => { return sizeMap.get(gridRef) ?? initialSize; }, [gridRef]), getServerSnapshot$1); useLayoutEffect(() => { const target = gridRef.current; targetToRefMap.set(target, gridRef); resizeObserver?.observe(target); if (!sizeMap.has(gridRef)) updateSize(gridRef, { inlineSize: target.clientWidth, blockSize: target.clientHeight }); return () => { resizeObserver?.unobserve(target); }; }, [gridRef]); return [inlineSize, blockSize]; } //#endregion //#region src/hooks/useLatestFunc.ts function useLatestFunc(fn) { const ref = useRef(fn); useLayoutEffect(() => { ref.current = fn; }); const callbackFn = useCallback((...args) => { ref.current(...args); }, []); return fn ? callbackFn : fn; } //#endregion //#region src/hooks/useRovingTabIndex.ts function useRovingTabIndex(isActive) { const [isChildFocused, setIsChildFocused] = useState(false); if (isChildFocused && !isActive) setIsChildFocused(false); function onFocus(event) { if (event.target === event.currentTarget) { const elementToFocus = event.currentTarget.querySelector("[tabindex=\"0\"]"); if (elementToFocus !== null) { elementToFocus.focus({ preventScroll: true }); setIsChildFocused(true); } else setIsChildFocused(false); } else setIsChildFocused(true); } return { tabIndex: isActive && !isChildFocused ? 0 : -1, childTabIndex: isActive ? 0 : -1, onFocus: isActive ? onFocus : void 0 }; } //#endregion //#region src/hooks/useRowSelection.ts const RowSelectionContext = createContext(void 0); RowSelectionContext.displayName = "RowSelectionContext"; const RowSelectionChangeContext = createContext(void 0); RowSelectionChangeContext.displayName = "RowSelectionChangeContext"; function useRowSelection() { const rowSelectionContext = use(RowSelectionContext); const rowSelectionChangeContext = use(RowSelectionChangeContext); if (rowSelectionContext === void 0 || rowSelectionChangeContext === void 0) throw new Error("useRowSelection must be used within renderCell"); return { isRowSelectionDisabled: rowSelectionContext.isRowSelectionDisabled, isRowSelected: rowSelectionContext.isRowSelected, onRowSelectionChange: rowSelectionChangeContext }; } const HeaderRowSelectionContext = createContext(void 0); HeaderRowSelectionContext.displayName = "HeaderRowSelectionContext"; const HeaderRowSelectionChangeContext = createContext(void 0); HeaderRowSelectionChangeContext.displayName = "HeaderRowSelectionChangeContext"; function useHeaderRowSelection() { const headerRowSelectionContext = use(HeaderRowSelectionContext); const headerRowSelectionChangeContext = use(HeaderRowSelectionChangeContext); if (headerRowSelectionContext === void 0 || headerRowSelectionChangeContext === void 0) throw new Error("useHeaderRowSelection must be used within renderHeaderCell"); return { isIndeterminate: headerRowSelectionContext.isIndeterminate, isRowSelected: headerRowSelectionContext.isRowSelected, onRowSelectionChange: headerRowSelectionChangeContext }; } //#endregion //#region src/hooks/useScrollState.ts const initialScrollState = { scrollTop: 0, scrollLeft: 0 }; function getServerSnapshot() { return initialScrollState; } const scrollStateMap = /* @__PURE__ */ new WeakMap(); function useScrollState(gridRef) { return useSyncExternalStore(useCallback((onStoreChange) => { if (gridRef.current === null) return () => {}; const el = gridRef.current; setScrollState(); function setScrollState() { const { scrollTop } = el; const scrollLeft = abs(el.scrollLeft); const prev = scrollStateMap.get(gridRef) ?? initialScrollState; if (prev.scrollTop === scrollTop && prev.scrollLeft === scrollLeft) return false; scrollStateMap.set(gridRef, { scrollTop, scrollLeft }); return true; } function onScroll() { if (setScrollState()) onStoreChange(); } el.addEventListener("scroll", onScroll); return () => el.removeEventListener("scroll", onScroll); }, [gridRef]), useCallback(() => { return scrollStateMap.get(gridRef) ?? initialScrollState; }, [gridRef]), getServerSnapshot); } //#endregion //#region src/hooks/useScrollToPosition.tsx function useScrollToPosition({ gridRef }) { const [scrollToPosition, setScrollToPosition] = useState(null); return { setScrollToPosition, scrollToPositionElement: scrollToPosition && /* @__PURE__ */ jsx("div", { ref: (div) => { if (div === null) return; const grid = gridRef.current; const { scrollLeft, scrollTop } = grid; scrollIntoView(div, "auto"); if (grid.scrollLeft === scrollLeft && grid.scrollTop === scrollTop) setScrollToPosition(null); }, style: { gridColumn: scrollToPosition.idx == null ? "1/-1" : scrollToPosition.idx + 1, gridRow: scrollToPosition.rowIdx == null ? "1/-1" : scrollToPosition.rowIdx + 1 } }) }; } //#endregion //#region src/hooks/useViewportColumns.ts function useViewportColumns({ columns, colSpanColumns, rows, topSummaryRows, bottomSummaryRows, colOverscanStartIdx, colOverscanEndIdx, lastStartFrozenColumnIndex, firstEndFrozenColumnIndex, rowOverscanStartIdx, rowOverscanEndIdx }) { const startIdx = useMemo(() => { if (colOverscanStartIdx === 0) return 0; function* iterateOverRowsForColSpanArgs() { yield { type: "HEADER" }; if (topSummaryRows != null) for (const row of topSummaryRows) yield { type: "SUMMARY", row }; for (let rowIdx = rowOverscanStartIdx; rowIdx <= rowOverscanEndIdx; rowIdx++) yield { type: "ROW", row: rows[rowIdx] }; if (bottomSummaryRows != null) for (const row of bottomSummaryRows) yield { type: "SUMMARY", row }; } for (const column of colSpanColumns) { if (column.frozen) continue; const colIdx = column.idx; if (colIdx >= colOverscanStartIdx) break; for (const args of iterateOverRowsForColSpanArgs()) { const colSpan = getColSpan(column, lastStartFrozenColumnIndex, firstEndFrozenColumnIndex, args); if (colSpan !== void 0 && colIdx + colSpan > colOverscanStartIdx) return colIdx; } } return colOverscanStartIdx; }, [ rowOverscanStartIdx, rowOverscanEndIdx, rows, topSummaryRows, bottomSummaryRows, colOverscanStartIdx, lastStartFrozenColumnIndex, firstEndFrozenColumnIndex, colSpanColumns ]); const effectiveOverscanEndIdx = firstEndFrozenColumnIndex > -1 ? Math.min(colOverscanEndIdx, firstEndFrozenColumnIndex - 1) : colOverscanEndIdx; const iterateOverViewportColumns = useCallback(function* (activeColumnIdx) { for (let colIdx = 0; colIdx <= lastStartFrozenColumnIndex; colIdx++) yield columns[colIdx]; const unfrozenLastIdx = firstEndFrozenColumnIndex > -1 ? firstEndFrozenColumnIndex - 1 : columns.length - 1; if (lastStartFrozenColumnIndex < unfrozenLastIdx) { if (activeColumnIdx > lastStartFrozenColumnIndex && activeColumnIdx < startIdx) yield columns[activeColumnIdx]; for (let colIdx = startIdx; colIdx <= effectiveOverscanEndIdx; colIdx++) yield columns[colIdx]; if (activeColumnIdx > effectiveOverscanEndIdx && activeColumnIdx <= unfrozenLastIdx) yield columns[activeColumnIdx]; } if (firstEndFrozenColumnIndex > -1) for (let colIdx = firstEndFrozenColumnIndex; colIdx < columns.length; colIdx++) yield columns[colIdx]; }, [ startIdx, effectiveOverscanEndIdx, columns, lastStartFrozenColumnIndex, firstEndFrozenColumnIndex ]); const iterateOverViewportColumnsForRow = useCallback(function* (activeColumnIdx = -1, args) { const iterator = iterateOverViewportColumns(activeColumnIdx); for (const column of iterator) { let colSpan = args && getColSpan(column, lastStartFrozenColumnIndex, firstEndFrozenColumnIndex, args); yield [ column, column.idx === activeColumnIdx, colSpan ]; while (colSpan !== void 0 && colSpan > 1) { iterator.next(); colSpan--; } } }, [ iterateOverViewportColumns, lastStartFrozenColumnIndex, firstEndFrozenColumnIndex ]); const iterateOverViewportColumnsForRowOutsideOfViewport = useCallback(function* (activeColumnIdx = -1, args) { if (activeColumnIdx >= 0 && activeColumnIdx < columns.length) { const column = columns[activeColumnIdx]; yield [ column, true, args && getColSpan(column, lastStartFrozenColumnIndex, firstEndFrozenColumnIndex, args) ]; } }, [ columns, lastStartFrozenColumnIndex, firstEndFrozenColumnIndex ]); return { viewportColumns: useMemo(() => { return iterateOverViewportColumns(-1).toArray(); }, [iterateOverViewportColumns]), iterateOverViewportColumnsForRow, iterateOverViewportColumnsForRowOutsideOfViewport }; } //#endregion //#region src/hooks/useViewportRows.ts function useViewportRows({ rows, rowHeight, clientHeight, scrollTop, enableVirtualization }) { const { totalRowHeight, gridTemplateRows, getRowTop, getRowHeight, findRowIdx } = useMemo(() => { if (typeof rowHeight === "number") return { totalRowHeight: rowHeight * rows.length, gridTemplateRows: ` repeat(${rows.length}, ${rowHeight}px)`, getRowTop: (rowIdx) => rowIdx * rowHeight, getRowHeight: () => rowHeight, findRowIdx: (offset) => floor(offset / rowHeight) }; let totalRowHeight = 0; let gridTemplateRows = ""; let currentHeight = null; let repeatCount = 0; const rowPositions = rows.map((row, index) => { const currentRowHeight = rowHeight(row); const position = { top: totalRowHeight, height: currentRowHeight }; totalRowHeight += currentRowHeight; if (currentHeight === null) { currentHeight = currentRowHeight; repeatCount = 1; } else if (currentHeight === currentRowHeight) repeatCount++; else { if (repeatCount > 1) gridTemplateRows += `repeat(${repeatCount}, ${currentHeight}px) `; else gridTemplateRows += `${currentHeight}px `; currentHeight = currentRowHeight; repeatCount = 1; } if (index === rows.length - 1) if (repeatCount > 1) gridTemplateRows += `repeat(${repeatCount}, ${currentHeight}px)`; else gridTemplateRows += `${currentHeight}px`; return position; }); const validateRowIdx = (rowIdx) => { return max(0, min(rows.length - 1, rowIdx)); }; return { totalRowHeight, gridTemplateRows, getRowTop: (rowIdx) => rowPositions[validateRowIdx(rowIdx)].top, getRowHeight: (rowIdx) => rowPositions[validateRowIdx(rowIdx)].height, findRowIdx(offset) { let start = 0; let end = rowPositions.length - 1; while (start <= end) { const middle = start + floor((end - start) / 2); const currentOffset = rowPositions[middle].top; if (currentOffset === offset) return middle; if (currentOffset < offset) start = middle + 1; else if (currentOffset > offset) end = middle - 1; if (start > end) return end; } return 0; } }; }, [rowHeight, rows]); let rowOverscanStartIdx = 0; let rowOverscanEndIdx = rows.length - 1; if (enableVirtualization) { const overscanThreshold = 4; const rowVisibleStartIdx = findRowIdx(scrollTop); const rowVisibleEndIdx = findRowIdx(scrollTop + clientHeight); rowOverscanStartIdx = max(0, rowVisibleStartIdx - overscanThreshold); rowOverscanEndIdx = min(rows.length - 1, rowVisibleEndIdx + overscanThreshold); } return { rowOverscanStartIdx, rowOverscanEndIdx, totalRowHeight, gridTemplateRows, getRowTop, getRowHeight, findRowIdx }; } //#endregion //#region src/Cell.tsx const cellDraggedOverClassname = `rdg-cell-dragged-over rdg-7-0-0-beta-60-35ccb4c8`; function Cell({ column, colSpan, isCellActive, isDraggedOver, row, rowIdx, className, onMouseDown, onCellMouseDown, onClick, onCellClick, onDoubleClick, onCellDoubleClick, onContextMenu, onCellContextMenu, onRowChange, setActivePosition, style, ...props }) { const { tabIndex, childTabIndex, onFocus } = useRovingTabIndex(isCellActive); const { cellClass } = column; className = getCellClassname(column, isDraggedOver && cellDraggedOverClassname, typeof cellClass === "function" ? cellClass(row) : cellClass, className); const isEditable = isCellEditableUtil(column, row); function setActivePositionWrapper(enableEditor = false) { setActivePosition({ rowIdx, idx: column.idx }, { enableEditor }); } function handleMouseEvent(event, eventHandler) { let eventHandled = false; if (eventHandler) { const cellEvent = createCellEvent(event); eventHandler({ rowIdx, row, column, setActivePosition: setActivePositionWrapper }, cellEvent); eventHandled = cellEvent.isGridDefaultPrevented(); } return eventHandled; } function handleMouseDown(event) { onMouseDown?.(event); if (!handleMouseEvent(event, onCellMouseDown)) setActivePositionWrapper(); } function handleClick(event) { onClick?.(event); handleMouseEvent(event, onCellClick); } function handleDoubleClick(event) { onDoubleClick?.(event); if (!handleMouseEvent(event, onCellDoubleClick)) setActivePositionWrapper(true); } function handleContextMenu(event) { onContextMenu?.(event); handleMouseEvent(event, onCellContextMenu); } function handleRowChange(newRow) { onRowChange(column, rowIdx, newRow); } return /* @__PURE__ */ jsx("div", { role: "gridcell", "aria-colindex": column.idx + 1, "aria-colspan": colSpan, "aria-selected": isCellActive, "aria-readonly": !isEditable || void 0, tabIndex, className, style: { ...getCellStyle(column, colSpan), ...style }, onClick: handleClick, onMouseDown: handleMouseDown, onDoubleClick: handleDoubleClick, onContextMenu: handleContextMenu, onFocus, ...props, children: column.renderCell({ column, row, rowIdx, isCellEditable: isEditable, tabIndex: childTabIndex, onRowChange: handleRowChange }) }); } const CellComponent = memo(Cell); function defaultRenderCell(key, props) { return /* @__PURE__ */ jsx(CellComponent, { ...props }, key); } //#endregion //#region src/EditCell.tsx const canUsePostTask = typeof scheduler === "object" && typeof scheduler.postTask === "function"; const cellEditing = "rdg-7-0-0-beta-60-46f9ea88"; function EditCell({ column, colSpan, row, rowIdx, onRowChange, closeEditor, onKeyDown, navigate }) { const captureEventRef = useRef(void 0); const abortControllerRef = useRef(void 0); const frameRequestRef = useRef(void 0); const commitOnOutsideClick = column.editorOptions?.commitOnOutsideClick ?? true; const commitOnOutsideMouseDown = useEffectEvent(() => { onClose(true, false); }); useLayoutEffect(() => { if (!commitOnOutsideClick) return; function onWindowCaptureMouseDown(event) { captureEventRef.current = event; if (canUsePostTask) { const abortController = new AbortController(); const { signal } = abortController; abortControllerRef.current = abortController; scheduler.postTask(commitOnOutsideMouseDown, { priority: "user-blocking", signal }).catch(() => {}); } else frameRequestRef.current = requestAnimationFrame(commitOnOutsideMouseDown); } function onWindowMouseDown(event) { if (captureEventRef.current === event) commitOnOutsideMouseDown(); } window.addEventListener("mousedown", onWindowCaptureMouseDown, { capture: true }); window.addEventListener("mousedown", onWindowMouseDown); return () => { window.removeEventListener("mousedown", onWindowCaptureMouseDown, { capture: true }); window.removeEventListener("mousedown", onWindowMouseDown); cancelTask(); }; }, [commitOnOutsideClick]); function cancelTask() { captureEventRef.current = void 0; if (abortControllerRef.current !== void 0) { abortControllerRef.current.abort(); abortControllerRef.current = void 0; } if (frameRequestRef.current !== void 0) { cancelAnimationFrame(frameRequestRef.current); frameRequestRef.current = void 0; } } function handleKeyDown(event) { if (onKeyDown) { const cellEvent = createCellEvent(event); onKeyDown({ mode: "EDIT", row, column, rowIdx, navigate() { navigate(event); }, onClose }, cellEvent); if (cellEvent.isGridDefaultPrevented()) return; } if (event.key === "Escape") onClose(); else if (event.key === "Enter") onClose(true); else if (onEditorNavigation(event)) navigate(event); } function onClose(commitChanges = false, shouldFocus = true) { if (commitChanges) onRowChange(row, true, shouldFocus); else closeEditor(shouldFocus); } function onEditorRowChange(row, commitChangesAndFocus = false) { onRowChange(row, commitChangesAndFocus, commitChangesAndFocus); } const { cellClass } = column; const className = getCellClassname(column, "rdg-editor-container", !column.editorOptions?.displayCellContent && cellEditing, typeof cellClass === "function" ? cellClass(row) : cellClass); return /* @__PURE__ */ jsx("div", { role: "gridcell", "aria-colindex": column.idx + 1, "aria-colspan": colSpan, "aria-selected": true, className, style: getCellStyle(column, colSpan), onKeyDown: handleKeyDown, onMouseDownCapture: cancelTask, children: column.renderEditCell != null && /* @__PURE__ */ jsxs(Fragment, { children: [column.renderEditCell({ column, row, rowIdx, onRowChange: onEditorRowChange, onClose }), column.editorOptions?.displayCellContent && column.renderCell({ column, row, rowIdx, isCellEditable: true, tabIndex: -1, onRowChange: onEditorRowChange })] }) }); } //#endregion //#region src/GroupedColumnHeaderCell.tsx function GroupedColumnHeaderCell({ column, rowIdx, isCellActive, setPosition }) { const { tabIndex, onFocus } = useRovingTabIndex(isCellActive); const { colSpan } = column; const rowSpan = getHeaderCellRowSpan(column, rowIdx); const index = column.idx + 1; function onMouseDown() { setPosition({ idx: column.idx, rowIdx }); } return /* @__PURE__ */ jsx("div", { role: "columnheader", "aria-colindex": index, "aria-colspan": colSpan, "aria-rowspan": rowSpan, "aria-selected": isCellActive, tabIndex, className: classnames(cellClassname, column.headerCellClass), style: { ...getHeaderCellStyle(column, rowIdx, rowSpan), gridColumnStart: index, gridColumnEnd: index + colSpan }, onFocus, onMouseDown, children: column.name }); } //#endregion //#region src/HeaderCell.tsx const cellSortableClassname = "rdg-7-0-0-beta-60-2a7e240d"; const cellResizableClassname = `rdg-cell-resizable rdg-7-0-0-beta-60-1893dc0f`; const resizeHandleClassname = `rdg-resize-handle rdg-7-0-0-beta-60-4e60db91`; const cellDraggableClassname = "rdg-cell-draggable"; const cellDraggingOrOver = "rdg-7-0-0-beta-60-f2d18717"; const cellDraggingClassname = `rdg-cell-dragging ${cellDraggingOrOver}`; const cellOverClassname = `rdg-cell-drag-over ${cellDraggingOrOver}`; const dragImageClassname = "rdg-7-0-0-beta-60-3d12c7ae"; function HeaderCell({ column, colSpan, rowIdx, isCellActive, onColumnResize, onColumnResizeEnd, onColumnsReorder, sortColumns, onSortColumnsChange, setPosition, shouldFocusGrid, direction, draggedColumnKey, setDraggedColumnKey }) { const [isOver, setIsOver] = useState(false); const dragImageRef = useRef(null); const isDragging = draggedColumnKey === column.key; const rowSpan = getHeaderCellRowSpan(column, rowIdx); const { tabIndex, childTabIndex, onFocus } = useRovingTabIndex(shouldFocusGrid || isCellActive); const sortIndex = sortColumns?.findIndex((sort) => sort.columnKey === column.key); const sortColumn = sortIndex !== void 0 && sortIndex > -1 ? sortColumns[sortIndex] : void 0; const sortDirection = sortColumn?.direction; const priority = sortColumn !== void 0 && sortColumns.length > 1 ? sortIndex + 1 : void 0; const ariaSort = sortDirection && !priority ? sortDirection === "ASC" ? "ascending" : "descending" : void 0; const { sortable, resizable, draggable } = column; const className = getCel