From b21b887adc4a5df3527dab62227a913a1373f169 Mon Sep 17 00:00:00 2001 From: Lloyd Date: Wed, 10 Sep 2025 20:49:08 +1000 Subject: [PATCH] =?UTF-8?q?=F0=9F=99=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/lib/components/grid/grid.svelte | 66 +++++++++---------- .../grid/{grid.ts => grid.svelte.ts} | 30 +++++---- frontend/tsconfig.json | 3 +- 3 files changed, 50 insertions(+), 49 deletions(-) rename frontend/src/lib/components/grid/{grid.ts => grid.svelte.ts} (89%) diff --git a/frontend/src/lib/components/grid/grid.svelte b/frontend/src/lib/components/grid/grid.svelte index 981d332..98cf191 100644 --- a/frontend/src/lib/components/grid/grid.svelte +++ b/frontend/src/lib/components/grid/grid.svelte @@ -6,8 +6,8 @@ import { colToStr, refToStr } from './utils'; import clsx from 'clsx'; import { Input } from '../ui/input'; - import { Grid, Position } from './grid'; import type { LeadMsg } from './messages'; + import { grid, Position } from './grid.svelte.ts'; let { socket, @@ -34,38 +34,35 @@ let rows = 50; let cols = 40; - let grid = $state(new Grid(socket)); - function handleCellInteraction(i: number, j: number, e: MouseEvent) { let pos = new Position(i, j); - console.log('clicked', pos); - // - // if (grid.isEditing(pos)) { - // // Get the actual input element that's being edited - // const el = document.querySelector('input:focus'); - // const currentInputValue = el?.value ?? ''; - // - // // ONLY treat this as a reference insert if it's a formula - // if (currentInputValue.trim().startsWith('=')) { - // // Prevent the input from losing focus - // e.preventDefault(); - // - // // --- This is the same reference-inserting logic as before --- - // const ref = refToStr(i, j); - // if (el) { - // const { selectionStart, selectionEnd } = el; - // const before = el.value.slice(0, selectionStart ?? 0); - // const after = el.value.slice(selectionEnd ?? 0); - // el.value = before + ref + after; - // const newPos = (selectionStart ?? 0) + ref.length; - // el.setSelectionRange(newPos, newPos); - // el.dispatchEvent(new Event('input', { bubbles: true })); - // el.focus(); - // } - // - // return; - // } - // } + + if (grid.isEditing(pos)) { + // Get the actual input element that's being edited + const el = document.querySelector('input:focus'); + const currentInputValue = el?.value ?? ''; + + // ONLY treat this as a reference insert if it's a formula + if (currentInputValue.trim().startsWith('=')) { + // Prevent the input from losing focus + e.preventDefault(); + + // --- This is the same reference-inserting logic as before --- + const ref = refToStr(i, j); + if (el) { + const { selectionStart, selectionEnd } = el; + const before = el.value.slice(0, selectionStart ?? 0); + const after = el.value.slice(selectionEnd ?? 0); + el.value = before + ref + after; + const newPos = (selectionStart ?? 0) + ref.length; + el.setSelectionRange(newPos, newPos); + el.dispatchEvent(new Event('input', { bubbles: true })); + el.focus(); + } + + return; + } + } // We are not editing, so this is a normal cell selection OR this is not a formula grid.setActive(pos); @@ -108,7 +105,7 @@ onmousedown={() => grid.setExternalEdit(grid.getActivePos())} onblur={() => grid.setExternalEdit(null)} bind:value={ - () => grid.getActiveCell().raw_val, (raw) => grid.quickEval(grid.getActivePos(), raw) + () => grid.getActiveCell()?.raw_val ?? '', (raw) => grid.quickEval(grid.getActivePos(), raw) } class="relative w-[200px] pl-9" > @@ -167,10 +164,7 @@ bind:cell={ () => grid.getCell(new Position(i, j)), (v) => grid.setCell(new Position(i, j), v) } - active={(() => { - console.log(grid.isActive(new Position(i, j))); - return grid.isActive(new Position(i, j)); - })()} + active={grid.isActive(new Position(i, j))} /> {/each} diff --git a/frontend/src/lib/components/grid/grid.ts b/frontend/src/lib/components/grid/grid.svelte.ts similarity index 89% rename from frontend/src/lib/components/grid/grid.ts rename to frontend/src/lib/components/grid/grid.svelte.ts index b248d7f..1710854 100644 --- a/frontend/src/lib/components/grid/grid.ts +++ b/frontend/src/lib/components/grid/grid.svelte.ts @@ -32,15 +32,16 @@ class Position { } class Grid { - data: Record = {}; + data: Record = $state({}); socket: WebSocket; - row_heights: Record = {}; - col_widths: Record = {}; + row_heights: Record = $state({}); + col_widths: Record = $state({}); default_row_height: string; default_col_width: string; - active_cell: Position | null = null; - editing_cell: Position | null = null; - external_editing_cell: Position | null = null; + active_cell: Position | null = $state(null); + editing_cell: Position | null = $state(null); + external_editing_cell: Position | null = $state(null); + editing_preview = $state(null); constructor(socket: WebSocket, default_col_width = '80px', default_row_height = '30px') { this.socket = socket; @@ -59,7 +60,7 @@ class Grid { } this.data[pos.key()] = { - raw_val: v.raw_val, + raw_val: v?.raw_val, val: v.val }; @@ -138,13 +139,15 @@ class Grid { } public getActiveCell(): CellT { - if (this.active_cell === null) return { - raw_val: '', - val: undefined - }; + if (this.active_cell === null) + return { + raw_val: '', + val: undefined + }; return this.getCell(this.active_cell); } + public getActivePos(): Position | null { return this.active_cell; } @@ -205,4 +208,7 @@ class Grid { } } -export { Grid, Position }; +export { Position }; + + +export const grid = new Grid(new WebSocket('')); diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index a5567ee..bab947a 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -9,7 +9,8 @@ "skipLibCheck": true, "sourceMap": true, "strict": true, - "moduleResolution": "bundler" + "moduleResolution": "bundler", + "allowImportingTsExtensions": true } // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files