mirror of
https://github.com/jeffvli/feishin.git
synced 2026-06-17 08:54:27 +02:00
split out item list table functionality
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
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,
|
||||
],
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user