| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| export const PANELS_GRID_MIN_TRACK_PX = 280; |
| |
| export const MAX_PANEL_ROW_SPAN = 4; |
| |
| export const MAX_PANEL_COL_SPAN = 3; |
|
|
| function getPanelGrid(element: HTMLElement): HTMLElement | null { |
| return (element.closest('.panels-grid') || element.closest('.map-bottom-grid')) as HTMLElement | null; |
| } |
|
|
| function getPanelGridWidth(grid: HTMLElement): number { |
| const width = grid.getBoundingClientRect().width; |
| return Number.isFinite(width) ? width : 0; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| export function isPanelGridColumnCountReady(element: HTMLElement): boolean { |
| const grid = getPanelGrid(element); |
| if (!grid || typeof window === 'undefined' || typeof window.getComputedStyle !== 'function') return true; |
|
|
| const style = window.getComputedStyle(grid); |
| const template = style.gridTemplateColumns; |
| if (!template || template === 'none' || !template.includes('repeat(')) return true; |
| if (/repeat\(\s*\d+\s*,/i.test(template)) return true; |
| if (/repeat\(\s*auto-(fill|fit)\s*,/i.test(template)) { |
| return getPanelGridWidth(grid) > 0; |
| } |
| return true; |
| } |
|
|
| |
| |
| |
| |
| |
| export function getGridColumnCount(element: HTMLElement): number { |
| const grid = getPanelGrid(element); |
| if (!grid || typeof window === 'undefined' || typeof window.getComputedStyle !== 'function') return MAX_PANEL_COL_SPAN; |
| const style = window.getComputedStyle(grid); |
| const template = style.gridTemplateColumns; |
| if (!template || template === 'none') return MAX_PANEL_COL_SPAN; |
|
|
| if (template.includes('repeat(')) { |
| const repeatCountMatch = template.match(/repeat\(\s*(\d+)\s*,/i); |
| if (repeatCountMatch) { |
| const parsed = Number.parseInt(repeatCountMatch[1] ?? '0', 10); |
| if (Number.isFinite(parsed) && parsed > 0) return parsed; |
| } |
|
|
| |
| const autoRepeatMatch = template.match(/repeat\(\s*auto-(fill|fit)\s*,/i); |
| if (autoRepeatMatch) { |
| const gap = Number.parseFloat(style.columnGap || '0') || 0; |
| const width = getPanelGridWidth(grid); |
| if (width > 0) { |
| return Math.max(1, Math.floor((width + gap) / (PANELS_GRID_MIN_TRACK_PX + gap))); |
| } |
| return MAX_PANEL_COL_SPAN; |
| } |
| } |
|
|
| const columns = template.trim().split(/\s+/).filter(Boolean); |
| return columns.length > 0 ? columns.length : MAX_PANEL_COL_SPAN; |
| } |
|
|
| |
| export function getMaxColSpan(element: HTMLElement): number { |
| return Math.max(1, Math.min(MAX_PANEL_COL_SPAN, getGridColumnCount(element))); |
| } |
|
|
| |
| export function clampColSpan(span: number, maxSpan: number): number { |
| return Math.max(1, Math.min(maxSpan, span)); |
| } |
|
|
| |
| |
| |
| |
| export function getExplicitColSpanClass(element: HTMLElement): number | undefined { |
| if (element.classList.contains('col-span-3')) return 3; |
| if (element.classList.contains('col-span-2')) return 2; |
| if (element.classList.contains('col-span-1')) return 1; |
| return undefined; |
| } |
|
|
| |
| export function clearColSpanClass(element: HTMLElement): void { |
| element.classList.remove('col-span-1', 'col-span-2', 'col-span-3'); |
| } |
|
|
| |
| export function setColSpanClass(element: HTMLElement, span: number): void { |
| clearColSpanClass(element); |
| element.classList.add(`col-span-${span}`); |
| } |
|
|