Studio: keep chat input visible and fix compare pane clipping (#4924)

* fix(chat): sticky composer bar in thread

* fix(chat): fix compare pane clipping

* fix(chat): tighten scroll-to-bottom placement and compare footer spacing

* Fix TypeScript build break and clean up ViewportFooter classes

- Remove unused `compact` prop from ThreadScrollToBottom call site
  (component is FC with no props, passing it caused TS2322)
- Extract shared classes (sticky, bottom-0, z-20, bg-transparent) from
  ternary branches into the unconditional className string
- Restore `relative` on normal-mode footer so the inner absolute
  bg-background strip has a positioning context
- Remove redundant md:pb-3 / md:pb-4 (same value as base pb-3 / pb-4)
- Remove no-op `sticky bottom-0` from SharedComposer wrapper in both
  LoraCompareContent and GeneralCompareContent (flex layout with
  shrink-0 already pins it at the bottom; parent has no scrollable
  overflow for sticky to bind to)
- Fix truncated comment on pointer-events rationale

---------

Co-authored-by: Daniel Han <danielhanchen@gmail.com>
This commit is contained in:
Lee Jackson 2026-04-09 14:00:56 +01:00 committed by GitHub
commit dc16e0c65b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 21 additions and 8 deletions

View file

@ -89,14 +89,27 @@ export const Thread: FC<{ hideComposer?: boolean; hideWelcome?: boolean }> = ({
}}
/>
<ThreadPrimitive.ViewportFooter className={cn(
"aui-thread-viewport-footer sticky bottom-0 z-20 mt-auto flex w-full flex-col gap-4 overflow-visible pb-4 md:pb-4",
hideComposer ? "bg-background" : "relative bg-transparent",
)}>
<ThreadPrimitive.ViewportFooter
className={cn(
"aui-thread-viewport-footer sticky bottom-0 z-20 mt-auto flex w-full flex-col overflow-visible bg-transparent",
hideComposer ? "gap-2" : "gap-4",
// Compare: pointer-events pass-through so messages behind footer stay clickable
hideComposer
? "pointer-events-none pb-3"
: "relative pb-4",
)}
>
{!hideComposer && (
<div className="pointer-events-none absolute inset-x-0 bottom-0 h-4 bg-background" aria-hidden />
)}
<ThreadScrollToBottom />
<div
className={cn(
"flex justify-center",
hideComposer && "pointer-events-auto",
)}
>
<ThreadScrollToBottom />
</div>
<AuiIf condition={({ thread }) => !thread.isEmpty}>
{!hideComposer && <ComposerAnimated />}
</AuiIf>
@ -112,7 +125,7 @@ const ThreadScrollToBottom: FC = () => {
<TooltipIconButton
tooltip="Scroll to bottom"
variant="outline"
className="aui-thread-scroll-to-bottom absolute -top-12 z-10 self-center rounded-full p-4 disabled:invisible dark:bg-background dark:hover:bg-accent"
className="aui-thread-scroll-to-bottom absolute -top-6 z-10 self-center rounded-full p-4 disabled:invisible dark:bg-background dark:hover:bg-accent"
>
<ArrowDownIcon />
</TooltipIconButton>

View file

@ -251,7 +251,7 @@ const LoraCompareContent = memo(function LoraCompareContent({
</div>
</div>
</div>
<div className="mx-auto w-full max-w-4xl px-4 py-4">
<div className="z-20 mx-auto w-full max-w-4xl shrink-0 border-t border-border/60 bg-background px-4 pt-2 pb-4">
<SharedComposer handlesRef={handlesRef} />
</div>
</div>
@ -387,7 +387,7 @@ const GeneralCompareContent = memo(function GeneralCompareContent({
</div>
</div>
</div>
<div className="mx-auto w-full max-w-4xl px-4 py-4">
<div className="z-20 mx-auto w-full max-w-4xl shrink-0 border-t border-border/60 bg-background px-4 pt-2 pb-4">
<SharedComposer
handlesRef={handlesRef}
model1={model1}