Skip to content

Graceful handling of long/awkward input: auto-fit + mobile zoom#10

Merged
dani-polani merged 5 commits into
mainfrom
feat/autofit-text
Jul 2, 2026
Merged

Graceful handling of long/awkward input: auto-fit + mobile zoom#10
dani-polani merged 5 commits into
mainfrom
feat/autofit-text

Conversation

@dani-polani

@dani-polani dani-polani commented Jul 2, 2026

Copy link
Copy Markdown
Member

One PR = one deploy. This group makes any input — however long or careless — look adequate automatically, and stays usable on mobile. Auto-fit isn't worth shipping without the zoom that makes the resulting small text tappable, so it's all here.

Auto-fit (never wrap a line)

A single input line never wraps to multiple display rows. Text (font-size + word-gap) scales down — never above the user's size — until each line fits its container. Applied identically to preview and export (display-only; the size slider stays the max).

  • Per-line with a variance control: 0 = all lines share one scale (uniform), 1 = each line fits independently. Default 0.5. Toggle Auto-fit (default on); off restores legacy wrapping.
  • Hyphenated tokens no longer break inside their block (white-space: nowrap), which also fixed a preview↔export mismatch.
  • When text shrinks, connectors and the attribution credit shrink proportionally (partial, via strength coefficients) so they aren't oversized.
  • New settings persist in the share URL (compact af/av, omitted at defaults). Pure fit math in src/lib/domain/autofit.ts.

Mobile zoom (create links on tiny text)

An interaction-only magnifier: pinch (touch) or ctrl/trackpad-pinch (desktop) to zoom, drag to pan, double-click/tap to reset. touch-action is pan-y at 1× (page scroll + clean tap still selects a token) and none above 1×. A discoverability pill appears when the text is small and the user hasn't zoomed yet.

  • Pure CSS transform on a wrapper around the tokens + connector layers, so they scale together and stay aligned.
  • Export fully decoupled: measurements are taken relative to the wrapper and divided by the scale (rounded to 1/100), so the exported SVG is byte-identical at any zoom. At 1× nothing changes → no regression. Pure zoom math in src/lib/domain/zoom.ts.

Testing

npm run check, lint, 110 tests green. Playwright: long line stays one row and shrinks; hyphen tokens don't wrap; ctrl-wheel zoom magnifies tokens with connectors tracking; exported SVG byte-identical before/after zoom; 1× tap still creates links.

🤖 Generated with Claude Code

dani-polani and others added 4 commits July 3, 2026 01:12
Long or careless input produced diagrams where one input line wrapped onto
several display rows, breaking the connectors. There is no valid case for
that in this diagram type, so shrink the text to fit instead.

- `.token-row` no longer wraps; a display-only auto-fit scales each line's
  effective font-size + word-gap down (never above the user's size) until it
  fits the container. Applied identically to the DOM and the exporter (the
  export draws glyphs at the scaled size, matching the measured boxes).
- Per-line fit with a "variance" control: 0 = every line shares one scale
  (uniform), 1 = each line fits independently. Default 0.5.
- Toggle "Auto-fit text to width" (default on); off restores legacy wrapping.
- New settings persist in the share URL (compact `af`/`av`, omitted at
  defaults). Pure fit math in `src/lib/domain/autofit.ts` (unit-tested).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… with fit

- A token is one alignment unit: `white-space: nowrap` on the token text so
  it never breaks inside (e.g. at a hyphen). This also fixed a preview↔export
  mismatch where a hyphen-wrapped token measured as two rows.
- When auto-fit shrinks the text, connectors (stroke + ribbon + endpoint dots)
  and the attribution credit now shrink too — partially, via a strength
  coefficient (lines 0.4, credit 0.65) applied to the mean text scale — so
  they don't look oversized on small text. Applied in preview and export.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Long sentences auto-fit to tiny text, which is hard to tap on mobile. Add
an interaction-only magnifier over the preview:
- Pinch (touch) or ctrl/trackpad-pinch (desktop) to zoom; drag to pan when
  zoomed; double-click/tap resets. `touch-action` stays `pan-y` at 1× (page
  scroll + a clean tap still selects tokens) and switches to `none` when
  zoomed so one-finger drag pans.
- It's a pure viewing transform on a wrapper around the tokens + connector
  layers, so tokens and links scale together and stay aligned.
- Export is fully decoupled: measurements are taken relative to the zoom
  wrapper and divided by the scale (rounded to hundredths), yielding
  layout-space coordinates — the exported SVG is byte-identical at any zoom.
- At 1× nothing changes (pan only engages above 1×), so no regression.

Pure zoom math in src/lib/domain/zoom.ts (unit-tested).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Show a small pill when auto-fit has shrunk the text (so zoom is useful) and
the user hasn't zoomed yet: "Pinch to zoom in" on touch, "Ctrl + scroll to
zoom in" on desktop. Switches to a reset hint while zoomed; hidden for
short text, readonly and hide-chrome/export.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@dani-polani dani-polani changed the title Auto-fit text so a line never wraps Graceful handling of long/awkward input: auto-fit + mobile zoom Jul 2, 2026
@dani-polani dani-polani merged commit 8651ef7 into main Jul 2, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant