Skip to content

Unfold research and investigation previews with a shared disclosure - #481

Merged
MaggieAppleton merged 10 commits into
mainfrom
unfold-previews
Oct 11, 2026
Merged

MaggieAppleton merged 10 commits into
mainfrom
unfold-previews

Conversation

@MaggieAppleton

@MaggieAppleton MaggieAppleton commented Oct 11, 2026 •

Copy link
Copy Markdown
Collaborator

What changes

This adds a shared, accessible Unfold disclosure to @chopin/visuals and puts it to use across research and investigation cards.

How the disclosure works

  • It is a real <button> with aria-expanded and aria-controls. The panel stays mounted and folds open through its grid row while the content fades and tips down.
  • Speed: card previews take 600 ms (--duration-linger). Plain accordions take about 250 ms.
  • Interrupting: a second press reverses from the current frame.
  • When folded: the content is inert, aria-hidden and visibility-hidden, and focus returns to the toggle if it was inside.
  • Reduced motion: the height snaps and a short crossfade remains.

Where it's used

  • Research cards: a Preview chevron unfolds the question asked and up to five sources, plus "N more". Only http(s) sources become links. Clicking the card itself still opens the child fully, and preview controls keep the editor's caret where it was.
  • Investigation cards: they become accordions, folded once complete, with Report and evidence sections inside.
  • "Propose investigation", "View saved evidence" and the research child's Brief all move onto Unfold.

Slice 2 of the nested-documents work.

Screenshots

Research card, folded

Research card folded

Research preview, unfolded

Research preview unfolded

Investigation card, folded and unfolded

Investigation folded
Investigation unfolded

Propose investigation, open with focus

Propose investigation

Research child Brief

Child brief

Notable fixes found by the tests

  • The editor's global reduced-motion rule (.plan * { transition: none !important }) also removed the unfold's crossfade. It now exempts .cv-unfold-content, so only a 200 ms opacity fade remains under reduced motion.
  • Pressing a preview toggle or source link cleared the editor's caret. Mousedown is now prevented on those controls.
  • The Unfold clip leaves room for the outside focus ring, so focus rings inside open panels aren't cut off.

Testing

  • New e2e/unfold-previews.e2e.ts covers:
    • keyboard use
    • clicking text to open the child
    • frame-sampled reversal mid-fold
    • reduced motion
    • focus return
    • the editor selection staying unchanged
    • the source list styling
  • experiments.e2e.ts and connector.e2e.ts are updated off the <details>/summary selectors and onto role selectors, with accordion timing and focus checks.
  • The research-child-recovery Brief checks are updated.
  • Unit tests cover the primitive, safeSourceHref, the preview and the investigation card.
  • bun run types, unit tests (804 in the touched packages) and the design-contract check pass on the rebased head.
  • Locally on macOS, three End-key caret tests fail in files this branch doesn't touch: connection, editing and github-pills. This is the known macOS Chromium End-key difference (editing.e2e.ts already works around it), and CI runs on Linux.

Design-contract review

Three exact exception groups were added for unfold.tsx, with the maintainer's approval. They cover the caller button props, with ARIA, ref and type omitted, and the trigger object, which holds only ARIA state, a handler, a ref and the type. Each follows the wording of its sibling entries.

🤖 Generated with Claude Code

@MaggieAppleton
MaggieAppleton enabled auto-merge (rebase) October 11, 2026 11:05
MaggieAppleton and others added 10 commits October 11, 2026 12:11
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Keep the editor caret when pressing the toggle or a source link, let the
unfold crossfade survive the editor's reduced-motion reset, clamp the
question, and key duplicate source URLs uniquely.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Render the investigation card toggle only once its panel has loaded.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
packages/visuals/src/ui/unfold.tsx: UnfoldToggle and UnfoldPanel forward typed
DOM props (the controlled attributes are omitted from the type and set after the
spread); the useUnfold trigger holds only ARIA state, a handler, a ref and
type=button. Class merges join a caller string to a fixed cv-unfold base; every
caller passes a static literal that is scanned at its call site.

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

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaggieAppleton
MaggieAppleton merged commit 36578e3 into main Oct 11, 2026
3 checks passed
@MaggieAppleton
MaggieAppleton deleted the unfold-previews branch October 11, 2026 11:25
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