import { useMemo } from 'react'; import { parseTableColumns } from '/@/renderer/components/item-list/helpers/parse-table-columns'; import { ItemTableListColumnConfig } from '/@/renderer/components/item-list/types'; export const useTableColumnModel = ({ autoFitColumns, centerContainerWidth, columns, totalContainerWidth, }: { autoFitColumns: boolean; centerContainerWidth: number; columns: ItemTableListColumnConfig[]; totalContainerWidth: number; }) => { const parsedColumns = useMemo(() => parseTableColumns(columns), [columns]); const calculatedColumnWidths = useMemo(() => { const baseWidths = parsedColumns.map((c) => c.width); // When autoSizeColumns is enabled, treat all widths as proportions and scale to fit container if (autoFitColumns) { const totalReferenceWidth = baseWidths.reduce((sum, width) => sum + width, 0); if (totalReferenceWidth === 0 || totalContainerWidth === 0) { return baseWidths.map((width) => Math.round(width)); } const scaleFactor = totalContainerWidth / totalReferenceWidth; const scaledWidths = baseWidths.map((width) => Math.round(width * scaleFactor)); // Adjust for rounding errors: ensure total equals totalContainerWidth const totalScaled = scaledWidths.reduce((sum, width) => sum + width, 0); const difference = totalContainerWidth - totalScaled; if (difference !== 0 && scaledWidths.length > 0) { const sortedIndices = scaledWidths .map((width, idx) => ({ idx, width })) .sort((a, b) => b.width - a.width); const adjustmentPerColumn = Math.sign(difference); const adjustmentCount = Math.abs(difference); for (let i = 0; i < adjustmentCount && i < sortedIndices.length; i++) { scaledWidths[sortedIndices[i].idx] += adjustmentPerColumn; } } return scaledWidths; } // Original behavior: distribute extra space to auto-size columns const distributed = baseWidths.slice(); const unpinnedIndices: number[] = []; const autoUnpinnedIndices: number[] = []; parsedColumns.forEach((col, idx) => { if (col.pinned === null) { unpinnedIndices.push(idx); if (col.autoSize) { autoUnpinnedIndices.push(idx); } } }); if (unpinnedIndices.length === 0 || autoUnpinnedIndices.length === 0) { return distributed.map((width) => Math.round(width)); } const unpinnedBaseTotal = unpinnedIndices.reduce((sum, idx) => sum + baseWidths[idx], 0); const extra = Math.max(0, centerContainerWidth - unpinnedBaseTotal); if (extra <= 0) { return distributed.map((width) => Math.round(width)); } const extraPer = extra / autoUnpinnedIndices.length; autoUnpinnedIndices.forEach((idx) => { distributed[idx] = Math.round(baseWidths[idx] + extraPer); }); return distributed.map((width) => Math.round(width)); }, [autoFitColumns, centerContainerWidth, parsedColumns, totalContainerWidth]); const pinnedLeftColumnCount = useMemo( () => parsedColumns.filter((col) => col.pinned === 'left').length, [parsedColumns], ); const pinnedRightColumnCount = useMemo( () => parsedColumns.filter((col) => col.pinned === 'right').length, [parsedColumns], ); const columnCount = parsedColumns.length; const totalColumnCount = columnCount - pinnedLeftColumnCount - pinnedRightColumnCount; return useMemo( () => ({ calculatedColumnWidths, columnCount, parsedColumns, pinnedLeftColumnCount, pinnedRightColumnCount, totalColumnCount, }), [ calculatedColumnWidths, columnCount, parsedColumns, pinnedLeftColumnCount, pinnedRightColumnCount, totalColumnCount, ], ); };