From a7b2d569048400f3b9646ca2aac52e9af53850fd Mon Sep 17 00:00:00 2001 From: Marco Beretta <81851188+berry-13@users.noreply.github.com> Date: Fri, 31 Jul 2026 18:58:45 +0200 Subject: [PATCH] style(client): rebuild the ask question surfaces on shared option rows The popover and the chat card rendered the same question two different ways: numbered rows in one, wrapped chip buttons in the other, and the panel was painted with hardcoded white/gray instead of theme tokens. Both surfaces now render one AskOptions list, so numbering, check badges, rounding and hover states match wherever a question appears. The card groups its prompt with the description, styles the answer box like the composer, and gains a Skip button beside Submit so declining does not require the popover. While the popover holds the question the card keeps a hidden copy of itself in the thread, reserving the exact space the card will need so nothing reflows when the question moves back. --- .../Chat/Input/AskUserQuestionPopover.tsx | 99 ++++------ .../Chat/Messages/Content/AskUserQuestion.tsx | 171 +++++++++++------- client/src/components/Chat/ask/options.tsx | 76 ++++++++ client/src/locales/en/translation.json | 2 + 4 files changed, 216 insertions(+), 132 deletions(-) create mode 100644 client/src/components/Chat/ask/options.tsx diff --git a/client/src/components/Chat/Input/AskUserQuestionPopover.tsx b/client/src/components/Chat/Input/AskUserQuestionPopover.tsx index 66c73e2654..e0c0f85c85 100644 --- a/client/src/components/Chat/Input/AskUserQuestionPopover.tsx +++ b/client/src/components/Chat/Input/AskUserQuestionPopover.tsx @@ -1,12 +1,12 @@ import { memo, useEffect, useRef } from 'react'; import { useWatch } from 'react-hook-form'; -import { Button } from '@librechat/client'; -import { Check, ChevronDown, CornerDownLeft, TriangleAlert, X } from 'lucide-react'; +import { Button, TooltipAnchor } from '@librechat/client'; +import { ChevronDown, CornerDownLeft, TriangleAlert, X } from 'lucide-react'; import AskUserQuestions from '~/components/Chat/Messages/Content/AskUserQuestions'; import useAskAnswerMode from '~/hooks/Input/useAskAnswerMode'; +import AskOptions from '~/components/Chat/ask/options'; import { useChatFormContext } from '~/Providers'; import { useLocalize } from '~/hooks'; -import { cn } from '~/utils'; /** * Composer popover for a live `ask_user_question` pause. Single-select rows @@ -16,10 +16,10 @@ import { cn } from '~/utils'; * Submit confirms — * folding in any free-form text typed in the composer, exactly like Enter * would. The footer hint is a button that focuses the composer — the - * free-form answer box. Collapse (chevron) hides the popover but keeps - * answer mode live via the chat card; × dismisses it entirely. Pure - * rendering off {@link useAskAnswerMode}; disappears the moment an answer - * submits from any surface, and locks while one is in flight. + * free-form answer box. The chevron moves the question to the chat card and + * releases the composer (the card's chevron moves it back). Pure rendering + * off {@link useAskAnswerMode}; disappears the moment an answer submits from + * any surface, and locks while one is in flight. */ function AskUserQuestionPopoverContent({ conversationId, @@ -114,7 +114,6 @@ function AskUserQuestionPopoverPanel({ submit, submitOption, skip, - dismiss, collapse, handlePopoverKeyDown, } = ask; @@ -156,7 +155,7 @@ function AskUserQuestionPopoverPanel({ scroll region: the panel is absolutely positioned, so anything that overflows it is unreachable by page scroll. */}
@@ -170,64 +169,34 @@ function AskUserQuestionPopoverPanel({

)}
-
- - -
-
-
- {options.map((option, index) => { - const isChecked = multiSelect && checked.includes(index); - return ( - - ); - })} +
+ (multiSelect ? toggleChecked(index) : submitOption(index))} + optionRefs={optionRefs} + listRef={listRef} + className="relative min-h-0 flex-1 overflow-y-auto" + /> {/** A failed submission keeps the question answerable (controls stay * enabled), but the chat card that would show the error is hidden * while the popover is up — so surface it here for retry guidance. */} @@ -240,7 +209,7 @@ function AskUserQuestionPopoverPanel({
- {/** Mirrors the popover's ×: the collapsed card is the only chrome - * left, so the way out of answer mode has to live here too. */} - -
+ +