Skip to content

Make tabs authorable in place and label empty table headers - #382

Merged
MaggieAppleton merged 6 commits into
mainfrom
design/tabs-authoring
Oct 8, 2026
Merged

MaggieAppleton merged 6 commits into
mainfrom
design/tabs-authoring

Conversation

@MaggieAppleton

@MaggieAppleton MaggieAppleton commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

Why

/Tabs inserted tabs called "One" and "Two" that nobody could rename, add to or remove. The panel had no visible end, so its content ran into the next block. /Table inserted an unlabelled grid that stopped halfway across the page.

What changed

  • Rename: double-click a tab, or press Enter or F2 on a focused one, to edit its name in place. A tap on the open tab works on touch. Enter or blur saves, Escape cancels, and an empty name keeps the old one. Labels are trimmed to one line within the dialect's 60 characters.
  • Add: a ghost "+" at the end of the strip appears on hover or focus, and always without hover. It adds "Tab N" with an empty paragraph, selects it and opens its name for editing.
  • Remove: a removable tab keeps a fixed slot at its end, and a × appears on hover or focus without shifting neighbouring tabs. Delete or × removes a tab, including one with content, in one step; document undo from Undo and redo each person's own document edits #352 can restore it. On touch, the selected tab exposes × directly, while a long press reveals × for another tab. The last tab cannot be removed.
  • Keys stay out of the document: the strip handles its keys with native listeners, so Lexical's root never applies Enter, Delete, typing, paste or undo from the strip or the name field to the document selection.
  • Collaboration: if a collaborator removes the tab you have open, the panel falls back to the first tab instead of hiding every panel.
  • Panel end: the panel ends on the same hairline as the strip. An empty panel, including a tab with no blocks at all, shows "Write in this tab…" while the document is editable.
  • Tables: empty header cells read "Column 1", "Column 2" and so on, using a CSS counter, only while the document is editable. The full-width table behavior from merged Let short tables fill the prose width #386 is inherited; this diff adds header placeholders.
  • Read-only: no add, remove or rename controls.
  • Reorder is not included.

Screenshots

Before: tabs, then a new table

Before tabs
Before table

After: new table, with header placeholders

After table

After: phone, renaming by tap

After phone rename

Verification

  • Five commits, including the one-step removal review fix, remain patch-identical on the refreshed stack.
  • Focused tab-authoring tests: 4 passed. bun run fix, bun run ci, bun run types, and bun run build passed.
  • Earlier isolated browser checks passed for undo restoring a deleted tab and its contents after reload, and one-tap removal on touch. Fresh GitHub CI must run after the prepared head is published.
  • Initial JavaScript: 251,414 B raw / 79,332 B gzip, within budget.

🤖 Generated with Claude Code

@MaggieAppleton

Copy link
Copy Markdown
Collaborator Author

Hold — please don't merge yet. Splitting the global table-width change out of this PR for a separate design decision, then a review. I'll post here when ready.

🤖 Generated with Claude Code

@MaggieAppleton MaggieAppleton changed the title Make tabs authorable in place and label new tables Make tabs authorable in place and label empty table headers Oct 8, 2026
@MaggieAppleton

Copy link
Copy Markdown
Collaborator Author

Review: Looks good

Checked in a worktree build against the fake server (headless Playwright, desktop 1440x900 and phone 390x844), plus code read. CI is green on all three jobs.

Verified

  • Round trip: rename, add (Tab N, skips used numbers), remove all land in canonical MDX; 60-char label survives and the field caps at 60; reload keeps tabs. Empty label and Escape keep the old name; blur commits.
  • Keys stay out of the document: Enter, Delete, Backspace, Cmd+A, Cmd+Z, Cmd+Shift+Z and a multi-line paste in the name field (collapsed to one line) left the text after the tabs unchanged; Cmd+Z on a focused tab does nothing to the document.
  • Keyboard: tablist/tab/tabpanel semantics intact, roving tabindex, arrows/Home/End select and move focus, Enter/F2 rename, Delete on an empty tab removes it and focus lands on the successor; Delete on a tab with content arms (4s timeout, aria-description), last tab protected.
  • Two users: B removed the tab A was renaming; A's field closed and A fell back to the first tab. Concurrent add from both produced two "Tab 3" tabs (harmless, same label).
  • Phone: tap on the open tab opens rename; Add is visible without hover. Read-only: covered by the new e2e (no add/remove/rename after the socket drops).
  • Look: panel end rule, "Write in this tab…" on an added tab, and "Column 1/2" header placeholders look right and are consistent with the formula placeholder.

Non-blocking findings

  1. packages/editor/src/styles.css .plan-tab-remove overlays the label end, so short labels clip on hover on desktop ("Mobi×", "Deskt×") and, because @media (hover: none) shows × on the open tab permanently, on phone the open tab clips at rest ("Ze×" for "Zed"). Suggest reserving the remove width (padding-inline-end) only when the label is shorter than the strip allows, or on touch relying on the long-press/armed path instead of a permanent ×.
  2. On touch the × is 16px (spacing*4), well under the 44px target in Fix touch ergonomics on phones #299. Enlarge the hit area with an invisible ::after inset rather than the glyph.
  3. tabs.tsx RenameField: Backspace on an already-empty field deletes an empty tab. A user clearing the name with two Backspaces loses the tab. Consider limiting that to a fresh, untouched field, or dropping it (Delete on the tab already covers it).
  4. A tab from MDX with no children (<Tab> containing only a blank line) renders no placeholder, since only a childless panel exists; tabs added with + do. Pre-existing shape, but worth a paragraph on import.
  5. Tab strip hover/focus-within reveal of + is not reachable by tapping on non-hover devices when a comment marker sits at the strip's end (seed artifact in my run); not this PR's regression.

Keep the confirm once #352 (undo) lands? Keep it until #352 merges AND an e2e proves Cmd+Z restores a removed tab with its content. Then drop the arm step for tabs with content: immediate remove plus undo is cheaper than a two-step Delete and matches Linear/Vercel. Caveat: undo is per person, so a collaborator's removal still cannot be undone by you; if that matters, keep the confirm only when other people are present in the document.

@MaggieAppleton

Copy link
Copy Markdown
Collaborator Author

Hold lifted.

@MaggieAppleton

Copy link
Copy Markdown
Collaborator Author

Polish pushed in 6d100d5:

  1. A removable tab now always keeps a fixed slot at its end, and the × shows there on hover, so it never covers the label or moves the tabs beside it. On touch, tabs keep even padding at rest. A long press (500 ms) arms a tab, which opens the slot and shows the ×. A tap on that × then removes it, so the confirm step is still there.
  2. On coarse pointers, the × has a 44px target from an ::after inset. The + already gets one through the shared btn-icon rule.
  3. Backspace in an empty name field no longer removes the tab.
  4. A tab with no blocks at all now shows the "Write in this tab…" placeholder too.
    The confirm step stays until Undo and redo each person's own document edits #352 lands.

MaggieAppleton and others added 5 commits October 8, 2026 18:11
…th grid

Tab labels rename on double-click or Enter, a quiet add button ends the strip,
and tabs remove from a hover close button or Delete. A tab with content asks
once before it goes, because document undo does not exist yet. The panel now
ends on a hairline, and an empty one says what belongs there. Tables span the
prose measure, and empty header cells read "Column 1", "Column 2" and so on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ip icons

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…op Backspace removal

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaggieAppleton
MaggieAppleton merged commit 727ca9c into main Oct 8, 2026
4 checks passed
@MaggieAppleton
MaggieAppleton deleted the design/tabs-authoring branch October 8, 2026 17:43
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