import type { GridEditorCell, GridZone } from './types' import { MIN_ROW_HEIGHT } from './gridTableConstants' /** Dominant non-black color from a cell's word_boxes, or null. * `color_override` takes priority when set. */ export function getCellColor(cell: GridEditorCell | undefined): string | null { if (!cell) return null // Manual override: explicit color or null (= "clear color bar") if (cell.color_override !== undefined) return cell.color_override ?? null if (!cell.word_boxes?.length) return null for (const wb of cell.word_boxes) { if (wb.color_name && wb.color_name !== 'black' && wb.color) { return wb.color } } return null } /** Compute the rendered height for a row in px. */ export function getRowHeight( zone: GridZone, rowIndex: number, isHeader: boolean, avgRowHeightPx: number, scale: number, ): number { const row = zone.rows.find((r) => r.index === rowIndex) if (!row) return Math.max(MIN_ROW_HEIGHT, avgRowHeightPx * scale) // Multi-line cells (containing \n): expand height based on line count const rowCells = zone.cells.filter((c) => c.row_index === rowIndex) const maxLines = Math.max(1, ...rowCells.map((c) => (c.text ?? '').split('\n').length)) if (maxLines > 1) { const lineH = Math.max(MIN_ROW_HEIGHT, avgRowHeightPx * scale) return lineH * maxLines } if (isHeader) { const measuredH = row.y_max_px - row.y_min_px return Math.max(MIN_ROW_HEIGHT, measuredH * scale) } return Math.max(MIN_ROW_HEIGHT, avgRowHeightPx * scale) }