feat: add animations

This commit is contained in:
Henry Li
2026-01-22 09:41:01 +08:00
parent 37e2c3d3c9
commit e8e522c2fe
3 changed files with 22 additions and 23 deletions

View File

@@ -162,25 +162,27 @@ export default function ChatPage() {
<Welcome /> <Welcome />
</div> </div>
)} )}
<div className="absolute -top-4 right-0 left-0 z-0">
<div className="absolute right-0 bottom-0 left-0 px-4">
<TodoList
className="bg-background/5"
todos={thread.values.todos ?? []}
collapsed={todoListCollapsed}
hidden={
!thread.values.todos ||
thread.values.todos.length === 0
}
onToggle={() =>
setTodoListCollapsed(!todoListCollapsed)
}
/>
</div>
</div>
<InputBox <InputBox
className={cn("bg-background/5 w-full -translate-y-4")} className={cn("bg-background/5 w-full -translate-y-4")}
autoFocus={isNewThread} autoFocus={isNewThread}
status={thread.isLoading ? "streaming" : "ready"} status={thread.isLoading ? "streaming" : "ready"}
context={settings.context} context={settings.context}
extraHeader={
thread.values.todos?.length ? (
<div className="mx-4">
<TodoList
className="bg-background/5"
todos={thread.values.todos ?? []}
collapsed={todoListCollapsed}
onToggle={() =>
setTodoListCollapsed(!todoListCollapsed)
}
/>
</div>
) : null
}
onContextChange={(context) => onContextChange={(context) =>
setSettings("context", context) setSettings("context", context)
} }

View File

@@ -35,7 +35,6 @@ export function InputBox({
autoFocus, autoFocus,
status = "ready", status = "ready",
context, context,
extraHeader,
onContextChange, onContextChange,
onSubmit, onSubmit,
onStop, onStop,
@@ -104,12 +103,7 @@ export function InputBox({
onSubmit={handleSubmit} onSubmit={handleSubmit}
{...props} {...props}
> >
{extraHeader && ( <PromptInputBody className="absolute top-0 right-0 left-0 z-3">
<div className="absolute top-0 right-0 left-0 z-100">
<div className="absolute right-0 bottom-0 left-0">{extraHeader}</div>
</div>
)}
<PromptInputBody>
<PromptInputTextarea <PromptInputTextarea
className={cn("size-full")} className={cn("size-full")}
placeholder={t.inputBox.placeholder} placeholder={t.inputBox.placeholder}

View File

@@ -14,22 +14,25 @@ export function TodoList({
className, className,
todos, todos,
collapsed = false, collapsed = false,
hidden = false,
onToggle, onToggle,
}: { }: {
className?: string; className?: string;
todos: Todo[]; todos: Todo[];
collapsed?: boolean; collapsed?: boolean;
hidden?: boolean;
onToggle?: () => void; onToggle?: () => void;
}) { }) {
return ( return (
<div <div
className={cn( className={cn(
"flex h-fit w-full flex-col overflow-hidden rounded-t-xl border bg-white backdrop-blur-sm", "flex h-fit w-full origin-bottom flex-col overflow-hidden rounded-t-xl border border-b-0 bg-white backdrop-blur-sm transition-all duration-200 ease-out",
hidden ? "pointer-events-none translate-y-8 opacity-0" : "",
className, className,
)} )}
> >
<header <header
className="bg-accent flex min-h-8 shrink-0 cursor-pointer items-center justify-between px-4 text-sm" className="bg-accent flex min-h-8 shrink-0 cursor-pointer items-center justify-between px-4 text-sm transition-all duration-300 ease-out"
onClick={() => { onClick={() => {
onToggle?.(); onToggle?.();
}} }}