Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions content/docs/learn/playground/alignment.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
---
title: "Align cells and wrap text"
description: "Horizontal (left/center/right) and vertical (top/middle/bottom) alignment plus text wrap are per-cell format attributes; the toolbar sets them (Ctrl+Shift+L/E/R for horizontal), an explicit alignment overrides the type-based default, and a wrapped cell grows its row to fit its lines."
---

{/* GENERATED — do not edit by hand */}

## What it does

Select a cell or range and use the toolbar's **alignment** controls — a horizontal
group (**left / center / right**), a vertical group (**top / middle / bottom**), and a
**wrap** toggle — to place text inside each cell like Google Sheets. Horizontal
alignment also has keyboard shortcuts: **Ctrl+Shift+L** (left), **Ctrl+Shift+E**
(center), **Ctrl+Shift+R** (right).

**Horizontal** alignment defaults to the cell type — numbers, dates, and booleans hug
the right, text hugs the left. Choosing an explicit alignment **overrides** that default
(left-align a number and it moves left); re-choosing the alignment a cell already has
clears it back to automatic. **Vertical** alignment defaults to **bottom** (Sheets'
default) and is visible when the row is taller than one line.

**Wrap** breaks a value too wide for its column onto multiple lines at word boundaries
(a word longer than the column breaks mid-word) and **grows the row** so every line is
visible. With wrap off, long text is clipped at the cell edge and the row keeps its
default height.

All three are **presentation** attributes, separate from the cell's value: aligning or
wrapping `=A1+B1` repositions the number without touching the formula. They are per-cell,
survive value edits, and undo/redo like any other edit.

## Verified behavior

_Matches Google Sheets:_ In Google Sheets, horizontal alignment defaults to type-based (numbers/dates/booleans hug the right, text the left); an explicit Left/Center/Right (toolbar or Ctrl+Shift+L/E/R) overrides that default and re-selecting the current alignment clears it back to automatic. Vertical alignment (Top/Middle/Bottom, toolbar only) defaults to BOTTOM and is visible when a row is taller than one line. Text wrap breaks a value too wide for its column onto multiple lines at word boundaries (a word longer than the column breaks mid-word) and GROWS the row so every line is visible; with wrap off the text overflows/clips and the row stays default height. All three are per-cell presentation attributes: they survive value/formula edits, never change the computed value, and undo/redo like any edit. (Text rotation, also offered by Sheets, is a deferred follow-up — not built in this slice.)

#### Ctrl+Shift+E centers the selected cell

**Given**
- **A1** = `hello`

**When** I click **A1**, then press `Control+Shift+e`

**Then**
- **A1** is align=center

#### an explicit left-align overrides a number's automatic right-align

**Given**
- **A1** = `42`

**When** I click **A1**, then press `Control+Shift+l`

**Then**
- **A1** shows `42`
- **A1** is align=left

#### alignment is presentation only — the value and formula are untouched

**Given**
- **A1** = `=2+3`

**When** I click **A1**, then press `Control+Shift+r`

**Then**
- **A1** shows `5`
- **A1** has formula `=2+3`
- **A1** is align=right

#### alignment survives a value edit

**Given**
- **A1** = `x`

**When** I click **A1**, then press `Control+Shift+e`, then type `changed` into **A1**

**Then**
- **A1** shows `changed`
- **A1** is align=center

#### alignment undoes and redoes with the command log

**Given**
- **A1** = `x`

**When** I click **A1**, then press `Control+Shift+r`, then undo, then redo

**Then**
- **A1** is align=right
48 changes: 48 additions & 0 deletions content/docs/learn/playground/autofit-row-height.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
title: "Rows grow to fit the tallest cell font"
description: "Enlarging a cell's font grows its row to fit; reducing it (or clearing the cell) shrinks the row back."
---

{/* GENERATED — do not edit by hand */}

## What it does

Rows size themselves to their content. Type into a cell and make its font bigger — with the **[−] size [+]** stepper or **Ctrl+Shift+Period** — and the **whole row grows** so the larger text fits instead of overflowing into its neighbours. Shrink the font (or clear the cell) and the row **shrinks back**. The row always fits its **tallest** cell, so a big font in column A grows the entire row across every column.

Only cells that actually **hold content** drive the height: a cell formatted large but left empty leaves its row at the default height — matching Google Sheets.

## Verified behavior

