feat(create): 对话页布局 - 加宽输入区并修正参数弹窗

开始对话后工具条进顶栏、模式切换横排到录音左侧,输入区加宽并去掉黑底;参数弹窗改用工作台表面色,去掉细线描边。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
ddCatandCursor committed 2026-09-17 23:32:38 +08:00
1 parent 7143d54b64
commit 707b6494da
7 files changed
+627 -234

No files matched your search

+9 -3
View File
@@ -1,9 +1,11 @@
import { ImageSizePicker } from "@/components/image-size-picker";
import { imageResolutionUsesQuality } from "@/lib/image-size-presets";
import { createPortal } from "react-dom";
import { lazy, Suspense, useCallback, useEffect, useMemo, useRef, useState, type CSSProperties, type PointerEvent, type ReactNode, type RefObject } from "react";
import { App, Button, Dropdown, Popover } from "antd";
import { AppDrawer } from "@/components/ui/product/app-drawer";
import { AppModal } from "@/components/ui/product/app-modal";
import { useWorkspaceTopBarMount } from "@/components/layout/workspace-top-bar-extension";
import { Tooltip } from "@/components/ui/base/tooltip";
import { Reorder, LayoutGroup, motion, useReducedMotion } from "motion/react";
import { ArrowDown, ArrowUp, Brain, ChevronDown, ChevronLeft, ChevronRight, Clapperboard, Clock3, Copy, Download, FileText, Film, History, Image as ImageIcon, LoaderCircle, Maximize2, MessageSquareText, Minimize2, MoreHorizontal, Music2, Pencil, Plus, RefreshCw, Search, SlidersHorizontal, Sparkles, Trash2, UserRound, WandSparkles, Waves, X } from "lucide-react";
@@ -174,7 +176,8 @@ export function CreationWorkspaceToolbar({ shots, onJumpToShot, onNewConversatio
window.addEventListener("mousedown", onPointerDown);
return () => window.removeEventListener("mousedown", onPointerDown);
}, [railOpen]);
return <header className="creation-thread-toolbar">
const mount = useWorkspaceTopBarMount();
const toolbar = <header className="creation-thread-toolbar">
<div className="creation-toolbar-shots" ref={railRef}>
<button type="button" className="creation-rail-trigger" aria-expanded={railOpen} aria-haspopup="listbox" onClick={() => setRailOpen((open) => !open)}><Clapperboard />镜头时间线{shots.length > 0 ? <em className="creation-rail-count">{shots.length}</em> : null}</button>
{railOpen ? <div className="creation-rail-pop" role="listbox" aria-label="镜头时间线">
@@ -196,6 +199,9 @@ export function CreationWorkspaceToolbar({ shots, onJumpToShot, onNewConversatio
<Tooltip title="历史对话"><button type="button" aria-label="查看历史对话" className="creation-toolbar-action" onClick={onOpenHistory}><History /></button></Tooltip>
</div>
</header>;
if (mount) return createPortal(toolbar, mount);
if (mount === null) return null;
return toolbar;
}
export function CreationMessageView({ item, shotNumber, onRetryFailure, onCreateVariant, onEditUserMessage, onContinueCanvas, openingCanvas }: { item: CreationMessage; shotNumber: number; onRetryFailure: () => void; onCreateVariant: () => void; onEditUserMessage: (text: string) => void; onContinueCanvas: (ids?: string[]) => void; openingCanvas: boolean }) {
@@ -492,7 +498,6 @@ export function CreationComposer(props: ComposerProps) {
spotlightColor="color-mix(in srgb, var(--user-ink) 12%, transparent)"
spotlightRadius={280}
>
{props.variant === "thread" ? <div className="creation-composer-mode-row"><ModePicker mode={props.mode} onModeChange={props.onModeChange} /></div> : null}
<div className="creation-chat-writing-surface">
<div className="creation-chat-editor">
<CanvasResourceMentionTextarea ref={props.composerFocusRef} value={props.prompt} references={props.references} mentionMenuWidth={400} sendOnEnter onFocus={props.onPromptFocus} onChange={props.setPrompt} onSubmit={props.onSubmit} containerClassName="creation-chat-mention-container" className="creation-chat-mention-editor creation-scrollbar" style={{ color: "var(--creation-text)" }} placeholder={props.placeholderOverride || (props.variant === "empty" ? emptyPlaceholder : placeholder)} aria-label="创作提示词,可使用 @ 引用当前参考内容或技能;回车发送,Shift+回车换行" spellCheck disabled={interactionBusy} activeDropReferenceId={dropTargetReferenceId} onReferenceFilesDrop={(reference, files) => { const target = props.references.find((item) => item.id === reference.id); if (target?.attachmentId) props.onReplaceReferenceFiles(target.attachmentId, files); }} />
@@ -564,6 +569,7 @@ export function CreationComposer(props: ComposerProps) {
</div>
<footer className="creation-chat-dock">
<div className="creation-chat-controls">
{props.variant === "thread" ? <ModePicker mode={props.mode} onModeChange={props.onModeChange} /> : null}
<VoiceRecordingButton
className="creation-voice-trigger"
disabled={interactionBusy}
@@ -663,7 +669,7 @@ export function CreationModeTabs({ mode, onModeChange, agentActive = false, onAg
}
function ModePicker({ mode, onModeChange }: { mode: CreationMode; onModeChange: (mode: CreationMode) => void }) {
return <CreationModeTabs mode={mode} onModeChange={onModeChange} orientation="vertical" />;
return <CreationModeTabs mode={mode} onModeChange={onModeChange} />;
}
function GenerationSettingsMenu(props: ComposerProps) {