Skip to content

对话组件的嵌套宽度与列布局 ​

状态:implemented 类型:bug-fix Owner:frontend/src/shared/ui/WidgetRenderer.vue

问题 ​

合法组件组合出现布局缺陷:全宽卡片中的默认子卡片和列表仍受 440px 限制,列表重复外框;卡片和列表项的横向 padding 叠加,标题默认 20px、sm 为 18px,信息卡片显得过松。显式 flex:1 覆盖列的换行基准,flex:0 将内容列压为零宽。嵌套表单还通过后代选择器改变所有祖先卡片的宽度和间距。

决策 ​

实现方案 ​

WidgetRenderer 区分独立容器与嵌套容器:嵌套默认卡片填满父容器,嵌套列表不承担外框,显式 sm/lg 卡片保留尺寸上限。WidgetNode 的 flex 属性保留 Row 对 Col 的换行基准,非扩展列使用内容宽度;Form 与其他容器共用嵌套布局边界,表单外观只属于最近的 Card,允许中间存在 Row/Col。入口仍为 MarkdownPreview 挂载的实际组件树,不改变 JSON 协议、会话动作或持久化。内置 chat-widgets Skill 同步说明布局语义。

嵌套列表的普通项与可点击项共用 12px 垂直间距,横向不重复缩进;独立列表保留自身内边距。Title 默认及 md 为 16px,sm 为 14px,lg 为 18px,其他档位按同一紧凑比例收小,正文和说明字号保持现有层次。

该决定补充对话组件决定,收窄桌面表单布局决定中的表单外观作用范围。

替代方案 ​

  • 只修改模型提示:历史消息仍然存在合法但失效的组合,不能修复渲染器。
  • 删除所有最大宽度:会改变独立卡片与显式尺寸的用途。
  • 增加布局协议字段:当前组合已能表达意图,无需扩展模型与维护面。

后果 ​

历史消息的嵌套默认卡片使用可用宽度,窄容器中的等分列改为多行。独立默认容器保持 440px 上限,显式 sm/lg 尺寸与图片高度限制继续生效。仅内层拥有表单时,外层不再获得表单外观。Skill 更新沿既有发布与投影机制生效。

标题尺寸映射同时影响历史消息中的显式 Title.size;变化属于信息卡片的统一呈现调整,协议枚举保持不变。

验证 ​

验收主张失败面语义 Owner直接证据 / 命令负向案例当前结果
嵌套默认容器使用可用宽度,独立及显式尺寸保留CSS 级联与容器嵌套WidgetRendererwidgetCompositionLayout 浏览器尺寸、表面样式与截图修改前相同用例因 440px 限制与重复外框失败Passed
等分列可换行,非扩展列保持内容宽度flex 属性映射与 CSS 装配WidgetNode / WidgetRendererwidgetLayout unit 与浏览器列宽、坐标及标签边界修改前 unit 失败,浏览器检测到不换行、零宽与重叠Passed
表单样式止于最近 Card组件树归属WidgetNode / WidgetRendererunit、浏览器外层卡片宽度及样式修改前相同浏览器用例因外层宽度、间距改变失败Passed
嵌套列表左右对齐,标题呈现紧凑层次padding 继承、可点击项及显式字号WidgetNode / WidgetRenderer浏览器测量标题 left 坐标与实际字号,明暗截图调整前六组 density 用例均因缩进叠加、默认及显式字号过大失败Passed

playwright-cli -s=<session> run-code --filename=frontend/test/browser/widgetCompositionLayout.js 在真实 Vite 页面运行正式 Markdown/Vue 组件,1440、1024、768px 视口与明暗主题共 54 组组合检查通过。根 Form 的额外六组用例在补齐通用容器类前,因内部卡片、列表仍为 440px 及重复外框失败。脚本不创建会话、不发送消息,不将构造组件树的结果计为真实模型生成或持久化验证。浏览器回归作为独立审查的直接证据,现有 frontend workflow 执行 unit、lint 与 build。

实际命令结果
宿主 frontend:pnpm run lint:check、pnpm run test:unitPassed,852 tests
docker compose exec -T frontend pnpm run lint:check、pnpm run buildPassed,build 含 typecheck
docker compose exec -T frontend pnpm run test:unit843 passed、9 failed;容器 eslint-boundaries.js 为旧镜像文件,未挂载的规则与宿主仓库哈希不同,当前仓库配置由宿主完整 unit 验证
docker compose exec -T api uv run --no-sync --group test pytest test/unit -m 'not slow'Passed,3273 passed、122 skipped、7 subtests passed;跳过项不计能力通过
Skill 中五个 widget 示例逐个调用 parseWidgetPassed
python3 scripts/verify_engineering_contracts.pyPassed
python3 -m unittest scripts.test_verify_engineering_contractsPassed,66 tests
docs:pnpm run buildPassed,包含相对链接检查

真实模型选择与运行中已有 Skill 投影的更新未执行;该边界不影响历史消息的前端渲染修复。

本项目基于 MIT License 开源,欢迎使用和贡献。