This commit is contained in:
2025-09-05 23:23:26 +10:00
parent fb40c0a2ce
commit d0163020f9
4 changed files with 51 additions and 35 deletions

View File

@@ -74,14 +74,14 @@
'resizer-col': direction === 'col',
'resizer-row': direction === 'row'
})}
/>
></div>
</div>
<style>
.placeholder {
font-size: 14px;
border: 1px solid var(--input);
overflow: hidden;
overflow: visible;
}
.active {
@@ -95,31 +95,32 @@
/* Make it easier to grab */
z-index: 10;
/* Subtle visual cue, becomes more visible on hover */
background-color: transparent;
transition: background-color 0.2s ease-in-out;
background-color: var(--color-primary);
opacity: 0;
transition: opacity 0.1s ease-in-out;
}
/* Style for vertical (column) resizing */
.resizer-col {
cursor: col-resize;
top: 0;
right: 0;
width: 8px; /* Larger grab area */
right: -5px;
width: 9px; /* Larger grab area */
height: 100%;
}
/* Style for horizontal (row) resizing */
.resizer-row {
cursor: row-resize;
bottom: 0;
bottom: -5px;
left: 0;
height: 8px; /* Larger grab area */
height: 9px; /* Larger grab area */
width: 100%;
}
/* Make the handle visible when hovering over the component */
.resizer:hover,
.group:hover > .resizer {
background-color: var(--color-primary);
opacity: 0.5;
}
</style>

View File

@@ -80,7 +80,9 @@
<style>
.placeholder {
border: 1px solid var(--input);
white-space: nowrap;
overflow: hidden;
text-overflow: clip;
}
.active {

View File

@@ -4,10 +4,10 @@
import { onDestroy, onMount } from 'svelte';
import CellHeader from './cell-header.svelte';
import {
fromGridRef,
refFromStr,
splitErrorString,
toColLetter,
toGridRef,
colToStr,
refFromPos,
type CellData,
type CellValue
} from './utils';
@@ -30,46 +30,46 @@
return;
}
let cellRef: string | undefined;
let strRef: string | undefined;
let evalStr: string | undefined;
// Case 1: "Cell D4 = Integer(4)"
let match = input.match(/^Cell\s+([A-Z]+\d+)\s*=\s*(.+)$/);
if (match) {
[, cellRef, evalStr] = match;
[, strRef, evalStr] = match;
}
// Case 2: "D6 String("hello")" or "E9 Double(4.0)"
if (!match) {
match = input.match(/^([A-Z]+\d+)\s+(.+)$/);
if (match) {
[, cellRef, evalStr] = match;
[, strRef, evalStr] = match;
}
}
if (!cellRef || !evalStr) {
if (!strRef || !evalStr) {
console.warn('Unrecognized message:', input);
return;
}
console.log(`Cell: ${cellRef}`);
console.log(`Cell: ${strRef}`);
console.log(`Eval: ${evalStr}`);
let [i, j] = fromGridRef(cellRef);
let { row, col } = refFromStr(strRef);
// Parse eval types
if (evalStr.startsWith('Integer(')) {
const num = parseInt(evalStr.match(/^Integer\(([-\d]+)\)$/)?.[1] ?? 'NaN', 10);
console.log(`Parsed integer:`, num);
setCellVal(i, j, num);
setCellVal(row, col, num);
} else if (evalStr.startsWith('Double(')) {
const num = parseFloat(evalStr.match(/^Double\(([-\d.]+)\)$/)?.[1] ?? 'NaN');
console.log(`Parsed double:`, num);
setCellVal(i, j, num);
setCellVal(row, col, num);
} else if (evalStr.startsWith('String(')) {
const str = evalStr.match(/^String\("(.+)"\)$/)?.[1];
console.log(`Parsed string:`, str);
setCellVal(i, j, str);
setCellVal(row, col, str);
}
};
@@ -77,7 +77,7 @@
let cols = 60;
let default_row_height = '30px';
let default_col_width = '60px';
let default_col_width = '80px';
// Only store touched cells
let grid_vals: Record<string, CellData> = $state({});
@@ -150,7 +150,7 @@
else {
setCellRaw(i, j, v);
console.log(i, j);
socket.send(`set ${toGridRef(i, j)} ${v}`);
socket.send(`set ${refFromPos(i, j).str} ${v}`);
}
};
@@ -170,7 +170,7 @@
e.preventDefault();
// --- This is the same reference-inserting logic as before ---
const ref = toGridRef(i, j);
const ref = refFromPos(i, j).str;
if (el) {
const { selectionStart, selectionEnd } = el;
const before = el.value.slice(0, selectionStart ?? 0);
@@ -211,7 +211,7 @@
width={getColWidth(j)}
setColWidth={(width) => setColWidth(j, width)}
direction="col"
val={toColLetter(j + 1)}
val={colToStr(j)}
active={active_cell !== null && active_cell[1] === j}
/>
{/each}

View File

@@ -5,7 +5,16 @@ export interface CellData {
val: CellValue;
}
export function fromGridRef(ref: string): [number, number] {
export interface CellRef {
row: number;
col: number;
str: string;
}
/**
* Zero indexed | A1 == {row: 0, col: 0};
*/
export function refFromStr(ref: string): CellRef {
const match = ref.match(/^([A-Z]+)([0-9]+)$/i);
if (!match) throw new Error('Invalid reference');
@@ -17,25 +26,29 @@ export function fromGridRef(ref: string): [number, number] {
}
const row = parseInt(rowStr, 10);
return [row - 1, col - 1];
return { row: row - 1, col: col - 1, str: ref };
}
export function toColLetter(col: number): string {
/**
* Zero indexed | 0 == A;
*/
export function colToStr(col: number): string {
let result = '';
let n = col;
while (n > 0) {
const rem = (n - 1) % 26;
while (n >= 0) {
const rem = n % 26;
result = String.fromCharCode(65 + rem) + result; // 65 = 'A'
n = Math.floor((n - 1) / 26);
n = Math.floor(n / 26) - 1;
}
return result;
}
export function toGridRef(row: number, col: number): string {
row++;
col++;
return toColLetter(col) + row.toString();
/**
* Zero indexed | A1 == {row: 0, col: 0};
*/
export function refFromPos(row: number, col: number): CellRef {
return { row, col, str: colToStr(col) + (row + 1).toString() };
}
export function splitErrorString(errorString: string) {