diff --git a/docs/content/docs/progress/pending-test.mdx b/docs/content/docs/progress/pending-test.mdx index 249c171fb..355cc9286 100644 --- a/docs/content/docs/progress/pending-test.mdx +++ b/docs/content/docs/progress/pending-test.mdx @@ -5,6 +5,13 @@ description: 当前项目已实现功能的手工验证清单与未确认边界 # 待测试 +## 模型选择弹窗长描述与视口边界 + +- 已调整:共用 `ModelPicker` 的宽度由共享样式统一控制,移除按内容撑宽及触发器最小宽度约束;渠道描述支持换行,字号统一使用说明文字 token(12px),行高为 1.5,移除旧 9px / 10px 覆盖;模型名称与价格在空间不足时分行显示,长价格文本可换行。 +- 调用方排查:画布与创作、短剧新建/章节提取/分镜制作/项目默认模型、Agent 对话与设置、提示词优化、批量生成、图片编辑/蒙版/图层拆解及视频分段等入口复用同一组件,均继承修复。 +- [x] 现有模型分组、价格展示、共享样式、Agent 和分镜选择器共 20 项专项测试通过;不代表浏览器布局验收通过。 +- [ ] 真实页面验证 500 字中英文描述、连续无空格文本、长价格、禁用原因与无描述选项;检查 1440px / 768px / 390px 视口、明暗主题、靠近浏览器左右边缘的弹窗、键盘切换和关闭。本次未完成浏览器验收。 + ## 分镜视频预览画幅 - 已调整:分镜制作右侧的视频播放器使用媒体原始比例和完整画面适配,避免共享预览样式的固定 16:9 与 `object-fit: cover` 裁剪竖屏视频。 diff --git a/web/src/components/model-picker.tsx b/web/src/components/model-picker.tsx index 9243dd4eb..58550f653 100644 --- a/web/src/components/model-picker.tsx +++ b/web/src/components/model-picker.tsx @@ -1,4 +1,4 @@ -import { useEffect, useId, useLayoutEffect, useMemo, useRef, useState, type CSSProperties, type KeyboardEvent } from "react"; +import { useEffect, useId, useMemo, useRef, useState, type KeyboardEvent } from "react"; import { Check, ChevronDown, Coins } from "lucide-react"; import { Popover } from "antd"; @@ -55,7 +55,6 @@ export function ModelPicker({ const theme = (canvasThemes[rawTheme as keyof typeof canvasThemes] ?? canvasThemes.dark) as CanvasTheme; const [open, setOpen] = useState(false); const [activeGroupKey, setActiveGroupKey] = useState(null); - const [triggerWidth, setTriggerWidth] = useState(null); const menuRef = useRef(null); const triggerRef = useRef(null); const options = useMemo(() => Array.from(new Set(selectableModelsByCapability(config, capability).filter(Boolean))), [capability, config]); @@ -71,16 +70,6 @@ export function ModelPicker({ const [routeQuote, setRouteQuote] = useState(); const creationVariant = variant === "creation"; - useLayoutEffect(() => { - const trigger = triggerRef.current; - if (!trigger) return; - const updateTriggerWidth = () => setTriggerWidth(Math.ceil(trigger.getBoundingClientRect().width)); - updateTriggerWidth(); - const observer = new ResizeObserver(updateTriggerWidth); - observer.observe(trigger); - return () => observer.disconnect(); - }, [className, fullWidth, showSelectedPrice, variant, value]); - useEffect(() => { if (!showSelectedPrice || !creditsEnabled || !quoteRequest) { setRouteQuote(undefined); @@ -167,13 +156,7 @@ export function ModelPicker({ "canvas-model-picker-menu creation-model-picker-menu max-w-[calc(100vw-24px)]", activeGroupKey === null ? "is-brand-list" : "is-model-list", )} - style={ - { - background: theme.node.panel, - color: theme.node.text, - "--canvas-model-picker-trigger-width": triggerWidth ? String(triggerWidth) + "px" : undefined, - } as CSSProperties - } + style={{ background: theme.node.panel, color: theme.node.text }} role="listbox" aria-label={placeholder} onKeyDown={handleMenuKeyDown} @@ -337,19 +320,21 @@ export function ModelLabel({ - - {label || pickerModelDisplayName(config, model, showConfiguredModelName)} - + + + {label || pickerModelDisplayName(config, model, showConfiguredModelName)} + {showPrice ? ( + + {/* 候选模型展示自身价目;当前参数的精确报价只在选中后的触发器显示。 */} + + + ) : null} + + {capabilitySummary} - {showPrice ? ( - - {/* 候选模型展示自身价目;当前参数的精确报价只在选中后的触发器显示。 */} - - - ) : null} {!creationVariant && meta.time ? ( {meta.time} diff --git a/web/src/styles/shared/model-picker.css b/web/src/styles/shared/model-picker.css index 17fe4c105..d018ba950 100644 --- a/web/src/styles/shared/model-picker.css +++ b/web/src/styles/shared/model-picker.css @@ -66,7 +66,6 @@ } .creation-model-picker-menu { - width: min(384px, calc(100vw - 24px)) !important; max-height: min(460px, calc(100vh - 24px)); overflow-x: hidden; overflow-y: auto; @@ -141,11 +140,6 @@ font-size: 13px; } - .creation-model-picker-menu .canvas-model-picker-option > span:first-child > span:nth-child(2) > span:nth-child(2) { - margin-top: 5px; - font-size: 10px; - } - .creation-model-picker.canvas-composer-model-picker { display: inline-flex; height: 48px; @@ -222,9 +216,6 @@ html:not(.dark) .creation-model-picker.canvas-composer-model-picker[aria-expande height: 34px; } - .creation-model-picker-menu { - width: min(440px, calc(100vw - 96px)) !important; - } .creation-model-picker.canvas-composer-model-picker { height: 42px; border-radius: 12px; padding: 0 11px; font-size: 12px; } .creation-model-picker.canvas-composer-model-picker { width: min(150px, 44vw); } } @@ -309,11 +300,12 @@ html:not(.dark) .creation-model-picker.canvas-composer-model-picker[aria-expande .canvas-model-picker-popover { filter: none !important; + max-width: calc(100vw - 24px); } .canvas-model-picker-menu { - width: max-content !important; - min-width: max(var(--canvas-model-picker-trigger-width, 0px), 260px); + box-sizing: border-box; + min-width: 0; max-width: calc(100vw - 24px); max-height: min(420px, calc(100vh - 32px)); overflow-x: hidden; @@ -375,17 +367,6 @@ html:not(.dark) .creation-model-picker.canvas-composer-model-picker[aria-expande width: 100%; } - .canvas-model-picker-popover .canvas-model-picker-option > span:first-child > span:nth-child(2) { - flex: 1 1 auto; - min-width: 0; - overflow: visible; - } - - .canvas-model-picker-popover .canvas-model-picker-option > span:first-child > span:nth-child(2) > span { - overflow: visible; - text-overflow: clip; - } - .canvas-model-picker-option-check { flex: 0 0 14px; height: 14px; @@ -541,7 +522,7 @@ html:not(.dark) .creation-chat-composer .creation-model-picker.canvas-composer-m .creation-model-picker-surface .ant-popover-inner-content { padding: 0 !important; } -.creation-model-picker-menu { width: min(332px, calc(100vw - 24px)) !important; max-height: min(420px, calc(100vh - 24px)); padding: 7px !important; background: transparent !important; color: #f0f1f2 !important; } +.creation-model-picker-menu { max-height: min(420px, calc(100vh - 24px)); padding: 7px !important; background: transparent !important; color: #f0f1f2 !important; } .creation-model-picker-heading { display: flex; align-items: center; gap: 6px; padding: 4px 7px 7px; color: #8e949d; font-size: 10px; } .creation-model-picker-heading strong { color: #e6e8eb; font-weight: 500; } .creation-model-picker-menu .canvas-model-picker-group-label { padding: 6px 7px 5px; font-size: 10px; } @@ -549,7 +530,6 @@ html:not(.dark) .creation-chat-composer .creation-model-picker.canvas-composer-m .creation-model-picker-menu .canvas-model-picker-option > span:first-child { gap: 8px; } .creation-model-picker-menu .canvas-model-picker-option > span:first-child > span:first-child { width: 26px; height: 26px; border: 0; border-radius: 5px; background: rgba(255, 255, 255, .07) !important; } .creation-model-picker-menu .canvas-model-picker-option > span:first-child > span:nth-child(2) > span:first-child { font-size: 11px; } -.creation-model-picker-menu .canvas-model-picker-option > span:first-child > span:nth-child(2) > span:nth-child(2) { margin-top: 3px; font-size: 9px; } html:not(.dark) .creation-model-picker-surface { background: rgba(255, 255, 255, .94) !important; box-shadow: 0 16px 38px rgba(28, 32, 37, .12) !important; } html:not(.dark) .creation-model-picker-menu { color: #727980 !important; } @@ -648,10 +628,10 @@ html:not(.dark) .creation-home .creation-chat-composer .creation-model-picker.ca } /* 品牌/模型两级菜单是 ModelPicker 默认结构,不能只写在 creation variant 下。 */ .canvas-model-picker-menu.is-brand-list { - width: min(360px, calc(100vw - 24px)) !important; + width: min(360px, calc(100vw - 24px)); } .canvas-model-picker-menu.is-model-list { - width: min(800px, calc(100vw - 24px)) !important; + width: min(800px, calc(100vw - 24px)); } .canvas-model-picker-two-pane { display: grid; @@ -676,7 +656,7 @@ html:not(.dark) .creation-home .creation-chat-composer .creation-model-picker.ca } @media (max-width: 720px) { .canvas-model-picker-menu:is(.is-brand-list, .is-model-list) { - width: calc(100vw - 24px) !important; + width: calc(100vw - 24px); } .canvas-model-picker-two-pane { grid-template-columns: minmax(0, 1fr); @@ -723,10 +703,33 @@ html:not(.dark) .creation-home .creation-chat-composer .creation-model-picker.ca color: color-mix(in srgb, currentColor 52%, transparent); font-size: 10px; } +.canvas-model-picker-option-heading { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 6px 8px; +} + +.canvas-model-picker-option-name { + flex: 1 1 10rem; + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.canvas-model-picker-option-price { + min-width: 0; + max-width: 100%; +} + .canvas-model-picker-description { - height: 16px; - line-height: 16px; + font-size: var(--fs-caption); + min-height: 1.5em; + line-height: 1.5; margin-top: 5px !important; + white-space: normal; + overflow-wrap: anywhere; visibility: hidden; opacity: 0; } @@ -761,6 +764,10 @@ html:not(.dark) .creation-home .creation-chat-composer .creation-model-picker.ca border-radius: var(--r-sm); background: color-mix(in srgb, var(--model-price-ink) 9%, transparent); padding: 2px 5px; + max-width: 100%; + flex-wrap: wrap; + white-space: normal; + overflow-wrap: anywhere; } @media (prefers-reduced-motion: reduce) { @@ -795,7 +802,6 @@ html:not(.dark) .creation-home .creation-chat-composer .creation-model-picker.ca .app-user-workspace .creation-model-picker-menu.is-brand-list { max-height: none !important; overflow: visible !important; - width: min(360px, calc(100vw - 24px)) !important; padding: 10px !important; } .app-user-workspace .creation-model-picker-menu .canvas-model-picker-brands { display: grid; gap: 5px; } @@ -835,7 +841,6 @@ html:not(.dark) .creation-home .creation-chat-composer .creation-model-picker.ca .creation-model-picker-surface .creation-model-picker-menu.is-brand-list { max-height: none !important; overflow: visible !important; - width: min(360px, calc(100vw - 24px)) !important; padding: 10px !important; } .creation-model-picker-surface .canvas-model-picker-brands { display: grid; gap: 5px; } diff --git a/web/src/styles/workspace-product.css b/web/src/styles/workspace-product.css index 8aa5801b9..fea94f3e3 100644 --- a/web/src/styles/workspace-product.css +++ b/web/src/styles/workspace-product.css @@ -656,14 +656,12 @@ .app-user-workspace .creation-composer-stage .creation-empty-composer { min-width: 0; flex: 1 1 auto; } .app-user-workspace .creation-composer-stage.is-agent-mode .creation-agent-entry { min-width: 0; flex: 1 1 auto; } -.creation-model-picker-surface .creation-model-picker-menu.is-brand-list { width: min(360px, calc(100vw - 24px)) !important; } -.creation-model-picker-surface .creation-model-picker-menu.is-model-list { width: min(720px, calc(100vw - 24px)) !important; } .creation-model-picker-surface .creation-model-picker-menu.is-model-list .canvas-model-picker-two-pane { display: grid; grid-template-columns: 250px minmax(0, 1fr); gap: 14px; min-height: 0; align-items: start; } .creation-model-picker-surface .creation-model-picker-menu.is-model-list .canvas-model-picker-brand-rail { display: grid; align-content: start; gap: 5px; border-right: 1px solid var(--workspace-border); padding-right: 14px; } .creation-model-picker-surface .creation-model-picker-menu.is-model-list .canvas-model-picker-brand { width: 100%; } .creation-model-picker-surface .creation-model-picker-menu.is-model-list .canvas-model-picker-model-pane { border: 0; margin: 0; padding: 0; } -@media (max-width: 720px) { .creation-floating-prompt { top: 8px; width: calc(100% - 24px); min-height: 60px; gap: 10px; padding: 8px 9px 8px 16px; border-radius: 19px; } .creation-floating-prompt input { font-size: 14px; } .creation-floating-prompt button { width: 40px; height: 40px; flex-basis: 40px; } .creation-model-picker-surface .creation-model-picker-menu:is(.is-brand-list, .is-model-list) { width: calc(100vw - 24px) !important; } .creation-model-picker-surface .creation-model-picker-menu.is-model-list .canvas-model-picker-two-pane { grid-template-columns: minmax(0, 1fr); min-height: 0; } .creation-model-picker-surface .creation-model-picker-menu.is-model-list .canvas-model-picker-brand-rail { display: none; } .app-user-workspace .creation-chat-composer.is-thread .creation-chat-dock .creation-mode-tabs { height: 30px; } .app-user-workspace .creation-chat-composer.is-thread .creation-chat-dock .creation-mode-button { height: 26px; min-height: 26px; padding: 0 6px; font-size: 10px; } } +@media (max-width: 720px) { .creation-floating-prompt { top: 8px; width: calc(100% - 24px); min-height: 60px; gap: 10px; padding: 8px 9px 8px 16px; border-radius: 19px; } .creation-floating-prompt input { font-size: 14px; } .creation-floating-prompt button { width: 40px; height: 40px; flex-basis: 40px; } .creation-model-picker-surface .creation-model-picker-menu.is-model-list .canvas-model-picker-two-pane { grid-template-columns: minmax(0, 1fr); min-height: 0; } .creation-model-picker-surface .creation-model-picker-menu.is-model-list .canvas-model-picker-brand-rail { display: none; } .app-user-workspace .creation-chat-composer.is-thread .creation-chat-dock .creation-mode-tabs { height: 30px; } .app-user-workspace .creation-chat-composer.is-thread .creation-chat-dock .creation-mode-button { height: 26px; min-height: 26px; padding: 0 6px; font-size: 10px; } } /* Shared controls: one size system and one state vocabulary. */ .app-product-workspace :where(.ant-btn, .ant-input-affix-wrapper, .ant-select-selector, .ant-picker, .ant-input-number),