Skip to content

Add React Grab agent skill#310

Draft
aidenybai wants to merge 7 commits into
polish/toolbar-and-ui-animationsfrom
cursor/react-grab-skill-a585
Draft

Add React Grab agent skill#310
aidenybai wants to merge 7 commits into
polish/toolbar-and-ui-animationsfrom
cursor/react-grab-skill-a585

Conversation

@aidenybai
Copy link
Copy Markdown
Owner

@aidenybai aidenybai commented Apr 24, 2026

Summary

  • Remove the browser MCP client bundle/export and localhost /context push path
  • Have get_element_context read React Grab context from the system clipboard with clipboardy
  • Add a plain-text x-react-grab envelope to copied React Grab clipboard contents while keeping the custom MIME metadata
  • Add the repo-local React Grab agent skill and update architecture docs

Testing

  • Pending: build/test/lint/typecheck/format and adversarial browser check
Open in Web Open in Cursor 

Summary by cubic

Adds a react-grab agent skill and switches MCP context retrieval to a clipboard-backed x-react-grab text envelope read with clipboardy. Updates get_element_context to parse the envelope (including legacy entries/commentText), adds parsing tests and docs, and removes the browser MCP client bundle/export and the localhost /context push path.

Written for commit 645e38e. Summary will update on new commits.

Several coordinated fixes to the toolbar collapse/expand animation after
evidence-based debugging against runtime logs:

- Animate padding and border-radius alongside transform so the outer
  container's height/corners morph in lockstep with the inner grid
  instead of the height popping instantly while everything else slides.
- Swap weak built-in ease-out for a custom iOS-style drawer curve
  (cubic-bezier(0.32, 0.72, 0, 1)) registered as --ease-drawer in the
  @theme block, applied across all 7 collapse-related transitions.
- Asymmetric timing: 140ms collapse (opacity leads, size follows) and
  220ms expand (size leads, opacity delayed 80ms) so each direction
  reads as intentional.
- Correct TOOLBAR_COLLAPSED_SHORT_PX / TOOLBAR_COLLAPSED_LONG_PX to
  match the real rendered collapsed rect (16x30 not 14x28), removing
  sub-pixel drift between transform target and actual post-collapse
  position.
- Initialize collapsedDimensions signal based on the snap edge
  orientation at mount (horizontal edges: 30x16, vertical: 16x30)
  instead of a square default, so the first collapse has a correct
  transform target for the current edge.
- Reset collapsedDimensions in onSnapEdgeChange whenever the edge
  orientation flips (horizontal <-> vertical) so a drag from bottom
  to right doesn't leave stale horizontal dims that cause a visible
  14px snap at the end of the first post-switch collapse animation.
- Make getExpandedFromCollapsed's null-rect fallback edge-aware too,
  so the fallback width/height match the edge being expanded from.
- Add chevron press squish: pressing the chevron briefly scales the
  outer container perpendicular to the snap edge (scale(1, 0.97) on
  horizontal, scale(0.97, 1) on vertical) with a 60ms linear-ease-out
  press transition and a drawer-curve release.
- Dim the toolbar (opacity 0.55, scale 0.97) when grab mode is active
  and the user isn't directly interacting with it, so it recedes
  during element selection and snaps back to full presence on hover,
  drag, context menu, collapse animation, or chevron press. Required
  explicit pointer-events-auto because freeze-pseudo-states sets
  html { pointer-events: none } during active grab.

Also disables the transform transition during active drag so the
toolbar follows the pointer frame-to-frame without lag.
Apply Emil Kowalski / Budge-inspired taste principles to the rest of
the UI (complementing the toolbar polish):

- Dropdowns (comments, toolbar-menu, clear-comments-prompt): spring
  pop on enter (220ms cubic-bezier(0.34, 1.56, 0.64, 1), scale from
  0.92) and snappy drawer exit (120ms ease-drawer). Previously both
  directions used the same 100ms ease-out, which read as flat. The
  spring curve is registered as --ease-spring in @theme for reuse.
- Selection label: add blur-mask (drop-shadow + blur(3px)) during the
  fading transition so the label materializes from focus instead of
  flat-fading. Removes the "popping in and out" feel during rapid
  selection changes.
- Tag badge: replace generic transition-all with explicit
  transition-[opacity,transform,margin,width] + ease-drawer.
  transition-all cascades unexpectedly when future properties are
  added; explicit property list matches Emil's review guidance.
Three issues surfaced by the PR's automated reviewers + CI:

1. (CI typecheck, storybook) Add @types/react and @types/react-dom to
   @react-grab/storybook devDependencies. The playground/*.react.tsx
   stories ship React code but were relying on hoisted types from
   other workspaces, which disappeared in a clean pnpm install on CI.

2. (bugbot medium, cubic 1-3) Bump DROPDOWN_ANIMATION_DURATION_MS from
   100ms to 120ms so createAnchoredDropdown's setShouldMount(false)
   timeout matches the new 120ms exit CSS transition on the three
   dropdown components (comments, toolbar-menu, clear-comments). The
   dropdown DOM was being unmounted 20ms before the close animation
   finished, cutting off the exit.

3. (cubic issue 4) Extract syncCollapsedDimensionsToEdge helper and
   call it from both onSnapEdgeChange (drag) AND the
   onSubscribeToStateChanges subscription path. Previously only the
   drag path reset the orientation. An external state sync flipping
   the edge horizontal<->vertical would leave collapsedDimensions
   stale for the next collapse on the new edge.
Extract two shared helpers to packages/react-grab/src/utils/toolbar-position.ts
(the existing home for edge geometry):

- isHorizontalEdge(edge): named predicate replacing inline
  `edge === "top" || edge === "bottom"` checks
- getCollapsedDimsForEdge(edge): returns width/height matching the edge
  orientation, replacing duplicated LONG/SHORT ternary pairs

Eliminates 3 duplicate sites in toolbar/index.tsx (initial dims seed,
syncCollapsedDimensionsToEdge, and getExpandedFromCollapsed fallback).

Also simplify pressSquishStyle -> pressSquishTransform: returns undefined
when not pressed instead of an empty object spread, so the style binding
stays a single property assignment.

Net: +40 / -38, no behavior change.
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Apr 24, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
react-grab-storybook Ready Ready Preview, Comment Apr 24, 2026 10:38pm
react-grab-website Error Error Apr 24, 2026 10:38pm

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Apr 24, 2026

Open in StackBlitz

npm i https://pkg.pr.new/aidenybai/react-grab/@react-grab/cli@310
npm i https://pkg.pr.new/aidenybai/react-grab/grab@310
npm i https://pkg.pr.new/aidenybai/react-grab/@react-grab/mcp@310
npm i https://pkg.pr.new/aidenybai/react-grab@310

commit: 645e38e

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