githubnext/chopinPublic

Let's compose rich plans together

Redesign code block controls as a header bar #218

MergedMaggieAppletonmerged 10 commits intomainfromrefs/pull/218/head
  1. MA

    Turns the loose row of code block controls into one bordered unit with a slim header, and replaces the native language `<select>` with the app's own menu.

    ## Change - **One box.** A code block is a single bordered, rounded unit. Its header (inset background, 4px padding) sits on top, and the rendered code, source panel, diagram and errors sit below it. - **Language menu.** A new `LanguageMenu` has a ghost `btn-sm` trigger and a portalled listbox with the app's dropdown motion. It supports keyboard use (arrows, Home/End, Enter/Space, Escape, Tab, type-to-jump) and dismisses on an outside click without moving the editor caret. Read-only viewers see a plain label instead of a disabled grey field. - **Source toggle.** "Show source" / "Hide source" is now a standard `btn-icon btn-ghost` with a new `CodeIcon` and a tooltip, and it tints petrol while the source is open. - **One text edge.** The language label, rendered code, source, invalid diffs and diagram errors all start 0.75rem in. Rendered code has 0.75rem above and below, matching a plain fence. Real diffs keep their line-number column. - **File title.** A titled file's name now appears in the header after the language (the renderer's own file header is off). Diffs keep the renderer's header. - **Focus.** The header uses the theme's `data-focus-boundary`, so focus rings draw inside the controls and the rounded box never crops them. The listbox panel has no ring of its own, because its highlighted option shows the keyboard position. That rule lives in `theme.css`, where the focus guard allows it.

    ## Verification - `bun test`, `bun run types` and `bun run ci` pass. - `e2e/code.e2e.ts` and `e2e/responsive-content.e2e.ts` pass 15 of 15 on Chromium, including a new keyboard listbox test: ArrowDown opens the menu, Escape returns focus to the trigger, an outside click dismisses it, Tab moves to the source toggle, and Enter selects. - Alignment was measured in the design audit: every text line starts 12px from the box's inner edge. - A code review found two bugs, both fixed: - Tab from the open menu left the page. - The highlighted option could go stale after a collaborator's language change. - It also flagged a duplicate diff title and wasted repositioning while the menu scrolled. Both are fixed too.

    ## Screenshots

    Captured from the dev-only design audit page at 2x, on `main` and on this branch, with the code specimen made editable so the controls are live.

    ### Code blocks

    | Before (`main`) | After (this PR) | | --- | --- | | ![Code blocks before](https://github.com/githubnext/chopin/blob/design-pr-assets/pr-218/before-code.png?raw=true) | ![Code blocks after](https://github.com/githubnext/chopin/blob/design-pr-assets/pr-218/after-code.png?raw=true) |

    ### Language menu open, and source shown

    | Menu open | Source shown | | --- | --- | | ![Language menu open](https://github.com/githubnext/chopin/blob/design-pr-assets/pr-218/after-code-menu.png?raw=true) | ![Source shown](https://github.com/githubnext/chopin/blob/design-pr-assets/pr-218/after-code-source.png?raw=true) |

    ### Diffs and diagrams

    | Before (`main`) | After (this PR) | | --- | --- | | ![Diffs before](https://github.com/githubnext/chopin/blob/design-pr-assets/pr-218/before-diff.png?raw=true) | ![Diffs after](https://github.com/githubnext/chopin/blob/design-pr-assets/pr-218/after-diff.png?raw=true) | | ![Diagrams before](https://github.com/githubnext/chopin/blob/design-pr-assets/pr-218/before-diagram.png?raw=true) | ![Diagrams after](https://github.com/githubnext/chopin/blob/design-pr-assets/pr-218/after-diagram.png?raw=true) |

    Taking these showed that consecutive fences now touched once the loose control rows became a header inside the box, so `eb3afb62` gives code blocks the same `margin-block: 1em` as tables.

    ## Review fixes

    - Focus the language listbox after it is positioned, before the next animation frame, so rapid keyboard selection works. - Preserve an authored filename when invalid diff content falls back to plain code. - Both new Chromium regression tests failed before the fixes and pass afterwards. All 17 code-block browser tests, 1,723 tests (2 PostgreSQL suites skipped), types, CI checks, and the build pass locally.

    The real editor below shows a normal code title and the restored filename on an invalid diff.

    ![Normal code title and restored invalid-diff filename](https://github.com/user-attachments/assets/01220bab-2c63-4eda-b558-4b90219eb521)

    馃 Generated with [Claude Code](https://claude.com/claude-code)

    ### CI navigation regression

    Fixes a race inherited from [#153](https://github.com/githubnext/chopin/pull/153): canonicalizing the current document URL could cancel navigation to a newly created document. The guard now tracks navigation separately from canonical URL changes. The onboarding test also uses a fresh identity for each retry.

    Validated with 51 creation, onboarding and navigation browser tests, plus five repeated runs of each race-sensitive case; types, CI checks and build passed.

    ![Document creation continues through URL canonicalization and respects later navigation](https://github.com/user-attachments/assets/5fc55a20-39c8-4c8f-a08d-2d92106579cc)

  2. MaggieAppletonhead-ref-force-pushed 924c95612171last month on GitHub

  3. MaggieAppletonreferenced this in Show diagram errors as a callout #223last month on GitHub

  4. MaggieAppletonhead-ref-force-pushed 404e81e96a02last month on GitHub

  5. MaggieAppletonadded-to-stacklast month on GitHub

  6. MaggieAppletonhead-ref-force-pushed b04879caff55last month on GitHub

  7. MaggieAppletonmerged 8181170bd083last month on GitHub

  8. MaggieAppletonclosedlast month on GitHub

  9. MaggieAppletonhead-ref-deletedlast month on GitHub

  10. MaggieAppletonreferenced this in Quiet rendered block chrome and steady diagram previews #370last month on GitHub