Skip to content

No guidance on Radix Accordion custom height-animation + forceMount pitfalls #6197

Description

@webstudio-issue-reporter

User story

As a user asking an AI agent to fix a Radix Accordion's open/close animation via the Webstudio MCP tools, I expect the agent to land on a correct, stable implementation in a small number of iterations, without regressions along the way.

Summary

Getting a Radix Accordion's height-based open/close animation right required several iterations and produced one real regression (all items appearing open by default), even though every individual MCP tool call succeeded and did exactly what its dry-run predicted. The difficulty was purely domain knowledge about how this project's Accordion is configured, not a tool malfunction.

What the agent tried

  1. Diagnosed initial abrupt-open behavior as a conflict between a custom animation prop and a native CSS transition on the AccordionContent height
  2. Removed the conflicting prop; issue persisted
  3. Traced it further to a Radix Primitives implementation detail: Radix sets inline transition-duration:0 and animation-name:none while it measures content height, which suppresses the very first open transition
  4. Proposed and applied a CSS grid-template-rows based workaround to sidestep the Radix-measured height variable entirely
  5. User reported this made things worse and asked to revert; reverted cleanly using the same tools
  6. User replaced the accordion instances with fresh ones and pasted the official Radix documentation CSS for AccordionContent (animation-based open/close using keyframes and the --radix-accordion-content-height variable)
  7. Implemented that official pattern by removing the old height/transition declarations and adding an HtmlEmbed style block with the pasted keyframes, scoped via a literal class name
  8. This produced a regression: all accordion items rendered open by default, because the instances have forceMount:true (content always stays mounted in the DOM), and the official Radix demo CSS assumes Radix's Presence component unmounts closed content instead
  9. With forceMount, removing the static closed-state height:0 rule left closed panels with no persistent collapsed state once the keyframe animation finished playing
  10. Diagnosed and started re-adding a static height:0 rule for the closed resting state alongside the animation, which was in progress when the user asked to stop and file this report

Expected behavior

Either the MCP tooling or its accompanying guidance/instructions would flag, before or during implementation, that this project's Accordion uses forceMount:true, and that copying the official Radix documentation's animation-only CSS verbatim is known to break when forceMount is enabled, because that demo relies on Radix's Presence unmounting closed content, which forceMount disables. This is a well-known Radix Primitives gotcha independent of Webstudio.

Actual result

No individual tool call failed or returned a misleading result -- every dry-run accurately predicted its commit, and every commit succeeded. The end-to-end task nonetheless required many iterations and produced one visible regression that a domain-aware human or an agent pre-warned about the forceMount interaction would likely have avoided.

Recovery attempts

  1. Regression caught immediately by user testing after the change
  2. Started re-adding a static closed-state height rule; had a working dry-run when the user asked to stop and report instead

User impact

Users watching an agent iterate live on a visual/interactive component can lose confidence when a fix visibly regresses functionality, even though the underlying tool calls are all working exactly as documented. This is especially costly for design/CSS animation tasks where correctness is only obvious after a manual/visual check, not from any structured tool response.

Technical context

MCP server 'webstudio', component '@webstudio-is/sdk-components-react-radix:AccordionContent', reached via Claude Code's MCP tool integration. The relevant Webstudio-specific facts that were not surfaced anywhere in tool descriptions or guidance: (1) Radix Accordion/Collapsible internally sets inline transition-duration:0 and animation-name:none during content-height measurement, which can suppress a from-scratch CSS transition/animation on the very first open; (2) this project's Accordion instances use forceMount:true, which changes the correctness requirements for any custom open/close animation CSS compared to the un-mounted-when-closed default Radix behavior documented on the public Radix Primitives site.

Agent environment

  • Client: claude-code-cli
  • Provider: unknown
  • Model: claude-sonnet-5
  • Reasoning effort: low
  • Trigger: user-requested
  • Category: other

Technical runtime

  • CLI: 0.293.0
  • Node.js: 22.11.0
  • Operating system: darwin 23 (arm64)
  • Execution mode: mcp
  • API contract: public-api:iqd6ok

Acceptance criteria

  1. When an AccordionContent or similar Radix Presence-based component instance has forceMount:true, surface a note in component discovery output that copying animation-only height CSS from Radix public docs requires an explicit resting-state height rule for the closed state, since Presence-based unmounting is disabled
  2. Consider documenting the Radix inline transition-duration/animation-name override during height measurement somewhere discoverable via the MCP tools, since it is a common source of animation-only-works-one-direction bug reports

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions