Auto-sizing cell editor, multi-ref F4, and Alt+Enter line breaks
1. In-cell editor width/height ("nur in der Breite der Zelle angezeigt"):
the editor now lives as an overlay (like the clip/fill markers) instead
of inside its <td>, so it can grow past the cell -- width first, up to
an approximated display-width cap, then wrapping and growing height.
Sized via a hidden mirror element (same font/padding, real DOM
measurement -- a <textarea> can't self-size to content with CSS alone).
2. F4 now cycles every reference a real text selection overlaps, each from
its own lock state, not just the one at the caret -- select a stretch of
formula spanning several references and F4 adjusts all of them at once,
same as Excel. cycleReferenceLock(formula, caret) -> cycleReferenceLocks
(formula, start, end); a collapsed selection (start === end) keeps the
old single-reference caret behaviour. Wired into both the in-cell editor
and the formula bar.
3. Alt+Enter inserts a literal newline in the editor instead of committing
(explicit splice at the caret, not relying on the textarea's native
Enter handling, which isn't consistently reachable for Alt+Enter). A
cell holding a newline displays it wrapped (.cell.multiline) instead of
collapsing to one ellipsised line.
Along the way: a <td>'s own max-height doesn't cap table-row growth in any
browser (a table-layout quirk) -- a wrapped multi-line cell was silently
growing its row past rowH(r), which would have desynced every pixel
position computed from rowH()/rowTop() (the overlays, sticky frozen panes,
the row-resize handle). Fixed by moving cell text into its own block-level
.cell-content child, which *does* respect max-height + overflow:hidden.
Verified interactively against the dev server with Playwright: a long
formula gets a ~300px editor instead of the 104px cell; Alt+Enter produces
a real "\n" that survives commit and displays wrapped, with the row height
unchanged (26px, not the ~40px it grew to before the .cell-content fix);
F4 on a full-formula selection turns every reference absolute in one press
and keeps cycling all of them on repeated presses; existing selection,
copy/paste and fill-handle behaviour all regression-checked clean.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -13,7 +13,7 @@ Vorbild von **Apple Numbers**. Zwei Dinge stehen im Mittelpunkt:
|
||||
```bash
|
||||
npm install
|
||||
npm run dev # Vite-Devserver
|
||||
npm run test # Vitest-Suite (Engine + Store + IO), 127 Tests
|
||||
npm run test # Vitest-Suite (Engine + Store + IO), 132 Tests
|
||||
npm run build # Typecheck + Produktionsbuild
|
||||
npm run lint # ESLint (flat config)
|
||||
```
|
||||
@@ -97,12 +97,21 @@ umbenennen, löschen, per Drag sortieren). Zoom 40–200 % pro Blatt
|
||||
| `Pos1` / `Strg`+`Pos1` / `Ende` / `Strg`+`Ende` | Zeilenanfang / A1 / Zeilenende / letzte Zelle |
|
||||
| `Bild↑` / `Bild↓` | seitenweise (bei festen Tabellen nach Viewport-Höhe) |
|
||||
| **`Strg`/`Cmd`+`C`/`X`/`V`** | Kopieren / Ausschneiden / Einfügen (Zellen + Formatierung, bezugsangepasst) |
|
||||
| **`F4`** (im Editor/in der Formelleiste) | Bezug unter dem Cursor sperren/zyklisch umschalten: `A1` → `$A$1` → `A$1` → `$A1` → `A1` |
|
||||
| **`F4`** (im Editor/in der Formelleiste) | Bezug am Cursor sperren/zyklisch umschalten: `A1` → `$A$1` → `A$1` → `$A1` → `A1`; bei markiertem Text werden **alle** darin gefundenen Bezüge auf einmal umgeschaltet, jeder ausgehend vom eigenen Zustand |
|
||||
| **`Alt`+`Enter`** (im Editor) | Zeilenumbruch in der Zelle einfügen, statt zu committen |
|
||||
|
||||
Bei **festen (scrollbaren) Tabellen** wird die aktive Zelle bei jeder Navigation
|
||||
automatisch in den sichtbaren Bereich gescrollt (unter Beachtung fixierter
|
||||
Zeilen/Spalten).
|
||||
|
||||
**In-Zellen-Editor**: das Eingabefeld liegt als Overlay über der Zelle (nicht
|
||||
in ihr) und wächst mit dem Inhalt — in der Breite bis zu einer angenäherten
|
||||
„sichtbaren Anzeigebreite", danach umbrechend; in der Höhe mit `Alt`+`Enter`
|
||||
eingefügten Zeilenumbrüchen, bis zu einem Maximum, danach intern scrollbar.
|
||||
Ein Zeilenumbruch bleibt auch nach dem Committen erhalten und wird in der
|
||||
Zelle als solcher dargestellt (umbrechend statt einzeiliger Ellipse), auf die
|
||||
Zeilenhöhe der Tabelle geklemmt.
|
||||
|
||||
### Zell-Formatierung
|
||||
|
||||
Auswahl (Zelle, Bereich, Mehrfachauswahl, ganze Zeile/Spalte über den Kopf) → im
|
||||
@@ -315,14 +324,17 @@ Grundrechenarten: `Übersicht!B2 = =SUM(Umsatz!B2:E2)`, `D2 = =B2-C2`,
|
||||
|
||||
## Tests
|
||||
|
||||
`npm run test` — Vitest, 127 Tests:
|
||||
`npm run test` — Vitest, 132 Tests:
|
||||
|
||||
- **lexer / parser** — Präzedenz & Assoziativität (`^` vor `*/` vor `+-`, `^`
|
||||
rechts, `-2^2 = -(2^2)`), lokale/qualifizierte/quoted Bezüge, `!` **und** `::`,
|
||||
Bereiche, `;`-Argumente, Parse-Fehler.
|
||||
- **refs (`$`-Sperrachsen, `F4`)** — `parseA1`/`toA1` runden relativ/absolut/
|
||||
gemischt; `cycleReferenceLock` durchläuft die vier Kombinationen, trifft
|
||||
bei Cursor auf einem Bereich die richtige Seite, liefert `null` ohne Treffer.
|
||||
gemischt; `cycleReferenceLocks` durchläuft die vier Kombinationen, trifft
|
||||
bei Cursor auf einem Bereich die richtige Seite, liefert `null` ohne
|
||||
Treffer; bei echter Textauswahl schaltet es **alle** überlappten Bezüge auf
|
||||
einmal um (jeden vom eigenen Zustand aus) und lässt Tabellen-Qualifier, die
|
||||
wie eine Zelle aussehen (`AB12!A1`), unangetastet.
|
||||
- **evaluator** — Arithmetik, leere Zelle = 0, alle Funktionen inkl. Alias,
|
||||
Cross-Table, Case-/`::`-Toleranz, jeder Fehlerfall, Fehler-Propagierung.
|
||||
- **graph** — `affected`, topologische Ordnung, Selbst-/2er-/längerer Zyklus.
|
||||
|
||||
Reference in New Issue
Block a user