in src/data-table/measure-column-widths.tsx [114:190]
export default function MeasureColumnWidths({
columns,
rows,
widths,
isSelectable,
onWidthsChange,
}: MeasureColumnWidthsProps) {
const [css] = useStyletron();
const widthMap = React.useMemo(() => {
return new Map();
}, [rows]);
const sampleSize = rows.length < MAX_SAMPLE_SIZE ? rows.length : MAX_SAMPLE_SIZE;
const finishedMeasurementCount = (sampleSize + 1) * columns.length;
const sampleIndexes = React.useMemo<number[]>(() => {
return generateSampleIndices(0, rows.length - 1, sampleSize);
}, [columns, rows, widths, sampleSize]);
const handleDimensionsChange = React.useCallback(
(columnIndex: number, dimensions: { width: number; height: number }) => {
const nextWidth = Math.min(
Math.max(
columns[columnIndex].minWidth || 0,
widthMap.get(columnIndex) || 0,
dimensions.width + 1
),
columns[columnIndex].maxWidth || Infinity
);
if (nextWidth !== widthMap.get(columnIndex)) {
widthMap.set(columnIndex, nextWidth);
}
if (
// Refresh at 100% of done
widthMap.size === columns.length ||
// ...50%
widthMap.size === Math.floor(columns.length / 2) ||
// ...25%
widthMap.size === Math.floor(columns.length / 4)
) {
onWidthsChange(Array.from(widthMap.values()));
}
},
[columns, rows, finishedMeasurementCount, onWidthsChange]
);
const hiddenStyle = css({
position: 'absolute',
overflow: 'hidden',
height: 0,
});
// Remove the measurement nodes after we are done updating our column width
if (widthMap.size === columns.length) {
return null;
}
return (
<div className={hiddenStyle} aria-hidden="true" role="none">
{columns.map((column, i) => {
return (
<MeasureColumn
key={column.title + i}
column={column}
rows={rows}
isSelectable={isSelectable}
onLayout={handleDimensionsChange}
columnIndex={i}
sampleIndexes={sampleIndexes}
/>
);
})}
</div>
);
}