summaryrefslogtreecommitdiff
path: root/hooks/useAutoSizeColumns.ts
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-03-26 00:37:41 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-03-26 00:37:41 +0000
commite0dfb55c5457aec489fc084c4567e791b4c65eb1 (patch)
tree68543a65d88f5afb3a0202925804103daa91bc6f /hooks/useAutoSizeColumns.ts
3/25 까지의 대표님 작업사항
Diffstat (limited to 'hooks/useAutoSizeColumns.ts')
-rw-r--r--hooks/useAutoSizeColumns.ts86
1 files changed, 86 insertions, 0 deletions
diff --git a/hooks/useAutoSizeColumns.ts b/hooks/useAutoSizeColumns.ts
new file mode 100644
index 00000000..3750de97
--- /dev/null
+++ b/hooks/useAutoSizeColumns.ts
@@ -0,0 +1,86 @@
+// hooks/useAutoSizeColumns.ts
+import { useEffect, useRef } from "react"
+import { Table } from "@tanstack/react-table"
+
+export function useAutoSizeColumns<T>(
+ table: Table<T>,
+ 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<string, number> = {}
+
+ // 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 } }
+} \ No newline at end of file