🙃
This commit is contained in:
@@ -74,14 +74,14 @@
|
|||||||
'resizer-col': direction === 'col',
|
'resizer-col': direction === 'col',
|
||||||
'resizer-row': direction === 'row'
|
'resizer-row': direction === 'row'
|
||||||
})}
|
})}
|
||||||
/>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.placeholder {
|
.placeholder {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
border: 1px solid var(--input);
|
border: 1px solid var(--input);
|
||||||
overflow: hidden;
|
overflow: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
.active {
|
.active {
|
||||||
@@ -95,31 +95,32 @@
|
|||||||
/* Make it easier to grab */
|
/* Make it easier to grab */
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
/* Subtle visual cue, becomes more visible on hover */
|
/* Subtle visual cue, becomes more visible on hover */
|
||||||
background-color: transparent;
|
background-color: var(--color-primary);
|
||||||
transition: background-color 0.2s ease-in-out;
|
opacity: 0;
|
||||||
|
transition: opacity 0.1s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Style for vertical (column) resizing */
|
/* Style for vertical (column) resizing */
|
||||||
.resizer-col {
|
.resizer-col {
|
||||||
cursor: col-resize;
|
cursor: col-resize;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: -5px;
|
||||||
width: 8px; /* Larger grab area */
|
width: 9px; /* Larger grab area */
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Style for horizontal (row) resizing */
|
/* Style for horizontal (row) resizing */
|
||||||
.resizer-row {
|
.resizer-row {
|
||||||
cursor: row-resize;
|
cursor: row-resize;
|
||||||
bottom: 0;
|
bottom: -5px;
|
||||||
left: 0;
|
left: 0;
|
||||||
height: 8px; /* Larger grab area */
|
height: 9px; /* Larger grab area */
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make the handle visible when hovering over the component */
|
/* Make the handle visible when hovering over the component */
|
||||||
|
.resizer:hover,
|
||||||
.group:hover > .resizer {
|
.group:hover > .resizer {
|
||||||
background-color: var(--color-primary);
|
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -80,7 +80,9 @@
|
|||||||
<style>
|
<style>
|
||||||
.placeholder {
|
.placeholder {
|
||||||
border: 1px solid var(--input);
|
border: 1px solid var(--input);
|
||||||
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
text-overflow: clip;
|
||||||
}
|
}
|
||||||
|
|
||||||
.active {
|
.active {
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
import { onDestroy, onMount } from 'svelte';
|
import { onDestroy, onMount } from 'svelte';
|
||||||
import CellHeader from './cell-header.svelte';
|
import CellHeader from './cell-header.svelte';
|
||||||
import {
|
import {
|
||||||
fromGridRef,
|
refFromStr,
|
||||||
splitErrorString,
|
splitErrorString,
|
||||||
toColLetter,
|
colToStr,
|
||||||
toGridRef,
|
refFromPos,
|
||||||
type CellData,
|
type CellData,
|
||||||
type CellValue
|
type CellValue
|
||||||
} from './utils';
|
} from './utils';
|
||||||
@@ -30,46 +30,46 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let cellRef: string | undefined;
|
let strRef: string | undefined;
|
||||||
let evalStr: string | undefined;
|
let evalStr: string | undefined;
|
||||||
|
|
||||||
// Case 1: "Cell D4 = Integer(4)"
|
// Case 1: "Cell D4 = Integer(4)"
|
||||||
let match = input.match(/^Cell\s+([A-Z]+\d+)\s*=\s*(.+)$/);
|
let match = input.match(/^Cell\s+([A-Z]+\d+)\s*=\s*(.+)$/);
|
||||||
if (match) {
|
if (match) {
|
||||||
[, cellRef, evalStr] = match;
|
[, strRef, evalStr] = match;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Case 2: "D6 String("hello")" or "E9 Double(4.0)"
|
// Case 2: "D6 String("hello")" or "E9 Double(4.0)"
|
||||||
if (!match) {
|
if (!match) {
|
||||||
match = input.match(/^([A-Z]+\d+)\s+(.+)$/);
|
match = input.match(/^([A-Z]+\d+)\s+(.+)$/);
|
||||||
if (match) {
|
if (match) {
|
||||||
[, cellRef, evalStr] = match;
|
[, strRef, evalStr] = match;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cellRef || !evalStr) {
|
if (!strRef || !evalStr) {
|
||||||
console.warn('Unrecognized message:', input);
|
console.warn('Unrecognized message:', input);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Cell: ${cellRef}`);
|
console.log(`Cell: ${strRef}`);
|
||||||
console.log(`Eval: ${evalStr}`);
|
console.log(`Eval: ${evalStr}`);
|
||||||
|
|
||||||
let [i, j] = fromGridRef(cellRef);
|
let { row, col } = refFromStr(strRef);
|
||||||
|
|
||||||
// Parse eval types
|
// Parse eval types
|
||||||
if (evalStr.startsWith('Integer(')) {
|
if (evalStr.startsWith('Integer(')) {
|
||||||
const num = parseInt(evalStr.match(/^Integer\(([-\d]+)\)$/)?.[1] ?? 'NaN', 10);
|
const num = parseInt(evalStr.match(/^Integer\(([-\d]+)\)$/)?.[1] ?? 'NaN', 10);
|
||||||
console.log(`Parsed integer:`, num);
|
console.log(`Parsed integer:`, num);
|
||||||
setCellVal(i, j, num);
|
setCellVal(row, col, num);
|
||||||
} else if (evalStr.startsWith('Double(')) {
|
} else if (evalStr.startsWith('Double(')) {
|
||||||
const num = parseFloat(evalStr.match(/^Double\(([-\d.]+)\)$/)?.[1] ?? 'NaN');
|
const num = parseFloat(evalStr.match(/^Double\(([-\d.]+)\)$/)?.[1] ?? 'NaN');
|
||||||
console.log(`Parsed double:`, num);
|
console.log(`Parsed double:`, num);
|
||||||
setCellVal(i, j, num);
|
setCellVal(row, col, num);
|
||||||
} else if (evalStr.startsWith('String(')) {
|
} else if (evalStr.startsWith('String(')) {
|
||||||
const str = evalStr.match(/^String\("(.+)"\)$/)?.[1];
|
const str = evalStr.match(/^String\("(.+)"\)$/)?.[1];
|
||||||
console.log(`Parsed string:`, str);
|
console.log(`Parsed string:`, str);
|
||||||
setCellVal(i, j, str);
|
setCellVal(row, col, str);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
let cols = 60;
|
let cols = 60;
|
||||||
|
|
||||||
let default_row_height = '30px';
|
let default_row_height = '30px';
|
||||||
let default_col_width = '60px';
|
let default_col_width = '80px';
|
||||||
|
|
||||||
// Only store touched cells
|
// Only store touched cells
|
||||||
let grid_vals: Record<string, CellData> = $state({});
|
let grid_vals: Record<string, CellData> = $state({});
|
||||||
@@ -150,7 +150,7 @@
|
|||||||
else {
|
else {
|
||||||
setCellRaw(i, j, v);
|
setCellRaw(i, j, v);
|
||||||
console.log(i, j);
|
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();
|
e.preventDefault();
|
||||||
|
|
||||||
// --- This is the same reference-inserting logic as before ---
|
// --- This is the same reference-inserting logic as before ---
|
||||||
const ref = toGridRef(i, j);
|
const ref = refFromPos(i, j).str;
|
||||||
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);
|
||||||
@@ -211,7 +211,7 @@
|
|||||||
width={getColWidth(j)}
|
width={getColWidth(j)}
|
||||||
setColWidth={(width) => setColWidth(j, width)}
|
setColWidth={(width) => setColWidth(j, width)}
|
||||||
direction="col"
|
direction="col"
|
||||||
val={toColLetter(j + 1)}
|
val={colToStr(j)}
|
||||||
active={active_cell !== null && active_cell[1] === j}
|
active={active_cell !== null && active_cell[1] === j}
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
|
|||||||
@@ -5,7 +5,16 @@ export interface CellData {
|
|||||||
val: CellValue;
|
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);
|
const match = ref.match(/^([A-Z]+)([0-9]+)$/i);
|
||||||
if (!match) throw new Error('Invalid reference');
|
if (!match) throw new Error('Invalid reference');
|
||||||
|
|
||||||
@@ -17,25 +26,29 @@ export function fromGridRef(ref: string): [number, number] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const row = parseInt(rowStr, 10);
|
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 result = '';
|
||||||
let n = col;
|
let n = col;
|
||||||
while (n > 0) {
|
while (n >= 0) {
|
||||||
const rem = (n - 1) % 26;
|
const rem = n % 26;
|
||||||
result = String.fromCharCode(65 + rem) + result; // 65 = 'A'
|
result = String.fromCharCode(65 + rem) + result; // 65 = 'A'
|
||||||
n = Math.floor((n - 1) / 26);
|
n = Math.floor(n / 26) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function toGridRef(row: number, col: number): string {
|
/**
|
||||||
row++;
|
* Zero indexed | A1 == {row: 0, col: 0};
|
||||||
col++;
|
*/
|
||||||
return toColLetter(col) + row.toString();
|
export function refFromPos(row: number, col: number): CellRef {
|
||||||
|
return { row, col, str: colToStr(col) + (row + 1).toString() };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function splitErrorString(errorString: string) {
|
export function splitErrorString(errorString: string) {
|
||||||
|
|||||||
Reference in New Issue
Block a user