( items: T[], availableWidth: number, )
| 27 | const COLUMN_GAP = 1 |
| 28 | |
| 29 | export function computeGridLayout<T>( |
| 30 | items: T[], |
| 31 | availableWidth: number, |
| 32 | ): GridLayoutResult<T> { |
| 33 | // Force single column for very narrow terminals where multi-column wouldn't fit |
| 34 | const minWidthForTwoColumns = MIN_COLUMN_WIDTH * 2 + COLUMN_GAP |
| 35 | if (availableWidth < minWidthForTwoColumns) { |
| 36 | return { |
| 37 | columns: 1, |
| 38 | columnWidth: Math.max(1, availableWidth), |
| 39 | columnGroups: [items], |
| 40 | } |
| 41 | } |
| 42 | |
| 43 | // Determine max columns from width thresholds |
| 44 | const maxColumns = WIDTH_THRESHOLDS.filter(t => availableWidth >= t).length + 1 |
| 45 | |
| 46 | const columns = computeSmartColumns(items.length, maxColumns) |
| 47 | |
| 48 | let columnWidth: number |
| 49 | if (columns === 1) { |
| 50 | columnWidth = availableWidth |
| 51 | } else { |
| 52 | const totalGap = columns - 1 |
| 53 | const rawWidth = Math.floor((availableWidth - totalGap) / columns) |
| 54 | columnWidth = Math.max(MIN_COLUMN_WIDTH, rawWidth) |
| 55 | } |
| 56 | |
| 57 | const columnGroups: T[][] = Array.from({ length: columns }, () => []) |
| 58 | items.forEach((item, idx) => { |
| 59 | columnGroups[idx % columns].push(item) |
| 60 | }) |
| 61 | |
| 62 | return { columns, columnWidth, columnGroups } |
| 63 | } |
| 64 | |
| 65 | export function useGridLayout<T>( |
| 66 | items: T[], |
no test coverage detected