Skip to content

docs(playground): Show fixtures in row playgrounds from the live preview's header - #4386

Merged
ntucker merged 20 commits into
masterfrom
claude/project-thread-um6a5p
Oct 15, 2026
Merged

ntucker merged 20 commits into
masterfrom
claude/project-thread-um6a5p

Conversation

@ntucker

@ntucker ntucker commented Oct 14, 2026 •

Copy link
Copy Markdown
Collaborator

Before: row playgrounds (code beside the preview, e.g. /docs/api/useDLE) hid their fixtures entirely, so readers couldn't see what the demo's mocked endpoints return. In a narrow preview, a navigating demo's path was truncated to "/pos…" next to the Live Preview label.

After: the Live Preview header gets a small network icon (up/down arrows, like the devtools Network tab) beside the Store toggle. Hovering it previews the fixtures (the same collapsed rows as #4379) in a floating panel. Clicking or tapping pins the panel open, and that is also how it works on touch screens. The panel hangs from the preview's right edge and is up to 36rem wide. When code and preview sit side by side, it extends left over the code so a response has room. When they're stacked, it covers the result, and the result grows while the panel is pinned. Neither the code nor the preview moves. Stacked playgrounds' "Fixtures" header above the code shows the same icon, so readers learn it in both layouts. When a demo navigates and the header is narrow, "Live Preview" shrinks to its red dot, so the path shows in full.

Readers want the fixtures when they inspect what the demo did, the same moment they reach for the Store, so the toggle sits with the Store's in the preview rather than in the code's tab bar.

How:

  • PreviewWrapper takes an optional fixtures node. When it's set, it renders a headerButton toggle (with NetworkIcon, named by aria-label/title like the Store toggle, aria-expanded/aria-controls), plus an absolutely positioned popover in a zero-height anchor under the header.
  • index.tsx builds the FixturePreview once. For row playgrounds it goes to LivePreview and to PreviewLoading, so the toggle is in the SSR HTML too.
  • The popover shows on [data-open] (the click/tap pin) or, under @media (hover: hover), while the pointer is on the toggle or the popover (:has()). It fades with --motion-smooth, and visibility transitions with it so the pointer can cross into it.
  • The popover is right-anchored with width: min(100%, 36rem). Side by side, the preview isn't positioned, so its containing block is the playground and the preview's clip doesn't cut it off. The Store layers (z 2/3) stay above it, and .editorDocs is isolated so Monaco's layers stay below it.
  • The label's text is visually hidden under a 36rem container query on .previewHeader when it holds router controls.
  • EditorSurface's Fixtures header gets the NetworkIcon.

Checked in production builds on /docs/api/useDLE, /docs/api/useSuspense, /docs/getting-started/data-dependency, /docs/concepts/error-policy and the homepage demo, at 1600, 1280, 375 and 360px, in light and dark, with hover, click and tap. No sideways scroll and no hydration warnings at any width.

Adds PreviewWrapper.test.tsx.

Website-only, so no changeset.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LmaSKAuPn9J3ULHbYcxKmA


Note

Low Risk
Website-only playground UI and CSS; no API or data-path changes, covered by a focused component test.

Overview
Row-layout playgrounds no longer hide mocked API fixtures: they move from the code column into the Live Preview header via a new network icon toggle (with matching icon on the stacked editor fixtures header for visual consistency).

PreviewWrapper accepts optional fixtures and renders an accessible header button plus a right-anchored popover that previews on hover (pointer devices) and pins on click/tap. Playground builds FixturePreview once and passes it to LivePreview and PreviewLoading in row mode so fixtures work during SSR/loading too. CSS positions the panel over the result (and over the code when side-by-side), adjusts z-index vs the Store drawer, and visually hides the "Live Preview" label text on narrow headers when router path controls need space.

Adds NetworkIcon, PreviewWrapper tests, and small DemoLabel markup tweaks for the label text wrapper.

Reviewed by Cursor Bugbot for commit a9d1a05. Bugbot is set up for automated code reviews on this repo. Configure here.

Row playgrounds hid their fixtures entirely. A "ƒ Fixtures" toggle now
sits at the end of the code's file tab bar and unfolds the fixture rows
above the code, so row stays compact (no added height while closed).
Narrow, it shows just the ƒ.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LmaSKAuPn9J3ULHbYcxKmA
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@changeset-bot

changeset-bot Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: a9d1a05

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Docs preview: https://docs-site-pr-4386-data-client.vercel.app

Built from a9d1a05 merged into master (this build).

@codecov

codecov Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.37%. Comparing base (61d637c) to head (a9d1a05).
⚠️ Report is 5 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #4386   +/-   ##
=======================================
  Coverage   98.37%   98.37%           
=======================================
  Files         161      161           
  Lines        3072     3072           
  Branches      604      604           
=======================================
  Hits         3022     3022           
  Misses         10       10           
  Partials       40       40           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread website/src/components/Playground/styles.module.css
Only multi-file row playgrounds fold fixtures behind the toggle; a
single-file row shows them as stacked does, so no lone tab or empty
tablist appears. Reuse clean-btn and the ƒ mark, transition the hover
background, and map useIsomorphicLayoutEffect to a Jest stand-in.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LmaSKAuPn9J3ULHbYcxKmA

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread website/src/components/Playground/editor/EditorSurface.tsx Outdated
…n open

The row layout wraps the files in the Store's cover, which never got the
folded fixtures, so the toggle opened nothing. The open toggle also set
the selected tab's light text on the light bar; it now keeps the bar's
hover colors in both themes. The test renders row with a cover, as
Playground does.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LmaSKAuPn9J3ULHbYcxKmA
@ntucker

ntucker commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator Author

Staff engineer (Cursor agent): LGTM at 855f77e, with one small follow-up you can fold in here or skip.

Follow-up (not blocking): .tabControls + .unfold .fixtureBlock { border-bottom: 1px solid var(--pg-bar-edge) } never draws a line. --pg-bar-edge is transparent in :root, the dark-theme block doesn't override it, and only .endpointPlayground gives it a color. EndpointPlayground passes no fixtureContent, so it never reaches this toggle. Either drop the rule, or use a token that's visible on the code's dark ground, such as --store-line-strong, which the fixture rows already use.

What I validated, and how:

  • I read the full diff, plus EditorSurface.tsx, Unfold.tsx and styles.module.css at d6e84fa, and the d6e84fa...855f77e compare.
  • Bugbot's light-theme contrast finding was real at d6e84fa. I worked this out from the CSS and the preview's built stylesheet (#e3e8f2 on --pg-bar = Infima gray-200 #ebedf0, about 1.05:1). 855f77e switches the open state to --pg-tab-hover-bg / --pg-tab-hover, which is about 12:1 in light theme by the same calculation. The hover rule already uses that pair, so it's also the simplest fix.
  • Bugbot's second finding (fixtures missing when the Store cover path renders) is fixed in 855f77e by rendering {fixtures} inside .editorDocs. The test now passes cover the way Playground does in row.
  • The separator point comes from reading the CSS and checking the class chain in the preview page's HTML (.tabControls then .unfold then .fixtureBlock).

Not checked: I didn't open the page in a browser or look at it, and I didn't run the Jest tests locally. CI at d6e84fa was green except unit_tests-latest, which was still pending when I looked.

Nathaniel's review: the labeled toggle crowded the tab bar, and fixtures
pushed in below didn't read as the open control. The tab bar now holds
just a ƒ (labeled for screen readers). Hovering it previews the fixtures
in a layer floating over the code; a click or tap pins them open, which
is also the touch path.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LmaSKAuPn9J3ULHbYcxKmA
--pg-bar-edge is transparent outside EndpointPlayground.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LmaSKAuPn9J3ULHbYcxKmA

ntucker commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator Author

Folded in the separator follow-up: I confirmed that --pg-bar-edge is transparent everywhere except .endpointPlayground. Since 855f77e, the fixtures float over the code as a popover (e08f75c). That .unfold rule is gone, but the popover's bottom edge had the same problem. a3062eb switches it to --store-line-strong.


Generated by Claude Code

Nathaniel: it blended into the code. It's now an inset card, lighter than
the code, bordered and shadowed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LmaSKAuPn9J3ULHbYcxKmA

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread website/src/components/Playground/styles.module.css
Nathaniel: the lighter card clashed and looked detached from the ƒ. The
ƒ now opens like a selected tab (code color, accent top edge) and the
card is its panel in the same color, hung from the bar's end, lifted off
the code by an edge and shadow.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LmaSKAuPn9J3ULHbYcxKmA
The popover's z-index escaped .editorDocs, painting over the Store layer
and its badge; isolating .editorDocs keeps it with the code it covers.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LmaSKAuPn9J3ULHbYcxKmA
Nathaniel: fixtures stand in for network calls, so a network icon says
what they are better than the ƒ.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LmaSKAuPn9J3ULHbYcxKmA
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LmaSKAuPn9J3ULHbYcxKmA
One fragment instead of two values rendered in both cover branches,
the duplication that once dropped the popover from one of them.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LmaSKAuPn9J3ULHbYcxKmA
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LmaSKAuPn9J3ULHbYcxKmA
Readers inspect fixtures when they look at what the demo did, as with
the Store, so the network toggle sits beside the Store's in the preview
header and the fixtures float over the result. The code tab bar is back
to plain file tabs.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LmaSKAuPn9J3ULHbYcxKmA
@ntucker ntucker changed the title docs(playground): Show fixtures in row playgrounds behind a code-header toggle docs(playground): Show fixtures in row playgrounds from the live preview's header Oct 14, 2026

ntucker commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator Author

Staff engineer (Cursor agent): FOLLOW_UP only — no change requested on this PR.

Tip 417745b3 moves row fixtures from the code tab bar into the Live Preview header (network icon beside Store). That is a clear gain over master, which hid row fixtures entirely. Nothing here is a CHANGE_THIS_PR finding.

Validated

  • Read compare 446a8822...417745b3 and tip PreviewWrapper / LivePreview / CSS / PreviewWrapper.test.tsx.
  • Tip CI: Bugbot, website, regenerate, docs deploy, gates, CircleCI lint/typecheck/unit — all success as of this review.
  • Ran PreviewWrapper + FixturePreview Jest suites at tip (passed). Drove the PR docs deploy (docs-site-pr-4386-data-client.vercel.app) with headless Chrome: useDLE at 1600 / 1280 / 360 (touch) — hover preview, click/tap pin, aria-expanded, no sideways scroll, no console errors.
  • Measured opened-fixture panel vs preview height on several docs pages; curled SSR HTML for useDLE (no fixturesToggle in server HTML).

Follow-ups after merge (design trade-offs, not blockers)

  1. The fixtures popover is capped to .playgroundResult height (max-height: 100%). When a row playground stacks (e.g. 1280px with sidebar), short previews clip hard — on /docs/api/useSuspense the first demo’s preview was ~93px, so an opened response (~189px) sat in a ~92px scroll box. The prior code-bar popover used min(20rem, 60svh) over the editor and did not hit this. One option is to grow the preview area only while pinned; accepting the clip is also fine given “preview never moves.”
  2. PreviewLoading still renders only the Store header control, so the fixtures toggle is absent from SSR/crawler HTML and appears after live preview hydration. Low impact (header height unchanged); wiring row/fixtures through would match the disabled-Store layout-hold pattern.

Inferred, not checked: commonality of 1280px reader width; real devices; that pin-only grow is the simplest fix.

… loads

A short row result clipped an unfolded response to a ~90px scroll box,
so the result grows while the fixtures are pinned. The loading (SSR and
crawler) preview now carries the fixtures toggle too, instead of it
appearing only once the live preview loads.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LmaSKAuPn9J3ULHbYcxKmA

ntucker commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator Author

Both follow-ups are folded into this PR in 39dbe74, since each was small and made the change better:

  1. Short previews clipping: while the fixtures are pinned, the result grows to min(14rem, 50svh). On /docs/api/useSuspense at 1280px, the first demo's result goes from 93px to 224px when pinned, and an unfolded /profiles/1 response fits without scrolling. Hover previews still float without moving anything.
  2. Toggle missing from SSR: PreviewLoading now gets row's fixtures too, so the toggle and fixtures are in the server HTML and already usable before the live preview loads. That also covers crawlers. index.tsx builds the FixturePreview once and hands it to the editor (stacked), PreviewLoading and LivePreview (row).

Checked in a production build: the toggle's class is in the useSuspense and useDLE HTML, there are no hydration warnings, and the preview tests pass.


Generated by Claude Code

Side by side, the preview column was too thin for a response, so the
fixtures panel now spans the code too. The preview is no longer their
containing block there, so its clip doesn't cut them off.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LmaSKAuPn9J3ULHbYcxKmA

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit de4bd47. Configure here.

Comment thread website/src/components/Playground/styles.module.css
Comment thread website/src/components/Playground/styles.module.css
Side by side, pinned fixtures painted over an opened Store; the Store's
layers now sit above them, and the code's own (Monaco's) stay below.
Stacked, a pinned panel taller than the room it gets was clipped with no
way to scroll, so it now caps at that same height.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LmaSKAuPn9J3ULHbYcxKmA
With a demo's back/home controls in a header under 36rem, the label
keeps only its dot (still named for screen readers), so the path gets
the room instead of truncating.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LmaSKAuPn9J3ULHbYcxKmA
Side by side, the panel spanned the whole playground, which on wide
playgrounds ran far past what a response line needs. It now hangs from
the preview's right edge at up to 36rem.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LmaSKAuPn9J3ULHbYcxKmA
Name the toggle with aria-label/title like the Store's, share its lit
state rule, and fade the panel with the site's motion token (instant
under reduced motion) and the Store's line color.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LmaSKAuPn9J3ULHbYcxKmA
The Fixtures header above the code now carries the same icon as row
playgrounds' preview toggle, so readers learn it in both layouts.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LmaSKAuPn9J3ULHbYcxKmA
@ntucker
ntucker added this pull request to the merge queue Oct 15, 2026
Merged via the queue into master with commit 7ad074c Oct 15, 2026
30 checks passed
@ntucker
ntucker deleted the claude/project-thread-um6a5p branch October 15, 2026 14:45

This branch was successfully deployed

1 active deployment
docs-preview — a9d1a055 Deployed Oct 15, 2026 by ntucker via docs deploy #3249
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.

2 participants