diff --git a/webui/frontend/app/components/common/Composer.tsx b/webui/frontend/app/components/common/Composer.tsx index 156fe534a..72ce629a4 100644 --- a/webui/frontend/app/components/common/Composer.tsx +++ b/webui/frontend/app/components/common/Composer.tsx @@ -1278,7 +1278,7 @@ export function Composer({ // rather than the viewport — the composer can be narrow while // the viewport stays wide (e.g. a detail rail is open), where a // viewport-relative rule overflows or wraps. -
+
{/* Left: pills. Collapsed behind a toggle while the footer is narrower than the row needs, inline above that. @@ -1289,11 +1289,13 @@ export function Composer({ viewport, so keep the pills inline" and let them wrap into three rows there. - 600px is what one row costs: the four standing pills come - to ~510px with a long model name (PillButton caps each at - 240px) plus ~90px for the attach/send cluster. A session - can carry two more pills, so this is the common case, not a - guarantee. + 550px is the threshold: the four standing pills plus the + ~90px attach/send cluster fit inline in a fairly narrow + column, so opening the workspace panel (which splits the + chat column) no longer collapses them into the toggle right + away. Above it the pills shrink to one line; below it + collapses to the scroll row. A session can carry two more + pills, so this is the common case, not a guarantee. Visibility is CSS-driven so the first paint is correct with no SSR/hydration flash. When expanded on a narrow footer @@ -1309,22 +1311,22 @@ export function Composer({ transcript. One line can never do that, whatever the pill count or label length. - `flex-wrap` is declared per branch instead of on the base: - it and `flex-nowrap` are the same utility group, so keeping - both here would let stylesheet order — not this class - list — decide the winner. */} + Pills never wrap: `flex-nowrap` plus `min-w-0` on every + wrapper let an over-long row shrink each pill to its + `min-w-24` floor and truncate the label instead of spilling + onto a second line. */}
{/* Toggle button: shown only while collapsed */} {!pillsExpanded && ( } onClick={() => setPillsExpanded(true)} /> @@ -1333,8 +1335,8 @@ export function Composer({
{/* Model pill */} @@ -1399,14 +1401,11 @@ export function Composer({ hand-rolled button) so the background, padding and height match the selector pills exactly — copying its classes by hand drifted on all of them. `caret={false}`: - it navigates rather than opening a panel. `fitContent` - drops the shared width cap so the whole "search not set - up" message reads instead of collapsing to "Searc…". */} + it navigates rather than opening a panel. */} {searchNeedsKey && ( navigate('/settings/search')} icon={} className="!text-msa-text-3" diff --git a/webui/frontend/app/components/common/PillButton.tsx b/webui/frontend/app/components/common/PillButton.tsx index 2ade4471c..827d73a81 100644 --- a/webui/frontend/app/components/common/PillButton.tsx +++ b/webui/frontend/app/components/common/PillButton.tsx @@ -30,10 +30,6 @@ interface PillButtonProps extends Omit { /** Panel open state — flips the caret (same 180° + transition as the * accordion headers) so the pill reads as expanded. */ open?: boolean - /** Drop the shared max-width cap so the pill grows to its full label instead - * of truncating. Used by the search-not-configured hint, whose message has to - * read in full rather than collapse to "Searc…". */ - fitContent?: boolean } export const PillButton = forwardRef( @@ -41,7 +37,6 @@ export const PillButton = forwardRef( { caret = true, open = false, - fitContent = false, children, className = '', classNames, @@ -69,12 +64,12 @@ export const PillButton = forwardRef( classNames && typeof classNames === 'object' ? (classNames as Record) : {} - // The width cap is `!important`, so a caller can't undo it with its own - // `max-w-*`; `fitContent` omits it here instead. `min-w-24` stays either way - // so a short label keeps the shared minimum pill size. - const width = fitContent - ? 'min-w-24' - : '!max-w-[min(96px,55cqw)] min-w-24' + // `min-w-24` (96px) is the floor, `max-w-[250px]` the cap: a pill grows with + // its label up to 250px, then truncates. The pills row still owns the rest of + // overflow — a tight row shrinks each pill (flex) toward the floor and scrolls + // once collapsed. When flex forces a pill narrower than its label the inner + // span truncates and the label tooltip engages. + const width = 'min-w-24 max-w-[250px]' return (