🪄 style: Improved Input Collapse UI (#10659)

* feat: shift collapse chevron inside ChatForm input area

* feat: add soft gradient on bottom of collapsed text input so there isn't a hard cut off when text overflows

* feat: add better scroll bar behavior for main chat input

* fix: smooth out purple gradient for temporary chats

* feat: better colors for gradient

* feat: use blur instead of colors

* chore: address copilot comments
This commit is contained in:
Dustin Healy 2025-11-25 14:02:52 -08:00 committed by GitHub
parent 30df16f5b5
commit 8b7af65265
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 63 additions and 30 deletions

View file

@ -260,37 +260,50 @@ const ChatForm = memo(({ index = 0 }: { index?: number }) => {
<FileFormChat conversation={conversation} /> <FileFormChat conversation={conversation} />
{endpoint && ( {endpoint && (
<div className={cn('flex', isRTL ? 'flex-row-reverse' : 'flex-row')}> <div className={cn('flex', isRTL ? 'flex-row-reverse' : 'flex-row')}>
<TextareaAutosize <div className="relative flex-1">
{...registerProps} <TextareaAutosize
ref={(e) => { {...registerProps}
ref(e); ref={(e) => {
(textAreaRef as React.MutableRefObject<HTMLTextAreaElement | null>).current = e; ref(e);
}} (textAreaRef as React.MutableRefObject<HTMLTextAreaElement | null>).current =
disabled={disableInputs || isNotAppendable} e;
onPaste={handlePaste} }}
onKeyDown={handleKeyDown} disabled={disableInputs || isNotAppendable}
onKeyUp={handleKeyUp} onPaste={handlePaste}
onCompositionStart={handleCompositionStart} onKeyDown={handleKeyDown}
onCompositionEnd={handleCompositionEnd} onKeyUp={handleKeyUp}
id={mainTextareaId} onCompositionStart={handleCompositionStart}
tabIndex={0} onCompositionEnd={handleCompositionEnd}
data-testid="text-input" id={mainTextareaId}
rows={1} tabIndex={0}
onFocus={() => { data-testid="text-input"
handleFocusOrClick(); rows={1}
setIsTextAreaFocused(true); onFocus={() => {
}} handleFocusOrClick();
onBlur={setIsTextAreaFocused.bind(null, false)} setIsTextAreaFocused(true);
aria-label={localize('com_ui_message_input')} }}
onClick={handleFocusOrClick} onBlur={setIsTextAreaFocused.bind(null, false)}
style={{ height: 44, overflowY: 'auto' }} aria-label={localize('com_ui_message_input')}
className={cn( onClick={handleFocusOrClick}
baseClasses, style={{ height: 44, overflowY: 'auto' }}
removeFocusRings, className={cn(
'transition-[max-height] duration-200 disabled:cursor-not-allowed', baseClasses,
removeFocusRings,
'scrollbar-hover transition-[max-height] duration-200 disabled:cursor-not-allowed',
)}
/>
{isCollapsed && (
<div
className="pointer-events-none absolute bottom-0 left-0 right-0 h-10 transition-all duration-200"
style={{
backdropFilter: 'blur(2px)',
WebkitMaskImage: 'linear-gradient(to top, black 15%, transparent 75%)',
maskImage: 'linear-gradient(to top, black 15%, transparent 75%)',
}}
/>
)} )}
/> </div>
<div className="flex flex-col items-start justify-start pt-1.5"> <div className="flex flex-col items-start justify-start pr-2.5 pt-1.5">
<CollapseChat <CollapseChat
isCollapsed={isCollapsed} isCollapsed={isCollapsed}
isScrollable={isMoreThanThreeRows} isScrollable={isMoreThanThreeRows}

View file

@ -1487,6 +1487,26 @@ button {
background-color: transparent; background-color: transparent;
} }
/* Show scrollbar only on hover */
.scrollbar-hover {
scrollbar-width: thin;
scrollbar-color: transparent transparent;
}
.scrollbar-hover:hover {
scrollbar-color: var(--border-medium) transparent;
}
.scrollbar-hover::-webkit-scrollbar-thumb {
background-color: transparent;
transition: background-color 0.3s ease 0.5s;
}
.scrollbar-hover:hover::-webkit-scrollbar-thumb {
background-color: var(--border-medium);
transition-delay: 0s;
}
body, body,
html { html {
height: 100%; height: 100%;