This commit is contained in:
2025-09-10 20:49:08 +10:00
parent e17d66fed1
commit b21b887adc
3 changed files with 50 additions and 49 deletions

View File

@@ -6,8 +6,8 @@
import { colToStr, refToStr } from './utils'; import { colToStr, refToStr } from './utils';
import clsx from 'clsx'; import clsx from 'clsx';
import { Input } from '../ui/input'; import { Input } from '../ui/input';
import { Grid, Position } from './grid';
import type { LeadMsg } from './messages'; import type { LeadMsg } from './messages';
import { grid, Position } from './grid.svelte.ts';
let { let {
socket, socket,
@@ -34,38 +34,35 @@
let rows = 50; let rows = 50;
let cols = 40; let cols = 40;
let grid = $state(new Grid(socket));
function handleCellInteraction(i: number, j: number, e: MouseEvent) { function handleCellInteraction(i: number, j: number, e: MouseEvent) {
let pos = new Position(i, j); let pos = new Position(i, j);
console.log('clicked', pos);
// if (grid.isEditing(pos)) {
// if (grid.isEditing(pos)) { // Get the actual input element that's being edited
// // Get the actual input element that's being edited const el = document.querySelector<HTMLInputElement>('input:focus');
// const el = document.querySelector<HTMLInputElement>('input:focus'); const currentInputValue = el?.value ?? '';
// const currentInputValue = el?.value ?? '';
// // ONLY treat this as a reference insert if it's a formula
// // ONLY treat this as a reference insert if it's a formula if (currentInputValue.trim().startsWith('=')) {
// if (currentInputValue.trim().startsWith('=')) { // Prevent the input from losing focus
// // Prevent the input from losing focus e.preventDefault();
// e.preventDefault();
// // --- This is the same reference-inserting logic as before ---
// // --- This is the same reference-inserting logic as before --- const ref = refToStr(i, j);
// const ref = refToStr(i, j); if (el) {
// if (el) { const { selectionStart, selectionEnd } = el;
// const { selectionStart, selectionEnd } = el; const before = el.value.slice(0, selectionStart ?? 0);
// const before = el.value.slice(0, selectionStart ?? 0); const after = el.value.slice(selectionEnd ?? 0);
// const after = el.value.slice(selectionEnd ?? 0); el.value = before + ref + after;
// el.value = before + ref + after; const newPos = (selectionStart ?? 0) + ref.length;
// const newPos = (selectionStart ?? 0) + ref.length; el.setSelectionRange(newPos, newPos);
// el.setSelectionRange(newPos, newPos); el.dispatchEvent(new Event('input', { bubbles: true }));
// el.dispatchEvent(new Event('input', { bubbles: true })); el.focus();
// el.focus(); }
// }
// return;
// return; }
// } }
// }
// We are not editing, so this is a normal cell selection OR this is not a formula // We are not editing, so this is a normal cell selection OR this is not a formula
grid.setActive(pos); grid.setActive(pos);
@@ -108,7 +105,7 @@
onmousedown={() => grid.setExternalEdit(grid.getActivePos())} onmousedown={() => grid.setExternalEdit(grid.getActivePos())}
onblur={() => grid.setExternalEdit(null)} onblur={() => grid.setExternalEdit(null)}
bind:value={ 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" class="relative w-[200px] pl-9"
></Input> ></Input>
@@ -167,10 +164,7 @@
bind:cell={ bind:cell={
() => grid.getCell(new Position(i, j)), (v) => grid.setCell(new Position(i, j), v) () => grid.getCell(new Position(i, j)), (v) => grid.setCell(new Position(i, j), v)
} }
active={(() => { active={grid.isActive(new Position(i, j))}
console.log(grid.isActive(new Position(i, j)));
return grid.isActive(new Position(i, j));
})()}
/> />
{/each} {/each}
</div> </div>

View File

@@ -32,15 +32,16 @@ class Position {
} }
class Grid { class Grid {
data: Record<string, CellT> = {}; data: Record<string, CellT> = $state({});
socket: WebSocket; socket: WebSocket;
row_heights: Record<number, string> = {}; row_heights: Record<number, string> = $state({});
col_widths: Record<number, string> = {}; col_widths: Record<number, string> = $state({});
default_row_height: string; default_row_height: string;
default_col_width: string; default_col_width: string;
active_cell: Position | null = null; active_cell: Position | null = $state(null);
editing_cell: Position | null = null; editing_cell: Position | null = $state(null);
external_editing_cell: Position | null = null; external_editing_cell: Position | null = $state(null);
editing_preview = $state(null);
constructor(socket: WebSocket, default_col_width = '80px', default_row_height = '30px') { constructor(socket: WebSocket, default_col_width = '80px', default_row_height = '30px') {
this.socket = socket; this.socket = socket;
@@ -59,7 +60,7 @@ class Grid {
} }
this.data[pos.key()] = { this.data[pos.key()] = {
raw_val: v.raw_val, raw_val: v?.raw_val,
val: v.val val: v.val
}; };
@@ -138,13 +139,15 @@ class Grid {
} }
public getActiveCell(): CellT { public getActiveCell(): CellT {
if (this.active_cell === null) return { if (this.active_cell === null)
return {
raw_val: '', raw_val: '',
val: undefined val: undefined
}; };
return this.getCell(this.active_cell); return this.getCell(this.active_cell);
} }
public getActivePos(): Position | null { public getActivePos(): Position | null {
return this.active_cell; return this.active_cell;
} }
@@ -205,4 +208,7 @@ class Grid {
} }
} }
export { Grid, Position }; export { Position };
export const grid = new Grid(new WebSocket(''));

View File

@@ -9,7 +9,8 @@
"skipLibCheck": true, "skipLibCheck": true,
"sourceMap": true, "sourceMap": true,
"strict": true, "strict": true,
"moduleResolution": "bundler" "moduleResolution": "bundler",
"allowImportingTsExtensions": true
} }
// Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias // 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 // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files