wandertable 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +505 -0
  3. package/dist/style.css +1 -0
  4. package/dist/types/WanderTable.d.ts +112 -0
  5. package/dist/types/WanderTable.d.ts.map +1 -0
  6. package/dist/types/__tests__/ColumnModel.test.d.ts +2 -0
  7. package/dist/types/__tests__/ColumnModel.test.d.ts.map +1 -0
  8. package/dist/types/__tests__/CommandBus.test.d.ts +2 -0
  9. package/dist/types/__tests__/CommandBus.test.d.ts.map +1 -0
  10. package/dist/types/__tests__/DataModel.test.d.ts +2 -0
  11. package/dist/types/__tests__/DataModel.test.d.ts.map +1 -0
  12. package/dist/types/__tests__/Export.test.d.ts +2 -0
  13. package/dist/types/__tests__/Export.test.d.ts.map +1 -0
  14. package/dist/types/__tests__/GroupedHeaders.test.d.ts +2 -0
  15. package/dist/types/__tests__/GroupedHeaders.test.d.ts.map +1 -0
  16. package/dist/types/__tests__/MergeModel.test.d.ts +2 -0
  17. package/dist/types/__tests__/MergeModel.test.d.ts.map +1 -0
  18. package/dist/types/__tests__/SelectionModel.test.d.ts +2 -0
  19. package/dist/types/__tests__/SelectionModel.test.d.ts.map +1 -0
  20. package/dist/types/__tests__/ViewMapping.test.d.ts +2 -0
  21. package/dist/types/__tests__/ViewMapping.test.d.ts.map +1 -0
  22. package/dist/types/columns/ColumnModel.d.ts +25 -0
  23. package/dist/types/columns/ColumnModel.d.ts.map +1 -0
  24. package/dist/types/columns/GroupedHeaders.d.ts +20 -0
  25. package/dist/types/columns/GroupedHeaders.d.ts.map +1 -0
  26. package/dist/types/core/CommandBus.d.ts +63 -0
  27. package/dist/types/core/CommandBus.d.ts.map +1 -0
  28. package/dist/types/core/DataModel.d.ts +27 -0
  29. package/dist/types/core/DataModel.d.ts.map +1 -0
  30. package/dist/types/core/EventEmitter.d.ts +10 -0
  31. package/dist/types/core/EventEmitter.d.ts.map +1 -0
  32. package/dist/types/core/MergeModel.d.ts +35 -0
  33. package/dist/types/core/MergeModel.d.ts.map +1 -0
  34. package/dist/types/core/PaginationModel.d.ts +24 -0
  35. package/dist/types/core/PaginationModel.d.ts.map +1 -0
  36. package/dist/types/core/RowGroupModel.d.ts +36 -0
  37. package/dist/types/core/RowGroupModel.d.ts.map +1 -0
  38. package/dist/types/core/SelectionModel.d.ts +47 -0
  39. package/dist/types/core/SelectionModel.d.ts.map +1 -0
  40. package/dist/types/core/ViewMapping.d.ts +37 -0
  41. package/dist/types/core/ViewMapping.d.ts.map +1 -0
  42. package/dist/types/core/ViewportModel.d.ts +9 -0
  43. package/dist/types/core/ViewportModel.d.ts.map +1 -0
  44. package/dist/types/editors/BlankEditor.d.ts +20 -0
  45. package/dist/types/editors/BlankEditor.d.ts.map +1 -0
  46. package/dist/types/editors/DropdownEditor.d.ts +23 -0
  47. package/dist/types/editors/DropdownEditor.d.ts.map +1 -0
  48. package/dist/types/editors/EditorManager.d.ts +22 -0
  49. package/dist/types/editors/EditorManager.d.ts.map +1 -0
  50. package/dist/types/index.d.ts +35 -0
  51. package/dist/types/index.d.ts.map +1 -0
  52. package/dist/types/interaction/ClipboardManager.d.ts +19 -0
  53. package/dist/types/interaction/ClipboardManager.d.ts.map +1 -0
  54. package/dist/types/interaction/ColumnReorder.d.ts +20 -0
  55. package/dist/types/interaction/ColumnReorder.d.ts.map +1 -0
  56. package/dist/types/interaction/ColumnResize.d.ts +15 -0
  57. package/dist/types/interaction/ColumnResize.d.ts.map +1 -0
  58. package/dist/types/interaction/FillHandle.d.ts +39 -0
  59. package/dist/types/interaction/FillHandle.d.ts.map +1 -0
  60. package/dist/types/interaction/KeyboardNav.d.ts +19 -0
  61. package/dist/types/interaction/KeyboardNav.d.ts.map +1 -0
  62. package/dist/types/interaction/RowResize.d.ts +15 -0
  63. package/dist/types/interaction/RowResize.d.ts.map +1 -0
  64. package/dist/types/plugins/ContextMenu.d.ts +44 -0
  65. package/dist/types/plugins/ContextMenu.d.ts.map +1 -0
  66. package/dist/types/plugins/Export.d.ts +16 -0
  67. package/dist/types/plugins/Export.d.ts.map +1 -0
  68. package/dist/types/render/AutoFit.d.ts +23 -0
  69. package/dist/types/render/AutoFit.d.ts.map +1 -0
  70. package/dist/types/render/DOMRenderer.d.ts +91 -0
  71. package/dist/types/render/DOMRenderer.d.ts.map +1 -0
  72. package/dist/types/render/LoadingOverlay.d.ts +9 -0
  73. package/dist/types/render/LoadingOverlay.d.ts.map +1 -0
  74. package/dist/types/render/PaginationBar.d.ts +20 -0
  75. package/dist/types/render/PaginationBar.d.ts.map +1 -0
  76. package/dist/types/renderers/BadgeRenderer.d.ts +5 -0
  77. package/dist/types/renderers/BadgeRenderer.d.ts.map +1 -0
  78. package/dist/types/renderers/BlankRenderer.d.ts +9 -0
  79. package/dist/types/renderers/BlankRenderer.d.ts.map +1 -0
  80. package/dist/types/renderers/CheckboxRenderer.d.ts +5 -0
  81. package/dist/types/renderers/CheckboxRenderer.d.ts.map +1 -0
  82. package/dist/types/renderers/NumberRenderer.d.ts +7 -0
  83. package/dist/types/renderers/NumberRenderer.d.ts.map +1 -0
  84. package/dist/types/renderers/ProgressRenderer.d.ts +5 -0
  85. package/dist/types/renderers/ProgressRenderer.d.ts.map +1 -0
  86. package/dist/types/renderers/RendererRegistry.d.ts +10 -0
  87. package/dist/types/renderers/RendererRegistry.d.ts.map +1 -0
  88. package/dist/types/renderers/TextRenderer.d.ts +5 -0
  89. package/dist/types/renderers/TextRenderer.d.ts.map +1 -0
  90. package/dist/types/rows/RowModel.d.ts +20 -0
  91. package/dist/types/rows/RowModel.d.ts.map +1 -0
  92. package/dist/types/themes.d.ts +5 -0
  93. package/dist/types/themes.d.ts.map +1 -0
  94. package/dist/types/types/index.d.ts +348 -0
  95. package/dist/types/types/index.d.ts.map +1 -0
  96. package/dist/wandertable.cjs +14 -0
  97. package/dist/wandertable.cjs.map +1 -0
  98. package/dist/wandertable.global.js +14 -0
  99. package/dist/wandertable.global.js.map +1 -0
  100. package/dist/wandertable.js +2757 -0
  101. package/dist/wandertable.js.map +1 -0
  102. package/dist/wandertable.umd.js +14 -0
  103. package/dist/wandertable.umd.js.map +1 -0
  104. package/package.json +36 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wandertable.umd.js","sources":["../src/types/index.ts","../src/core/DataModel.ts","../src/core/EventEmitter.ts","../src/core/SelectionModel.ts","../src/core/CommandBus.ts","../src/columns/ColumnModel.ts","../src/rows/RowModel.ts","../src/render/DOMRenderer.ts","../src/render/AutoFit.ts","../src/renderers/TextRenderer.ts","../src/renderers/CheckboxRenderer.ts","../src/renderers/BadgeRenderer.ts","../src/renderers/NumberRenderer.ts","../src/renderers/ProgressRenderer.ts","../src/renderers/BlankRenderer.ts","../src/renderers/RendererRegistry.ts","../src/editors/EditorManager.ts","../src/interaction/KeyboardNav.ts","../src/interaction/ClipboardManager.ts","../src/interaction/ColumnResize.ts","../src/interaction/RowResize.ts","../src/plugins/ContextMenu.ts","../src/interaction/FillHandle.ts","../src/interaction/ColumnReorder.ts","../src/core/RowGroupModel.ts","../src/core/ViewMapping.ts","../src/core/MergeModel.ts","../src/core/PaginationModel.ts","../src/columns/GroupedHeaders.ts","../src/render/PaginationBar.ts","../src/render/LoadingOverlay.ts","../src/plugins/Export.ts","../src/WanderTable.ts","../src/editors/DropdownEditor.ts","../src/editors/BlankEditor.ts","../src/themes.ts"],"sourcesContent":["// ── Cell ──\n\nexport type CellKey = `${number}:${number}`;\n\nexport interface CellStyle {\n bgColor?: string;\n textColor?: string;\n fontWeight?: 'normal' | 'bold';\n fontStyle?: 'normal' | 'italic';\n textAlign?: 'left' | 'center' | 'right';\n borderLeft?: string;\n borderRight?: string;\n borderTop?: string;\n borderBottom?: string;\n padding?: number;\n}\n\nexport interface CellData {\n value: unknown;\n meta?: Record<string, unknown>;\n type?: string;\n readOnly?: boolean;\n className?: string;\n style?: CellStyle;\n}\n\nexport interface CellPatch {\n row: number;\n col: number;\n data: Partial<CellData>;\n}\n\nexport interface CellState {\n selected: boolean;\n focused: boolean;\n editing: boolean;\n hover: boolean;\n}\n\nexport interface CellBounds {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n// ── Selection ──\n\nexport interface SelectionRange {\n startRow: number;\n startCol: number;\n endRow: number;\n endCol: number;\n}\n\nexport interface CellAddress {\n row: number;\n col: number;\n}\n\nexport interface SelectionInfo {\n /** Currently focused cell */\n focus: CellAddress | null;\n /** All selection ranges */\n ranges: SelectionRange[];\n /** Normalized bounding box (min/max) across all ranges */\n bounds: { startRow: number; startCol: number; endRow: number; endCol: number } | null;\n /** Total number of cells in the selection */\n cellCount: number;\n /** Number of ranges (1 = single range, >1 = multi-select with Ctrl) */\n rangeCount: number;\n /** Whether more than one cell is selected */\n isMultiCell: boolean;\n /** Whether the selection spans an entire row (all columns) */\n isFullRow: boolean;\n /** Whether the selection spans an entire column (all rows) */\n isFullCol: boolean;\n /** Whether everything is selected */\n isAll: boolean;\n /** Whether nothing is selected */\n isEmpty: boolean;\n /** Number of rows spanned */\n rowSpan: number;\n /** Number of columns spanned */\n colSpan: number;\n}\n\n// ── Column ──\n\nexport interface DropdownOption {\n value: unknown;\n label: string;\n icon?: string;\n disabled?: boolean;\n group?: string;\n}\n\nexport interface DropdownConfig {\n options?: DropdownOption[];\n source?: (query: string, row: number, col: number) => Promise<DropdownOption[]>;\n multiple?: boolean;\n searchable?: boolean;\n placeholder?: string;\n renderOption?: (option: DropdownOption, el: HTMLElement) => void;\n}\n\nexport interface ColumnConfig {\n key?: string;\n label?: string;\n width?: number;\n minWidth?: number;\n maxWidth?: number;\n type?: string;\n editor?: string;\n readOnly?: boolean;\n sortable?: boolean;\n filterable?: boolean;\n dropdown?: DropdownConfig;\n align?: 'left' | 'center' | 'right';\n frozen?: boolean;\n /** Grouped/nested columns (table mode). Creates a multi-level header. */\n children?: ColumnConfig[];\n}\n\n// ── Row ──\n\nexport interface RowConfig {\n height?: number;\n readOnly?: boolean;\n className?: string;\n}\n\n// ── Viewport ──\n\nexport interface Viewport {\n startRow: number;\n endRow: number;\n startCol: number;\n endCol: number;\n scrollX: number;\n scrollY: number;\n}\n\n// ── Theme ──\n\nexport interface ThemeConfig {\n bgColor?: string;\n cellBgColor?: string;\n cellTextColor?: string;\n headerBgColor?: string;\n headerTextColor?: string;\n gridLineColor?: string;\n selectionBgColor?: string;\n selectionBorderColor?: string;\n focusBorderColor?: string;\n fontFamily?: string;\n fontSize?: number;\n headerFontSize?: number;\n cellPadding?: number;\n headerHeight?: number;\n rowHeaderWidth?: number;\n}\n\n// ── Renderer ──\n\nexport interface CellRenderer {\n render(cell: HTMLElement, data: CellData | undefined, state: CellState): void;\n cleanup?(cell: HTMLElement): void;\n}\n\n// ── Editor ──\n\nexport interface CellEditor {\n createElement(container: HTMLElement): HTMLElement;\n open(value: unknown, bounds: CellBounds, cellData: CellData | undefined): void;\n getValue(): unknown;\n close(): void;\n validate?(value: unknown): boolean | string;\n}\n\n// ── Events ──\n\nexport interface CommandChangeEvent {\n row: number;\n col: number;\n oldValue: unknown;\n newValue: unknown;\n}\n\nexport interface WanderTableEvents {\n 'cell:change': { row: number; col: number; oldValue: unknown; newValue: unknown };\n 'cell:click': { row: number; col: number; event: MouseEvent };\n 'cell:dblclick': { row: number; col: number; event: MouseEvent };\n 'cell:contextmenu': { row: number; col: number; event: MouseEvent };\n 'selection:change': { ranges: SelectionRange[] };\n 'editor:open': { row: number; col: number };\n 'editor:close': { row: number; col: number; value: unknown; cancelled: boolean };\n 'scroll': { viewport: Viewport };\n 'column:resize': { col: number; width: number };\n 'row:resize': { row: number; height: number };\n 'data:patch': { patches: CellPatch[] };\n /** Fired after any command executes (edit, paste, delete, etc.) */\n 'command:execute': { changes: CommandChangeEvent[] };\n /** Fired after an undo - changes show what was RESTORED (old -> new is the undo direction) */\n 'command:undo': { changes: CommandChangeEvent[] };\n /** Fired after a redo - changes show what was RE-APPLIED */\n 'command:redo': { changes: CommandChangeEvent[] };\n}\n\n// ── Options ──\n\n// ── Pagination ──\n\nexport interface PaginationConfig {\n /** Enable pagination */\n enabled: boolean;\n /** Rows per page */\n pageSize: number;\n /** Current page (0-based) */\n page?: number;\n /** Total rows (for server-side pagination - if set, overrides data.rowCount) */\n totalRows?: number;\n}\n\nexport interface PaginationState {\n page: number;\n pageSize: number;\n totalRows: number;\n totalPages: number;\n startRow: number;\n endRow: number;\n}\n\nexport interface WanderTableOptions {\n /** 'spreadsheet' = independent cells (default), 'table' = column-driven rows */\n mode?: 'spreadsheet' | 'table';\n data?: CellPatch[];\n /** Table mode: array of row objects keyed by column.key */\n tableData?: Record<string, unknown>[];\n columns?: ColumnConfig[];\n rowCount?: number;\n colCount?: number;\n defaultRowHeight?: number;\n defaultColWidth?: number;\n readOnly?: boolean;\n showRowHeaders?: boolean;\n showColHeaders?: boolean;\n frozenRows?: number;\n frozenCols?: number;\n /** Allow column resize by dragging header edge. Default: true */\n allowColResize?: boolean;\n /** Allow row resize by dragging row header edge. Default: true */\n allowRowResize?: boolean;\n /** Allow multi-cell selection. Default: true */\n allowRangeSelection?: boolean;\n /** Allow editing cells (double click / typing). Default: true */\n allowEditing?: boolean;\n /** Allow clipboard operations (copy/paste/cut). Default: true */\n allowClipboard?: boolean;\n /** Allow context menu on right-click. Default: true */\n allowContextMenu?: boolean;\n /** Allow keyboard navigation. Default: true */\n allowKeyboardNav?: boolean;\n /** Allow cell selection at all. Default: true */\n allowSelection?: boolean;\n /** Enable undo/redo. Default: true */\n allowUndoRedo?: boolean;\n /** Show fill handle on selection for drag-to-fill. Default: true */\n allowFillHandle?: boolean;\n /** Allow column reorder by dragging headers. Default: false */\n allowColReorder?: boolean;\n /** Initial row groups for expand/collapse */\n rowGroups?: { startRow: number; count: number; label?: string; expanded?: boolean; depth?: number }[];\n /** Called when scroll reaches near the end - for lazy loading more data */\n onLoadMore?: (direction: 'down' | 'right') => void;\n /** Automatically fit row height to cell content after render. Default: false */\n autoRowHeight?: boolean;\n /** Show grid lines between cells. Default: true */\n showGridLines?: boolean;\n /** Show border around the grid. Default: true */\n showBorder?: boolean;\n /** Auto-expand grid when navigating/editing beyond current bounds. Default: false */\n infinite?: boolean;\n /**\n * 'scroll' (default): fixed height container with internal scroll + virtualization.\n * 'auto': grid grows to fit all content, scroll is on the page. No virtualization.\n */\n layout?: 'scroll' | 'auto';\n undoLimit?: number;\n /** Renderer used for cells without data or without a type. Default: 'text' */\n defaultCellType?: string;\n /** Initial merged cell ranges */\n merges?: { row: number; col: number; rowSpan: number; colSpan: number }[];\n /** Initial sort */\n sort?: { col: number; direction: 'asc' | 'desc' };\n /** Initial filters: key is column index */\n filters?: Record<number, (row: number, data: any) => boolean>;\n /** Pagination config */\n pagination?: PaginationConfig;\n /** Loading state - shows overlay */\n loading?: boolean;\n theme?: Partial<ThemeConfig>;\n\n onCellChange?: (row: number, col: number, oldValue: unknown, newValue: unknown) => void;\n onSelectionChange?: (ranges: SelectionRange[]) => void;\n onScroll?: (viewport: Viewport) => void;\n onContextMenu?: (row: number, col: number, event: MouseEvent) => void;\n /**\n * External sort callback. If set, sorting is NOT done internally -\n * the callback is responsible for re-supplying data in the correct order.\n * Return true to indicate the sort was handled externally.\n */\n onSort?: (col: number, direction: 'asc' | 'desc' | null, key?: string) => boolean | void;\n /**\n * External filter callback. If set, filtering is NOT done internally.\n * Return true to indicate the filter was handled externally.\n */\n onFilter?: (col: number, key: string | undefined, active: boolean) => boolean | void;\n /**\n * Fill handle callback. Called when user drags the fill handle.\n * Receives the source range (what was selected) and the fill range (where it's being filled).\n * Return a CellPatch[] to apply custom values, or true to cancel default fill behavior.\n * Return void/false to use default fill (repeat pattern).\n */\n onFill?: (source: SelectionRange, fill: SelectionRange, direction: 'down' | 'up' | 'right' | 'left' | 'diagonal') => CellPatch[] | boolean | void;\n /** Called when page changes (pagination) */\n onPageChange?: (page: number, pageSize: number) => void;\n}\n\nexport const DEFAULT_THEME: ThemeConfig = {\n bgColor: '#ffffff',\n cellBgColor: '#ffffff',\n cellTextColor: '#1e293b',\n headerBgColor: '#f8fafc',\n headerTextColor: '#475569',\n gridLineColor: '#e2e8f0',\n selectionBgColor: 'rgba(59, 130, 246, 0.08)',\n selectionBorderColor: '#3b82f6',\n focusBorderColor: '#3b82f6',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n fontSize: 13,\n headerFontSize: 12,\n cellPadding: 8,\n headerHeight: 28,\n rowHeaderWidth: 50,\n};\n","import type { CellData, CellKey, CellPatch } from '../types/index.js';\n\nexport class DataModel {\n private cells = new Map<CellKey, CellData>();\n private _rowCount: number;\n private _colCount: number;\n private _inTransaction = false;\n private _dirtyKeys = new Set<CellKey>();\n\n // Callback set by WanderTable to trigger re-render\n onChange: ((dirty: Set<CellKey>) => void) | null = null;\n\n constructor(rowCount: number, colCount: number) {\n this._rowCount = rowCount;\n this._colCount = colCount;\n }\n\n get rowCount(): number { return this._rowCount; }\n set rowCount(v: number) { this._rowCount = v; }\n\n get colCount(): number { return this._colCount; }\n set colCount(v: number) { this._colCount = v; }\n\n private key(row: number, col: number): CellKey {\n return `${row}:${col}`;\n }\n\n getCell(row: number, col: number): CellData | undefined {\n return this.cells.get(this.key(row, col));\n }\n\n setCell(row: number, col: number, data: CellData): void {\n const k = this.key(row, col);\n this.cells.set(k, data);\n this.markDirty(k);\n }\n\n setCellValue(row: number, col: number, value: unknown): void {\n const k = this.key(row, col);\n const existing = this.cells.get(k);\n if (existing) {\n existing.value = value;\n } else {\n this.cells.set(k, { value });\n }\n this.markDirty(k);\n }\n\n deleteCell(row: number, col: number): void {\n const k = this.key(row, col);\n this.cells.delete(k);\n this.markDirty(k);\n }\n\n hasCell(row: number, col: number): boolean {\n return this.cells.has(this.key(row, col));\n }\n\n applyPatch(patches: CellPatch[]): void {\n this.transaction(() => {\n for (const p of patches) {\n const k = this.key(p.row, p.col);\n const existing = this.cells.get(k);\n if (existing) {\n Object.assign(existing, p.data);\n } else {\n this.cells.set(k, { value: undefined, ...p.data });\n }\n this._dirtyKeys.add(k);\n }\n });\n }\n\n transaction(fn: () => void): void {\n if (this._inTransaction) {\n fn();\n return;\n }\n this._inTransaction = true;\n this._dirtyKeys.clear();\n try {\n fn();\n } finally {\n this._inTransaction = false;\n if (this._dirtyKeys.size > 0) {\n this.onChange?.(new Set(this._dirtyKeys));\n this._dirtyKeys.clear();\n }\n }\n }\n\n private markDirty(k: CellKey): void {\n if (this._inTransaction) {\n this._dirtyKeys.add(k);\n } else {\n this.onChange?.(new Set([k]));\n }\n }\n\n clear(): void {\n this.cells.clear();\n this.onChange?.(new Set());\n }\n\n /** Iterate all cells that have data */\n forEach(fn: (row: number, col: number, data: CellData) => void): void {\n for (const [key, data] of this.cells) {\n const [r, c] = key.split(':').map(Number);\n fn(r, c, data);\n }\n }\n}\n","export class EventEmitter<Events extends { [K in keyof Events]: unknown }> {\n private listeners = new Map<keyof Events, Set<(data: never) => void>>();\n\n on<K extends keyof Events>(event: K, fn: (data: Events[K]) => void): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(fn as (data: never) => void);\n return () => this.off(event, fn);\n }\n\n off<K extends keyof Events>(event: K, fn: (data: Events[K]) => void): void {\n this.listeners.get(event)?.delete(fn as (data: never) => void);\n }\n\n emit<K extends keyof Events>(event: K, data: Events[K]): void {\n this.listeners.get(event)?.forEach(fn => {\n try {\n (fn as (data: Events[K]) => void)(data);\n } catch (e) {\n console.error(`[WanderTable] Error in \"${String(event)}\" handler:`, e);\n }\n });\n }\n\n removeAllListeners(): void {\n this.listeners.clear();\n }\n}\n","import type { CellAddress, SelectionInfo, SelectionRange } from '../types/index.js';\n\nexport class SelectionModel {\n private _focus: CellAddress | null = null;\n private _ranges: SelectionRange[] = [];\n private _rowCount: number;\n private _colCount: number;\n\n onChange: (() => void) | null = null;\n\n constructor(rowCount: number, colCount: number) {\n this._rowCount = rowCount;\n this._colCount = colCount;\n }\n\n get focus(): CellAddress | null {\n return this._focus;\n }\n\n get ranges(): SelectionRange[] {\n return this._ranges;\n }\n\n setDimensions(rowCount: number, colCount: number): void {\n this._rowCount = rowCount;\n this._colCount = colCount;\n }\n\n /** Set focus and single selection */\n focusCell(row: number, col: number): void {\n row = this.clampRow(row);\n col = this.clampCol(col);\n this._focus = { row, col };\n this._ranges = [{ startRow: row, startCol: col, endRow: row, endCol: col }];\n this.onChange?.();\n }\n\n /** Extend selection from focus to target */\n extendTo(row: number, col: number): void {\n if (!this._focus) return;\n row = this.clampRow(row);\n col = this.clampCol(col);\n this._ranges = [{\n startRow: this._focus.row,\n startCol: this._focus.col,\n endRow: row,\n endCol: col,\n }];\n this.onChange?.();\n }\n\n /** Add a new range (Ctrl+Click) */\n addRange(range: SelectionRange): void {\n this._ranges.push(range);\n this._focus = { row: range.startRow, col: range.startCol };\n this.onChange?.();\n }\n\n /** Select entire column */\n selectColumn(col: number): void {\n this._focus = { row: 0, col };\n this._ranges = [{\n startRow: 0, startCol: col,\n endRow: Infinity, endCol: col,\n }];\n this.onChange?.();\n }\n\n /** Select entire row */\n selectRow(row: number): void {\n this._focus = { row, col: 0 };\n this._ranges = [{\n startRow: row, startCol: 0,\n endRow: row, endCol: Infinity,\n }];\n this.onChange?.();\n }\n\n /** Select all */\n selectAll(): void {\n this._focus = { row: 0, col: 0 };\n this._ranges = [{\n startRow: 0, startCol: 0,\n endRow: Infinity, endCol: Infinity,\n }];\n this.onChange?.();\n }\n\n /** Check if a cell is within any selected range */\n isSelected(row: number, col: number): boolean {\n return this._ranges.some(r => this.inRange(row, col, r));\n }\n\n isFocused(row: number, col: number): boolean {\n return this._focus?.row === row && this._focus?.col === col;\n }\n\n /** Iterate all selected cells (clamped to actual dimensions) */\n forEachSelected(fn: (row: number, col: number) => void): void {\n for (const r of this._ranges) {\n const r1 = Math.min(r.startRow, r.endRow);\n const r2 = Math.min(Math.max(r.startRow, r.endRow), this._rowCount - 1);\n const c1 = Math.min(r.startCol, r.endCol);\n const c2 = Math.min(Math.max(r.startCol, r.endCol), this._colCount - 1);\n for (let row = r1; row <= r2; row++) {\n for (let col = c1; col <= c2; col++) {\n fn(row, col);\n }\n }\n }\n }\n\n /** Get the bounding box of the current selection (clamped to actual dimensions) */\n getBounds(): { r1: number; c1: number; r2: number; c2: number } | null {\n if (this._ranges.length === 0) return null;\n let r1 = Infinity, c1 = Infinity, r2 = -Infinity, c2 = -Infinity;\n for (const r of this._ranges) {\n r1 = Math.min(r1, r.startRow, r.endRow);\n c1 = Math.min(c1, r.startCol, r.endCol);\n r2 = Math.max(r2, r.startRow, r.endRow);\n c2 = Math.max(c2, r.startCol, r.endCol);\n }\n // Clamp Infinity to actual dimensions\n r2 = Math.min(r2, this._rowCount - 1);\n c2 = Math.min(c2, this._colCount - 1);\n return { r1, c1, r2, c2 };\n }\n\n /** Get rich selection info */\n getInfo(): SelectionInfo {\n const bounds = this.getBounds();\n let cellCount = 0;\n this.forEachSelected(() => { cellCount++; });\n\n const startRow = bounds?.r1 ?? 0;\n const startCol = bounds?.c1 ?? 0;\n const endRow = bounds?.r2 ?? 0;\n const endCol = bounds?.c2 ?? 0;\n\n // Check raw ranges for Infinity to detect full row/col selections\n const hasInfRow = this._ranges.some(r => r.endRow === Infinity || r.startRow === Infinity);\n const hasInfCol = this._ranges.some(r => r.endCol === Infinity || r.startCol === Infinity);\n const isFullRow = bounds !== null && (hasInfCol || (startCol === 0 && endCol === this._colCount - 1));\n const isFullCol = bounds !== null && (hasInfRow || (startRow === 0 && endRow === this._rowCount - 1));\n\n return {\n focus: this._focus ? { ...this._focus } : null,\n ranges: this._ranges.map(r => ({ ...r })),\n bounds: bounds ? { startRow, startCol, endRow, endCol } : null,\n cellCount,\n rangeCount: this._ranges.length,\n isMultiCell: cellCount > 1,\n isFullRow,\n isFullCol,\n isAll: isFullRow && isFullCol,\n isEmpty: this._ranges.length === 0,\n rowSpan: bounds ? endRow - startRow + 1 : 0,\n colSpan: bounds ? endCol - startCol + 1 : 0,\n };\n }\n\n clear(): void {\n this._focus = null;\n this._ranges = [];\n this.onChange?.();\n }\n\n /** Move focus in a direction */\n move(dRow: number, dCol: number, extend: boolean): void {\n if (!this._focus) {\n this.focusCell(0, 0);\n return;\n }\n const newRow = this.clampRow(this._focus.row + dRow);\n const newCol = this.clampCol(this._focus.col + dCol);\n if (extend) {\n this.extendTo(newRow, newCol);\n } else {\n this.focusCell(newRow, newCol);\n }\n }\n\n private inRange(row: number, col: number, r: SelectionRange): boolean {\n const r1 = Math.min(r.startRow, r.endRow);\n const r2 = Math.max(r.startRow, r.endRow);\n const c1 = Math.min(r.startCol, r.endCol);\n const c2 = Math.max(r.startCol, r.endCol);\n return row >= r1 && row <= r2 && col >= c1 && col <= c2;\n }\n\n /** When true, navigation beyond bounds is allowed (grid will expand) */\n infinite = false;\n\n private clampRow(row: number): number {\n if (this.infinite) return Math.max(0, row);\n return Math.max(0, Math.min(this._rowCount - 1, row));\n }\n\n private clampCol(col: number): number {\n if (this.infinite) return Math.max(0, col);\n return Math.max(0, Math.min(this._colCount - 1, col));\n }\n}\n","export interface CommandChange {\n row: number;\n col: number;\n oldValue: unknown;\n newValue: unknown;\n}\n\nexport interface Command {\n execute(): void;\n undo(): void;\n /** Return a description of what this command changes, for external sync */\n getChanges(): CommandChange[];\n}\n\nexport class CommandBus {\n private undoStack: Command[] = [];\n private redoStack: Command[] = [];\n private limit: number;\n\n onChange: (() => void) | null = null;\n\n constructor(limit = 100) {\n this.limit = limit;\n }\n\n execute(cmd: Command): void {\n cmd.execute();\n this.undoStack.push(cmd);\n if (this.undoStack.length > this.limit) {\n this.undoStack.shift();\n }\n // Executing a new command clears redo history\n this.redoStack.length = 0;\n this.onChange?.();\n }\n\n undo(): Command | null {\n const cmd = this.undoStack.pop();\n if (!cmd) return null;\n cmd.undo();\n this.redoStack.push(cmd);\n this.onChange?.();\n return cmd;\n }\n\n redo(): Command | null {\n const cmd = this.redoStack.pop();\n if (!cmd) return null;\n cmd.execute();\n this.undoStack.push(cmd);\n this.onChange?.();\n return cmd;\n }\n\n get canUndo(): boolean {\n return this.undoStack.length > 0;\n }\n\n get canRedo(): boolean {\n return this.redoStack.length > 0;\n }\n\n clear(): void {\n this.undoStack.length = 0;\n this.redoStack.length = 0;\n }\n}\n\n// ── Concrete commands ──\n\nimport type { CellData, CellPatch } from '../types/index.js';\nimport type { DataModel } from './DataModel.js';\n\n/** Set a single cell value */\nexport class SetCellValueCommand implements Command {\n private oldValue: unknown;\n constructor(\n private data: DataModel,\n private row: number,\n private col: number,\n private newValue: unknown,\n ) {\n this.oldValue = data.getCell(row, col)?.value;\n }\n\n execute(): void {\n this.data.setCellValue(this.row, this.col, this.newValue);\n }\n\n undo(): void {\n if (this.oldValue === undefined) {\n this.data.deleteCell(this.row, this.col);\n } else {\n this.data.setCellValue(this.row, this.col, this.oldValue);\n }\n }\n\n getChanges(): CommandChange[] {\n return [{ row: this.row, col: this.col, oldValue: this.oldValue, newValue: this.newValue }];\n }\n}\n\n/** Apply a batch of patches (stores snapshots of old cell data) */\nexport class PatchCommand implements Command {\n private snapshots: { row: number; col: number; old: CellData | undefined }[];\n\n constructor(\n private data: DataModel,\n private patches: CellPatch[],\n ) {\n this.snapshots = patches.map(p => ({\n row: p.row,\n col: p.col,\n old: data.getCell(p.row, p.col) ? { ...data.getCell(p.row, p.col)! } : undefined,\n }));\n }\n\n execute(): void {\n this.data.applyPatch(this.patches);\n }\n\n undo(): void {\n this.data.transaction(() => {\n for (const snap of this.snapshots) {\n if (snap.old === undefined) {\n this.data.deleteCell(snap.row, snap.col);\n } else {\n this.data.setCell(snap.row, snap.col, snap.old);\n }\n }\n });\n }\n\n getChanges(): CommandChange[] {\n return this.snapshots.map((snap, i) => ({\n row: snap.row,\n col: snap.col,\n oldValue: snap.old?.value,\n newValue: this.patches[i]?.data?.value,\n }));\n }\n}\n\n/** Delete selected cells (stores snapshots) */\nexport class DeleteCellsCommand implements Command {\n private snapshots: { row: number; col: number; old: CellData }[] = [];\n\n constructor(\n private data: DataModel,\n private cells: { row: number; col: number }[],\n ) {\n for (const { row, col } of cells) {\n const old = data.getCell(row, col);\n if (old) {\n this.snapshots.push({ row, col, old: { ...old } });\n }\n }\n }\n\n execute(): void {\n this.data.transaction(() => {\n for (const { row, col } of this.cells) {\n this.data.deleteCell(row, col);\n }\n });\n }\n\n undo(): void {\n this.data.transaction(() => {\n for (const snap of this.snapshots) {\n this.data.setCell(snap.row, snap.col, snap.old);\n }\n });\n }\n\n getChanges(): CommandChange[] {\n return this.snapshots.map(snap => ({\n row: snap.row,\n col: snap.col,\n oldValue: snap.old.value,\n newValue: undefined,\n }));\n }\n}\n","import type { ColumnConfig } from '../types/index.js';\n\nexport class ColumnModel {\n private configs: ColumnConfig[];\n private widths: number[];\n private prefixSums: number[];\n private defaultWidth: number;\n\n constructor(colCount: number, defaultWidth: number, configs?: ColumnConfig[]) {\n this.defaultWidth = defaultWidth;\n this.configs = configs ?? [];\n this.widths = new Array(colCount);\n for (let i = 0; i < colCount; i++) {\n this.widths[i] = this.configs[i]?.width ?? defaultWidth;\n }\n this.prefixSums = this.buildPrefixSums();\n }\n\n private buildPrefixSums(): number[] {\n const sums = new Array(this.widths.length + 1);\n sums[0] = 0;\n for (let i = 0; i < this.widths.length; i++) {\n sums[i + 1] = sums[i] + this.widths[i];\n }\n return sums;\n }\n\n get count(): number {\n return this.widths.length;\n }\n\n getWidth(col: number): number {\n return this.widths[col] ?? this.defaultWidth;\n }\n\n setWidth(col: number, width: number): void {\n const cfg = this.configs[col];\n const min = cfg?.minWidth ?? 30;\n const max = cfg?.maxWidth ?? Infinity;\n this.widths[col] = Math.max(min, Math.min(max, width));\n this.prefixSums = this.buildPrefixSums();\n }\n\n getX(col: number): number {\n return this.prefixSums[col] ?? 0;\n }\n\n getTotalWidth(): number {\n return this.prefixSums[this.widths.length] ?? 0;\n }\n\n getConfig(col: number): ColumnConfig | undefined {\n return this.configs[col];\n }\n\n setCount(count: number): void {\n while (this.widths.length < count) {\n this.widths.push(this.defaultWidth);\n }\n this.widths.length = count;\n this.prefixSums = this.buildPrefixSums();\n }\n\n /** Find column at pixel X using binary search */\n getColAtX(x: number): number {\n let lo = 0;\n let hi = this.widths.length - 1;\n while (lo <= hi) {\n const mid = (lo + hi) >>> 1;\n if (this.prefixSums[mid + 1] <= x) {\n lo = mid + 1;\n } else if (this.prefixSums[mid] > x) {\n hi = mid - 1;\n } else {\n return mid;\n }\n }\n return Math.max(0, Math.min(lo, this.widths.length - 1));\n }\n\n static columnLabel(index: number): string {\n return columnLabel(index);\n }\n}\n\n/**\n * Convert a 0-based column index to a spreadsheet-style label.\n * 0 -> A, 1 -> B, ..., 25 -> Z, 26 -> AA, 27 -> AB, ..., 701 -> ZZ, 702 -> AAA\n */\nexport function columnLabel(index: number): string {\n let label = '';\n let i = index;\n while (i >= 0) {\n label = String.fromCharCode(65 + (i % 26)) + label;\n i = Math.floor(i / 26) - 1;\n }\n return label;\n}\n","import type { RowConfig } from '../types/index.js';\n\nexport class RowModel {\n private heights: number[];\n private prefixSums: number[];\n private defaultHeight: number;\n private configs: Map<number, RowConfig> = new Map();\n\n constructor(rowCount: number, defaultHeight: number) {\n this.defaultHeight = defaultHeight;\n this.heights = new Array(rowCount).fill(defaultHeight);\n this.prefixSums = this.buildPrefixSums();\n }\n\n private buildPrefixSums(): number[] {\n const sums = new Array(this.heights.length + 1);\n sums[0] = 0;\n for (let i = 0; i < this.heights.length; i++) {\n sums[i + 1] = sums[i] + this.heights[i];\n }\n return sums;\n }\n\n get count(): number {\n return this.heights.length;\n }\n\n getHeight(row: number): number {\n return this.heights[row] ?? this.defaultHeight;\n }\n\n setHeight(row: number, height: number): void {\n const minH = 20;\n this.heights[row] = Math.max(minH, height);\n this.prefixSums = this.buildPrefixSums();\n }\n\n getY(row: number): number {\n return this.prefixSums[row] ?? 0;\n }\n\n getTotalHeight(): number {\n return this.prefixSums[this.heights.length] ?? 0;\n }\n\n getConfig(row: number): RowConfig | undefined {\n return this.configs.get(row);\n }\n\n setConfig(row: number, config: RowConfig): void {\n this.configs.set(row, config);\n if (config.height != null) {\n this.setHeight(row, config.height);\n }\n }\n\n setCount(count: number): void {\n while (this.heights.length < count) {\n this.heights.push(this.defaultHeight);\n }\n this.heights.length = count;\n this.prefixSums = this.buildPrefixSums();\n }\n\n /** Find row at pixel Y using binary search */\n getRowAtY(y: number): number {\n let lo = 0;\n let hi = this.heights.length - 1;\n while (lo <= hi) {\n const mid = (lo + hi) >>> 1;\n if (this.prefixSums[mid + 1] <= y) {\n lo = mid + 1;\n } else if (this.prefixSums[mid] > y) {\n hi = mid - 1;\n } else {\n return mid;\n }\n }\n return Math.max(0, Math.min(lo, this.heights.length - 1));\n }\n}\n","import type { CellRenderer, CellState, ThemeConfig, Viewport } from '../types/index.js';\nimport type { DataModel } from '../core/DataModel.js';\nimport type { ColumnModel } from '../columns/ColumnModel.js';\nimport type { RowModel } from '../rows/RowModel.js';\nimport type { SelectionModel } from '../core/SelectionModel.js';\nimport type { ViewMapping } from '../core/ViewMapping.js';\nimport type { MergeModel } from '../core/MergeModel.js';\nimport { ColumnModel as CM } from '../columns/ColumnModel.js';\n\ninterface RendererContext {\n data: DataModel;\n columns: ColumnModel;\n rows: RowModel;\n selection: SelectionModel;\n viewMapping: ViewMapping;\n merges: MergeModel;\n theme: ThemeConfig;\n renderers: Map<string, CellRenderer>;\n defaultRenderer: CellRenderer;\n defaultCellType: string;\n showRowHeaders: boolean;\n showColHeaders: boolean;\n frozenRows: number;\n frozenCols: number;\n autoRowHeight: boolean;\n showGridLines: boolean;\n showBorder: boolean;\n layout: 'scroll' | 'auto';\n headerRows?: import('../columns/GroupedHeaders.js').HeaderCell[][];\n}\n\ninterface PooledRow {\n el: HTMLElement;\n cells: HTMLElement[];\n rowIndex: number;\n}\n\nexport class DOMRenderer {\n private container: HTMLElement;\n private scrollContainer: HTMLElement;\n private scrollSentinel: HTMLElement;\n private viewportEl: HTMLElement;\n private colHeaderEl: HTMLElement;\n private rowHeaderEl: HTMLElement;\n private cornerEl: HTMLElement;\n\n private rowPool: PooledRow[] = [];\n private activeRows = new Map<number, PooledRow>();\n private viewport: Viewport = { startRow: 0, endRow: 0, startCol: 0, endCol: 0, scrollX: 0, scrollY: 0 };\n private ctx!: RendererContext;\n\n private rafId = 0;\n private needsRender = false;\n\n onScroll: ((viewport: Viewport) => void) | null = null;\n onCellClick: ((row: number, col: number, event: MouseEvent) => void) | null = null;\n onCellDblClick: ((row: number, col: number, event: MouseEvent) => void) | null = null;\n onCellContextMenu: ((row: number, col: number, event: MouseEvent) => void) | null = null;\n onHeaderClick: ((type: 'col' | 'row' | 'corner', index: number, event: MouseEvent) => void) | null = null;\n onColumnResizeStart: ((col: number, startX: number) => void) | null = null;\n onHeaderContextMenu: ((type: 'col' | 'row', index: number, event: MouseEvent) => void) | null = null;\n\n constructor(container: HTMLElement) {\n this.container = container;\n this.container.classList.add('wt-root');\n this.container.setAttribute('tabindex', '0');\n\n // Corner cell\n this.cornerEl = document.createElement('div');\n this.cornerEl.className = 'wt-corner';\n\n // Column headers\n this.colHeaderEl = document.createElement('div');\n this.colHeaderEl.className = 'wt-col-headers';\n\n // Row headers\n this.rowHeaderEl = document.createElement('div');\n this.rowHeaderEl.className = 'wt-row-headers';\n\n // Scroll container (native scrollbar)\n this.scrollContainer = document.createElement('div');\n this.scrollContainer.className = 'wt-scroll-container';\n\n // Sentinel (gives the scroll container its full size)\n this.scrollSentinel = document.createElement('div');\n this.scrollSentinel.className = 'wt-scroll-sentinel';\n\n // Viewport (holds visible rows)\n this.viewportEl = document.createElement('div');\n this.viewportEl.className = 'wt-viewport';\n\n this.scrollContainer.appendChild(this.scrollSentinel);\n this.scrollContainer.appendChild(this.viewportEl);\n\n this.container.appendChild(this.cornerEl);\n this.container.appendChild(this.colHeaderEl);\n this.container.appendChild(this.rowHeaderEl);\n this.container.appendChild(this.scrollContainer);\n\n this.scrollContainer.addEventListener('scroll', this.handleScroll, { passive: true });\n this.viewportEl.addEventListener('mousedown', this.handleMouseDown);\n this.viewportEl.addEventListener('dblclick', this.handleDblClick);\n this.viewportEl.addEventListener('contextmenu', this.handleContextMenu);\n this.colHeaderEl.addEventListener('mousedown', this.handleColHeaderMouse);\n this.colHeaderEl.addEventListener('contextmenu', this.handleColHeaderContextMenu);\n this.rowHeaderEl.addEventListener('mousedown', this.handleRowHeaderMouse);\n this.rowHeaderEl.addEventListener('contextmenu', this.handleRowHeaderContextMenu);\n this.cornerEl.addEventListener('mousedown', this.handleCornerMouse);\n }\n\n init(ctx: RendererContext): void {\n this.ctx = ctx;\n this.container.classList.toggle('wt-root--no-gridlines', !ctx.showGridLines);\n this.container.classList.toggle('wt-root--no-border', !ctx.showBorder);\n if (ctx.layout === 'auto') {\n this.container.classList.add('wt-root--auto');\n this.scrollContainer.classList.add('wt-scroll-container--auto');\n }\n this.applyTheme();\n this.updateLayout();\n this.scheduleRender();\n }\n\n private applyTheme(): void {\n const t = this.ctx.theme;\n const s = this.container.style;\n s.setProperty('--wt-bg', t.bgColor!);\n s.setProperty('--wt-cell-bg', t.cellBgColor!);\n s.setProperty('--wt-cell-text', t.cellTextColor!);\n s.setProperty('--wt-header-bg', t.headerBgColor!);\n s.setProperty('--wt-header-text', t.headerTextColor!);\n s.setProperty('--wt-grid-line', t.gridLineColor!);\n s.setProperty('--wt-sel-bg', t.selectionBgColor!);\n s.setProperty('--wt-sel-border', t.selectionBorderColor!);\n s.setProperty('--wt-focus-border', t.focusBorderColor!);\n s.setProperty('--wt-font', t.fontFamily!);\n s.setProperty('--wt-font-size', `${t.fontSize}px`);\n s.setProperty('--wt-header-font-size', `${t.headerFontSize}px`);\n s.setProperty('--wt-cell-padding', `${t.cellPadding}px`);\n s.setProperty('--wt-header-height', `${t.headerHeight}px`);\n s.setProperty('--wt-row-header-width', `${t.rowHeaderWidth}px`);\n }\n\n updateLayout(): void {\n const { columns, rows, viewMapping, showColHeaders, showRowHeaders, theme } = this.ctx;\n const totalW = columns.getTotalWidth();\n const visibleRows = viewMapping.visibleRowCount;\n const totalH = visibleRows === rows.count\n ? rows.getTotalHeight()\n : rows.getY(visibleRows);\n\n const headerLevels = this.ctx.headerRows ? this.ctx.headerRows.length : 1;\n const headerH = showColHeaders ? theme.headerHeight! * headerLevels : 0;\n const headerW = showRowHeaders ? theme.rowHeaderWidth! : 0;\n\n if (this.ctx.layout === 'auto') {\n // Auto layout: CSS grid, content determines size\n this.container.style.display = 'grid';\n this.container.style.gridTemplateColumns = `${headerW}px ${totalW}px`;\n this.container.style.gridTemplateRows = `${headerH}px auto`;\n this.container.style.width = `${headerW + totalW}px`;\n this.container.style.minWidth = '100%';\n\n this.cornerEl.style.display = (showColHeaders && showRowHeaders) ? '' : 'none';\n this.cornerEl.style.position = 'static';\n this.cornerEl.style.width = '';\n this.cornerEl.style.height = '';\n\n this.colHeaderEl.style.display = showColHeaders ? '' : 'none';\n this.colHeaderEl.style.position = 'static';\n this.colHeaderEl.style.left = '';\n this.colHeaderEl.style.right = '';\n this.colHeaderEl.style.height = `${headerH}px`;\n this.colHeaderEl.style.overflow = 'visible';\n\n this.rowHeaderEl.style.display = showRowHeaders ? '' : 'none';\n this.rowHeaderEl.style.position = 'static';\n this.rowHeaderEl.style.top = '';\n this.rowHeaderEl.style.bottom = '';\n this.rowHeaderEl.style.width = `${headerW}px`;\n this.rowHeaderEl.style.overflow = 'visible';\n\n this.scrollContainer.style.position = 'static';\n this.scrollContainer.style.top = '';\n this.scrollContainer.style.left = '';\n this.scrollContainer.style.right = '';\n this.scrollContainer.style.bottom = '';\n this.scrollContainer.style.overflow = 'visible';\n this.scrollContainer.style.gridColumn = showRowHeaders ? '2' : '1 / -1';\n\n this.scrollSentinel.style.width = `${totalW}px`;\n this.scrollSentinel.style.height = '0';\n\n this.viewportEl.style.position = 'relative';\n this.viewportEl.style.height = `${totalH}px`;\n this.viewportEl.style.width = `${totalW}px`;\n\n if (showRowHeaders) {\n const innerDiv = this.rowHeaderEl.querySelector('.wt-row-headers-inner') as HTMLElement;\n if (innerDiv) innerDiv.style.height = `${totalH}px`;\n this.rowHeaderEl.style.height = `${totalH}px`;\n this.rowHeaderEl.style.gridRow = '2';\n this.rowHeaderEl.style.gridColumn = '1';\n }\n } else {\n // Scroll layout: absolute positioning (original)\n this.scrollSentinel.style.width = `${totalW}px`;\n this.scrollSentinel.style.height = `${totalH}px`;\n\n this.cornerEl.style.display = (showColHeaders && showRowHeaders) ? '' : 'none';\n this.cornerEl.style.width = `${headerW}px`;\n this.cornerEl.style.height = `${headerH}px`;\n\n this.colHeaderEl.style.display = showColHeaders ? '' : 'none';\n this.colHeaderEl.style.left = `${headerW}px`;\n this.colHeaderEl.style.height = `${headerH}px`;\n this.colHeaderEl.style.right = '0';\n\n this.rowHeaderEl.style.display = showRowHeaders ? '' : 'none';\n this.rowHeaderEl.style.top = `${headerH}px`;\n this.rowHeaderEl.style.width = `${headerW}px`;\n this.rowHeaderEl.style.bottom = '0';\n\n this.scrollContainer.style.top = `${headerH}px`;\n this.scrollContainer.style.left = `${headerW}px`;\n this.scrollContainer.style.right = '0';\n this.scrollContainer.style.bottom = '0';\n }\n }\n\n scheduleRender(): void {\n if (this.needsRender) return;\n this.needsRender = true;\n this.rafId = requestAnimationFrame(() => {\n this.needsRender = false;\n this.render();\n });\n }\n\n private render(): void {\n const { columns, rows, viewMapping, showColHeaders, showRowHeaders } = this.ctx;\n const sc = this.scrollContainer;\n const containerW = sc.clientWidth;\n const containerH = sc.clientHeight;\n const scrollX = sc.scrollLeft;\n const scrollY = sc.scrollTop;\n\n const totalVisibleRows = viewMapping.visibleRowCount;\n const isAutoLayout = this.ctx.layout === 'auto';\n\n // Inline viewport calculation\n const overscan = 3;\n\n let vpStartRow: number, vpEndRow: number, vpStartCol: number, vpEndCol: number;\n\n if (isAutoLayout) {\n // Auto layout: render all rows and columns\n vpStartRow = 0;\n vpEndRow = totalVisibleRows - 1;\n vpStartCol = 0;\n vpEndCol = columns.count - 1;\n } else {\n const rawStartRow = rows.getRowAtY(scrollY);\n const rawEndRow = rows.getRowAtY(scrollY + containerH);\n const rawStartCol = columns.getColAtX(scrollX);\n const rawEndCol = columns.getColAtX(scrollX + containerW);\n vpStartRow = Math.max(0, rawStartRow - overscan);\n vpEndRow = Math.min(totalVisibleRows - 1, rawEndRow + overscan);\n vpStartCol = Math.max(0, rawStartCol - overscan);\n vpEndCol = Math.min(columns.count - 1, rawEndCol + overscan);\n }\n\n const vp: Viewport = {\n startRow: vpStartRow,\n endRow: vpEndRow,\n startCol: vpStartCol,\n endCol: vpEndCol,\n scrollX,\n scrollY,\n };\n\n this.viewport = vp;\n\n const frozenRows = this.ctx.frozenRows;\n const frozenCols = this.ctx.frozenCols;\n\n // Determine which rows to render: frozen + viewport\n const visibleSet = new Set<number>();\n // Always include frozen rows\n for (let r = 0; r < frozenRows && r < totalVisibleRows; r++) {\n visibleSet.add(r);\n }\n // Viewport rows\n for (let r = vp.startRow; r <= vp.endRow; r++) {\n visibleSet.add(r);\n }\n\n // Recycle rows that left\n for (const [rowIdx, pooled] of this.activeRows) {\n if (!visibleSet.has(rowIdx)) {\n pooled.el.style.display = 'none';\n this.rowPool.push(pooled);\n this.activeRows.delete(rowIdx);\n }\n }\n\n // Render all needed rows\n for (const r of visibleSet) {\n this.renderRow(r, vp, scrollX, scrollY, frozenRows, frozenCols);\n }\n\n // Auto row height: measure actual cell content and adjust\n if (this.ctx.autoRowHeight) {\n let layoutChanged = false;\n for (const r of visibleSet) {\n const pooled = this.activeRows.get(r);\n if (!pooled) continue;\n let maxH = 20; // minimum\n for (const cellEl of pooled.cells) {\n if (cellEl.style.display === 'none') continue;\n const natural = cellEl.scrollHeight;\n if (natural > maxH) maxH = natural;\n }\n const currentH = rows.getHeight(r);\n if (Math.abs(maxH - currentH) > 1) {\n rows.setHeight(r, maxH);\n layoutChanged = true;\n }\n }\n if (layoutChanged) {\n // Re-position rows with updated heights (without recursing)\n this.updateLayout();\n for (const r of visibleSet) {\n const pooled = this.activeRows.get(r);\n if (!pooled) continue;\n const isFr = r < frozenRows;\n const newY = isFr ? rows.getY(r) + scrollY : rows.getY(r);\n const newH = rows.getHeight(r);\n pooled.el.style.transform = `translateY(${newY}px)`;\n pooled.el.style.height = `${newH}px`;\n for (const cellEl of pooled.cells) {\n if (cellEl.style.display !== 'none') {\n cellEl.style.height = `${newH}px`;\n }\n }\n }\n }\n }\n\n // Render headers\n if (showColHeaders) this.renderColHeaders(vp, scrollX);\n if (showRowHeaders) this.renderRowHeaders(vp, scrollY);\n\n this.onScroll?.(vp);\n }\n\n private renderRow(\n rowIndex: number,\n vp: Viewport,\n scrollX: number,\n scrollY: number,\n frozenRows: number,\n frozenCols: number,\n ): void {\n const { columns, rows, data, selection, viewMapping } = this.ctx;\n const dataRow = viewMapping.toDataRow(rowIndex);\n let pooled = this.activeRows.get(rowIndex);\n const y = rows.getY(rowIndex);\n const h = rows.getHeight(rowIndex);\n const colCount = vp.endCol - vp.startCol + 1;\n\n const isFrozenRow = rowIndex < frozenRows;\n\n if (!pooled) {\n pooled = this.acquireRow(colCount);\n pooled.rowIndex = rowIndex;\n this.activeRows.set(rowIndex, pooled);\n }\n\n // Position the row - frozen rows stick to top via scroll compensation\n const el = pooled.el;\n el.style.display = '';\n const rowY = isFrozenRow ? y + scrollY : y;\n el.style.transform = `translateY(${rowY}px)`;\n el.style.height = `${h}px`;\n el.style.zIndex = isFrozenRow ? '2' : '';\n el.dataset.row = String(dataRow);\n\n // Ensure correct number of cells\n this.ensureCells(pooled, colCount);\n\n // Render each cell\n const { merges } = this.ctx;\n for (let ci = 0; ci < colCount; ci++) {\n const col = vp.startCol + ci;\n const cellEl = pooled.cells[ci];\n\n // Skip cells hidden by a merge\n if (merges.isHidden(dataRow, col)) {\n cellEl.style.display = 'none';\n continue;\n }\n\n const x = columns.getX(col);\n let w = columns.getWidth(col);\n let cellH = h;\n\n // If this cell is a merge anchor, expand its width/height\n const merge = merges.getMerge(dataRow, col);\n if (merge && merge.row === dataRow && merge.col === col) {\n for (let mc = 1; mc < merge.colSpan; mc++) {\n w += columns.getWidth(col + mc);\n }\n for (let mr = 1; mr < merge.rowSpan; mr++) {\n cellH += rows.getHeight(rowIndex + mr);\n }\n cellEl.style.zIndex = '1';\n } else {\n cellEl.style.zIndex = '';\n }\n\n const isFrozenCol = col < frozenCols;\n const cellX = isFrozenCol ? x + scrollX : x;\n cellEl.style.transform = `translateX(${cellX}px)`;\n cellEl.style.width = `${w}px`;\n cellEl.style.height = `${cellH}px`;\n cellEl.style.display = '';\n if (isFrozenCol || isFrozenRow) {\n // Frozen cells need higher z-index to stay above scrolling content\n cellEl.style.zIndex = (isFrozenCol && isFrozenRow) ? '4' : '3';\n }\n cellEl.dataset.row = String(dataRow);\n cellEl.dataset.col = String(col);\n\n const cellData = data.getCell(dataRow, col);\n const state: CellState = {\n selected: selection.isSelected(dataRow, col),\n focused: selection.isFocused(dataRow, col),\n editing: false,\n hover: false,\n };\n\n // Apply selection classes\n cellEl.classList.toggle('wt-cell--selected', state.selected);\n cellEl.classList.toggle('wt-cell--focused', state.focused);\n\n // Apply cell style\n if (cellData?.style) {\n const cs = cellData.style;\n if (cs.bgColor) cellEl.style.backgroundColor = cs.bgColor;\n else cellEl.style.backgroundColor = '';\n if (cs.textColor) cellEl.style.color = cs.textColor;\n else cellEl.style.color = '';\n if (cs.textAlign) cellEl.style.textAlign = cs.textAlign;\n else cellEl.style.textAlign = '';\n if (cs.borderLeft) cellEl.style.borderLeft = cs.borderLeft;\n else cellEl.style.borderLeft = '';\n if (cs.borderRight) cellEl.style.borderRight = cs.borderRight;\n else cellEl.style.borderRight = '';\n if (cs.borderTop) cellEl.style.borderTop = cs.borderTop;\n else cellEl.style.borderTop = '';\n if (cs.borderBottom) cellEl.style.borderBottom = cs.borderBottom;\n else cellEl.style.borderBottom = '';\n } else {\n cellEl.style.backgroundColor = '';\n cellEl.style.color = '';\n cellEl.style.textAlign = '';\n cellEl.style.borderLeft = '';\n cellEl.style.borderRight = '';\n cellEl.style.borderTop = '';\n cellEl.style.borderBottom = '';\n }\n\n if (cellData?.className) {\n cellEl.className = `wt-cell ${cellData.className}`;\n if (state.selected) cellEl.classList.add('wt-cell--selected');\n if (state.focused) cellEl.classList.add('wt-cell--focused');\n }\n\n // Render content\n const type = cellData?.type ?? this.ctx.columns.getConfig(col)?.type ?? this.ctx.defaultCellType;\n const renderer = this.ctx.renderers.get(type) ?? this.ctx.defaultRenderer;\n renderer.render(cellEl, cellData, state);\n }\n\n // Hide extra cells\n for (let ci = colCount; ci < pooled.cells.length; ci++) {\n pooled.cells[ci].style.display = 'none';\n }\n }\n\n private renderColHeaders(vp: Viewport, scrollX: number): void {\n const { columns, theme } = this.ctx;\n const headerRows = this.ctx.headerRows;\n\n // Sync scroll with data area\n this.colHeaderEl.scrollLeft = scrollX;\n\n const innerDiv = this.colHeaderEl.querySelector('.wt-col-headers-inner') as HTMLElement\n ?? this.createColHeadersInner();\n\n innerDiv.style.width = `${columns.getTotalWidth()}px`;\n\n if (headerRows && headerRows.length > 1) {\n // Grouped headers: render multi-level\n const rowH = theme.headerHeight!;\n const totalH = rowH * headerRows.length;\n this.colHeaderEl.style.height = `${totalH}px`;\n innerDiv.style.height = `${totalH}px`;\n innerDiv.innerHTML = '';\n\n for (let level = 0; level < headerRows.length; level++) {\n for (const hc of headerRows[level]) {\n const cell = document.createElement('div');\n cell.className = hc.colSpan > 1\n ? 'wt-header-cell wt-col-header-group'\n : 'wt-header-cell wt-col-header-cell';\n const x = columns.getX(hc.col);\n let w = 0;\n for (let c = 0; c < hc.colSpan; c++) {\n w += columns.getWidth(hc.col + c);\n }\n cell.style.transform = `translate(${x}px, ${level * rowH}px)`;\n cell.style.width = `${w}px`;\n cell.style.height = `${rowH * hc.rowSpan}px`;\n cell.textContent = hc.label;\n if (hc.colSpan === 1) {\n cell.dataset.col = String(hc.col);\n }\n innerDiv.appendChild(cell);\n }\n }\n } else {\n // Simple single-row headers\n const needed = vp.endCol - vp.startCol + 1;\n while (innerDiv.children.length < needed) {\n const cell = document.createElement('div');\n cell.className = 'wt-header-cell wt-col-header-cell';\n innerDiv.appendChild(cell);\n }\n\n for (let i = 0; i < needed; i++) {\n const col = vp.startCol + i;\n const cell = innerDiv.children[i] as HTMLElement;\n cell.style.display = '';\n cell.style.transform = `translateX(${columns.getX(col)}px)`;\n cell.style.width = `${columns.getWidth(col)}px`;\n cell.style.height = `${theme.headerHeight}px`;\n cell.textContent = this.ctx.columns.getConfig(col)?.label ?? CM.columnLabel(col);\n cell.dataset.col = String(col);\n }\n\n for (let i = needed; i < innerDiv.children.length; i++) {\n (innerDiv.children[i] as HTMLElement).style.display = 'none';\n }\n }\n }\n\n private createColHeadersInner(): HTMLElement {\n const div = document.createElement('div');\n div.className = 'wt-col-headers-inner';\n this.colHeaderEl.appendChild(div);\n return div;\n }\n\n private renderRowHeaders(vp: Viewport, scrollY: number): void {\n const { rows, theme } = this.ctx;\n\n this.rowHeaderEl.scrollTop = scrollY;\n\n let innerDiv = this.rowHeaderEl.querySelector('.wt-row-headers-inner') as HTMLElement;\n if (!innerDiv) {\n innerDiv = document.createElement('div');\n innerDiv.className = 'wt-row-headers-inner';\n this.rowHeaderEl.appendChild(innerDiv);\n }\n innerDiv.style.height = `${rows.getTotalHeight()}px`;\n\n const needed = vp.endRow - vp.startRow + 1;\n while (innerDiv.children.length < needed) {\n const cell = document.createElement('div');\n cell.className = 'wt-header-cell wt-row-header-cell';\n innerDiv.appendChild(cell);\n }\n\n for (let i = 0; i < needed; i++) {\n const row = vp.startRow + i;\n const cell = innerDiv.children[i] as HTMLElement;\n cell.style.display = '';\n cell.style.transform = `translateY(${rows.getY(row)}px)`;\n cell.style.height = `${rows.getHeight(row)}px`;\n cell.style.width = `${theme.rowHeaderWidth}px`;\n cell.textContent = String(row + 1);\n cell.dataset.row = String(row);\n }\n\n for (let i = needed; i < innerDiv.children.length; i++) {\n (innerDiv.children[i] as HTMLElement).style.display = 'none';\n }\n }\n\n private acquireRow(cellCount: number): PooledRow {\n let pooled = this.rowPool.pop();\n if (!pooled) {\n const el = document.createElement('div');\n el.className = 'wt-row';\n this.viewportEl.appendChild(el);\n pooled = { el, cells: [], rowIndex: -1 };\n }\n this.ensureCells(pooled, cellCount);\n return pooled;\n }\n\n private ensureCells(pooled: PooledRow, count: number): void {\n while (pooled.cells.length < count) {\n const cell = document.createElement('div');\n cell.className = 'wt-cell';\n pooled.el.appendChild(cell);\n pooled.cells.push(cell);\n }\n }\n\n /** Resolve cell address from a mouse event target */\n getCellFromEvent(e: MouseEvent): { row: number; col: number } | null {\n const target = (e.target as HTMLElement).closest('.wt-cell') as HTMLElement | null;\n if (!target) return null;\n const row = parseInt(target.dataset.row ?? '', 10);\n const col = parseInt(target.dataset.col ?? '', 10);\n if (isNaN(row) || isNaN(col)) return null;\n return { row, col };\n }\n\n getViewport(): Viewport {\n return this.viewport;\n }\n\n scrollToCell(row: number, col: number): void {\n const { columns, rows } = this.ctx;\n const x = columns.getX(col);\n const y = rows.getY(row);\n const w = columns.getWidth(col);\n const h = rows.getHeight(row);\n\n const sc = this.scrollContainer;\n const viewW = sc.clientWidth;\n const viewH = sc.clientHeight;\n\n // Scroll horizontally if needed\n if (x < sc.scrollLeft) {\n sc.scrollLeft = x;\n } else if (x + w > sc.scrollLeft + viewW) {\n sc.scrollLeft = x + w - viewW;\n }\n\n // Scroll vertically if needed\n if (y < sc.scrollTop) {\n sc.scrollTop = y;\n } else if (y + h > sc.scrollTop + viewH) {\n sc.scrollTop = y + h - viewH;\n }\n }\n\n /** Get the pixel bounds of a cell relative to the scroll container */\n getCellBounds(row: number, col: number): { x: number; y: number; width: number; height: number } {\n const { columns, rows } = this.ctx;\n return {\n x: columns.getX(col) - this.scrollContainer.scrollLeft,\n y: rows.getY(row) - this.scrollContainer.scrollTop,\n width: columns.getWidth(col),\n height: rows.getHeight(row),\n };\n }\n\n getScrollContainer(): HTMLElement {\n return this.scrollContainer;\n }\n\n getViewportEl(): HTMLElement {\n return this.viewportEl;\n }\n\n getContainer(): HTMLElement {\n return this.container;\n }\n\n // ── Event handlers ──\n\n private handleScroll = (): void => {\n this.scheduleRender();\n };\n\n private handleMouseDown = (e: MouseEvent): void => {\n const cell = this.getCellFromEvent(e);\n if (cell) this.onCellClick?.(cell.row, cell.col, e);\n };\n\n private handleDblClick = (e: MouseEvent): void => {\n const cell = this.getCellFromEvent(e);\n if (cell) this.onCellDblClick?.(cell.row, cell.col, e);\n };\n\n private handleContextMenu = (e: MouseEvent): void => {\n const cell = this.getCellFromEvent(e);\n if (cell) this.onCellContextMenu?.(cell.row, cell.col, e);\n };\n\n private handleColHeaderMouse = (e: MouseEvent): void => {\n const target = (e.target as HTMLElement).closest('.wt-col-header-cell') as HTMLElement | null;\n if (!target) return;\n const col = parseInt(target.dataset.col ?? '', 10);\n if (isNaN(col)) return;\n\n // Check if clicking near the right edge (resize handle zone)\n const rect = target.getBoundingClientRect();\n if (e.clientX > rect.right - 5) {\n this.onColumnResizeStart?.(col, e.clientX);\n return;\n }\n\n this.onHeaderClick?.('col', col, e);\n };\n\n private handleRowHeaderMouse = (e: MouseEvent): void => {\n const target = (e.target as HTMLElement).closest('.wt-row-header-cell') as HTMLElement | null;\n if (!target) return;\n const row = parseInt(target.dataset.row ?? '', 10);\n if (isNaN(row)) return;\n this.onHeaderClick?.('row', row, e);\n };\n\n private handleCornerMouse = (_e: MouseEvent): void => {\n this.onHeaderClick?.('corner', -1, _e);\n };\n\n private handleColHeaderContextMenu = (e: MouseEvent): void => {\n e.preventDefault();\n const target = (e.target as HTMLElement).closest('.wt-col-header-cell') as HTMLElement | null;\n if (!target) return;\n const col = parseInt(target.dataset.col ?? '', 10);\n if (isNaN(col)) return;\n this.onHeaderContextMenu?.('col', col, e);\n };\n\n private handleRowHeaderContextMenu = (e: MouseEvent): void => {\n e.preventDefault();\n const target = (e.target as HTMLElement).closest('.wt-row-header-cell') as HTMLElement | null;\n if (!target) return;\n const row = parseInt(target.dataset.row ?? '', 10);\n if (isNaN(row)) return;\n this.onHeaderContextMenu?.('row', row, e);\n };\n\n destroy(): void {\n cancelAnimationFrame(this.rafId);\n this.scrollContainer.removeEventListener('scroll', this.handleScroll);\n this.viewportEl.removeEventListener('mousedown', this.handleMouseDown);\n this.viewportEl.removeEventListener('dblclick', this.handleDblClick);\n this.viewportEl.removeEventListener('contextmenu', this.handleContextMenu);\n this.colHeaderEl.removeEventListener('mousedown', this.handleColHeaderMouse);\n this.colHeaderEl.removeEventListener('contextmenu', this.handleColHeaderContextMenu);\n this.rowHeaderEl.removeEventListener('mousedown', this.handleRowHeaderMouse);\n this.rowHeaderEl.removeEventListener('contextmenu', this.handleRowHeaderContextMenu);\n this.cornerEl.removeEventListener('mousedown', this.handleCornerMouse);\n this.container.innerHTML = '';\n }\n}\n","import type { CellRenderer, CellState } from '../types/index.js';\nimport type { DataModel } from '../core/DataModel.js';\nimport type { ColumnModel } from '../columns/ColumnModel.js';\nimport type { RowModel } from '../rows/RowModel.js';\nimport { columnLabel } from '../columns/ColumnModel.js';\n\nconst DEFAULT_STATE: CellState = { selected: false, focused: false, editing: false, hover: false };\n\nexport class AutoFit {\n private measureEl: HTMLElement;\n private data: DataModel;\n private columns: ColumnModel;\n private renderers: Map<string, CellRenderer>;\n private defaultRenderer: CellRenderer;\n\n constructor(\n container: HTMLElement,\n data: DataModel,\n columns: ColumnModel,\n _rows: RowModel,\n renderers: Map<string, CellRenderer>,\n defaultRenderer: CellRenderer,\n ) {\n this.data = data;\n this.columns = columns;\n this.renderers = renderers;\n this.defaultRenderer = defaultRenderer;\n\n // Offscreen measure element\n this.measureEl = document.createElement('div');\n this.measureEl.className = 'wt-cell';\n this.measureEl.style.position = 'absolute';\n this.measureEl.style.visibility = 'hidden';\n this.measureEl.style.left = '-9999px';\n this.measureEl.style.top = '-9999px';\n this.measureEl.style.whiteSpace = 'nowrap';\n this.measureEl.style.height = 'auto';\n this.measureEl.style.width = 'auto';\n container.appendChild(this.measureEl);\n }\n\n /** Measure a single cell's natural width and height */\n measureCell(row: number, col: number): { width: number; height: number } {\n const cellData = this.data.getCell(row, col);\n const type = cellData?.type ?? this.columns.getConfig(col)?.type ?? 'text';\n const renderer = this.renderers.get(type) ?? this.defaultRenderer;\n\n renderer.render(this.measureEl, cellData, DEFAULT_STATE);\n\n const width = this.measureEl.scrollWidth + 1; // +1 for rounding\n const height = this.measureEl.scrollHeight + 1;\n\n this.measureEl.textContent = '';\n this.measureEl.innerHTML = '';\n\n return { width, height };\n }\n\n /** Auto-fit a column width to its content. Samples up to `maxRows` rows. */\n autoFitColumn(col: number, maxRows = 500): number {\n const padding = 16; // cell padding\n let maxWidth = 40; // minimum\n\n // Measure header\n // (Header is simple text, just measure label length)\n const label = this.columns.getConfig(col)?.label ?? columnLabel(col);\n this.measureEl.textContent = label;\n this.measureEl.style.fontWeight = '500';\n maxWidth = Math.max(maxWidth, this.measureEl.scrollWidth + padding);\n this.measureEl.style.fontWeight = '';\n\n // Sample rows\n const totalRows = this.data.rowCount;\n const step = totalRows > maxRows ? Math.floor(totalRows / maxRows) : 1;\n\n for (let r = 0; r < totalRows; r += step) {\n if (!this.data.hasCell(r, col)) continue;\n const { width } = this.measureCell(r, col);\n maxWidth = Math.max(maxWidth, width + padding);\n }\n\n const cfg = this.columns.getConfig(col);\n const min = cfg?.minWidth ?? 30;\n const max = cfg?.maxWidth ?? 600;\n\n return Math.max(min, Math.min(max, maxWidth));\n }\n\n /** Auto-fit a row height to its content */\n autoFitRow(row: number): number {\n let maxHeight = 20; // minimum\n\n for (let c = 0; c < this.columns.count; c++) {\n if (!this.data.hasCell(row, c)) continue;\n\n // Set width constraint for wrapping\n this.measureEl.style.width = `${this.columns.getWidth(c)}px`;\n this.measureEl.style.whiteSpace = 'normal';\n\n const { height } = this.measureCell(row, c);\n maxHeight = Math.max(maxHeight, height);\n\n this.measureEl.style.width = 'auto';\n this.measureEl.style.whiteSpace = 'nowrap';\n }\n\n return maxHeight;\n }\n\n destroy(): void {\n this.measureEl.remove();\n }\n}\n","import type { CellData, CellRenderer, CellState } from '../types/index.js';\n\nexport class TextRenderer implements CellRenderer {\n render(cell: HTMLElement, data: CellData | undefined, _state: CellState): void {\n const value = data?.value;\n if (value == null || value === '') {\n cell.textContent = '';\n return;\n }\n cell.textContent = String(value);\n }\n}\n","import type { CellData, CellRenderer, CellState } from '../types/index.js';\n\nexport class CheckboxRenderer implements CellRenderer {\n render(cell: HTMLElement, data: CellData | undefined, _state: CellState): void {\n const checked = !!data?.value;\n cell.innerHTML = `<label class=\"wt-checkbox\">\n <span class=\"wt-checkbox-box${checked ? ' wt-checkbox-box--checked' : ''}\">\n ${checked ? '<svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\"><path d=\"M2.5 6L5 8.5L9.5 3.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>' : ''}\n </span>\n </label>`;\n }\n}\n","import type { CellData, CellRenderer, CellState } from '../types/index.js';\n\nconst DEFAULT_COLORS: Record<string, { bg: string; text: string }> = {\n active: { bg: '#dcfce7', text: '#166534' },\n success: { bg: '#dcfce7', text: '#166534' },\n inactive: { bg: '#fef2f2', text: '#991b1b' },\n error: { bg: '#fef2f2', text: '#991b1b' },\n pending: { bg: '#fef9c3', text: '#854d0e' },\n warning: { bg: '#fef9c3', text: '#854d0e' },\n info: { bg: '#dbeafe', text: '#1e40af' },\n default: { bg: '#f1f5f9', text: '#475569' },\n};\n\nexport class BadgeRenderer implements CellRenderer {\n render(cell: HTMLElement, data: CellData | undefined, _state: CellState): void {\n if (data?.value == null || data.value === '') {\n cell.textContent = '';\n return;\n }\n\n const label = String(data.value);\n const key = label.toLowerCase();\n const colors = DEFAULT_COLORS[key] ?? DEFAULT_COLORS.default;\n const customBg = data.meta?.badgeBg as string | undefined;\n const customText = data.meta?.badgeText as string | undefined;\n\n cell.innerHTML = `<span class=\"wt-badge\" style=\"background:${customBg ?? colors.bg};color:${customText ?? colors.text}\">${label}</span>`;\n }\n}\n","import type { CellData, CellRenderer, CellState } from '../types/index.js';\n\nexport class NumberRenderer implements CellRenderer {\n private formatter: Intl.NumberFormat;\n\n constructor(locale?: string, options?: Intl.NumberFormatOptions) {\n this.formatter = new Intl.NumberFormat(locale, options);\n }\n\n render(cell: HTMLElement, data: CellData | undefined, _state: CellState): void {\n if (data?.value == null || data.value === '') {\n cell.textContent = '';\n return;\n }\n\n const num = Number(data.value);\n if (isNaN(num)) {\n cell.textContent = String(data.value);\n return;\n }\n\n cell.textContent = this.formatter.format(num);\n cell.style.textAlign = 'right';\n }\n}\n","import type { CellData, CellRenderer, CellState } from '../types/index.js';\n\nexport class ProgressRenderer implements CellRenderer {\n render(cell: HTMLElement, data: CellData | undefined, _state: CellState): void {\n if (data?.value == null) {\n cell.textContent = '';\n return;\n }\n\n const value = Math.max(0, Math.min(100, Number(data.value)));\n if (isNaN(value)) {\n cell.textContent = '';\n return;\n }\n\n const color = value >= 80 ? '#22c55e' : value >= 50 ? '#f59e0b' : value >= 25 ? '#f97316' : '#ef4444';\n\n cell.innerHTML = `<div class=\"wt-progress\">\n <div class=\"wt-progress-bar\" style=\"width:${value}%;background:${color}\"></div>\n <span class=\"wt-progress-label\">${Math.round(value)}%</span>\n </div>`;\n }\n}\n","import type { CellData, CellRenderer, CellState } from '../types/index.js';\n\n/**\n * Renderer for blank/empty cells.\n * Shows nothing and can optionally call a callback on render (e.g. for tracking).\n */\nexport class BlankRenderer implements CellRenderer {\n render(cell: HTMLElement, _data: CellData | undefined, _state: CellState): void {\n cell.textContent = '';\n }\n}\n","import type { CellRenderer } from '../types/index.js';\nimport { TextRenderer } from './TextRenderer.js';\nimport { CheckboxRenderer } from './CheckboxRenderer.js';\nimport { BadgeRenderer } from './BadgeRenderer.js';\nimport { NumberRenderer } from './NumberRenderer.js';\nimport { ProgressRenderer } from './ProgressRenderer.js';\nimport { BlankRenderer } from './BlankRenderer.js';\n\nexport class RendererRegistry {\n private renderers = new Map<string, CellRenderer>();\n readonly defaultRenderer: CellRenderer;\n\n constructor() {\n this.defaultRenderer = new TextRenderer();\n this.renderers.set('text', this.defaultRenderer);\n this.renderers.set('blank', new BlankRenderer());\n this.renderers.set('checkbox', new CheckboxRenderer());\n this.renderers.set('badge', new BadgeRenderer());\n this.renderers.set('number', new NumberRenderer());\n this.renderers.set('progress', new ProgressRenderer());\n }\n\n register(name: string, renderer: CellRenderer): void {\n this.renderers.set(name, renderer);\n }\n\n get(name: string): CellRenderer | undefined {\n return this.renderers.get(name);\n }\n\n getAll(): Map<string, CellRenderer> {\n return this.renderers;\n }\n}\n","import type { CellBounds, CellData, CellEditor } from '../types/index.js';\n\nexport class EditorManager {\n private editors = new Map<string, () => CellEditor>();\n private activeEditor: CellEditor | null = null;\n private activeEditorEl: HTMLElement | null = null;\n private activeRow = -1;\n private activeCol = -1;\n private overlayEl: HTMLElement;\n\n onClose: ((row: number, col: number, value: unknown, cancelled: boolean) => void) | null = null;\n\n constructor(container: HTMLElement) {\n this.overlayEl = document.createElement('div');\n this.overlayEl.className = 'wt-editor-overlay';\n this.overlayEl.style.display = 'none';\n container.appendChild(this.overlayEl);\n\n // Register default editors\n this.register('text', () => new TextEditorImpl());\n this.register('blank', () => new BlankEditorImpl());\n }\n\n register(name: string, factory: () => CellEditor): void {\n this.editors.set(name, factory);\n }\n\n get isEditing(): boolean {\n return this.activeEditor !== null;\n }\n\n get editingCell(): { row: number; col: number } | null {\n if (!this.activeEditor) return null;\n return { row: this.activeRow, col: this.activeCol };\n }\n\n open(\n row: number,\n col: number,\n editorType: string,\n value: unknown,\n bounds: CellBounds,\n cellData: CellData | undefined,\n initialChar?: string,\n ): void {\n this.close(false);\n\n const factory = this.editors.get(editorType);\n if (!factory) return;\n\n this.activeRow = row;\n this.activeCol = col;\n this.activeEditor = factory();\n\n // Position overlay\n this.overlayEl.style.display = '';\n this.overlayEl.style.left = `${bounds.x}px`;\n this.overlayEl.style.top = `${bounds.y}px`;\n this.overlayEl.style.width = `${bounds.width}px`;\n this.overlayEl.style.height = `${bounds.height}px`;\n\n this.activeEditorEl = this.activeEditor.createElement(this.overlayEl);\n\n // If initialChar is provided, start with that character instead of the current value\n const openValue = initialChar !== undefined ? initialChar : value;\n this.activeEditor.open(openValue, bounds, cellData);\n\n // Handle key events on the editor\n this.activeEditorEl.addEventListener('keydown', this.handleEditorKey);\n }\n\n close(save: boolean): void {\n if (!this.activeEditor) return;\n\n const editor = this.activeEditor;\n const row = this.activeRow;\n const col = this.activeCol;\n let value: unknown;\n\n if (save) {\n value = editor.getValue();\n if (editor.validate) {\n const result = editor.validate(value);\n if (result !== true) {\n // Validation failed\n return;\n }\n }\n }\n\n // Remove listener before clearing DOM\n if (this.activeEditorEl) {\n this.activeEditorEl.removeEventListener('keydown', this.handleEditorKey);\n this.activeEditorEl = null;\n }\n editor.close();\n this.overlayEl.innerHTML = '';\n this.overlayEl.style.display = 'none';\n this.activeEditor = null;\n this.activeRow = -1;\n this.activeCol = -1;\n\n this.onClose?.(row, col, save ? value : undefined, !save);\n }\n\n private handleEditorKey = (e: KeyboardEvent): void => {\n switch (e.key) {\n case 'Enter':\n if (!e.shiftKey) {\n e.preventDefault();\n e.stopPropagation();\n this.close(true);\n }\n break;\n case 'Escape':\n e.preventDefault();\n e.stopPropagation();\n this.close(false);\n break;\n case 'Tab':\n e.preventDefault();\n e.stopPropagation();\n this.close(true);\n break;\n }\n };\n\n destroy(): void {\n this.close(false);\n this.overlayEl.remove();\n }\n}\n\n// ── Built-in Text Editor ──\n\nclass TextEditorImpl implements CellEditor {\n private input!: HTMLInputElement;\n\n createElement(container: HTMLElement): HTMLElement {\n this.input = document.createElement('input');\n this.input.type = 'text';\n this.input.className = 'wt-editor-input';\n container.appendChild(this.input);\n return this.input;\n }\n\n open(value: unknown, _bounds: CellBounds, _cellData: CellData | undefined): void {\n this.input.value = value != null ? String(value) : '';\n requestAnimationFrame(() => {\n this.input.focus();\n this.input.select();\n });\n }\n\n getValue(): unknown {\n return this.input.value;\n }\n\n close(): void {\n this.input.remove();\n }\n}\n\n// ── Built-in Blank Editor (non-editable, closes immediately) ──\n\nclass BlankEditorImpl implements CellEditor {\n private el!: HTMLElement;\n\n createElement(container: HTMLElement): HTMLElement {\n this.el = document.createElement('div');\n container.appendChild(this.el);\n return this.el;\n }\n\n open(): void {\n // Blank cells are not editable - close immediately on next tick\n // The EditorManager.onClose will fire with cancelled=true\n }\n\n getValue(): unknown {\n return undefined;\n }\n\n close(): void {\n this.el?.remove();\n }\n}\n","import type { SelectionModel } from '../core/SelectionModel.js';\n\nexport interface KeyboardNavCallbacks {\n onStartEdit: (row: number, col: number, initialChar?: string) => void;\n onDelete: () => void;\n onCopy: () => void;\n onPaste: () => void;\n onCut: () => void;\n onUndo: () => void;\n onRedo: () => void;\n onScrollTo: (row: number, col: number) => void;\n}\n\nexport class KeyboardNav {\n private selection: SelectionModel;\n private callbacks: KeyboardNavCallbacks;\n\n constructor(selection: SelectionModel, callbacks: KeyboardNavCallbacks) {\n this.selection = selection;\n this.callbacks = callbacks;\n }\n\n handleKeyDown(e: KeyboardEvent): void {\n const ctrl = e.ctrlKey || e.metaKey;\n const shift = e.shiftKey;\n const focus = this.selection.focus;\n\n switch (e.key) {\n case 'ArrowUp':\n e.preventDefault();\n this.selection.move(-1, 0, shift);\n if (this.selection.focus) this.callbacks.onScrollTo(this.selection.focus.row, this.selection.focus.col);\n break;\n\n case 'ArrowDown':\n e.preventDefault();\n this.selection.move(1, 0, shift);\n if (this.selection.focus) this.callbacks.onScrollTo(this.selection.focus.row, this.selection.focus.col);\n break;\n\n case 'ArrowLeft':\n e.preventDefault();\n this.selection.move(0, -1, shift);\n if (this.selection.focus) this.callbacks.onScrollTo(this.selection.focus.row, this.selection.focus.col);\n break;\n\n case 'ArrowRight':\n e.preventDefault();\n this.selection.move(0, 1, shift);\n if (this.selection.focus) this.callbacks.onScrollTo(this.selection.focus.row, this.selection.focus.col);\n break;\n\n case 'Tab':\n e.preventDefault();\n this.selection.move(0, shift ? -1 : 1, false);\n if (this.selection.focus) this.callbacks.onScrollTo(this.selection.focus.row, this.selection.focus.col);\n break;\n\n case 'Enter':\n e.preventDefault();\n if (focus) {\n this.callbacks.onStartEdit(focus.row, focus.col);\n }\n break;\n\n case 'F2':\n e.preventDefault();\n if (focus) {\n this.callbacks.onStartEdit(focus.row, focus.col);\n }\n break;\n\n case 'Delete':\n case 'Backspace':\n e.preventDefault();\n this.callbacks.onDelete();\n break;\n\n case 'Escape':\n e.preventDefault();\n this.selection.clear();\n break;\n\n case 'Home':\n e.preventDefault();\n if (ctrl) {\n this.selection.focusCell(0, 0);\n } else if (focus) {\n this.selection.focusCell(focus.row, 0);\n }\n if (this.selection.focus) this.callbacks.onScrollTo(this.selection.focus.row, this.selection.focus.col);\n break;\n\n case 'End':\n e.preventDefault();\n if (this.selection.focus) this.callbacks.onScrollTo(this.selection.focus.row, this.selection.focus.col);\n break;\n\n case 'a':\n if (ctrl) {\n e.preventDefault();\n this.selection.selectAll();\n } else {\n this.handleCharInput(e);\n }\n break;\n\n case 'c':\n if (ctrl) {\n e.preventDefault();\n this.callbacks.onCopy();\n } else {\n this.handleCharInput(e);\n }\n break;\n\n case 'v':\n if (ctrl) {\n e.preventDefault();\n this.callbacks.onPaste();\n } else {\n this.handleCharInput(e);\n }\n break;\n\n case 'x':\n if (ctrl) {\n e.preventDefault();\n this.callbacks.onCut();\n } else {\n this.handleCharInput(e);\n }\n break;\n\n case 'z':\n if (ctrl) {\n e.preventDefault();\n if (shift) {\n this.callbacks.onRedo();\n } else {\n this.callbacks.onUndo();\n }\n } else {\n this.handleCharInput(e);\n }\n break;\n\n case 'y':\n if (ctrl) {\n e.preventDefault();\n this.callbacks.onRedo();\n } else {\n this.handleCharInput(e);\n }\n break;\n\n default:\n if (!ctrl && !e.altKey && e.key.length === 1) {\n this.handleCharInput(e);\n }\n break;\n }\n }\n\n private handleCharInput(e: KeyboardEvent): void {\n if (e.ctrlKey || e.metaKey || e.altKey) return;\n const focus = this.selection.focus;\n if (!focus) return;\n e.preventDefault();\n this.callbacks.onStartEdit(focus.row, focus.col, e.key);\n }\n}\n","import type { DataModel } from '../core/DataModel.js';\nimport type { SelectionModel } from '../core/SelectionModel.js';\nimport type { CellPatch } from '../types/index.js';\n\nexport class ClipboardManager {\n private data: DataModel;\n private selection: SelectionModel;\n\n onChange: ((patches: CellPatch[]) => void) | null = null;\n\n constructor(data: DataModel, selection: SelectionModel) {\n this.data = data;\n this.selection = selection;\n }\n\n async copy(): Promise<void> {\n const tsv = this.selectionToTSV();\n if (!tsv) return;\n\n try {\n await navigator.clipboard.writeText(tsv);\n } catch {\n // Fallback for non-secure contexts\n this.fallbackCopy(tsv);\n }\n }\n\n async cut(): Promise<void> {\n await this.copy();\n this.deleteSelected();\n }\n\n async paste(): Promise<void> {\n const focus = this.selection.focus;\n if (!focus) return;\n\n let text: string;\n try {\n text = await navigator.clipboard.readText();\n } catch {\n return;\n }\n\n const rows = this.parseTSV(text);\n if (rows.length === 0) return;\n\n const isSingleCell = rows.length === 1 && rows[0].length === 1;\n const patches: CellPatch[] = [];\n\n if (isSingleCell && !this.isFullRowOrColSelected()) {\n // Single cell copied: fill into all selected cells\n const value = rows[0][0];\n this.selection.forEachSelected((row, col) => {\n if (row < this.data.rowCount && col < this.data.colCount) {\n patches.push({ row, col, data: { value } });\n }\n });\n } else {\n // Multi-cell paste: place starting from focus\n for (let r = 0; r < rows.length; r++) {\n for (let c = 0; c < rows[r].length; c++) {\n const targetRow = focus.row + r;\n const targetCol = focus.col + c;\n if (targetRow >= this.data.rowCount || targetCol >= this.data.colCount) continue;\n patches.push({\n row: targetRow,\n col: targetCol,\n data: { value: rows[r][c] },\n });\n }\n }\n }\n\n if (patches.length > 0) {\n this.data.applyPatch(patches);\n this.onChange?.(patches);\n }\n }\n\n /** Check if current selection spans an entire row or column */\n private isFullRowOrColSelected(): boolean {\n const bounds = this.selection.getBounds();\n if (!bounds) return false;\n const isFullRow = bounds.c1 === 0 && bounds.c2 === this.data.colCount - 1;\n const isFullCol = bounds.r1 === 0 && bounds.r2 === this.data.rowCount - 1;\n return isFullRow || isFullCol;\n }\n\n deleteSelected(): void {\n const patches: CellPatch[] = [];\n this.selection.forEachSelected((row, col) => {\n if (this.data.hasCell(row, col)) {\n patches.push({ row, col, data: { value: undefined } });\n }\n });\n if (patches.length > 0) {\n this.data.applyPatch(patches);\n this.onChange?.(patches);\n }\n }\n\n private selectionToTSV(): string | null {\n const bounds = this.selection.getBounds();\n if (!bounds) return null;\n\n const lines: string[] = [];\n for (let r = bounds.r1; r <= bounds.r2; r++) {\n const cols: string[] = [];\n for (let c = bounds.c1; c <= bounds.c2; c++) {\n const cell = this.data.getCell(r, c);\n const val = cell?.value;\n cols.push(val != null ? String(val) : '');\n }\n lines.push(cols.join('\\t'));\n }\n return lines.join('\\n');\n }\n\n private parseTSV(text: string): string[][] {\n return text.split('\\n').map(line => line.split('\\t'));\n }\n\n private fallbackCopy(text: string): void {\n const textarea = document.createElement('textarea');\n textarea.value = text;\n textarea.style.position = 'fixed';\n textarea.style.left = '-9999px';\n document.body.appendChild(textarea);\n textarea.select();\n document.execCommand('copy');\n textarea.remove();\n }\n}\n","import type { ColumnModel } from '../columns/ColumnModel.js';\n\nexport class ColumnResize {\n private columns: ColumnModel;\n private resizing = false;\n private resizeCol = -1;\n private startX = 0;\n private startWidth = 0;\n\n onResize: ((col: number, width: number) => void) | null = null;\n\n constructor(columns: ColumnModel) {\n this.columns = columns;\n }\n\n start(col: number, clientX: number): void {\n if (col < 0 || col >= this.columns.count) return;\n this.resizing = true;\n this.resizeCol = col;\n this.startX = clientX;\n this.startWidth = this.columns.getWidth(col);\n\n document.addEventListener('mousemove', this.handleMove);\n document.addEventListener('mouseup', this.handleUp);\n document.body.style.cursor = 'col-resize';\n document.body.style.userSelect = 'none';\n }\n\n private handleMove = (e: MouseEvent): void => {\n if (!this.resizing) return;\n const delta = e.clientX - this.startX;\n const newWidth = Math.max(30, this.startWidth + delta);\n this.columns.setWidth(this.resizeCol, newWidth);\n this.onResize?.(this.resizeCol, newWidth);\n };\n\n private handleUp = (): void => {\n this.resizing = false;\n document.removeEventListener('mousemove', this.handleMove);\n document.removeEventListener('mouseup', this.handleUp);\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n };\n\n destroy(): void {\n document.removeEventListener('mousemove', this.handleMove);\n document.removeEventListener('mouseup', this.handleUp);\n }\n}\n","import type { RowModel } from '../rows/RowModel.js';\n\nexport class RowResize {\n private rows: RowModel;\n private resizing = false;\n private resizeRow = -1;\n private startY = 0;\n private startHeight = 0;\n\n onResize: ((row: number, height: number) => void) | null = null;\n\n constructor(rows: RowModel) {\n this.rows = rows;\n }\n\n start(row: number, clientY: number): void {\n this.resizing = true;\n this.resizeRow = row;\n this.startY = clientY;\n this.startHeight = this.rows.getHeight(row);\n\n document.addEventListener('mousemove', this.handleMove);\n document.addEventListener('mouseup', this.handleUp);\n document.body.style.cursor = 'row-resize';\n document.body.style.userSelect = 'none';\n }\n\n private handleMove = (e: MouseEvent): void => {\n if (!this.resizing) return;\n const delta = e.clientY - this.startY;\n const newHeight = Math.max(20, this.startHeight + delta);\n this.rows.setHeight(this.resizeRow, newHeight);\n this.onResize?.(this.resizeRow, newHeight);\n };\n\n private handleUp = (): void => {\n this.resizing = false;\n document.removeEventListener('mousemove', this.handleMove);\n document.removeEventListener('mouseup', this.handleUp);\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n };\n\n destroy(): void {\n document.removeEventListener('mousemove', this.handleMove);\n document.removeEventListener('mouseup', this.handleUp);\n }\n}\n","export type MenuTarget = 'cell' | 'column-header' | 'row-header';\n\n/** Context for evaluating dynamic menu item properties */\nexport interface MenuContext {\n /** What was right-clicked */\n target: MenuTarget;\n /** Row where the right-click happened (-1 for column headers) */\n row: number;\n /** Column where the right-click happened (-1 for row headers) */\n col: number;\n /** Number of selected cells */\n selectedCount: number;\n /** Whether multiple cells are selected */\n isMultiSelect: boolean;\n /** Whether an entire row is selected */\n isFullRow: boolean;\n /** Whether an entire column is selected */\n isFullCol: boolean;\n /** Whether the grid is readOnly */\n readOnly: boolean;\n /** Whether undo is available */\n canUndo: boolean;\n /** Whether redo is available */\n canRedo: boolean;\n}\n\nexport interface MenuItemConfig {\n label: string;\n shortcut?: string;\n /** Static boolean or callback evaluated at open time */\n disabled?: boolean | ((ctx: MenuContext) => boolean);\n /** Static boolean or callback - if false, item is not rendered */\n visible?: boolean | ((ctx: MenuContext) => boolean);\n separator?: boolean;\n action?: (ctx: MenuContext) => void;\n}\n\nexport class ContextMenu {\n private el: HTMLElement | null = null;\n private closeHandler = (e: MouseEvent) => {\n if (this.el && !this.el.contains(e.target as Node)) {\n this.close();\n }\n };\n private keyHandler = (e: KeyboardEvent) => {\n if (e.key === 'Escape') this.close();\n };\n\n open(x: number, y: number, items: MenuItemConfig[], ctx: MenuContext): void {\n this.close();\n\n this.el = document.createElement('div');\n this.el.className = 'wt-context-menu';\n\n for (const item of items) {\n // Evaluate visibility\n const visible = typeof item.visible === 'function'\n ? item.visible(ctx)\n : (item.visible ?? true);\n if (!visible) continue;\n\n if (item.separator) {\n const sep = document.createElement('div');\n sep.className = 'wt-context-menu-separator';\n this.el.appendChild(sep);\n continue;\n }\n\n // Evaluate disabled\n const disabled = typeof item.disabled === 'function'\n ? item.disabled(ctx)\n : (item.disabled ?? false);\n\n const row = document.createElement('div');\n row.className = 'wt-context-menu-item';\n if (disabled) row.classList.add('wt-context-menu-item--disabled');\n\n const label = document.createElement('span');\n label.textContent = item.label;\n row.appendChild(label);\n\n if (item.shortcut) {\n const shortcut = document.createElement('span');\n shortcut.className = 'wt-context-menu-shortcut';\n shortcut.textContent = item.shortcut;\n row.appendChild(shortcut);\n }\n\n if (!disabled && item.action) {\n const action = item.action;\n row.addEventListener('click', (e) => {\n e.stopPropagation();\n this.close();\n action(ctx);\n });\n }\n\n this.el.appendChild(row);\n }\n\n document.body.appendChild(this.el);\n\n // Adjust position to stay in viewport\n const rect = this.el.getBoundingClientRect();\n if (x + rect.width > window.innerWidth) x = window.innerWidth - rect.width - 4;\n if (y + rect.height > window.innerHeight) y = window.innerHeight - rect.height - 4;\n this.el.style.left = `${Math.max(0, x)}px`;\n this.el.style.top = `${Math.max(0, y)}px`;\n\n requestAnimationFrame(() => {\n document.addEventListener('mousedown', this.closeHandler);\n document.addEventListener('keydown', this.keyHandler);\n });\n }\n\n close(): void {\n if (this.el) {\n this.el.remove();\n this.el = null;\n }\n document.removeEventListener('mousedown', this.closeHandler);\n document.removeEventListener('keydown', this.keyHandler);\n }\n\n get isOpen(): boolean {\n return this.el !== null;\n }\n\n destroy(): void {\n this.close();\n }\n}\n","import type { CellPatch, SelectionRange } from '../types/index.js';\nimport type { DataModel } from '../core/DataModel.js';\nimport type { SelectionModel } from '../core/SelectionModel.js';\nimport type { ColumnModel } from '../columns/ColumnModel.js';\nimport type { RowModel } from '../rows/RowModel.js';\n\nexport type FillDirection = 'down' | 'up' | 'right' | 'left' | 'diagonal';\n\nexport type FillCallback = (\n source: SelectionRange,\n fill: SelectionRange,\n direction: FillDirection,\n) => CellPatch[] | boolean | void;\n\nexport class FillHandle {\n private handleEl: HTMLElement;\n private shadowEl: HTMLElement;\n private dragging = false;\n private currentRow = -1;\n private currentCol = -1;\n private data: DataModel;\n private selection: SelectionModel;\n\n getCellAtPoint: ((x: number, y: number) => { row: number; col: number } | null) | null = null;\n getCellBounds: ((row: number, col: number) => { x: number; y: number; width: number; height: number }) | null = null;\n onFill: ((patches: CellPatch[], source: SelectionRange, fill: SelectionRange, direction: FillDirection) => void) | null = null;\n onFillCallback: FillCallback | null = null;\n enabled = true;\n\n constructor(\n container: HTMLElement,\n data: DataModel,\n selection: SelectionModel,\n _columns: ColumnModel,\n _rows: RowModel,\n ) {\n this.data = data;\n this.selection = selection;\n\n // Handle dot\n this.handleEl = document.createElement('div');\n this.handleEl.className = 'wt-fill-handle';\n this.handleEl.style.display = 'none';\n container.appendChild(this.handleEl);\n\n // Shadow preview overlay\n this.shadowEl = document.createElement('div');\n this.shadowEl.className = 'wt-fill-shadow';\n this.shadowEl.style.display = 'none';\n container.appendChild(this.shadowEl);\n\n this.handleEl.addEventListener('mousedown', this.onMouseDown);\n }\n\n updatePosition(): void {\n const bounds = this.selection.getBounds();\n if (!this.enabled || !bounds || !this.getCellBounds) {\n this.handleEl.style.display = 'none';\n return;\n }\n\n const lastCell = this.getCellBounds(bounds.r2, bounds.c2);\n this.handleEl.style.display = '';\n this.handleEl.style.left = `${lastCell.x + lastCell.width - 4}px`;\n this.handleEl.style.top = `${lastCell.y + lastCell.height - 4}px`;\n }\n\n private onMouseDown = (e: MouseEvent): void => {\n e.preventDefault();\n e.stopPropagation();\n\n const bounds = this.selection.getBounds();\n if (!bounds) return;\n\n this.dragging = true;\n this.currentRow = bounds.r2;\n this.currentCol = bounds.c2;\n\n document.addEventListener('mousemove', this.onMouseMove);\n document.addEventListener('mouseup', this.onMouseUp);\n document.body.style.cursor = 'crosshair';\n document.body.style.userSelect = 'none';\n };\n\n private onMouseMove = (e: MouseEvent): void => {\n if (!this.dragging || !this.getCellAtPoint) return;\n const cell = this.getCellAtPoint(e.clientX, e.clientY);\n if (cell) {\n this.currentRow = cell.row;\n this.currentCol = cell.col;\n this.updateShadow();\n }\n };\n\n private updateShadow(): void {\n const bounds = this.selection.getBounds();\n if (!bounds || !this.getCellBounds) {\n this.shadowEl.style.display = 'none';\n return;\n }\n\n const { r1, c1, r2, c2 } = bounds;\n const cr = this.currentRow;\n const cc = this.currentCol;\n\n // If still inside the selection, hide shadow\n if (cr >= r1 && cr <= r2 && cc >= c1 && cc <= c2) {\n this.shadowEl.style.display = 'none';\n // Reset handle to original position\n this.updatePosition();\n return;\n }\n\n // Compute the full fill area (source + fill combined)\n const minR = Math.min(r1, cr);\n const maxR = Math.max(r2, cr);\n const minC = Math.min(c1, cc);\n const maxC = Math.max(c2, cc);\n\n const topLeft = this.getCellBounds(minR, minC);\n const bottomRight = this.getCellBounds(maxR, maxC);\n\n const sx = topLeft.x;\n const sy = topLeft.y;\n const sw = bottomRight.x + bottomRight.width - sx;\n const sh = bottomRight.y + bottomRight.height - sy;\n\n // Show shadow over the FILL area only (exclude source)\n // We show the full expanded area as the shadow, the source is already highlighted by selection\n this.shadowEl.style.display = '';\n this.shadowEl.style.left = `${sx}px`;\n this.shadowEl.style.top = `${sy}px`;\n this.shadowEl.style.width = `${sw}px`;\n this.shadowEl.style.height = `${sh}px`;\n\n // Move the handle dot to the current drag position\n const curCell = this.getCellBounds(cr, cc);\n this.handleEl.style.left = `${curCell.x + curCell.width - 4}px`;\n this.handleEl.style.top = `${curCell.y + curCell.height - 4}px`;\n }\n\n private onMouseUp = (): void => {\n if (!this.dragging) return;\n this.dragging = false;\n document.removeEventListener('mousemove', this.onMouseMove);\n document.removeEventListener('mouseup', this.onMouseUp);\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n\n // Hide shadow\n this.shadowEl.style.display = 'none';\n\n this.executeFill();\n\n // Reset handle to selection corner\n this.updatePosition();\n };\n\n private executeFill(): void {\n const bounds = this.selection.getBounds();\n if (!bounds) return;\n\n const { r1, c1, r2, c2 } = bounds;\n const cr = this.currentRow;\n const cc = this.currentCol;\n\n // If still inside selection, nothing to fill\n if (cr >= r1 && cr <= r2 && cc >= c1 && cc <= c2) return;\n\n // Determine direction\n const dRow = cr > r2 ? cr - r2 : cr < r1 ? r1 - cr : 0;\n const dCol = cc > c2 ? cc - c2 : cc < c1 ? c1 - cc : 0;\n\n let direction: FillDirection;\n let fillRange: SelectionRange;\n\n if (dRow > 0 && dCol > 0) {\n // Diagonal: fill the full expanded rectangle minus the source\n direction = 'diagonal';\n fillRange = {\n startRow: Math.min(r1, cr),\n startCol: Math.min(c1, cc),\n endRow: Math.max(r2, cr),\n endCol: Math.max(c2, cc),\n };\n } else if (dRow > 0 && dCol === 0) {\n // Expand rows only\n if (cr > r2) {\n direction = 'down';\n fillRange = { startRow: r2 + 1, startCol: c1, endRow: cr, endCol: c2 };\n } else {\n direction = 'up';\n fillRange = { startRow: cr, startCol: c1, endRow: r1 - 1, endCol: c2 };\n }\n } else if (dCol > 0 && dRow === 0) {\n if (cc > c2) {\n direction = 'right';\n fillRange = { startRow: r1, startCol: c2 + 1, endRow: r2, endCol: cc };\n } else {\n direction = 'left';\n fillRange = { startRow: r1, startCol: cc, endRow: r2, endCol: c1 - 1 };\n }\n } else {\n // Mixed: treat as diagonal\n direction = 'diagonal';\n fillRange = {\n startRow: Math.min(r1, cr),\n startCol: Math.min(c1, cc),\n endRow: Math.max(r2, cr),\n endCol: Math.max(c2, cc),\n };\n }\n\n const sourceRange: SelectionRange = { startRow: r1, startCol: c1, endRow: r2, endCol: c2 };\n\n // External callback\n if (this.onFillCallback) {\n const result = this.onFillCallback(sourceRange, fillRange, direction);\n if (result === true) return;\n if (Array.isArray(result)) {\n this.onFill?.(result, sourceRange, fillRange, direction);\n return;\n }\n }\n\n const patches = this.defaultFill(sourceRange, fillRange, direction);\n this.onFill?.(patches, sourceRange, fillRange, direction);\n }\n\n private defaultFill(\n source: SelectionRange,\n fill: SelectionRange,\n _direction: FillDirection,\n ): CellPatch[] {\n const patches: CellPatch[] = [];\n const srcRows = source.endRow - source.startRow + 1;\n const srcCols = source.endCol - source.startCol + 1;\n\n for (let r = fill.startRow; r <= fill.endRow; r++) {\n for (let c = fill.startCol; c <= fill.endCol; c++) {\n // Skip cells that are inside the source range\n if (r >= source.startRow && r <= source.endRow &&\n c >= source.startCol && c <= source.endCol) {\n continue;\n }\n\n // Map to source cell using modulo wrapping\n const srcRow = source.startRow + (((r - source.startRow) % srcRows) + srcRows) % srcRows;\n const srcCol = source.startCol + (((c - source.startCol) % srcCols) + srcCols) % srcCols;\n const srcCell = this.data.getCell(srcRow, srcCol);\n\n patches.push({\n row: r,\n col: c,\n data: { value: srcCell?.value },\n });\n }\n }\n\n return patches;\n }\n\n destroy(): void {\n this.handleEl.remove();\n this.shadowEl.remove();\n document.removeEventListener('mousemove', this.onMouseMove);\n document.removeEventListener('mouseup', this.onMouseUp);\n }\n}\n","import type { ColumnModel } from '../columns/ColumnModel.js';\n\nexport class ColumnReorder {\n private columns: ColumnModel;\n private dragging = false;\n private sourceCol = -1;\n private targetCol = -1;\n private ghostEl: HTMLElement | null = null;\n private indicatorEl: HTMLElement | null = null;\n\n onReorder: ((fromCol: number, toCol: number) => void) | null = null;\n\n /** Resolve column index from screen X */\n getColAtX: ((clientX: number) => number) | null = null;\n /** Get column header label */\n getColLabel: ((col: number) => string) | null = null;\n\n constructor(columns: ColumnModel) {\n this.columns = columns;\n }\n\n start(col: number, event: MouseEvent, container: HTMLElement): void {\n this.dragging = true;\n this.sourceCol = col;\n this.targetCol = col;\n\n // Create ghost element\n this.ghostEl = document.createElement('div');\n this.ghostEl.className = 'wt-reorder-ghost';\n this.ghostEl.textContent = this.getColLabel?.(col) ?? String(col);\n this.ghostEl.style.left = `${event.clientX}px`;\n this.ghostEl.style.top = `${event.clientY - 14}px`;\n document.body.appendChild(this.ghostEl);\n\n // Create drop indicator\n this.indicatorEl = document.createElement('div');\n this.indicatorEl.className = 'wt-reorder-indicator';\n this.indicatorEl.style.display = 'none';\n container.appendChild(this.indicatorEl);\n\n document.addEventListener('mousemove', this.onMouseMove);\n document.addEventListener('mouseup', this.onMouseUp);\n document.body.style.cursor = 'grabbing';\n document.body.style.userSelect = 'none';\n }\n\n private onMouseMove = (e: MouseEvent): void => {\n if (!this.dragging) return;\n\n // Move ghost\n if (this.ghostEl) {\n this.ghostEl.style.left = `${e.clientX}px`;\n this.ghostEl.style.top = `${e.clientY - 14}px`;\n }\n\n // Update target\n if (this.getColAtX) {\n this.targetCol = this.getColAtX(e.clientX);\n }\n\n // Position indicator\n if (this.indicatorEl && this.targetCol >= 0) {\n const x = this.columns.getX(this.targetCol);\n this.indicatorEl.style.display = '';\n this.indicatorEl.style.left = `${x}px`;\n }\n };\n\n private onMouseUp = (): void => {\n if (!this.dragging) return;\n this.dragging = false;\n\n document.removeEventListener('mousemove', this.onMouseMove);\n document.removeEventListener('mouseup', this.onMouseUp);\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n\n this.ghostEl?.remove();\n this.ghostEl = null;\n this.indicatorEl?.remove();\n this.indicatorEl = null;\n\n if (this.sourceCol !== this.targetCol && this.targetCol >= 0) {\n this.onReorder?.(this.sourceCol, this.targetCol);\n }\n };\n\n destroy(): void {\n this.ghostEl?.remove();\n this.indicatorEl?.remove();\n document.removeEventListener('mousemove', this.onMouseMove);\n document.removeEventListener('mouseup', this.onMouseUp);\n }\n}\n","export interface RowGroup {\n /** First data row of the group */\n startRow: number;\n /** Number of child rows (excluding the header row) */\n count: number;\n /** Label shown on the group header */\n label?: string;\n /** Is the group currently expanded? */\n expanded: boolean;\n /** Nesting depth (0 = top level) */\n depth: number;\n}\n\n/**\n * Manages row grouping with expand/collapse.\n * Groups hide/show rows by integrating with ViewMapping filters.\n */\nexport class RowGroupModel {\n private groups: RowGroup[] = [];\n private hiddenRows = new Set<number>();\n\n onChange: (() => void) | null = null;\n\n constructor(initialGroups?: RowGroup[]) {\n if (initialGroups) {\n this.groups = initialGroups.map(g => ({ ...g }));\n this.rebuildHidden();\n }\n }\n\n addGroup(group: RowGroup): void {\n this.groups.push({ ...group });\n this.rebuildHidden();\n this.onChange?.();\n }\n\n removeGroup(startRow: number): void {\n this.groups = this.groups.filter(g => g.startRow !== startRow);\n this.rebuildHidden();\n this.onChange?.();\n }\n\n toggleGroup(startRow: number): void {\n const group = this.groups.find(g => g.startRow === startRow);\n if (!group) return;\n group.expanded = !group.expanded;\n this.rebuildHidden();\n this.onChange?.();\n }\n\n expandAll(): void {\n for (const g of this.groups) g.expanded = true;\n this.rebuildHidden();\n this.onChange?.();\n }\n\n collapseAll(): void {\n for (const g of this.groups) g.expanded = false;\n this.rebuildHidden();\n this.onChange?.();\n }\n\n isGroupHeader(row: number): RowGroup | null {\n return this.groups.find(g => g.startRow === row) ?? null;\n }\n\n isHidden(row: number): boolean {\n return this.hiddenRows.has(row);\n }\n\n getGroups(): RowGroup[] {\n return [...this.groups];\n }\n\n /** Build the set of hidden rows based on collapsed groups */\n private rebuildHidden(): void {\n this.hiddenRows.clear();\n for (const g of this.groups) {\n if (!g.expanded) {\n // Hide all child rows (startRow+1 to startRow+count)\n for (let i = 1; i <= g.count; i++) {\n this.hiddenRows.add(g.startRow + i);\n }\n }\n }\n }\n\n /** Get a filter function compatible with ViewMapping */\n getFilter(): (row: number) => boolean {\n return (row: number) => !this.hiddenRows.has(row);\n }\n\n clear(): void {\n this.groups = [];\n this.hiddenRows.clear();\n this.onChange?.();\n }\n}\n","import type { DataModel } from './DataModel.js';\n\nexport type SortDirection = 'asc' | 'desc' | null;\n\nexport interface SortState {\n col: number;\n direction: SortDirection;\n compareFn?: (a: unknown, b: unknown) => number;\n}\n\nexport type FilterFn = (row: number, data: DataModel) => boolean;\n\n/**\n * Maps visual row indices to actual data row indices.\n * Handles sorting and filtering without mutating the DataModel.\n */\nexport class ViewMapping {\n /** visualIndex -> dataIndex */\n private mapping: number[] = [];\n private identity = true;\n\n private sortState: SortState | null = null;\n private filters = new Map<number, FilterFn>();\n private data: DataModel;\n\n onChange: (() => void) | null = null;\n\n constructor(data: DataModel) {\n this.data = data;\n this.rebuild();\n }\n\n /** Total visible row count after filtering */\n get visibleRowCount(): number {\n return this.identity ? this.data.rowCount : this.mapping.length;\n }\n\n /** Translate visual row to data row */\n toDataRow(visualRow: number): number {\n if (this.identity) return visualRow;\n return this.mapping[visualRow] ?? visualRow;\n }\n\n /** Translate data row to visual row (or -1 if filtered out) */\n toVisualRow(dataRow: number): number {\n if (this.identity) return dataRow;\n const idx = this.mapping.indexOf(dataRow);\n return idx;\n }\n\n // ── Sorting ──\n\n sort(col: number, direction: SortDirection, compareFn?: (a: unknown, b: unknown) => number): void {\n if (direction === null) {\n this.sortState = null;\n } else {\n this.sortState = { col, direction, compareFn };\n }\n this.rebuild();\n this.onChange?.();\n }\n\n getSortState(): SortState | null {\n return this.sortState;\n }\n\n clearSort(): void {\n this.sortState = null;\n this.rebuild();\n this.onChange?.();\n }\n\n // ── Filtering ──\n\n setFilter(col: number, fn: FilterFn): void {\n this.filters.set(col, fn);\n this.rebuild();\n this.onChange?.();\n }\n\n removeFilter(col: number): void {\n this.filters.delete(col);\n this.rebuild();\n this.onChange?.();\n }\n\n clearFilters(): void {\n this.filters.clear();\n this.rebuild();\n this.onChange?.();\n }\n\n getActiveFilters(): number[] {\n return Array.from(this.filters.keys());\n }\n\n // ── Rebuild ──\n\n rebuild(): void {\n const hasSort = this.sortState !== null;\n const hasFilter = this.filters.size > 0;\n\n if (!hasSort && !hasFilter) {\n this.identity = true;\n this.mapping = [];\n return;\n }\n\n this.identity = false;\n\n // Start with all rows\n let rows: number[] = [];\n for (let i = 0; i < this.data.rowCount; i++) {\n rows.push(i);\n }\n\n // Apply filters\n if (hasFilter) {\n rows = rows.filter(row => {\n for (const fn of this.filters.values()) {\n if (!fn(row, this.data)) return false;\n }\n return true;\n });\n }\n\n // Apply sort\n if (hasSort && this.sortState) {\n const { col, direction, compareFn } = this.sortState;\n const dir = direction === 'desc' ? -1 : 1;\n\n rows.sort((a, b) => {\n const va = this.data.getCell(a, col)?.value;\n const vb = this.data.getCell(b, col)?.value;\n\n if (compareFn) {\n return compareFn(va, vb) * dir;\n }\n\n return defaultCompare(va, vb) * dir;\n });\n }\n\n this.mapping = rows;\n }\n}\n\nfunction defaultCompare(a: unknown, b: unknown): number {\n // Nulls/undefined last\n if (a == null && b == null) return 0;\n if (a == null) return 1;\n if (b == null) return -1;\n\n // Numbers\n if (typeof a === 'number' && typeof b === 'number') {\n return a - b;\n }\n\n // Booleans\n if (typeof a === 'boolean' && typeof b === 'boolean') {\n return (a === b) ? 0 : a ? -1 : 1;\n }\n\n // Strings (locale-aware)\n return String(a).localeCompare(String(b), undefined, { numeric: true, sensitivity: 'base' });\n}\n","export interface MergeRange {\n row: number;\n col: number;\n rowSpan: number;\n colSpan: number;\n}\n\n/**\n * Tracks merged cell ranges.\n * A merge means one \"anchor\" cell (top-left) spans multiple rows/columns.\n * The other cells in the range are \"hidden\" (not rendered individually).\n */\nexport class MergeModel {\n /** All active merges */\n private merges: MergeRange[] = [];\n /** Quick lookup: \"row:col\" -> merge that covers this cell */\n private coverMap = new Map<string, MergeRange>();\n\n onChange: (() => void) | null = null;\n\n constructor(initialMerges?: MergeRange[]) {\n if (initialMerges) {\n for (const m of initialMerges) {\n this.addMerge(m, false);\n }\n }\n }\n\n private key(row: number, col: number): string {\n return `${row}:${col}`;\n }\n\n /** Add a merge. The anchor is (row, col). */\n addMerge(merge: MergeRange, notify = true): void {\n // Validate\n if (merge.rowSpan < 1 || merge.colSpan < 1) return;\n if (merge.rowSpan === 1 && merge.colSpan === 1) return; // not a merge\n\n // Check for overlap with existing merges\n for (let r = merge.row; r < merge.row + merge.rowSpan; r++) {\n for (let c = merge.col; c < merge.col + merge.colSpan; c++) {\n if (this.coverMap.has(this.key(r, c))) {\n // Cell already covered by another merge - remove that merge first\n const existing = this.coverMap.get(this.key(r, c))!;\n this.removeMerge(existing.row, existing.col, false);\n }\n }\n }\n\n this.merges.push(merge);\n\n // Fill the cover map\n for (let r = merge.row; r < merge.row + merge.rowSpan; r++) {\n for (let c = merge.col; c < merge.col + merge.colSpan; c++) {\n this.coverMap.set(this.key(r, c), merge);\n }\n }\n\n if (notify) this.onChange?.();\n }\n\n /** Remove the merge anchored at (row, col) */\n removeMerge(row: number, col: number, notify = true): boolean {\n const idx = this.merges.findIndex(m => m.row === row && m.col === col);\n if (idx === -1) return false;\n\n const merge = this.merges[idx];\n this.merges.splice(idx, 1);\n\n // Clear cover map\n for (let r = merge.row; r < merge.row + merge.rowSpan; r++) {\n for (let c = merge.col; c < merge.col + merge.colSpan; c++) {\n this.coverMap.delete(this.key(r, c));\n }\n }\n\n if (notify) this.onChange?.();\n return true;\n }\n\n /** Get the merge that covers (row, col), or null */\n getMerge(row: number, col: number): MergeRange | null {\n return this.coverMap.get(this.key(row, col)) ?? null;\n }\n\n /** Is this cell the anchor (top-left) of a merge? */\n isAnchor(row: number, col: number): boolean {\n const m = this.coverMap.get(this.key(row, col));\n return m !== undefined && m.row === row && m.col === col;\n }\n\n /** Is this cell hidden by a merge (i.e. not the anchor)? */\n isHidden(row: number, col: number): boolean {\n const m = this.coverMap.get(this.key(row, col));\n return m !== undefined && (m.row !== row || m.col !== col);\n }\n\n /** Get all merges */\n getAll(): MergeRange[] {\n return [...this.merges];\n }\n\n /** Clear all merges */\n clear(): void {\n this.merges.length = 0;\n this.coverMap.clear();\n this.onChange?.();\n }\n}\n","import type { PaginationConfig, PaginationState } from '../types/index.js';\n\nexport class PaginationModel {\n private _page: number;\n private _pageSize: number;\n private _totalRows: number;\n enabled: boolean;\n\n onChange: ((state: PaginationState) => void) | null = null;\n\n constructor(config?: PaginationConfig) {\n this.enabled = config?.enabled ?? false;\n this._pageSize = config?.pageSize ?? 50;\n this._page = config?.page ?? 0;\n this._totalRows = config?.totalRows ?? 0;\n }\n\n get page(): number { return this._page; }\n get pageSize(): number { return this._pageSize; }\n get totalRows(): number { return this._totalRows; }\n\n get totalPages(): number {\n if (this._totalRows === 0) return 0;\n return Math.ceil(this._totalRows / this._pageSize);\n }\n\n get startRow(): number {\n return this._page * this._pageSize;\n }\n\n get endRow(): number {\n return Math.min(this.startRow + this._pageSize, this._totalRows);\n }\n\n getState(): PaginationState {\n return {\n page: this._page,\n pageSize: this._pageSize,\n totalRows: this._totalRows,\n totalPages: this.totalPages,\n startRow: this.startRow,\n endRow: this.endRow,\n };\n }\n\n setPage(page: number): void {\n const clamped = Math.max(0, Math.min(page, this.totalPages - 1));\n if (clamped === this._page) return;\n this._page = clamped;\n this.onChange?.(this.getState());\n }\n\n setPageSize(size: number): void {\n this._pageSize = Math.max(1, size);\n // Reset to page 0 or clamp\n this._page = Math.min(this._page, this.totalPages - 1);\n if (this._page < 0) this._page = 0;\n this.onChange?.(this.getState());\n }\n\n setTotalRows(total: number): void {\n this._totalRows = total;\n // Clamp current page\n if (this._page >= this.totalPages) {\n this._page = Math.max(0, this.totalPages - 1);\n }\n this.onChange?.(this.getState());\n }\n\n nextPage(): void {\n this.setPage(this._page + 1);\n }\n\n prevPage(): void {\n this.setPage(this._page - 1);\n }\n\n firstPage(): void {\n this.setPage(0);\n }\n\n lastPage(): void {\n this.setPage(this.totalPages - 1);\n }\n}\n","import type { ColumnConfig } from '../types/index.js';\n\nexport interface HeaderCell {\n label: string;\n colSpan: number;\n rowSpan: number;\n col: number; // start column index (in flat columns)\n level: number; // header row (0 = top)\n config?: ColumnConfig;\n}\n\n/**\n * Flatten nested ColumnConfig[] into:\n * - flatColumns: leaf columns only (the actual data columns)\n * - headerRows: 2D array of header cells for multi-level rendering\n */\nexport function flattenColumns(columns: ColumnConfig[]): {\n flatColumns: ColumnConfig[];\n headerRows: HeaderCell[][];\n maxDepth: number;\n} {\n const flatColumns: ColumnConfig[] = [];\n const maxDepth = getMaxDepth(columns);\n const headerRows: HeaderCell[][] = [];\n\n for (let i = 0; i < maxDepth; i++) {\n headerRows.push([]);\n }\n\n flattenRecursive(columns, 0, flatColumns, headerRows, maxDepth);\n\n return { flatColumns, headerRows, maxDepth };\n}\n\nfunction getMaxDepth(columns: ColumnConfig[]): number {\n let max = 1;\n for (const col of columns) {\n if (col.children && col.children.length > 0) {\n max = Math.max(max, 1 + getMaxDepth(col.children));\n }\n }\n return max;\n}\n\nfunction flattenRecursive(\n columns: ColumnConfig[],\n level: number,\n flatColumns: ColumnConfig[],\n headerRows: HeaderCell[][],\n maxDepth: number,\n): void {\n for (const col of columns) {\n if (col.children && col.children.length > 0) {\n // Group header\n const startCol = flatColumns.length;\n flattenRecursive(col.children, level + 1, flatColumns, headerRows, maxDepth);\n const colSpan = flatColumns.length - startCol;\n\n headerRows[level].push({\n label: col.label ?? '',\n colSpan,\n rowSpan: 1,\n col: startCol,\n level,\n config: col,\n });\n } else {\n // Leaf column\n const colIdx = flatColumns.length;\n flatColumns.push(col);\n\n // Leaf spans from current level down to maxDepth\n const rowSpan = maxDepth - level;\n headerRows[level].push({\n label: col.label ?? '',\n colSpan: 1,\n rowSpan,\n col: colIdx,\n level,\n config: col,\n });\n }\n }\n}\n","import type { PaginationState } from '../types/index.js';\n\nexport class PaginationBar {\n private el: HTMLElement;\n private infoEl: HTMLElement;\n private prevBtn: HTMLButtonElement;\n private nextBtn: HTMLButtonElement;\n private firstBtn: HTMLButtonElement;\n private lastBtn: HTMLButtonElement;\n private pageInput: HTMLInputElement;\n\n private clickHandler: (e: MouseEvent) => void;\n private changeHandler: () => void;\n\n onPageChange: ((page: number) => void) | null = null;\n\n constructor(container: HTMLElement) {\n this.el = document.createElement('div');\n this.el.className = 'wt-pagination';\n\n this.infoEl = document.createElement('span');\n this.infoEl.className = 'wt-pagination-info';\n\n this.firstBtn = this.createBtn('first', '\\u00AB');\n this.prevBtn = this.createBtn('prev', '\\u2039');\n this.pageInput = document.createElement('input');\n this.pageInput.type = 'number';\n this.pageInput.className = 'wt-pagination-input';\n this.pageInput.min = '1';\n this.nextBtn = this.createBtn('next', '\\u203A');\n this.lastBtn = this.createBtn('last', '\\u00BB');\n\n this.el.appendChild(this.infoEl);\n this.el.appendChild(this.firstBtn);\n this.el.appendChild(this.prevBtn);\n this.el.appendChild(this.pageInput);\n this.el.appendChild(this.nextBtn);\n this.el.appendChild(this.lastBtn);\n\n // Event delegation for buttons\n this.clickHandler = (e: MouseEvent) => {\n const btn = (e.target as HTMLElement).closest('.wt-pagination-btn') as HTMLElement | null;\n if (!btn) return;\n const action = btn.dataset.action;\n if (action === 'first') this.onPageChange?.(0);\n else if (action === 'prev') this.onPageChange?.(-1);\n else if (action === 'next') this.onPageChange?.(-2);\n else if (action === 'last') this.onPageChange?.(-3);\n };\n this.el.addEventListener('click', this.clickHandler);\n\n // Page input change\n this.changeHandler = () => {\n const page = parseInt(this.pageInput.value, 10) - 1;\n if (!isNaN(page)) this.onPageChange?.(page);\n };\n this.pageInput.addEventListener('change', this.changeHandler);\n\n container.appendChild(this.el);\n }\n\n update(state: PaginationState): void {\n this.infoEl.textContent = `${state.startRow + 1}-${state.endRow} of ${state.totalRows}`;\n this.pageInput.value = String(state.page + 1);\n this.pageInput.max = String(state.totalPages);\n this.prevBtn.disabled = state.page <= 0;\n this.firstBtn.disabled = state.page <= 0;\n this.nextBtn.disabled = state.page >= state.totalPages - 1;\n this.lastBtn.disabled = state.page >= state.totalPages - 1;\n }\n\n show(): void {\n this.el.style.display = '';\n }\n\n hide(): void {\n this.el.style.display = 'none';\n }\n\n destroy(): void {\n this.el.removeEventListener('click', this.clickHandler);\n this.pageInput.removeEventListener('change', this.changeHandler);\n this.el.remove();\n }\n\n private createBtn(action: string, text: string): HTMLButtonElement {\n const btn = document.createElement('button');\n btn.className = 'wt-pagination-btn';\n btn.dataset.action = action;\n btn.textContent = text;\n return btn;\n }\n}\n","export class LoadingOverlay {\n private el: HTMLElement;\n\n constructor(container: HTMLElement) {\n this.el = document.createElement('div');\n this.el.className = 'wt-loading-overlay';\n this.el.innerHTML = '<div class=\"wt-loading-spinner\"></div>';\n this.el.style.display = 'none';\n container.appendChild(this.el);\n }\n\n show(): void {\n this.el.style.display = '';\n }\n\n hide(): void {\n this.el.style.display = 'none';\n }\n\n get isVisible(): boolean {\n return this.el.style.display !== 'none';\n }\n\n destroy(): void {\n this.el.remove();\n }\n}\n","import type { DataModel } from '../core/DataModel.js';\nimport type { ViewMapping } from '../core/ViewMapping.js';\nimport { columnLabel } from '../columns/ColumnModel.js';\n\nexport interface ExportOptions {\n /** Export only visible (filtered/sorted) rows. Default: true */\n visibleOnly?: boolean;\n /** Columns to include (by index). Default: all */\n columns?: number[];\n /** Include header row with column labels. Default: true */\n includeHeaders?: boolean;\n /** Column labels (if includeHeaders). Falls back to A, B, C... */\n headers?: string[];\n}\n\nexport function exportCSV(\n data: DataModel,\n viewMapping: ViewMapping,\n options: ExportOptions = {},\n): string {\n const {\n visibleOnly = true,\n columns,\n includeHeaders = true,\n headers,\n } = options;\n\n const colIndices = columns ?? Array.from({ length: data.colCount }, (_, i) => i);\n const lines: string[] = [];\n\n if (includeHeaders) {\n const headerRow = colIndices.map((c, i) => {\n const label = headers?.[i] ?? columnLabel(c);\n return csvEscape(label);\n });\n lines.push(headerRow.join(','));\n }\n\n const rowCount = visibleOnly ? viewMapping.visibleRowCount : data.rowCount;\n\n for (let vr = 0; vr < rowCount; vr++) {\n const dr = visibleOnly ? viewMapping.toDataRow(vr) : vr;\n const row = colIndices.map(col => {\n const cell = data.getCell(dr, col);\n const val = cell?.value;\n return csvEscape(val != null ? String(val) : '');\n });\n lines.push(row.join(','));\n }\n\n return lines.join('\\n');\n}\n\nexport function exportJSON(\n data: DataModel,\n viewMapping: ViewMapping,\n options: ExportOptions = {},\n): object[] {\n const {\n visibleOnly = true,\n columns,\n headers,\n } = options;\n\n const colIndices = columns ?? Array.from({ length: data.colCount }, (_, i) => i);\n const rowCount = visibleOnly ? viewMapping.visibleRowCount : data.rowCount;\n const result: object[] = [];\n\n for (let vr = 0; vr < rowCount; vr++) {\n const dr = visibleOnly ? viewMapping.toDataRow(vr) : vr;\n const row: Record<string, unknown> = {};\n for (let ci = 0; ci < colIndices.length; ci++) {\n const col = colIndices[ci];\n const key = headers?.[ci] ?? columnLabel(col);\n const cell = data.getCell(dr, col);\n row[key] = cell?.value ?? null;\n }\n result.push(row);\n }\n\n return result;\n}\n\nexport function downloadFile(content: string, filename: string, mimeType: string): void {\n const blob = new Blob([content], { type: mimeType });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = filename;\n a.click();\n URL.revokeObjectURL(url);\n}\n\nfunction csvEscape(value: string): string {\n if (value.includes(',') || value.includes('\"') || value.includes('\\n')) {\n return `\"${value.replace(/\"/g, '\"\"')}\"`;\n }\n return value;\n}\n","import type {\n CellData,\n CellEditor,\n CellPatch,\n CellRenderer,\n ColumnConfig,\n SelectionRange,\n ThemeConfig,\n Viewport,\n WanderTableEvents,\n WanderTableOptions,\n} from './types/index.js';\nimport { DEFAULT_THEME } from './types/index.js';\nimport { DataModel } from './core/DataModel.js';\nimport { EventEmitter } from './core/EventEmitter.js';\nimport { SelectionModel } from './core/SelectionModel.js';\nimport { CommandBus, SetCellValueCommand, DeleteCellsCommand, PatchCommand, type Command } from './core/CommandBus.js';\nimport { ColumnModel } from './columns/ColumnModel.js';\nimport { RowModel } from './rows/RowModel.js';\nimport { DOMRenderer } from './render/DOMRenderer.js';\nimport { AutoFit } from './render/AutoFit.js';\nimport { RendererRegistry } from './renderers/RendererRegistry.js';\nimport { EditorManager } from './editors/EditorManager.js';\nimport { KeyboardNav } from './interaction/KeyboardNav.js';\nimport { ClipboardManager } from './interaction/ClipboardManager.js';\nimport { ColumnResize } from './interaction/ColumnResize.js';\nimport { RowResize } from './interaction/RowResize.js';\nimport { ContextMenu, type MenuItemConfig, type MenuContext, type MenuTarget } from './plugins/ContextMenu.js';\nimport { FillHandle } from './interaction/FillHandle.js';\nimport { ColumnReorder } from './interaction/ColumnReorder.js';\nimport { RowGroupModel } from './core/RowGroupModel.js';\nimport { ViewMapping, type SortDirection, type FilterFn } from './core/ViewMapping.js';\nimport { MergeModel, type MergeRange } from './core/MergeModel.js';\nimport { PaginationModel } from './core/PaginationModel.js';\nimport { flattenColumns, type HeaderCell } from './columns/GroupedHeaders.js';\nimport { PaginationBar } from './render/PaginationBar.js';\nimport { LoadingOverlay } from './render/LoadingOverlay.js';\nimport { exportCSV, exportJSON, downloadFile, type ExportOptions } from './plugins/Export.js';\n\nexport class WanderTable extends EventEmitter<WanderTableEvents> {\n readonly data: DataModel;\n readonly selection: SelectionModel;\n readonly columns: ColumnModel;\n readonly rows: RowModel;\n readonly commands: CommandBus;\n readonly viewMapping: ViewMapping;\n readonly merges: MergeModel;\n readonly pagination: PaginationModel;\n readonly rowGroups: RowGroupModel;\n\n private renderer: DOMRenderer;\n private rendererRegistry: RendererRegistry;\n private editorManager: EditorManager;\n private keyboard: KeyboardNav;\n private clipboard: ClipboardManager;\n private columnResize: ColumnResize;\n private rowResize: RowResize;\n private contextMenu: ContextMenu;\n private autoFit: AutoFit;\n private paginationBar: PaginationBar | null = null;\n private loadingOverlay: LoadingOverlay;\n private fillHandle: FillHandle;\n private columnReorder: ColumnReorder;\n private headerRows: HeaderCell[][] = [];\n private theme: ThemeConfig;\n private options: WanderTableOptions;\n\n // Drag selection state\n private isDragging = false;\n private _infiniteScrollHandler: (() => void) | null = null;\n private _lazyLoadHandler: (() => void) | null = null;\n private _keydownHandler: ((e: KeyboardEvent) => void) | null = null;\n\n constructor(container: HTMLElement, options: WanderTableOptions = {}) {\n super();\n this.options = options;\n\n const defaultRowHeight = options.defaultRowHeight ?? 28;\n const defaultColWidth = options.defaultColWidth ?? 100;\n\n // Flatten grouped columns if needed\n let flatColumns = options.columns ?? [];\n if (flatColumns.some(c => c.children && c.children.length > 0)) {\n const result = flattenColumns(flatColumns);\n flatColumns = result.flatColumns;\n this.headerRows = result.headerRows;\n }\n\n // Determine dimensions\n const colCount = options.colCount ?? (flatColumns.length || 26);\n let rowCount: number;\n\n if (options.mode === 'table' && options.tableData) {\n rowCount = options.tableData.length;\n } else {\n rowCount = options.rowCount ?? 100;\n }\n\n // Theme\n this.theme = { ...DEFAULT_THEME, ...options.theme };\n\n // Models\n this.data = new DataModel(rowCount, colCount);\n this.selection = new SelectionModel(rowCount, colCount);\n if (options.infinite) this.selection.infinite = true;\n this.columns = new ColumnModel(colCount, defaultColWidth, flatColumns);\n this.rows = new RowModel(rowCount, defaultRowHeight);\n this.commands = new CommandBus(options.undoLimit ?? 100);\n this.viewMapping = new ViewMapping(this.data);\n this.merges = new MergeModel();\n this.pagination = new PaginationModel(options.pagination);\n this.rowGroups = new RowGroupModel(\n options.rowGroups?.map(g => ({\n ...g,\n expanded: g.expanded ?? true,\n depth: g.depth ?? 0,\n })),\n );\n\n // Renderer registry\n this.rendererRegistry = new RendererRegistry();\n\n // DOM Renderer\n this.renderer = new DOMRenderer(container);\n\n // Editor manager\n this.editorManager = new EditorManager(this.renderer.getScrollContainer());\n\n // Column resize\n this.columnResize = new ColumnResize(this.columns);\n this.columnReorder = new ColumnReorder(this.columns);\n\n // Row resize\n this.rowResize = new RowResize(this.rows);\n\n // Context menu\n this.contextMenu = new ContextMenu();\n\n // Clipboard\n this.clipboard = new ClipboardManager(this.data, this.selection);\n\n // Fill handle (inside viewport so position: absolute works correctly)\n this.fillHandle = new FillHandle(\n this.renderer.getViewportEl(),\n this.data,\n this.selection,\n this.columns,\n this.rows,\n );\n\n // Keyboard\n this.keyboard = new KeyboardNav(this.selection, {\n onStartEdit: (row, col, initialChar) => {\n if (this.options.allowEditing !== false) this.startEditing(row, col, initialChar);\n },\n onDelete: () => this.deleteSelected(),\n onCopy: () => { if (this.options.allowClipboard !== false) this.clipboard.copy(); },\n onPaste: () => { if (this.options.allowClipboard !== false) this.pasteWithUndo(); },\n onCut: () => { if (this.options.allowClipboard !== false) this.cutWithUndo(); },\n onUndo: () => { if (this.options.allowUndoRedo !== false) this.undo(); },\n onRedo: () => { if (this.options.allowUndoRedo !== false) this.redo(); },\n onScrollTo: (row, col) => this.renderer.scrollToCell(row, col),\n });\n\n // Wire up callbacks\n this.wireCallbacks();\n\n // Initialize renderer\n this.renderer.init({\n data: this.data,\n columns: this.columns,\n rows: this.rows,\n selection: this.selection,\n viewMapping: this.viewMapping,\n merges: this.merges,\n theme: this.theme,\n renderers: this.rendererRegistry.getAll(),\n defaultRenderer: this.rendererRegistry.defaultRenderer,\n defaultCellType: options.defaultCellType ?? 'text',\n showRowHeaders: options.showRowHeaders ?? true,\n showColHeaders: options.showColHeaders ?? true,\n frozenRows: options.frozenRows ?? 0,\n frozenCols: options.frozenCols ?? 0,\n autoRowHeight: options.autoRowHeight ?? false,\n showGridLines: options.showGridLines ?? true,\n showBorder: options.showBorder ?? true,\n layout: options.layout ?? 'scroll',\n headerRows: this.headerRows.length > 0 ? this.headerRows : undefined,\n });\n\n // AutoFit (needs renderer to be initialized)\n this.autoFit = new AutoFit(\n container,\n this.data,\n this.columns,\n this.rows,\n this.rendererRegistry.getAll(),\n this.rendererRegistry.defaultRenderer,\n );\n\n // Fill handle wiring\n // Fill handle lives inside viewportEl, so bounds are absolute (no scroll offset)\n this.fillHandle.getCellBounds = (row, col) => ({\n x: this.columns.getX(col),\n y: this.rows.getY(row),\n width: this.columns.getWidth(col),\n height: this.rows.getHeight(row),\n });\n this.fillHandle.getCellAtPoint = (x, y) => {\n // Convert screen coords to cell via the renderer\n const sc = this.renderer.getScrollContainer();\n const rect = sc.getBoundingClientRect();\n const scrollX = sc.scrollLeft;\n const scrollY = sc.scrollTop;\n const px = x - rect.left + scrollX;\n const py = y - rect.top + scrollY;\n const row = this.rows.getRowAtY(py);\n const col = this.columns.getColAtX(px);\n if (row >= 0 && col >= 0) return { row, col };\n return null;\n };\n this.fillHandle.enabled = options.allowFillHandle !== false;\n this.fillHandle.onFillCallback = options.onFill ?? null;\n this.fillHandle.onFill = (patches, _source, fill) => {\n if (patches.length > 0) {\n const cmd = new PatchCommand(this.data, patches);\n this.execCommand(cmd);\n this.emit('data:patch', { patches });\n }\n // Extend selection to include filled area\n this.selection.extendTo(fill.endRow, fill.endCol);\n };\n\n // Loading overlay\n this.loadingOverlay = new LoadingOverlay(container);\n if (options.loading) this.loadingOverlay.show();\n\n // Pagination bar\n if (options.pagination?.enabled) {\n this.paginationBar = new PaginationBar(container);\n this.pagination.setTotalRows(options.pagination.totalRows ?? rowCount);\n this.paginationBar.update(this.pagination.getState());\n this.paginationBar.onPageChange = (page) => {\n if (page === -1) this.pagination.prevPage();\n else if (page === -2) this.pagination.nextPage();\n else if (page === -3) this.pagination.lastPage();\n else this.pagination.setPage(page);\n };\n this.pagination.onChange = (state) => {\n this.paginationBar?.update(state);\n this.options.onPageChange?.(state.page, state.pageSize);\n this.renderer.scheduleRender();\n };\n }\n\n // Apply initial data\n if (options.mode === 'table' && options.tableData) {\n this.loadTableData(options.tableData, flatColumns);\n } else if (options.data) {\n this.data.applyPatch(options.data);\n }\n\n // Apply initial merges\n if (options.merges) {\n for (const m of options.merges) {\n this.merges.addMerge(m, false);\n }\n }\n\n // Apply initial sort/filter\n if (options.sort) {\n this.viewMapping.sort(options.sort.col, options.sort.direction);\n }\n if (options.filters) {\n for (const [col, fn] of Object.entries(options.filters)) {\n this.viewMapping.setFilter(Number(col), fn);\n }\n }\n\n // Merge changes trigger re-render\n this.merges.onChange = () => {\n this.renderer.scheduleRender();\n };\n\n // ViewMapping changes trigger layout + re-render\n this.viewMapping.onChange = () => {\n this.renderer.updateLayout();\n this.renderer.scheduleRender();\n };\n\n // Infinite scroll: expand when user scrolls near the bottom/right edge\n if (options.infinite) {\n const expandAmount = 20;\n const threshold = 200; // px from edge\n\n if (options.layout === 'auto') {\n // Auto layout: listen to window scroll (vertical + horizontal)\n this._infiniteScrollHandler = () => {\n let changed = false;\n const docH = document.documentElement.scrollHeight;\n const docW = document.documentElement.scrollWidth;\n const scrollBottom = window.scrollY + window.innerHeight;\n const scrollRight = window.scrollX + window.innerWidth;\n\n if (docH - scrollBottom < threshold) {\n this.data.rowCount += expandAmount;\n this.rows.setCount(this.data.rowCount);\n this.viewMapping.rebuild();\n changed = true;\n }\n if (docW - scrollRight < threshold) {\n this.data.colCount += expandAmount;\n this.columns.setCount(this.data.colCount);\n changed = true;\n }\n if (changed) {\n this.selection.setDimensions(this.data.rowCount, this.data.colCount);\n this.refresh();\n }\n };\n window.addEventListener('scroll', this._infiniteScrollHandler, { passive: true });\n } else {\n // Scroll layout: listen to scroll container\n const sc = this.renderer.getScrollContainer();\n this._infiniteScrollHandler = () => {\n if (sc.scrollTop + sc.clientHeight >= sc.scrollHeight - threshold) {\n this.data.rowCount += expandAmount;\n this.rows.setCount(this.data.rowCount);\n this.selection.setDimensions(this.data.rowCount, this.data.colCount);\n this.viewMapping.rebuild();\n this.refresh();\n }\n if (sc.scrollLeft + sc.clientWidth >= sc.scrollWidth - threshold) {\n this.data.colCount += expandAmount;\n this.columns.setCount(this.data.colCount);\n this.selection.setDimensions(this.data.rowCount, this.data.colCount);\n this.refresh();\n }\n };\n sc.addEventListener('scroll', this._infiniteScrollHandler, { passive: true });\n }\n }\n\n // Focus the container\n this.renderer.getContainer().focus();\n }\n\n private wireCallbacks(): void {\n // Data changes trigger re-render\n this.data.onChange = () => {\n this.renderer.scheduleRender();\n };\n\n // Selection changes trigger re-render + infinite expansion\n this.selection.onChange = () => {\n if (this.options.infinite && this.selection.focus) {\n this.expandIfNeeded(this.selection.focus.row, this.selection.focus.col);\n }\n this.renderer.scheduleRender();\n this.fillHandle.updatePosition();\n this.emit('selection:change', { ranges: this.selection.ranges });\n this.options.onSelectionChange?.(this.selection.ranges);\n };\n\n // Cell click\n this.renderer.onCellClick = (row, col, e) => {\n if (this.contextMenu.isOpen) {\n this.contextMenu.close();\n }\n if (this.editorManager.isEditing) {\n this.editorManager.close(true);\n }\n\n // Checkbox toggle on click\n const cellData = this.data.getCell(row, col);\n const colConfig = this.columns.getConfig(col);\n const defaultType = this.options.defaultCellType ?? 'text';\n const cellType = cellData?.type ?? colConfig?.type ?? defaultType;\n if (cellType === 'checkbox' && !this.options.readOnly && this.options.allowEditing !== false\n && !colConfig?.readOnly && !cellData?.readOnly) {\n const oldValue = !!cellData?.value;\n this.setCellValue(row, col, !oldValue);\n if (this.options.allowSelection !== false) this.selection.focusCell(row, col);\n this.emit('cell:click', { row, col, event: e });\n return;\n }\n\n if (this.options.allowSelection !== false) {\n if (e.shiftKey && this.options.allowRangeSelection !== false) {\n this.selection.extendTo(row, col);\n } else if ((e.ctrlKey || e.metaKey) && this.options.allowRangeSelection !== false) {\n this.selection.addRange({ startRow: row, startCol: col, endRow: row, endCol: col });\n } else {\n this.selection.focusCell(row, col);\n }\n }\n\n this.emit('cell:click', { row, col, event: e });\n\n // Start drag selection\n if (this.options.allowRangeSelection !== false && this.options.allowSelection !== false) {\n this.isDragging = true;\n const onMouseMove = (me: MouseEvent) => {\n if (!this.isDragging) return;\n const cell = this.renderer.getCellFromEvent(me);\n if (cell) {\n this.selection.extendTo(cell.row, cell.col);\n }\n };\n const onMouseUp = () => {\n this.isDragging = false;\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n };\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n }\n };\n\n // Double click -> edit\n this.renderer.onCellDblClick = (row, col, e) => {\n this.emit('cell:dblclick', { row, col, event: e });\n if (!this.options.readOnly && this.options.allowEditing !== false) {\n this.startEditing(row, col);\n }\n };\n\n // Context menu\n this.renderer.onCellContextMenu = (row, col, e) => {\n e.preventDefault();\n this.emit('cell:contextmenu', { row, col, event: e });\n if (this.options.allowContextMenu === false) return;\n\n // Select cell if not already selected\n if (this.options.allowSelection !== false && !this.selection.isSelected(row, col)) {\n this.selection.focusCell(row, col);\n }\n\n this.openContextMenu(e.clientX, e.clientY, row, col);\n };\n\n // Header clicks\n this.renderer.onHeaderClick = (type, index, e) => {\n if (type === 'col') {\n if (this.options.allowColReorder) {\n this.columnReorder.start(index, e, this.renderer.getContainer());\n } else {\n this.selection.selectColumn(index);\n }\n } else if (type === 'row') {\n // Check for bottom edge -> row resize\n const target = (e.target as HTMLElement).closest('.wt-row-header-cell') as HTMLElement | null;\n if (target) {\n const rect = target.getBoundingClientRect();\n if (e.clientY > rect.bottom - 4 && this.options.allowRowResize !== false) {\n this.rowResize.start(index, e.clientY);\n return;\n }\n }\n this.selection.selectRow(index);\n } else if (type === 'corner') {\n this.selection.selectAll();\n }\n };\n\n // Column resize\n this.renderer.onColumnResizeStart = (col, startX) => {\n if (this.options.allowColResize === false) return;\n this.columnResize.start(col, startX);\n };\n\n this.columnResize.onResize = (col, width) => {\n this.renderer.updateLayout();\n this.renderer.scheduleRender();\n this.emit('column:resize', { col, width });\n };\n\n // Row resize\n this.rowResize.onResize = (row, height) => {\n this.renderer.updateLayout();\n this.renderer.scheduleRender();\n this.emit('row:resize', { row, height });\n };\n\n // Scroll\n this.renderer.onScroll = (viewport) => {\n this.emit('scroll', { viewport });\n this.options.onScroll?.(viewport);\n };\n\n // Editor close\n this.editorManager.onClose = (row, col, value, cancelled) => {\n if (!cancelled && value !== undefined) {\n const oldValue = this.data.getCell(row, col)?.value;\n // Use command for undo support\n const cmd = new SetCellValueCommand(this.data, row, col, value);\n this.execCommand(cmd);\n this.emit('cell:change', { row, col, oldValue, newValue: value });\n this.options.onCellChange?.(row, col, oldValue, value);\n }\n this.emit('editor:close', { row, col, value, cancelled });\n this.renderer.getContainer().focus();\n };\n\n // Keyboard\n this._keydownHandler = (e: KeyboardEvent) => {\n if (this.options.allowKeyboardNav === false) return;\n if (this.editorManager.isEditing) return;\n this.keyboard.handleKeyDown(e);\n };\n this.renderer.getContainer().addEventListener('keydown', this._keydownHandler);\n\n // Header context menu\n this.renderer.onHeaderContextMenu = (type, index, e) => {\n const target = type === 'col' ? 'column-header' as const : 'row-header' as const;\n const row = type === 'row' ? index : -1;\n const col = type === 'col' ? index : -1;\n const ctx = this.buildMenuContext(row, col, target);\n this.contextMenu.open(e.clientX, e.clientY, this.contextMenuItems, ctx);\n };\n\n // Clipboard change\n this.clipboard.onChange = (patches) => {\n this.emit('data:patch', { patches });\n };\n\n // Column reorder\n this.columnReorder.getColAtX = (clientX) => {\n const sc = this.renderer.getScrollContainer();\n const rect = sc.getBoundingClientRect();\n return this.columns.getColAtX(clientX - rect.left + sc.scrollLeft);\n };\n this.columnReorder.getColLabel = (col) => {\n return this.columns.getConfig(col)?.label ?? ColumnModel.columnLabel(col);\n };\n this.columnReorder.onReorder = (from, to) => {\n this.reorderColumn(from, to);\n };\n\n // Row groups: apply filter to ViewMapping\n this.rowGroups.onChange = () => {\n const filter = this.rowGroups.getFilter();\n this.viewMapping.setFilter(-1, (row) => filter(row));\n };\n // Apply initial filter if groups exist\n if (this.options.rowGroups && this.options.rowGroups.length > 0) {\n const filter = this.rowGroups.getFilter();\n this.viewMapping.setFilter(-1, (row) => filter(row));\n }\n\n // Lazy loading: onLoadMore callback\n if (this.options.onLoadMore) {\n const onLoadMore = this.options.onLoadMore;\n const threshold = 200;\n\n if (this.options.layout === 'auto') {\n this._lazyLoadHandler = () => {\n const docH = document.documentElement.scrollHeight;\n const scrollBottom = window.scrollY + window.innerHeight;\n if (docH - scrollBottom < threshold) onLoadMore('down');\n };\n window.addEventListener('scroll', this._lazyLoadHandler, { passive: true });\n } else {\n const sc = this.renderer.getScrollContainer();\n this._lazyLoadHandler = () => {\n if (sc.scrollTop + sc.clientHeight >= sc.scrollHeight - threshold) {\n onLoadMore('down');\n }\n if (sc.scrollLeft + sc.clientWidth >= sc.scrollWidth - threshold) {\n onLoadMore('right');\n }\n };\n sc.addEventListener('scroll', this._lazyLoadHandler, { passive: true });\n }\n }\n }\n\n // ── Context Menu ──\n\n /** Override this to customize context menu items */\n contextMenuItems: MenuItemConfig[] = [\n // ── Cell items ──\n { label: 'Copy', shortcut: 'Ctrl+C', visible: (ctx) => ctx.target === 'cell', action: () => this.clipboard.copy() },\n {\n label: 'Paste', shortcut: 'Ctrl+V',\n visible: (ctx) => ctx.target === 'cell',\n disabled: (ctx) => ctx.readOnly,\n action: () => this.pasteWithUndo(),\n },\n {\n label: 'Cut', shortcut: 'Ctrl+X',\n visible: (ctx) => ctx.target === 'cell',\n disabled: (ctx) => ctx.readOnly,\n action: () => this.cutWithUndo(),\n },\n {\n label: '', separator: true,\n visible: (ctx) => ctx.target === 'cell',\n },\n {\n label: 'Delete content', shortcut: 'Del',\n visible: (ctx) => ctx.target === 'cell' && ctx.selectedCount > 0,\n disabled: (ctx) => ctx.readOnly,\n action: () => this.deleteSelected(),\n },\n {\n label: '', separator: true,\n visible: (ctx) => ctx.target === 'cell',\n },\n {\n label: 'Insert row above',\n visible: (ctx) => ctx.target === 'cell' || ctx.target === 'row-header',\n disabled: (ctx) => ctx.readOnly,\n action: (ctx) => this.insertRow(ctx.row),\n },\n {\n label: 'Insert row below',\n visible: (ctx) => ctx.target === 'cell' || ctx.target === 'row-header',\n disabled: (ctx) => ctx.readOnly,\n action: (ctx) => this.insertRow(ctx.row + 1),\n },\n {\n label: 'Insert column left',\n visible: (ctx) => (ctx.target === 'cell' && !ctx.isMultiSelect) || ctx.target === 'column-header',\n disabled: (ctx) => ctx.readOnly,\n action: (ctx) => this.insertColumn(ctx.col),\n },\n {\n label: 'Insert column right',\n visible: (ctx) => (ctx.target === 'cell' && !ctx.isMultiSelect) || ctx.target === 'column-header',\n disabled: (ctx) => ctx.readOnly,\n action: (ctx) => this.insertColumn(ctx.col + 1),\n },\n\n // ── Column header items ──\n {\n label: '', separator: true,\n visible: (ctx) => ctx.target === 'column-header',\n },\n {\n label: 'Sort ascending',\n visible: (ctx) => ctx.target === 'column-header',\n action: (ctx) => this.sort(ctx.col, 'asc'),\n },\n {\n label: 'Sort descending',\n visible: (ctx) => ctx.target === 'column-header',\n action: (ctx) => this.sort(ctx.col, 'desc'),\n },\n {\n label: 'Clear sort',\n visible: (ctx) => ctx.target === 'column-header' && this.viewMapping.getSortState() !== null,\n action: () => this.clearSort(),\n },\n {\n label: '', separator: true,\n visible: (ctx) => ctx.target === 'column-header',\n },\n {\n label: 'Auto-fit column width',\n visible: (ctx) => ctx.target === 'column-header' || ctx.target === 'cell',\n action: (ctx) => this.autoFitColumn(ctx.col >= 0 ? ctx.col : 0),\n },\n\n // ── Row header items ──\n {\n label: '', separator: true,\n visible: (ctx) => ctx.target === 'row-header',\n },\n {\n label: 'Select row',\n visible: (ctx) => ctx.target === 'row-header',\n action: (ctx) => this.selection.selectRow(ctx.row),\n },\n\n // ── Common items ──\n { label: '', separator: true },\n {\n label: 'Undo', shortcut: 'Ctrl+Z',\n disabled: (ctx) => !ctx.canUndo,\n action: () => this.undo(),\n },\n {\n label: 'Redo', shortcut: 'Ctrl+Y',\n disabled: (ctx) => !ctx.canRedo,\n action: () => this.redo(),\n },\n ];\n\n private buildMenuContext(row: number, col: number, target: MenuTarget = 'cell'): MenuContext {\n const bounds = this.selection.getBounds();\n let selectedCount = 0;\n this.selection.forEachSelected(() => { selectedCount++; });\n\n return {\n target,\n row,\n col,\n selectedCount,\n isMultiSelect: selectedCount > 1,\n isFullRow: bounds ? bounds.c1 === 0 && bounds.c2 === this.data.colCount - 1 : false,\n isFullCol: bounds ? bounds.r1 === 0 && bounds.r2 === this.data.rowCount - 1 : false,\n readOnly: !!this.options.readOnly,\n canUndo: this.commands.canUndo,\n canRedo: this.commands.canRedo,\n };\n }\n\n private openContextMenu(x: number, y: number, row: number, col: number): void {\n const ctx = this.buildMenuContext(row, col);\n this.contextMenu.open(x, y, this.contextMenuItems, ctx);\n }\n\n // ── Public API ──\n\n setCell(row: number, col: number, data: CellData): void {\n this.data.setCell(row, col, data);\n }\n\n getCell(row: number, col: number): CellData | undefined {\n return this.data.getCell(row, col);\n }\n\n setCellValue(row: number, col: number, value: unknown): void {\n const old = this.data.getCell(row, col)?.value;\n const cmd = new SetCellValueCommand(this.data, row, col, value);\n this.execCommand(cmd);\n this.emit('cell:change', { row, col, oldValue: old, newValue: value });\n }\n\n deleteCell(row: number, col: number): void {\n this.data.deleteCell(row, col);\n }\n\n applyPatch(patches: CellPatch[]): void {\n const cmd = new PatchCommand(this.data, patches);\n this.execCommand(cmd);\n this.emit('data:patch', { patches });\n }\n\n transaction(fn: () => void): void {\n this.data.transaction(fn);\n }\n\n undo(): void {\n const cmd = this.commands.undo();\n if (cmd) {\n const changes = cmd.getChanges().map(c => ({\n row: c.row, col: c.col,\n oldValue: c.newValue,\n newValue: c.oldValue,\n }));\n this.emit('command:undo', { changes });\n }\n }\n\n redo(): void {\n const cmd = this.commands.redo();\n if (cmd) {\n this.emit('command:redo', { changes: cmd.getChanges() });\n }\n }\n\n getSelection(): SelectionRange[] {\n return [...this.selection.ranges];\n }\n\n getSelectionInfo() {\n return this.selection.getInfo();\n }\n\n setSelection(ranges: SelectionRange[]): void {\n if (ranges.length > 0) {\n this.selection.focusCell(ranges[0].startRow, ranges[0].startCol);\n for (let i = 1; i < ranges.length; i++) {\n this.selection.addRange(ranges[i]);\n }\n }\n }\n\n scrollTo(row: number, col: number): void {\n this.renderer.scrollToCell(row, col);\n }\n\n registerRenderer(name: string, renderer: CellRenderer): void {\n this.rendererRegistry.register(name, renderer);\n }\n\n registerEditor(name: string, factory: () => CellEditor): void {\n this.editorManager.register(name, factory);\n }\n\n setColumnWidth(col: number, width: number): void {\n this.columns.setWidth(col, width);\n this.renderer.updateLayout();\n this.renderer.scheduleRender();\n }\n\n setRowHeight(row: number, height: number): void {\n this.rows.setHeight(row, height);\n this.renderer.updateLayout();\n this.renderer.scheduleRender();\n }\n\n autoFitColumn(col: number): void {\n const width = this.autoFit.autoFitColumn(col);\n this.columns.setWidth(col, width);\n this.renderer.updateLayout();\n this.renderer.scheduleRender();\n this.emit('column:resize', { col, width });\n }\n\n autoFitRow(row: number): void {\n const height = this.autoFit.autoFitRow(row);\n this.rows.setHeight(row, height);\n this.renderer.updateLayout();\n this.renderer.scheduleRender();\n this.emit('row:resize', { row, height });\n }\n\n insertRow(at: number): void {\n this.data.rowCount += 1;\n this.rows.setCount(this.data.rowCount);\n this.selection.setDimensions(this.data.rowCount, this.data.colCount);\n\n // Shift data down from `at`\n this.data.transaction(() => {\n for (let r = this.data.rowCount - 1; r > at; r--) {\n for (let c = 0; c < this.data.colCount; c++) {\n const cell = this.data.getCell(r - 1, c);\n if (cell) {\n this.data.setCell(r, c, { ...cell });\n } else {\n this.data.deleteCell(r, c);\n }\n }\n }\n // Clear the inserted row\n for (let c = 0; c < this.data.colCount; c++) {\n this.data.deleteCell(at, c);\n }\n });\n\n this.renderer.updateLayout();\n this.renderer.scheduleRender();\n }\n\n insertColumn(at: number): void {\n this.data.colCount += 1;\n this.columns.setCount(this.data.colCount);\n this.selection.setDimensions(this.data.rowCount, this.data.colCount);\n\n // Shift data right from `at`\n this.data.transaction(() => {\n for (let r = 0; r < this.data.rowCount; r++) {\n for (let c = this.data.colCount - 1; c > at; c--) {\n const cell = this.data.getCell(r, c - 1);\n if (cell) {\n this.data.setCell(r, c, { ...cell });\n } else {\n this.data.deleteCell(r, c);\n }\n }\n this.data.deleteCell(r, at);\n }\n });\n\n this.renderer.updateLayout();\n this.renderer.scheduleRender();\n }\n\n // ── Sort & Filter ──\n\n sort(col: number, direction: SortDirection, compareFn?: (a: unknown, b: unknown) => number): void {\n // External sort callback\n if (this.options.onSort) {\n const key = this.columns.getConfig(col)?.key;\n const handled = this.options.onSort(col, direction, key);\n if (handled === true) return; // externally handled, don't sort internally\n }\n this.viewMapping.sort(col, direction, compareFn);\n }\n\n clearSort(): void {\n if (this.options.onSort) {\n const handled = this.options.onSort(-1, null);\n if (handled === true) return;\n }\n this.viewMapping.clearSort();\n }\n\n getSortState() {\n return this.viewMapping.getSortState();\n }\n\n setFilter(col: number, fn: FilterFn): void {\n if (this.options.onFilter) {\n const key = this.columns.getConfig(col)?.key;\n const handled = this.options.onFilter(col, key, true);\n if (handled === true) return;\n }\n this.viewMapping.setFilter(col, fn);\n }\n\n removeFilter(col: number): void {\n if (this.options.onFilter) {\n const key = this.columns.getConfig(col)?.key;\n const handled = this.options.onFilter(col, key, false);\n if (handled === true) return;\n }\n this.viewMapping.removeFilter(col);\n }\n\n clearFilters(): void {\n this.viewMapping.clearFilters();\n }\n\n getActiveFilters(): number[] {\n return this.viewMapping.getActiveFilters();\n }\n\n // ── Merge ──\n\n mergeCells(row: number, col: number, rowSpan: number, colSpan: number): void {\n this.merges.addMerge({ row, col, rowSpan, colSpan });\n this.renderer.scheduleRender();\n }\n\n unmergeCells(row: number, col: number): void {\n this.merges.removeMerge(row, col);\n this.renderer.scheduleRender();\n }\n\n getMerge(row: number, col: number): MergeRange | null {\n return this.merges.getMerge(row, col);\n }\n\n clearMerges(): void {\n this.merges.clear();\n this.renderer.scheduleRender();\n }\n\n // ── Row Groups ──\n\n addRowGroup(startRow: number, count: number, label?: string, expanded = true): void {\n this.rowGroups.addGroup({ startRow, count, label, expanded, depth: 0 });\n }\n\n removeRowGroup(startRow: number): void {\n this.rowGroups.removeGroup(startRow);\n }\n\n toggleRowGroup(startRow: number): void {\n this.rowGroups.toggleGroup(startRow);\n }\n\n expandAllGroups(): void {\n this.rowGroups.expandAll();\n }\n\n collapseAllGroups(): void {\n this.rowGroups.collapseAll();\n }\n\n // ── Export ──\n\n exportCSV(options?: ExportOptions): string {\n return exportCSV(this.data, this.viewMapping, options);\n }\n\n exportJSON(options?: ExportOptions): object[] {\n return exportJSON(this.data, this.viewMapping, options);\n }\n\n downloadCSV(filename = 'export.csv', options?: ExportOptions): void {\n const csv = this.exportCSV(options);\n downloadFile(csv, filename, 'text/csv;charset=utf-8');\n }\n\n downloadJSON(filename = 'export.json', options?: ExportOptions): void {\n const json = JSON.stringify(this.exportJSON(options), null, 2);\n downloadFile(json, filename, 'application/json');\n }\n\n getViewport(): Viewport {\n return this.renderer.getViewport();\n }\n\n refresh(): void {\n this.renderer.updateLayout();\n this.renderer.scheduleRender();\n }\n\n destroy(): void {\n // Remove keyboard handler\n if (this._keydownHandler) {\n this.renderer.getContainer().removeEventListener('keydown', this._keydownHandler);\n }\n // Remove infinite scroll handler\n if (this._infiniteScrollHandler) {\n window.removeEventListener('scroll', this._infiniteScrollHandler);\n this.renderer.getScrollContainer().removeEventListener('scroll', this._infiniteScrollHandler);\n }\n // Remove lazy load handler\n if (this._lazyLoadHandler) {\n window.removeEventListener('scroll', this._lazyLoadHandler);\n this.renderer.getScrollContainer().removeEventListener('scroll', this._lazyLoadHandler);\n }\n this.fillHandle.destroy();\n this.columnReorder.destroy();\n this.editorManager.destroy();\n this.columnResize.destroy();\n this.rowResize.destroy();\n this.contextMenu.destroy();\n this.autoFit.destroy();\n this.loadingOverlay.destroy();\n this.paginationBar?.destroy();\n this.renderer.destroy();\n this.removeAllListeners();\n }\n\n // ── Private ──\n\n private startEditing(row: number, col: number, initialChar?: string): void {\n if (this.options.readOnly) return;\n\n const colConfig = this.columns.getConfig(col);\n const cellData = this.data.getCell(row, col);\n if (colConfig?.readOnly || cellData?.readOnly) return;\n\n const defaultType = this.options.defaultCellType ?? 'text';\n const cellType = cellData?.type ?? colConfig?.type ?? defaultType;\n const editorType = colConfig?.editor ?? cellType;\n\n // Blank cells: emit event but don't open editor\n if (editorType === 'blank') {\n this.emit('editor:open', { row, col });\n this.emit('editor:close', { row, col, value: undefined, cancelled: true });\n return;\n }\n\n const bounds = this.renderer.getCellBounds(row, col);\n const value = cellData?.value;\n\n this.emit('editor:open', { row, col });\n this.editorManager.open(row, col, editorType, value, bounds, cellData, initialChar);\n }\n\n private deleteSelected(): void {\n if (this.options.readOnly) return;\n const cells: { row: number; col: number }[] = [];\n this.selection.forEachSelected((row, col) => {\n if (this.data.hasCell(row, col)) {\n cells.push({ row, col });\n }\n });\n if (cells.length > 0) {\n const cmd = new DeleteCellsCommand(this.data, cells);\n this.execCommand(cmd);\n }\n }\n\n private async pasteWithUndo(): Promise<void> {\n // Snapshot before paste to support undo\n const focus = this.selection.focus;\n if (!focus) return;\n\n let text: string;\n try {\n text = await navigator.clipboard.readText();\n } catch {\n return;\n }\n\n const rows = text.split('\\n').map(line => line.split('\\t'));\n if (rows.length === 0) return;\n\n const isSingleCell = rows.length === 1 && rows[0].length === 1;\n const patches: CellPatch[] = [];\n\n if (isSingleCell && !this.isFullRowOrColSelected()) {\n const value = rows[0][0];\n this.selection.forEachSelected((row, col) => {\n if (row < this.data.rowCount && col < this.data.colCount) {\n patches.push({ row, col, data: { value } });\n }\n });\n } else {\n for (let r = 0; r < rows.length; r++) {\n for (let c = 0; c < rows[r].length; c++) {\n const targetRow = focus.row + r;\n const targetCol = focus.col + c;\n if (targetRow >= this.data.rowCount || targetCol >= this.data.colCount) continue;\n patches.push({ row: targetRow, col: targetCol, data: { value: rows[r][c] } });\n }\n }\n }\n\n if (patches.length > 0) {\n const cmd = new PatchCommand(this.data, patches);\n this.execCommand(cmd);\n this.emit('data:patch', { patches });\n }\n }\n\n private async cutWithUndo(): Promise<void> {\n await this.clipboard.copy();\n this.deleteSelected();\n }\n\n private execCommand(cmd: Command): void {\n this.commands.execute(cmd);\n this.emit('command:execute', { changes: cmd.getChanges() });\n }\n\n /** Move a column from one index to another, shifting data */\n reorderColumn(fromCol: number, toCol: number): void {\n if (fromCol === toCol) return;\n\n // Swap column data in every row\n this.data.transaction(() => {\n for (let r = 0; r < this.data.rowCount; r++) {\n const cells: (import('./types/index.js').CellData | undefined)[] = [];\n for (let c = 0; c < this.data.colCount; c++) {\n cells.push(this.data.getCell(r, c));\n }\n // Remove from old position, insert at new\n const moved = cells.splice(fromCol, 1)[0];\n cells.splice(toCol, 0, moved);\n // Write back\n for (let c = 0; c < cells.length; c++) {\n if (cells[c]) {\n this.data.setCell(r, c, cells[c]!);\n } else {\n this.data.deleteCell(r, c);\n }\n }\n }\n });\n\n // Reorder column widths\n const widths: number[] = [];\n for (let c = 0; c < this.columns.count; c++) {\n widths.push(this.columns.getWidth(c));\n }\n const movedW = widths.splice(fromCol, 1)[0];\n widths.splice(toCol, 0, movedW);\n for (let c = 0; c < widths.length; c++) {\n this.columns.setWidth(c, widths[c]);\n }\n\n this.refresh();\n }\n\n private expandIfNeeded(row: number, col: number): void {\n let changed = false;\n\n if (row >= this.data.rowCount) {\n const newCount = row + 2;\n this.data.rowCount = newCount;\n this.rows.setCount(newCount);\n this.viewMapping.rebuild();\n changed = true;\n }\n\n if (col >= this.data.colCount) {\n const newCount = col + 2;\n this.data.colCount = newCount;\n this.columns.setCount(newCount);\n changed = true;\n }\n\n if (changed) {\n this.selection.setDimensions(this.data.rowCount, this.data.colCount);\n this.refresh();\n }\n }\n\n private isFullRowOrColSelected(): boolean {\n const bounds = this.selection.getBounds();\n if (!bounds) return false;\n return (bounds.c1 === 0 && bounds.c2 === this.data.colCount - 1) ||\n (bounds.r1 === 0 && bounds.r2 === this.data.rowCount - 1);\n }\n\n /** Load row objects into the sparse DataModel using column keys */\n private loadTableData(rows: Record<string, unknown>[], columns: ColumnConfig[]): void {\n const keyToCol = new Map<string, number>();\n columns.forEach((c, i) => {\n if (c.key) keyToCol.set(c.key, i);\n });\n\n this.data.transaction(() => {\n for (let r = 0; r < rows.length; r++) {\n const row = rows[r];\n for (const [key, value] of Object.entries(row)) {\n const col = keyToCol.get(key);\n if (col !== undefined) {\n this.data.setCell(r, col, { value });\n }\n }\n }\n });\n }\n\n // ── Table Mode API ──\n\n /** Replace all table data (table mode) */\n setTableData(rows: Record<string, unknown>[]): void {\n const columns = this.options.columns ?? [];\n // Flatten if needed\n let flat = columns;\n if (columns.some(c => c.children && c.children.length > 0)) {\n flat = flattenColumns(columns).flatColumns;\n }\n\n this.data.clear();\n this.data.rowCount = rows.length;\n this.rows.setCount(rows.length);\n this.selection.setDimensions(rows.length, this.data.colCount);\n this.loadTableData(rows, flat);\n\n if (this.pagination.enabled) {\n this.pagination.setTotalRows(rows.length);\n }\n\n this.viewMapping.rebuild();\n this.refresh();\n }\n\n // ── Loading ──\n\n setLoading(loading: boolean): void {\n if (loading) {\n this.loadingOverlay.show();\n } else {\n this.loadingOverlay.hide();\n }\n }\n\n get isLoading(): boolean {\n return this.loadingOverlay.isVisible;\n }\n\n // ── Pagination API ──\n\n setPage(page: number): void {\n this.pagination.setPage(page);\n }\n\n setPageSize(size: number): void {\n this.pagination.setPageSize(size);\n }\n\n getPaginationState() {\n return this.pagination.getState();\n }\n}\n","import type { CellBounds, CellData, CellEditor, DropdownConfig, DropdownOption } from '../types/index.js';\n\nexport class DropdownEditor implements CellEditor {\n private config: DropdownConfig;\n private container!: HTMLElement;\n private listEl!: HTMLElement;\n private searchInput: HTMLInputElement | null = null;\n private selected: Set<unknown> = new Set();\n private options: DropdownOption[] = [];\n private highlightIndex = -1;\n private searchInputHandler: (() => void) | null = null;\n\n constructor(config: DropdownConfig) {\n this.config = config;\n }\n\n createElement(parent: HTMLElement): HTMLElement {\n this.container = document.createElement('div');\n this.container.className = 'wt-dropdown';\n\n if (this.config.searchable) {\n this.searchInput = document.createElement('input');\n this.searchInput.type = 'text';\n this.searchInput.className = 'wt-dropdown-search';\n this.searchInput.placeholder = this.config.placeholder ?? 'Search...';\n this.container.appendChild(this.searchInput);\n\n this.searchInputHandler = () => {\n this.loadOptions(this.searchInput!.value);\n };\n this.searchInput.addEventListener('input', this.searchInputHandler);\n }\n\n this.listEl = document.createElement('div');\n this.listEl.className = 'wt-dropdown-list';\n this.container.appendChild(this.listEl);\n\n // Event delegation for item clicks\n this.listEl.addEventListener('click', this.handleItemClick);\n\n parent.appendChild(this.container);\n\n this.container.addEventListener('keydown', this.handleKey);\n\n return this.container;\n }\n\n open(value: unknown, _bounds: CellBounds, _cellData: CellData | undefined): void {\n // Initialize selected values\n if (this.config.multiple && Array.isArray(value)) {\n this.selected = new Set(value);\n } else if (value != null) {\n this.selected = new Set([value]);\n }\n\n this.loadOptions('');\n\n requestAnimationFrame(() => {\n if (this.searchInput) {\n this.searchInput.focus();\n } else {\n this.container.focus();\n }\n });\n }\n\n getValue(): unknown {\n if (this.config.multiple) {\n return Array.from(this.selected);\n }\n return this.selected.size > 0 ? this.selected.values().next().value : null;\n }\n\n close(): void {\n if (this.searchInput && this.searchInputHandler) {\n this.searchInput.removeEventListener('input', this.searchInputHandler);\n }\n this.listEl.removeEventListener('click', this.handleItemClick);\n this.container.removeEventListener('keydown', this.handleKey);\n this.container.remove();\n }\n\n private handleItemClick = (e: MouseEvent): void => {\n const target = (e.target as HTMLElement).closest('.wt-dropdown-item') as HTMLElement | null;\n if (!target) return;\n e.stopPropagation();\n const idx = parseInt(target.dataset.index ?? '', 10);\n if (isNaN(idx) || idx < 0 || idx >= this.options.length) return;\n const opt = this.options[idx];\n if (opt.disabled) return;\n this.selectOption(opt);\n };\n\n private async loadOptions(query: string): Promise<void> {\n if (this.config.source) {\n this.options = await this.config.source(query, 0, 0);\n } else if (this.config.options) {\n const q = query.toLowerCase();\n this.options = q\n ? this.config.options.filter(o => o.label.toLowerCase().includes(q))\n : this.config.options;\n }\n this.renderOptions();\n }\n\n private renderOptions(): void {\n this.listEl.innerHTML = '';\n this.highlightIndex = -1;\n\n for (let i = 0; i < this.options.length; i++) {\n const opt = this.options[i];\n const el = document.createElement('div');\n el.className = 'wt-dropdown-item';\n el.dataset.index = String(i);\n if (this.selected.has(opt.value)) el.classList.add('wt-dropdown-item--selected');\n if (opt.disabled) el.classList.add('wt-dropdown-item--disabled');\n\n if (this.config.renderOption) {\n this.config.renderOption(opt, el);\n } else {\n el.textContent = opt.label;\n if (opt.icon) {\n const icon = document.createElement('span');\n icon.className = 'wt-dropdown-icon';\n icon.textContent = opt.icon;\n el.prepend(icon);\n }\n }\n\n this.listEl.appendChild(el);\n }\n }\n\n private selectOption(opt: DropdownOption): void {\n if (this.config.multiple) {\n if (this.selected.has(opt.value)) {\n this.selected.delete(opt.value);\n } else {\n this.selected.add(opt.value);\n }\n this.renderOptions();\n } else {\n this.selected.clear();\n this.selected.add(opt.value);\n }\n }\n\n private handleKey = (e: KeyboardEvent): void => {\n const items = this.listEl.children;\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n this.highlightIndex = Math.min(this.highlightIndex + 1, items.length - 1);\n this.updateHighlight();\n break;\n case 'ArrowUp':\n e.preventDefault();\n this.highlightIndex = Math.max(this.highlightIndex - 1, 0);\n this.updateHighlight();\n break;\n case 'Enter':\n e.preventDefault();\n if (this.highlightIndex >= 0 && this.highlightIndex < this.options.length) {\n this.selectOption(this.options[this.highlightIndex]);\n }\n break;\n }\n };\n\n private updateHighlight(): void {\n const items = this.listEl.children;\n for (let i = 0; i < items.length; i++) {\n items[i].classList.toggle('wt-dropdown-item--highlight', i === this.highlightIndex);\n }\n items[this.highlightIndex]?.scrollIntoView({ block: 'nearest' });\n }\n}\n","import type { CellBounds, CellData, CellEditor } from '../types/index.js';\n\n/**\n * Editor for blank cells - does not allow editing.\n * Optionally calls `onAttempt` when the user tries to edit,\n * so you can open a modal, redirect, etc.\n */\nexport class BlankEditor implements CellEditor {\n private el!: HTMLElement;\n private onAttempt: ((row: number, col: number) => void) | null;\n private row = -1;\n private col = -1;\n\n constructor(onAttempt?: (row: number, col: number) => void) {\n this.onAttempt = onAttempt ?? null;\n }\n\n createElement(container: HTMLElement): HTMLElement {\n this.el = document.createElement('div');\n container.appendChild(this.el);\n return this.el;\n }\n\n open(_value: unknown, _bounds: CellBounds, _cellData: CellData | undefined): void {\n // Fire the callback and immediately close\n if (this.onAttempt) {\n this.onAttempt(this.row, this.col);\n }\n }\n\n /** Called by EditorManager before open() to pass row/col */\n setPosition(row: number, col: number): void {\n this.row = row;\n this.col = col;\n }\n\n getValue(): unknown {\n return undefined;\n }\n\n close(): void {\n this.el?.remove();\n }\n}\n","import type { ThemeConfig } from './types/index.js';\n\nexport const THEME_LIGHT: ThemeConfig = {\n bgColor: '#ffffff',\n cellBgColor: '#ffffff',\n cellTextColor: '#1e293b',\n headerBgColor: '#f8fafc',\n headerTextColor: '#475569',\n gridLineColor: '#e2e8f0',\n selectionBgColor: 'rgba(59, 130, 246, 0.08)',\n selectionBorderColor: '#3b82f6',\n focusBorderColor: '#3b82f6',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n fontSize: 13,\n headerFontSize: 12,\n cellPadding: 8,\n headerHeight: 28,\n rowHeaderWidth: 50,\n};\n\nexport const THEME_DARK: ThemeConfig = {\n bgColor: '#0f172a',\n cellBgColor: '#1e293b',\n cellTextColor: '#e2e8f0',\n headerBgColor: '#0f172a',\n headerTextColor: '#94a3b8',\n gridLineColor: '#334155',\n selectionBgColor: 'rgba(59, 130, 246, 0.15)',\n selectionBorderColor: '#3b82f6',\n focusBorderColor: '#60a5fa',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n fontSize: 13,\n headerFontSize: 12,\n cellPadding: 8,\n headerHeight: 28,\n rowHeaderWidth: 50,\n};\n\nexport const THEME_MINIMAL: ThemeConfig = {\n bgColor: '#ffffff',\n cellBgColor: '#ffffff',\n cellTextColor: '#111827',\n headerBgColor: '#ffffff',\n headerTextColor: '#9ca3af',\n gridLineColor: '#f3f4f6',\n selectionBgColor: 'rgba(99, 102, 241, 0.06)',\n selectionBorderColor: '#6366f1',\n focusBorderColor: '#6366f1',\n fontFamily: '\"Inter\", -apple-system, BlinkMacSystemFont, sans-serif',\n fontSize: 13,\n headerFontSize: 11,\n cellPadding: 10,\n headerHeight: 32,\n rowHeaderWidth: 44,\n};\n"],"names":["DEFAULT_THEME","DataModel","rowCount","colCount","__publicField","v","row","col","data","k","value","existing","patches","p","fn","_a","key","r","c","EventEmitter","event","e","SelectionModel","range","_b","r1","r2","c1","c2","bounds","cellCount","startRow","startCol","endRow","endCol","hasInfRow","hasInfCol","isFullRow","isFullCol","dRow","dCol","extend","newRow","newCol","CommandBus","limit","cmd","SetCellValueCommand","newValue","PatchCommand","snap","i","_c","DeleteCellsCommand","cells","old","ColumnModel","defaultWidth","configs","sums","width","cfg","min","max","count","x","lo","hi","mid","index","columnLabel","label","RowModel","defaultHeight","height","config","y","DOMRenderer","container","cell","target","rect","_e","ctx","s","columns","rows","viewMapping","showColHeaders","showRowHeaders","theme","totalW","visibleRows","totalH","headerLevels","headerH","headerW","innerDiv","sc","containerW","containerH","scrollX","scrollY","totalVisibleRows","isAutoLayout","overscan","vpStartRow","vpEndRow","vpStartCol","vpEndCol","rawStartRow","rawEndRow","rawStartCol","rawEndCol","vp","frozenRows","frozenCols","visibleSet","rowIdx","pooled","layoutChanged","maxH","cellEl","natural","currentH","newY","newH","rowIndex","selection","dataRow","h","isFrozenRow","el","rowY","merges","ci","w","cellH","merge","mc","mr","isFrozenCol","cellX","cellData","state","cs","type","headerRows","rowH","level","hc","needed","CM","div","viewW","viewH","DEFAULT_STATE","AutoFit","_rows","renderers","defaultRenderer","maxRows","maxWidth","totalRows","step","maxHeight","TextRenderer","_state","CheckboxRenderer","checked","DEFAULT_COLORS","BadgeRenderer","colors","customBg","customText","NumberRenderer","locale","options","num","ProgressRenderer","color","BlankRenderer","_data","RendererRegistry","name","renderer","EditorManager","TextEditorImpl","BlankEditorImpl","factory","editorType","initialChar","openValue","save","editor","_bounds","_cellData","KeyboardNav","callbacks","ctrl","shift","focus","ClipboardManager","tsv","text","isSingleCell","targetRow","targetCol","lines","cols","val","line","textarea","ColumnResize","delta","newWidth","clientX","RowResize","newHeight","clientY","ContextMenu","items","item","sep","disabled","shortcut","action","FillHandle","_columns","lastCell","cr","cc","minR","maxR","minC","maxC","topLeft","bottomRight","sx","sy","sw","sh","curCell","direction","fillRange","sourceRange","result","source","fill","_direction","srcRows","srcCols","srcRow","srcCol","srcCell","ColumnReorder","RowGroupModel","initialGroups","g","group","ViewMapping","visualRow","compareFn","hasSort","hasFilter","dir","a","b","va","vb","defaultCompare","MergeModel","initialMerges","m","notify","idx","PaginationModel","page","clamped","size","total","flattenColumns","flatColumns","maxDepth","getMaxDepth","flattenRecursive","colSpan","colIdx","rowSpan","PaginationBar","btn","_d","LoadingOverlay","exportCSV","visibleOnly","includeHeaders","headers","colIndices","_","headerRow","csvEscape","vr","dr","exportJSON","downloadFile","content","filename","mimeType","blob","url","WanderTable","defaultRowHeight","defaultColWidth","px","py","_source","changed","docH","docW","scrollBottom","scrollRight","colConfig","defaultType","oldValue","onMouseMove","me","onMouseUp","startX","viewport","cancelled","from","to","filter","onLoadMore","threshold","selectedCount","changes","ranges","at","expanded","csv","json","cellType","fromCol","toCol","moved","widths","movedW","newCount","keyToCol","flat","loading","DropdownEditor","opt","parent","query","q","o","icon","BlankEditor","onAttempt","_value","THEME_LIGHT","THEME_DARK","THEME_MINIMAL"],"mappings":"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"}