_Matches Google Sheets:_ In Google Sheets every row auto-fits its content: a row's height is the height of its tallest cell, so increasing a cell's font size grows the whole row to fit the larger text and reducing it (or clearing the cell) shrinks the row back. Only NON-EMPTY cells count — a cell that carries a large font but no content does not grow its row. The tallest cell in the row wins (a big font in column A grows the entire row across every column). Row height is a layout consequence of the per-cell font-size presentation attribute; it never changes the cell's value or formula and undoes/redoes with the edit that caused it. Studio floors row height at its 24px default (Sheets' default is ~21px) so unrelated rows never reflow, and models the grown height with a line-box formula rather than pixel-matching Sheets' proprietary canvas metrics.

#### Enlarging a cell's font records the size that grows its row

**Given**
- **A1** = `Big`

**When** I click **A1**, then press `Control+Shift+Period`

**Then**
- **A1** is fontSize=11

#### Reducing the font records the size that shrinks the row back

**Given**
- **A1** = `Big`

**When** I click **A1**, then press `Control+Shift+Comma`

**Then**
- **A1** is fontSize=9

#### Row auto-fit is presentation — it never touches the value

**Given**
- **A1** = `=6*7`

**When** I click **A1**, then press `Control+Shift+Period`

**Then**
- **A1** shows `42`
- **A1** has formula `=6*7`
- **A1** is fontSize=11
99 changes: 99 additions & 0 deletions content/docs/learn/playground/cell-editing-modes.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
---
title: "Enter mode vs edit mode"
description: "Typing seeds a fresh value and arrows commit + move; F2 / Enter / double-click open the cell for editing so arrows move the caret; in a formula an arrow only steers a reference when the caret sits at a reference-valid position — so editing a formula never corrupts it."
---

{/* GENERATED — do not edit by hand */}

## What it does

There are two ways to start editing a cell, and they treat the arrow keys
differently — exactly like Google Sheets:

- **Enter mode** — _type a character_. It replaces the cell's contents, and pressing
an **arrow commits the value and moves the selection** one cell in that direction
(the fast data-entry flow: `42` → Down → `7` → Down …).
- **Edit mode** — press **F2**, press **Enter** on a selected cell, or
**double-click**. The existing content opens with a **caret**, and **arrows move
the caret** through the text (**Home** / **End** jump to the ends). Double-click
drops the caret near where you clicked.

## Editing a formula (point mode)

While editing a **formula**, an arrow key does one of two things depending on where
the caret is:

- **Steer a reference** ("point mode") — only when the caret is at the **end** of the
text, right after `=`, an operator (`+ - * / ^ & < > =`), `(` or `,`. This is how you
build a formula by pointing: type `=`, arrow to a cell; type `+`, arrow to the next.
- **Move the caret** — everywhere else. Moving the caret through a completed formula
such as `=B2+B1+C1` **never** rewrites a reference into it.

This caret gate is the fix for a data-corruption bug: previously _any_ arrow, at any
caret position, rewrote a reference into a formula you were only trying to move the
caret through (`=B2+B1` → `=B2+B1+D42+C1`).

## Try it

<TrueCalc mode="standalone" seed="A1==B2+B1+C1;B1=10;B2=20;C1=3" />

## Verified behavior

_Matches Google Sheets:_ In Google Sheets there are two ways an in-cell edit begins, and they behave differently. TYPING a character starts "enter" mode: the character replaces the cell's contents and pressing an arrow commits the value and moves the selection one cell in that direction. F2, Enter on a selected cell, or a DOUBLE-CLICK start "edit" mode: the existing text opens with a caret and arrows move the caret through it (Home/End jump to the ends). While editing a FORMULA, an arrow steers a cell reference ("point mode") ONLY when the caret sits at the end of the text right after "=", an operator, "(" or "," — i.e. the formula is expecting a reference next. Anywhere else the arrow moves the caret, so moving through an existing formula such as =B2+B1+C1 never rewrites a reference into it. Every edit is undoable.

#### Typing a value then pressing an arrow commits it (enter mode)

**Given**

**When** I click **A1**, then press `4`, then press `2`, then press `ArrowDown`

**Then**
- **A1** shows `42`

#### Editing a formula with arrows moves the caret and never corrupts it

**Given**
- **A1** = `=B2+B1+C1`
- **B1** = `10`
- **B2** = `20`
- **C1** = `3`

**When** I click **A1**, then press `F2`, then press `ArrowLeft`, then press `ArrowLeft`, then press `ArrowRight`, then press `Enter`

**Then**
- **A1** shows `33`
- **A1** has formula `=B2+B1+C1`

#### Arrowing from the start through a formula inserts no references

**Given**
- **A1** = `=B2+B1`
- **B1** = `10`
- **B2** = `20`

