fix(thread): adjust Composer component height for improved user experience

This commit is contained in:
Anish Sarkar 2026-06-02 23:44:36 +05:30
parent 5fce4e1621
commit 9daaf12658
2 changed files with 27 additions and 19 deletions

View file

@ -445,6 +445,7 @@ const Composer: FC = () => {
const [actionQuery, setActionQuery] = useState(""); const [actionQuery, setActionQuery] = useState("");
const [suggestionAnchorPoint, setSuggestionAnchorPoint] = const [suggestionAnchorPoint, setSuggestionAnchorPoint] =
useState<ComposerSuggestionAnchorPoint | null>(null); useState<ComposerSuggestionAnchorPoint | null>(null);
const [isComposerInputEmpty, setIsComposerInputEmpty] = useState(true);
const editorRef = useRef<InlineMentionEditorRef>(null); const editorRef = useRef<InlineMentionEditorRef>(null);
const prevMentionedDocsRef = useRef<Map<string, MentionedDocumentInfo>>(new Map()); const prevMentionedDocsRef = useRef<Map<string, MentionedDocumentInfo>>(new Map());
const documentPickerRef = useRef<DocumentMentionPickerRef>(null); const documentPickerRef = useRef<DocumentMentionPickerRef>(null);
@ -536,6 +537,7 @@ const Composer: FC = () => {
// short-circuit keeps pure-text keystrokes from churning the atom. // short-circuit keeps pure-text keystrokes from churning the atom.
const handleEditorChange = useCallback( const handleEditorChange = useCallback(
(text: string, docs: MentionedDocument[]) => { (text: string, docs: MentionedDocument[]) => {
setIsComposerInputEmpty(text.trim().length === 0 && docs.length === 0);
aui.composer().setText(text); aui.composer().setText(text);
setMentionedDocuments((prev) => { setMentionedDocuments((prev) => {
if (prev.length === docs.length) { if (prev.length === docs.length) {
@ -651,6 +653,7 @@ const Composer: FC = () => {
: action.prompt; : action.prompt;
editorRef.current?.setText(finalPrompt); editorRef.current?.setText(finalPrompt);
aui.composer().setText(finalPrompt); aui.composer().setText(finalPrompt);
setIsComposerInputEmpty(false);
setShowPromptPicker(false); setShowPromptPicker(false);
setActionQuery(""); setActionQuery("");
setSuggestionAnchorPoint(null); setSuggestionAnchorPoint(null);
@ -662,6 +665,7 @@ const Composer: FC = () => {
(prompt: string) => { (prompt: string) => {
editorRef.current?.setText(prompt); editorRef.current?.setText(prompt);
aui.composer().setText(prompt); aui.composer().setText(prompt);
setIsComposerInputEmpty(false);
editorRef.current?.focus(); editorRef.current?.focus();
}, },
[aui] [aui]
@ -676,6 +680,7 @@ const Composer: FC = () => {
: `${action.prompt}\n\n${clipboardInitialText}`; : `${action.prompt}\n\n${clipboardInitialText}`;
editorRef.current?.setText(finalPrompt); editorRef.current?.setText(finalPrompt);
aui.composer().setText(finalPrompt); aui.composer().setText(finalPrompt);
setIsComposerInputEmpty(false);
setShowPromptPicker(false); setShowPromptPicker(false);
setActionQuery(""); setActionQuery("");
setSuggestionAnchorPoint(null); setSuggestionAnchorPoint(null);
@ -755,6 +760,7 @@ const Composer: FC = () => {
aui.composer().send(); aui.composer().send();
editorRef.current?.clear(); editorRef.current?.clear();
setIsComposerInputEmpty(true);
setMentionedDocuments([]); setMentionedDocuments([]);
}, [ }, [
showDocumentPopover, showDocumentPopover,
@ -904,7 +910,7 @@ const Composer: FC = () => {
onDismiss={() => setClipboardInitialText(undefined)} onDismiss={() => setClipboardInitialText(undefined)}
/> />
)} )}
<div className="aui-composer-input-wrapper px-4 pt-3 pb-6"> <div className="aui-composer-input-wrapper px-4 pt-3 pb-2 sm:pb-6">
<InlineMentionEditor <InlineMentionEditor
ref={editorRef} ref={editorRef}
placeholder={currentPlaceholder} placeholder={currentPlaceholder}
@ -916,7 +922,7 @@ const Composer: FC = () => {
onDocumentRemove={handleDocumentRemove} onDocumentRemove={handleDocumentRemove}
onSubmit={handleSubmit} onSubmit={handleSubmit}
onKeyDown={handleKeyDown} onKeyDown={handleKeyDown}
className="min-h-[24px] **:data-slate-placeholder:font-normal" className="min-h-[48px] sm:min-h-[24px] **:data-slate-placeholder:font-normal"
/> />
</div> </div>
<ComposerAction isBlockedByOtherUser={isBlockedByOtherUser} /> <ComposerAction isBlockedByOtherUser={isBlockedByOtherUser} />
@ -926,7 +932,9 @@ const Composer: FC = () => {
isThreadEmpty={isThreadEmpty} isThreadEmpty={isThreadEmpty}
onVisibleChange={setConnectToolsTrayVisible} onVisibleChange={setConnectToolsTrayVisible}
/> />
{isThreadEmpty && <ChatExamplePrompts onSelect={handleExampleSelect} />} {isThreadEmpty && isComposerInputEmpty ? (
<ChatExamplePrompts onSelect={handleExampleSelect} />
) : null}
</div> </div>
</ComposerPrimitive.Root> </ComposerPrimitive.Root>
); );

View file

@ -23,40 +23,40 @@ export const CHAT_EXAMPLE_CATEGORIES: ChatExampleCategory[] = [
id: "search", id: "search",
label: "Search & Summarize", label: "Search & Summarize",
prompts: [ prompts: [
"Summarize the key points across all the documents in this space.", "Summarize the key points across all the documents in this space",
"What do my files say about [topic]? Answer with citations.", "What do my files say about [topic]? Answer with citations",
"Find every mention of [keyword] and list the sources.", "Find every mention of [keyword] and list the sources",
"Compare these two documents and highlight the differences.", "Compare these two documents and highlight the differences",
], ],
}, },
{ {
id: "create", id: "create",
label: "Create", label: "Create",
prompts: [ prompts: [
"Write a cited research report on [topic] from my documents.", "Write a cited research report on [topic] from my documents",
"Turn this folder into a two-host podcast I can listen to.", "Turn this folder into a two-host podcast I can listen to",
"Create a slide deck and a narrated video overview from these sources.", "Create a slide deck and a narrated video overview from these sources",
"Tailor my resume to this job description so it gets past ATS and lands an interview.", "Tailor my resume to this job description so it gets past ATS and lands an interview",
], ],
}, },
{ {
id: "automate", id: "automate",
label: "Automate", label: "Automate",
prompts: [ prompts: [
"Email me a daily brief of new documents in my knowledge base every morning.", "Email me a daily brief of new documents in my knowledge base every morning",
"When a PDF lands in my Research folder, generate a cited AI summary.", "When a PDF lands in my Research folder, generate a cited AI summary",
"Generate a weekly status report from my Slack and Gmail every Friday.", "Generate a weekly status report from my Slack and Gmail every Friday",
"Build an automation that turns new meeting notes into minutes with action items.", "Build an automation that turns new meeting notes into minutes with action items",
], ],
}, },
{ {
id: "tools", id: "tools",
label: "Across your tools", label: "Across your tools",
prompts: [ prompts: [
"Search across my Notion, Slack, Google Drive and Gmail for [topic].", "Search across my Notion, Slack, Google Drive and Gmail for [topic]",
"Post this research summary to my Notion workspace.", "Post this research summary to my Notion workspace",
"Send these meeting action items to our team Slack channel.", "Send these meeting action items to our team Slack channel",
"Create a Jira ticket from this bug report.", "Create a Jira ticket from this bug report",
], ],
}, },
]; ];