( panelCount: number, sizes: readonly number[], available: number, sizeMode: "percent" | "absolute", dividerSize: number = DEFAULT_DIVIDER_SIZE, minSizes?: readonly number[], maxSizes?: readonly number[], )
| 140 | * @param maxSizes - Maximum sizes per panel (cells) |
| 141 | */ |
| 142 | export function computePanelCellSizes( |
| 143 | panelCount: number, |
| 144 | sizes: readonly number[], |
| 145 | available: number, |
| 146 | sizeMode: "percent" | "absolute", |
| 147 | dividerSize: number = DEFAULT_DIVIDER_SIZE, |
| 148 | minSizes?: readonly number[], |
| 149 | maxSizes?: readonly number[], |
| 150 | ): PanelSizes { |
| 151 | if (panelCount <= 0) { |
| 152 | return Object.freeze({ sizes: Object.freeze([]), dividerPositions: Object.freeze([]) }); |
| 153 | } |
| 154 | |
| 155 | const totalDividerSpace = Math.max(0, panelCount - 1) * dividerSize; |
| 156 | const availableForPanels = Math.max(0, available - totalDividerSpace); |
| 157 | |
| 158 | const cellSizes = new Array<number>(panelCount); |
| 159 | const percentWeights = new Array<number>(panelCount).fill(0); |
| 160 | for (let i = 0; i < panelCount; i++) { |
| 161 | const rawSizeSpec = sizes[i]; |
| 162 | const sizeSpec = Number.isFinite(rawSizeSpec) |
| 163 | ? (rawSizeSpec as number) |
| 164 | : sizeMode === "percent" |
| 165 | ? 100 / panelCount |
| 166 | : Math.floor(availableForPanels / panelCount); |
| 167 | |
| 168 | if (sizeMode === "percent") { |
| 169 | percentWeights[i] = sizeSpec > 0 ? sizeSpec : 0; |
| 170 | } else { |
| 171 | cellSizes[i] = Math.max(0, Math.trunc(sizeSpec)); |
| 172 | } |
| 173 | } |
| 174 | |
| 175 | if (sizeMode === "percent") { |
| 176 | const distributed = distributeInteger(availableForPanels, percentWeights); |
| 177 | for (let i = 0; i < panelCount; i++) { |
| 178 | cellSizes[i] = distributed[i] ?? 0; |
| 179 | } |
| 180 | } |
| 181 | |
| 182 | normalizePanelCellSizes(cellSizes, availableForPanels, minSizes, maxSizes); |
| 183 | |
| 184 | const dividerPositions: number[] = []; |
| 185 | let position = 0; |
| 186 | for (let j = 0; j < cellSizes.length - 1; j++) { |
| 187 | position += cellSizes[j] ?? 0; |
| 188 | dividerPositions.push(position); |
| 189 | position += dividerSize; |
| 190 | } |
| 191 | |
| 192 | return Object.freeze({ |
| 193 | sizes: Object.freeze(cellSizes), |
| 194 | dividerPositions: Object.freeze(dividerPositions), |
| 195 | }); |
| 196 | } |
| 197 | |
| 198 | /** |
| 199 | * Handle divider drag to resize panels. |
no test coverage detected