**When** I click **A1**, then press `F2`, then press `Home`, then press `ArrowRight`, then press `ArrowRight`, then press `ArrowRight`, then press `Enter`

**Then**
- **A1** shows `30`
- **A1** has formula `=B2+B1`

#### Point mode — typing = then arrowing inserts a reference

**Given**
- **B1** = `10`

**When** I click **A1**, then press `=`, then press `ArrowRight`, then press `Enter`

**Then**
- **A1** shows `10`
- **A1** has formula `=B1`

#### An edit is undoable

**Given**
- **A1** = `5`

**When** I click **A1**, then press `9`, then press `Enter`, then undo

**Then**
- **A1** shows `5`
72 changes: 72 additions & 0 deletions content/docs/learn/playground/clear-paint-format.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
---
title: "Clear formatting + Paint format"
description: "Ctrl+\\ (or the toolbar \"Tx\" button) resets a range's format to default without touching its value; the toolbar Paint format roller copies one range's full format onto another (single click = one-shot, double click = sticky until Escape or re-clicking the roller).\n"
---

{/* GENERATED — do not edit by hand */}

## What it does

**Clear formatting** — select a range and press **Ctrl+\\** (or click the **Tx** button in the toolbar) to reset every presentation attribute back to default: no bold/italic/strike, no font/color/fill overrides, no borders, no explicit number format, no alignment/wrap override. The cell's **value or formula is never touched** — clearing the format on `=A1+B1` resets its styling without changing what it computes to. It undoes and redoes like any other edit, and applying it to a range is **one** undoable command.

**Paint format** — the roller icon in the toolbar copies a range's **full** format onto another range, exactly like Google Sheets' format painter:

- **Single click** arms a **one-shot** paint: your very next click (or shift-click to extend to a range) applies the copied format and the tool immediately disarms.
- **Double click** arms a **sticky** paint: it stays armed across repeated applies — keep clicking new targets — until you press **Escape** or click the roller again.

Applying **replaces** the target's format wholesale, the same way Sheets does: if the target had its own border or fill that the source didn't carry, painting removes it too — this isn't a merge of the two formats. Painting onto a range bigger than the captured source tiles the source pattern across it (Sheets' own repeat-the-pattern behavior). A multi-cell apply is **one** undoable command regardless of size.

## Verification

The scenario runner can drive Ctrl+\\ end-to-end (a real keyboard chord), so clear-formatting's scenarios above are fully automated. Paint format's arm/apply gesture is a toolbar click followed by a click on a DIFFERENT target cell — the runner has no verb for driving a toolbar action button yet (the same gap `format-fill-color.mdx` documents for its color swatch), so it's browser-verified instead: arming via a single click on the roller shows the pressed toolbar state and the source range gets a dashed "copying" outline; clicking a target cell applies the source's format, replaces the target's own prior formatting, and the roller un-presses itself (one-shot); double-clicking the roller instead keeps it pressed across repeated target clicks until Escape.

## Verified behavior

_Matches Google Sheets:_ In Google Sheets, Format → Clear formatting (Ctrl+\ / Cmd+\ on Mac) resets every presentation attribute on the selection — bold/italic/strikethrough, fonts, colors, borders, number format, alignment, wrap — back to the default, without touching the cell's value or formula. It undoes/redoes like any edit. The Paint format toolbar button (the roller icon) captures the CURRENT selection's format pattern: a single click arms a ONE-SHOT paint that applies to the next click/drag target and immediately disarms; a double click arms a STICKY paint that stays armed — repeatedly applying to each subsequent click/drag target — until Escape is pressed or the roller is clicked again. Applying replaces the target's format wholesale (not a merge): a target's own fill/border/etc. that the source didn't carry is cleared too. A multi-cell target range is one undoable command regardless of size.

#### Ctrl+\ resets a bold+bordered cell's format, value unchanged

**Given**
- **A1** = `hello`

**When** I click **A1**, then press `Control+b`, then press `Control+Shift+7`, then press `Control+Backslash`

**Then**
- **A1** shows `hello`
- **A1** is bold=false, borders=false

#### Ctrl+\ on a formula cell clears format only — value and formula survive

**Given**
- **A1** = `5`
- **A2** = `=A1*2`

**When** I click **A2**, then press `Control+b`, then press `Control+Backslash`

**Then**
- **A2** shows `10`
- **A2** has formula `=A1*2`
- **A2** is bold=false

#### Ctrl+\ a second time is a no-op (already-default format stays default)

**Given**
- **A1** = `hello`

**When** I click **A1**, then press `Control+Backslash`, then press `Control+Backslash`

**Then**
- **A1** shows `hello`
- **A1** is bold=false

