// hooks/useAutoSizeColumns.ts import { useEffect, useRef } from "react" import { Table } from "@tanstack/react-table" export function useAutoSizeColumns( table: Table, enabled: boolean = true ) { const hasResized = useRef(false) useEffect(() => { if (!enabled || hasResized.current) return // Wait for the table to render const timer = setTimeout(() => { const calculateColumnWidths = () => { const defaultMinWidth = 80 const defaultPadding = 24 const newColumnSizing: Record = {} // Process each visible column table.getAllColumns().forEach(column => { if (column.id === 'select' || column.id === 'actions') { // Fixed width for utility columns newColumnSizing[column.id] = column.id === 'select' ? 40 : 60 return } const columnId = column.id // Get column-specific padding from meta if available const paddingFactor = column.columnDef.meta?.paddingFactor as number || 1 const extraPadding = paddingFactor * defaultPadding // Get all cells for this column const headerElement = document.querySelector(`th[data-column-id="${columnId}"]`) const cells = document.querySelectorAll(`tbody td[data-column-id="${columnId}"]`) // Create measuring element const measureElement = document.createElement('div') measureElement.style.position = 'absolute' measureElement.style.visibility = 'hidden' measureElement.style.whiteSpace = 'nowrap' measureElement.style.font = headerElement ? window.getComputedStyle(headerElement).font : window.getComputedStyle(document.body).font document.body.appendChild(measureElement) // Measure header const headerText = headerElement?.textContent || "" measureElement.textContent = headerText let maxWidth = measureElement.getBoundingClientRect().width // Measure cells (limit to first 20 for performance) Array.from(cells).slice(0, 20).forEach(cell => { const cellText = cell.textContent || "" measureElement.textContent = cellText const cellWidth = measureElement.getBoundingClientRect().width maxWidth = Math.max(maxWidth, cellWidth) }) // Clean up measuring element document.body.removeChild(measureElement) // Calculate final width let finalWidth = maxWidth + extraPadding const minWidth = column.columnDef.minSize || defaultMinWidth finalWidth = Math.max(finalWidth, minWidth) // Add to sizing object newColumnSizing[columnId] = finalWidth }) // Apply all column sizes at once table.setColumnSizing(newColumnSizing) hasResized.current = true } calculateColumnWidths() }, 100) // Short delay to ensure DOM is ready return () => clearTimeout(timer) }, [table, enabled]) return { resetAutoSize: () => { hasResized.current = false } } }