feat: Add copilot sidebar mode with drag-to-resize#2785
Open
EyalAmitay wants to merge 9 commits intoChainlit:mainfrom
Open
feat: Add copilot sidebar mode with drag-to-resize#2785EyalAmitay wants to merge 9 commits intoChainlit:mainfrom
EyalAmitay wants to merge 9 commits intoChainlit:mainfrom
Conversation
Add sidebar display mode as an alternative to the floating popover. The sidebar opens as a fixed panel on the right edge with a drag handle on the left edge for Notion-style resize (300px min, 50% viewport max). Width persists to localStorage. Includes display mode toggle in header and E2E tests for sidebar open/close/resize/mode-switch.
- Fix stale originalMargin capture by splitting into lifecycle + sync effects so the true original margin is captured once on open via ref, not re-captured on every width change - Fix userSelect not restored on unmount when drag is in progress - Fix CSS transition lag during drag by disabling transition on mousedown and re-enabling on mouseup - Add window.blur handler to cancel stuck drags when mouse released outside browser - Extract resize logic into useSidebarResize hook, consolidate DisplayMode type - Deduplicate chatContent and renderButtonIcon in widget.tsx - Add E2E tests for unmount cleanup and localStorage persistence across remounts
Replace drag-based resize test with localStorage pre-set approach. The Cypress trigger-based drag simulation was unreliable in CI headless mode, causing the test to fail with 'expected 400 to be above 400'.
- Add copilot.displayMode translation keys to all 20 language files - Use useTranslation in Header for Floating/Sidebar dropdown labels - Remove unnecessary code comments across modified files
- Remove backward-compat regression: stop clearing body margin/transition in unmountChainlitWidget (React cleanup handles it) - Guard localStorage write to only persist sidebar width in sidebar mode - Gate mousemove/mouseup/blur listeners on sidebar mode and open state - Remove hidden test-only button from sidebar production code - Remove renderButtonIcon and inline icon in sidebar closed-state button - Revert unrelated formatting changes in test file - Remove unnecessary non-null assertions in tests
…nts" This reverts commit c90790d.
Disable Radix UI's modal scroll-lock on the display mode DropdownMenu, which was adding overflow:hidden and padding-right to document.body.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a new sidebar display mode for the copilot widget. Instead of the default floating popover, the copilot can now render as a full-height side panel anchored to the right edge of the viewport, pushing the host page content to make room. Users can drag the left edge to resize and switch between sidebar and floating modes via a dropdown in the header.
Changes
useSidebarResizehook: Encapsulates resize logic, body margin management, and drag lifecycle (includingwindow.blurhandling for edge cases)DisplayModetype: Consolidated intotypes.ts, replacing inline string unionsBackward Compatibility
Fully backward compatible — no breaking changes to any existing API or behavior.
displayModeoption inIWidgetConfigis additive and optional; defaults to'floating'when not specified, preserving existing behaviormountChainlitWidget()calls withoutdisplayModework unchangedunmountChainlitWidget()continues to work as beforechainlit-copilot-displayMode,chainlit-copilot-sidebarWidth) — only read/written when the feature is used, no effect on existing deploymentsConfiguration
To default to the sidebar mode:
Test plan
Screen.Recording.2026-02-18.at.5.54.15.PM.mov