Skip to content

fix(web): make plan sidebar resizable like diff panel#2598

Open
jonathanperis wants to merge 2 commits into
pingdotgg:mainfrom
jonathanperis:main
Open

fix(web): make plan sidebar resizable like diff panel#2598
jonathanperis wants to merge 2 commits into
pingdotgg:mainfrom
jonathanperis:main

Conversation

@jonathanperis
Copy link
Copy Markdown

@jonathanperis jonathanperis commented May 8, 2026

What Changed

The plan sidebar panel was rendered as a plain `

` with a hardcoded `w-[340px]` width inside `ChatView`. It could not be resized by the user.

This PR adds drag-to-resize support, a max-width constraint, and localStorage width persistence — matching the behavior already present on the diff panel.

Changes across 5 files:

  • `rightPanelLayout.ts` — adds `PLAN_INLINE_*` constants, `COMPOSER_COMPACT_MIN_LEFT_CONTROLS_WIDTH_PX`, and `createComposerWidthValidator(cssVarName)` factory (shared by both panels)
  • `PlanSidebar.tsx` — removes hardcoded `w-[340px] shrink-0 border-l`; width/border controlled by the parent wrapper
  • `hooks/useResizeHandle.ts` — new hook encapsulating pointer capture, RAF-batched width updates, body style management, click suppression, localStorage persistence with viewport-aware restore validation, and three cleanup paths: (1) `isDisabled` effect for sheet-mode flip mid-drag, (2) `setWrapperRef(null)` for programmatic sidebar close mid-drag, (3) React unmount effect; uses `useMemo` for the width validator
  • `ChatView.tsx` — replaces ~90 lines of inline resize logic with `useResizeHandle({ cssVarName, storageKey, minWidth, isDisabled: shouldUsePlanSidebarSheet })`
  • `routes/_chat.$environmentId.$threadId.tsx` — removes duplicate `COMPOSER_COMPACT_MIN_LEFT_CONTROLS_WIDTH_PX` constant; replaces `shouldAcceptInlineSidebarWidth` inline body with `useMemo(() => createComposerWidthValidator("--sidebar-width"), [])`

Why a plain div instead of `SidebarProvider > Sidebar`?

The `Sidebar` component uses `position: fixed; right: 0; z-10` hardcoded in its JSX. When both the diff and plan panels are open simultaneously, two `fixed` elements at `right: 0` overlap. The plain flex div stays in normal document flow — it renders to the left of the diff panel's fixed container with no overlap.

Default width: `clamp(20rem, 30vw, 28rem)` (~340px). Minimum: 320px. The `shouldAcceptWidth` validator rejects resize attempts that would overflow the chat composer or drop it below its minimum usable width — same behaviour as the diff panel. Width persists under `localStorage` key `chat_plan_sidebar_width`. Sheet/mobile behaviour (≤1180px) is unchanged.

Why

The diff panel has had resize support since it was introduced. The plan sidebar did not, despite being the same visual pattern. Users working with large plans benefit from being able to widen the panel to read content without scrolling.

UI Changes

2026-04-19.15-37-07.mp4

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

[!NOTE]

Make plan sidebar resizable with persisted width like the diff panel

  • Adds a drag handle to the inline plan sidebar in ChatView.tsx, backed by a new useResizeHandle hook that manages pointer capture, RAF-batched width updates, and localStorage persistence.
  • Introduces createComposerWidthValidator in rightPanelLayout.ts as a shared utility that validates proposed panel widths by checking for composer overflow; the diff panel's inline sidebar now uses this instead of its own inline implementation.
  • Removes the mode prop from PlanSidebar, which now fills its parent container and relies on the parent wrapper for sizing and borders.
  • Resizing is disabled when the sheet layout is active, and width is constrained by PLAN_INLINE_SIDEBAR_MIN_WIDTH.

Macroscope summarized 4b79313.


[!NOTE]
Medium Risk
Adds new pointer-driven resize/persist behavior for the plan sidebar and refactors shared layout validation used by both plan and diff panels; bugs here could impact composer layout or leave interaction styles stuck during mode switches.

Overview
Plan sidebar can now be resized in inline mode. ChatView wraps PlanSidebar in a width-controlled container (--plan-sidebar-width) with a left-edge drag handle, persists width to localStorage, and enforces a minimum width while keeping sheet/mobile behavior unchanged.

Resize/validation logic is centralized. Adds useResizeHandle to encapsulate pointer capture + RAF updates + cleanup, and introduces createComposerWidthValidator (plus plan sizing constants) in rightPanelLayout.ts; the diff panel route switches to this shared validator and PlanSidebar drops its hardcoded width/border so the parent controls sizing.

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

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 8, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 85bd381a-f890-4ecb-b19f-bf7d0663cda2

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels May 8, 2026
@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp Bot commented May 8, 2026

Approvability

Verdict: Needs human review

This PR adds new user-facing functionality (drag-to-resize capability for the plan sidebar with width persistence) rather than fixing existing behavior. The author is a first-time contributor. While the implementation follows existing patterns and is well-scoped, new features warrant human review.

You can customize Macroscope's approvability policy. Learn more.

Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

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 1 potential issue.

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 93c50ee. Configure here.

Comment thread apps/web/src/components/PlanSidebar.tsx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant