Skip to content

fix(frontend): restore click-to-open for side elements - #2982

Open
axelray-dev wants to merge 6 commits into
Chainlit:mainfrom
axelray-dev:fix/side-panel-click-only-2979
Open

axelray-dev wants to merge 6 commits into
Chainlit:mainfrom
axelray-dev:fix/side-panel-click-only-2979

Conversation

@axelray-dev

@axelray-dev axelray-dev commented Jul 14, 2026

Copy link
Copy Markdown

Summary

Since 2.11.0, the element side panel opened automatically whenever a message with display="side" elements arrived. In 2.10.x the panel only opened when the user clicked the element link. Closing the panel did not stick, because the next side-element update forced it open again.

Changes

  • In MessagesContainer, stop auto-calling setSideView when side elements change.
  • Still clear sideView when no side elements remain so a closed/stale panel does not linger.
  • Leave click-to-open via onElementRefClick unchanged.
  • Add Vitest coverage: new side elements do not auto-open; clearing elements clears an open side view; an open element refreshes when its content changes.

Verification

  • Vitest frontend/tests/MessagesContainer.spec.tsx (2 tests)
  • ESLint, Prettier, and frontend typecheck on touched files

Fixes #2979

Fixes Chainlit#2979

Co-Authored-By: Codex <codex@openai.com>
@axelray-dev
axelray-dev marked this pull request as ready for review July 14, 2026 08:40
@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. bug Something isn't working frontend Pertains to the frontend. unit-tests Has unit tests. labels Jul 14, 2026

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 2 files

Re-trigger cubic

@dokterbob
dokterbob requested a review from Copilot July 28, 2026 17:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@dokterbob

Copy link
Copy Markdown
Collaborator

@codex review

@dokterbob

Copy link
Copy Markdown
Collaborator

@codex review

@dokterbob
dokterbob requested a review from Copilot July 29, 2026 14:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@dokterbob

Copy link
Copy Markdown
Collaborator

Code looks good to me, but I'm no react buff. Are other maintainers still alive? @hayescode @asvishnyakov @sandangel Anyone of you in a better position to verify quality?

Feedback/approval from other users would also help!

@janis-bauer-rsu

Copy link
Copy Markdown

Just a user report in support of this PR: the auto-opening side panel since 2.11.0 is a real annoyance in our app. It affects the UX on every single message with a side element, which makes it hard to live with long-term.

#2979 covered the same regression and was closed as stale while this PR was already open, so it would be a shame to lose it the same way.

@axelray-dev

Copy link
Copy Markdown
Author

I revalidated this PR and merged the current upstream main branch as commit 645bd8e. The targeted Vitest suite passes 2/2, the frontend type-check passes after building the workspace client, and ESLint plus Prettier pass on the changed files. The earlier e2e failure was from the older base; please re-run CI on the updated head. I left the review thread open for verification.

@kairntech

Copy link
Copy Markdown

I also do support this PR, in our app we had to restrict "chainlit>=2.10.1,<2.11" to avoid this which is very annoying

Regards
Olivier

@minwookshin

Copy link
Copy Markdown

I reviewed axelray-dev's change at 645bd8e294b9909100d62d8084ac91d80a6192e9 and found one regression worth addressing before merge: an already-open preview keeps stale element content after that element is updated.

Reproduction: receive Source A → click its reference → update A's URL/content. The incoming state is revision 2, but the open panel still displays revision 1 because sideViewState.elements retains the old objects.

I prepared a small supplemental patch and reproducible browser review. It refreshes the current selection by ID, preserves a manual close and unrelated selection, and keeps custom titles/keys. The combined patch includes the complete regression test file and can be applied to this PR head; no duplicate upstream PR was opened.

Nine relevant tests pass with the supplement. Restoring the original production file makes the three content/title refresh cases fail. The linked evidence includes before/after screenshots, exact commands, full frontend and harness type checks, and browser checks using real Chainlit components. The mobile Sheet and Copilot Dialog were also rendered, with the backend and shadow-root integration limits called out.

One separate accessibility observation from the unmodified views: in the fixture, Copilot Escape dismissal returns focus to body, and the desktop close icon has no accessible name. Those are outside this state-refresh supplement, so I would not treat this review as a complete accessibility sign-off.

@axelray-dev
axelray-dev force-pushed the fix/side-panel-click-only-2979 branch from 5a69ec8 to 7f12f2c Compare September 23, 2026 08:19

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

1 issue found and verified against the latest diff

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="frontend/src/components/chat/MessagesContainer/index.tsx">

<violation number="1" location="frontend/src/components/chat/MessagesContainer/index.tsx:97">
P1: Adding `sideView` to the effect deps makes this clear branch run right after *any* `setSideView`, so the panel is closed the moment it opens whenever the global `elements` list has no `display: "side"` element. That breaks two open paths: clicking a `page`-display element in no-navigate embeds (`libs/copilot/src/chat/body.tsx` renders `MessagesContainer` without `navigate`), and the backend-driven `ElementSidebar` (`set_sidebar_elements`, `useChatSession.ts:393`) whose elements are not guaranteed to be `display: "side"`. The old effect only ran on `elements` changes, so these panels stayed open. Scope the clearing to panels that track side-display elements.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

knownSideOrderRef.current = [];
setSideView(undefined);
if (!elements.some((element) => element.display === 'side')) {
if (sideView) setSideView(undefined);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1: Adding sideView to the effect deps makes this clear branch run right after any setSideView, so the panel is closed the moment it opens whenever the global elements list has no display: "side" element. That breaks two open paths: clicking a page-display element in no-navigate embeds (libs/copilot/src/chat/body.tsx renders MessagesContainer without navigate), and the backend-driven ElementSidebar (set_sidebar_elements, useChatSession.ts:393) whose elements are not guaranteed to be display: "side". The old effect only ran on elements changes, so these panels stayed open. Scope the clearing to panels that track side-display elements.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At frontend/src/components/chat/MessagesContainer/index.tsx, line 97:

<comment>Adding `sideView` to the effect deps makes this clear branch run right after *any* `setSideView`, so the panel is closed the moment it opens whenever the global `elements` list has no `display: "side"` element. That breaks two open paths: clicking a `page`-display element in no-navigate embeds (`libs/copilot/src/chat/body.tsx` renders `MessagesContainer` without `navigate`), and the backend-driven `ElementSidebar` (`set_sidebar_elements`, `useChatSession.ts:393`) whose elements are not guaranteed to be `display: "side"`. The old effect only ran on `elements` changes, so these panels stayed open. Scope the clearing to panels that track side-display elements.</comment>

<file context>
@@ -41,95 +42,83 @@ const MessagesContainer = ({ navigate }: Props) => {
-      knownSideOrderRef.current = [];
-      setSideView(undefined);
+    if (!elements.some((element) => element.display === "side")) {
+      if (sideView) setSideView(undefined);
       return;
     }
</file context>
Suggested change
if (sideView) setSideView(undefined);
if (sideView?.elements.some((element) => element.display === "side")) {
setSideView(undefined);
}

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working frontend Pertains to the frontend. size:M This PR changes 30-99 lines, ignoring generated files. unit-tests Has unit tests.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Side panel force-opens on every new display="side" element since 2.11.0 — no way to opt out

6 participants