#### Selecting a formula cell leaves its value and formula unchanged (presentation-independence)

**Given**
- **A1** = `5`
- **A2** = `=A1*2`

**When** I click **A2**

**Then**
- **A2** shows `10`
- **A2** has formula `=A1*2`
12 changes: 3 additions & 9 deletions content/docs/learn/playground/clipboard.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,18 @@ title: "Copy, cut, and paste"
description: "Copy adjusts references to the paste target; cut moves a cell verbatim."
---

{/* GENERATED — do not edit by hand */}

## What it does

Select a cell and press **Ctrl+C** to copy or **Ctrl+X** to cut, then select a target and press **Ctrl+V** to paste.

- **Copy + paste** adjusts the formula's relative references by the paste offset — `=A1+B1` copied from **C1** to **C3** becomes `=A3+B3`, while `$`-anchored parts stay put (`=$A$1+B1` → `=$A$1+B3`). The source is left untouched and the clipboard stays loaded, so you can paste it again.
- **Cut + paste** _moves_ the cell: the formula is written to the destination **verbatim** (no reference adjustment) and the source cell is cleared. The clipboard is consumed after that one paste.

## Try it

<TrueCalc mode="standalone" seed="A1=10;B1=20;C1==A1+B1;A3=5;B3=7" />

## How it works

TrueCalc owns the calc. Copy and cut record the source cell's raw input; paste branches on which one it was. A copy adjusts the input (relative references shift, `$`-anchored references stay fixed) and writes the adjusted text to the target. A cut skips adjustment entirely — it writes the raw text unchanged and clears the source as a single undoable move — because a move should preserve exactly what the formula pointed at. Every result recomputes through the single engine, so the grid matches Google Sheets.

## Verified behavior

_Matches Google Sheets:_ In Google Sheets, copying a formula and pasting it adjusts the formula's relative references by the row/column offset (copying "=A1+B1" from C1 to C3 yields "=A3+B3"), while $-anchored parts stay fixed ("=$A$1+B1" → "=$A$1+B3"); copy leaves the source and the clipboard intact, so it can be pasted again. Cutting and pasting instead MOVES the cell: the formula is written to the destination verbatim (no reference adjustment) and the source is cleared, and the clipboard is consumed after that one paste.
_Matches Google Sheets:_ In Google Sheets, copying a formula and pasting it adjusts the formula's relative references by the row/column offset (copying "=A1+B1" from C1 to C3 yields "=A3+B3"), while $-anchored parts stay fixed ("=$A$1+B1" → "=$A$1+B3"); copy leaves the source and the clipboard intact, so it can be pasted again. Cutting and pasting instead MOVES the cell: the formula is written to the destination verbatim (no reference adjustment) and the source is cleared, and the clipboard is consumed after that one paste. (Sheets additionally rewrites OTHER formulas that referenced the moved cell so they keep pointing at it — that cross-reference remap needs engine support and is not yet modeled here; tracked as a follow-up.)

#### Copy a relative formula and paste — references shift by the offset

Expand Down
35 changes: 35 additions & 0 deletions content/docs/learn/playground/command-history.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
title: "Command history panel"
description: "A togglable side panel lists every committed operation with a human label, the cells it touched, and a timestamp; clicking an entry reverts the document to that state."
---

{/* GENERATED — do not edit by hand */}

## What it does

A togglable **History** panel (the clock-arrow icon at the right of the toolbar) lists every committed operation — typed edits, fills, pastes, clears, and every formatting toggle — as a labeled row: a human-readable story ("Bold on B2", "Filled A2:A5"), the affected cell(s) in monospace, and a timestamp. Clicking a row **reverts the document to that state** and highlights what changed. The log isn't persisted across reloads yet.

## Verified behavior

_Matches Google Sheets:_ Google Sheets has a Version History feature (File > Version history), but it operates on named SNAPSHOTS of the whole spreadsheet at a point in time — it does not list individual operations (each keystroke, each formatting toggle) as discrete, clickable, labeled entries the way this panel does. There is no Sheets equivalent to reproduce: this is a TrueCalc-original feature, built from the Store's own command log rather than replicated oracle behavior.

#### An edit and a bold each add one entry to the command log

**Given**
- **A1** = `10`

**When** I type `20` into **A2**, then click **A2**, then press `Control+b`

**Then**
- **A2** shows `20`
- **A2** is bold

#### Undoing a command removes it from the visible (committed) log

**Given**
- **A1** = `10`

**When** I type `20` into **A2**, then undo

**Then**
- **A2** shows `null`
Loading
Loading