24 KiB
样式设计指南
供水前端统一以本地 shadcn/ui 为组件基础,使用 Tailwind CSS、共享变体和语义变量。Agent 相关弹窗、面板与菜单,以及 Dev 测试面板、外围系统面板、调查与本地预览展示面板保持 shadcn/ui 设计;其他地图控件与工作台浮层使用本文规定的 Acrylic 视觉。适用于工作台、地图控件、Agent、报告、表单和弹层。
本文是唯一的样式规范。业务交互见 Agent 交互与报告设计,状态含义见 状态语言。本文规定统一目标;历史局部配色和样式覆盖需在后续组件修改中逐步对齐,文档合并不代表运行样式已全部迁移。
1. 组件基础
- 优先复用 src/shared/ui 的本地组件;缺少能力时,按需引入与现有 Radix 技术栈匹配的 shadcn/ui 源码,再做样式适配。
- shadcn/ui 提供组件结构与组合方式,Radix 提供相应的基础交互。定制外观时保留语义、键盘操作、焦点管理、禁用和加载行为。
- 业务模块组合共享组件,负责数据、权限和动作;共享组件保持通用。AI Elements 用于聊天展示组合,与 Agent 的 shadcn/ui 组件使用同一套主题变量。
- 不批量覆盖已有组件,不引入第二套 UI 或样式体系。使用 CLI 前先核对
components.json;配置继续指向 Vite、TypeScript、Tailwind 4、@/shared/ui和@/shared/ui/cn,关闭 React Server Components。 - 界面图标统一从
lucide-react按名称引入,使用其默认 2px 描边,不复制图标 SVG 路径或用字符替代操作图标。常规控件图标为 16px,紧凑说明可用 12px 至 14px;图标尺寸与按钮命中区域分别设置。图标按钮提供中文可访问名称,装饰性图标使用aria-hidden。 - 界面动画统一使用 Motion,React 动画组件与 Hook 从
motion/react引入,覆盖入场、退出、位置与布局变化及交互过渡。尊重prefers-reduced-motion,减少动态效果时关闭非必要动画;连续拖拽调宽不附加布局动画。 - 保留本地 shadcn/ui 组件自带的基础动效,避免重复叠加。
AgentPersona等已有 Rive 专用资源动画继续按其功能文档维护,Motion 不替代资源内部的状态机与动画。
Agent 弹窗与面板
回答正文与注意事项、表格等结构块之间使用 20px 的布局间距。Markdown 复制容器使用 display: contents 时,不使用直接子元素 margin 实现这段间距,避免间距丢失。
回复生成期间只在正文左侧显示一处“正在回复”状态,状态组与正文左边缘对齐;不再在空正文中重复显示“正在生成”。
过程切换为正式结果时,先将旧内容淡出,再统一切换正文、过程归档与底部操作,最后淡入结果,整体约 200ms;只改变透明度,不对长内容高度做插值。切换期间保护阅读锚点,用户滚动或操作后停止自动位置补偿。系统要求减少动态效果时直接交接,仍保留阅读位置和工具展开状态。
面板头部使用紧凑字号:助手名称为 14px/20px,在线状态和主题选择为 12px/16px,保留原有按钮点击区域。对话中的用户消息、回答正文与输入文字为 16px,消息正文与输入行高为 28px;回复状态、依据轮次、输入引用、协作标签及操作文字为 14px,说明行高为 20px。引用标题通过字重区分,说明与标题间隔 4px。输入框顶部不重复显示等待回答的常驻提示,提问与继续状态由对应提问卡片呈现。
起始推荐问题及其加载、失败提示统一使用 14px/20px、常规字重,窄屏下允许完整换行。
输入框按上方引用、中间编辑、下方工具栏排列,外壳使用 22px 圆角和轻边框。任务引用使用无独立底色的紧凑行,引用图标为 14px,文字为 14px/20px;任务名称与轮次、报告版本放在同一文字流中,窄屏在完整短语之间换行。上下内边距各 4px,不在输入底栏重复显示“任务协作问答”标签。内容引用复用紧凑行,原文与分析方向按需展开。权限、模型和消息发送方式的下拉入口沿用 10px 圆角矩形,箭头不设独立圆形区域;悬停和打开时使用整行的淡底色,箭头保持中性颜色;整行保持可点击。语音与发送按钮继续使用圆形。
Agent 输入框使用 --shadow-agent-composer 的柔和双层阴影区分白色阅读背景,桌面、窄屏和浮动输入框复用同一规则。聚焦与未聚焦保持相同边框和阴影,不显示蓝色外圈;工具按钮保留键盘焦点提示。左侧始终显示权限模式与文字,任务协作会话同样保留该入口,运行期间按原规则禁用。右侧依次放模型、语音和发送操作;运行时模型位置切换为引导或排队方式,主按钮沿用原有停止与发送切换;停止使用柔和红底和深红图标,悬停时红底略深,发送保持蓝色。工具图标统一为 16px、2px 描边,下拉箭头统一为 12px 单箭头;语音使用声波图标,监听时保留动态声波反馈。发送使用左右对称的 20px 上箭头和 40px 圆形按钮,图标通过网格居中;禁用时使用浅底、灰色图标,启用时使用蓝底、白色图标。模型名称按输入框实际宽度显示。待处理消息队列位于编辑框上方,区别于尚未发送的草稿。
助手回复底部使用单行操作栏:“查看处理过程”靠左,语音与复制组成右侧操作组,复制位于最右。展开区域使用白色背景、细边框和完整圆角,与回答正文区分;外边缘与过程入口左侧对齐,普通进度与工具调用的状态图标统一左对齐;工具调用平铺显示,不额外包裹卡片、边框或背景,参数内容按文字列对齐。过程入口保留标准 hover 反馈,使用对称的水平留白。普通步骤和工具调用复用同一状态图标组件:24px 圆形容器、14px 线性图标,完成为圆圈勾选、失败为圆圈叉号、进行中为加载图标。操作图标统一为 16px、2px 描边,按钮高 32px;窄容器下语音与复制收起可见标签,保留中文可访问名称和提示。复制反馈不改变操作栏布局,过程展开、语音播放与复制各自独立。
Dev 测试、外围系统、调查实时展示与本地预览展示面板也遵循本节:使用实体表面、语义颜色、细边框和标准控件,复用 workbench-shadcn-surface 主题;日期与选择菜单通过 Portal 渲染时继续传递这一主题。外围面板内的工单、SCADA 和 Dev 内的 JSONL 测试区采用同一规则。Dev 按调查测试与地图调试两个页签组织;工单用分类标题和摘要列表组织,完整报告按需展开,避免多层边框挤压表单;SCADA 先展示最新值,再提供异常演练。调查与本地展示面板使用固定标题和状态、独立滚动区、紧凑的地图操作及图表 Card;图表标题与关闭按钮同行,嵌入式渲染不再叠加旧灰色图表容器,长标题与图例可换行。面板与图表进入退出、依据展开使用 Motion 的短时透明度和位移过渡,布局变化采用 transform 投影;键盘操作及减少动态效果模式即时完成。地图定位采用可中断的 450ms 平滑 fit,覆盖层以 180ms 淡入淡出,减少动态效果时关闭这些过渡。两个浮层保持非模态,仅自身表面接收指针输入,外部地图保留点击、拖拽和滚轮操作。 展示面板的动作切换放在固定标题区,使用紧凑的 Select、前后按钮和“回到当前”;历史状态与后续动作数可见。回看切换保留短时淡入淡出,退出画面立即设为 inert 并从无障碍树隐藏,避免旧操作仍可点击。Dev 只显示测试输入、校验与原始数据,业务表格、卡片与图表统一进入展示面板。
Agent 相关界面保持项目本地 shadcn/ui 组件的设计,包括背景、边框、圆角、阴影、排版、间距及交互状态。该规则覆盖主对话面板、手机 Agent 面板、历史对话、主题新建与管理、模型菜单、权限与问题确认、Agent 回答的展开阅读面板,以及这些界面的子弹窗和提示。
| 场景 | 组件与组合 |
|---|---|
| 历史、主题表单、独立详情与确认 | Dialog、DialogTitle、DialogDescription,组合 Input、Button 和列表 |
| 对话、审批、问答与展开阅读面板 | 本地 shadcn/ui 面板布局,按需组合 Card、Separator、Tabs、ResizablePanelGroup 与 AI Elements |
| 模型、主题与会话操作菜单 | DropdownMenu 及其菜单项、分组和分隔线 |
| 辅助说明与状态 | Alert、Tooltip、HoverCard、Badge 及共享状态组件 |
- 使用已配置的 shadcn/ui 主题变量:
bg-background、bg-card、bg-popover、text-foreground、text-muted-foreground、border-border、ring-ring等。按钮、输入和菜单项优先使用本地默认样式及variant、size,不为 Agent 另建配色和控件外观。 - 历史和主题弹窗使用
bg-card,与 Agent 主对话区保持白色实体表面,标题区和列表不另铺灰色底。通过 Portal 渲染的弹窗及菜单标记data-agent-theme="chat",复用主面板的现有主题变量,避免继承工作台银灰色底板;保留本地Dialog的遮罩、边框、阴影与交互样式。 - Agent 表面不套用
acrylic-panel、acrylic-panel-white、acrylic-control、glass-transient等地图材质类,也不以surface-dock、surface-reading等材质类替换 shadcn/ui 面板背景。不叠加毛玻璃、噪点、渐变高光、发光边缘或额外阴影。 - 业务适配可调整宽高、最大高度、滚动、分栏、层级和响应式布局;手机全屏历史与抽屉布局仍沿用相同的组件设计。保留组件的标题、说明、关闭、焦点、键盘和禁用行为,避免用全局 CSS 重绘 Agent 内的按钮、输入、菜单或弹窗。
- 危险操作使用明确的确认步骤和
destructive按钮变体;失败保留输入与原内容。审批、提问与历史操作的业务规则由对应功能文档维护。 - Agent 打开的既有地图或业务工具仍遵循其所属模块规范。
AgentPersona动画资源按专用设计文档维护,周边面板与控件遵循本节。
2. Tailwind 定制方式
样式统一进入 src/styles.css。Tailwind 工具类负责布局、间距、尺寸、排版、响应式及交互状态;共享变量负责颜色和材质参数,共享变体负责重复的组件外观。
- 先选组件,再选语义表面,最后调整布局与状态。常用差异通过组件的
variant、size表达;局部差异通过className与 cn 合并。 - 使用
bg-background、bg-card、bg-popover、text-foreground、border-border和ring-ring等语义工具类。@theme inline将它们映射到项目变量;背景与前景成对维护。 - 地图与工作台 Acrylic 的混合层、噪点和回退集中封装为材质类,组件内不重复拼装颜色、模糊和阴影配方,也不把整个控件设置为半透明而降低文字对比度。
- 需要允许工具类覆盖的复合样式放入
@layer components;需要支持 Tailwind 变体的自定义工具使用@utility。修改现有未分层规则前,先核对层叠关系及回退,不直接搬移整段样式。 - 避免同一属性的冲突类;
cn处理已知 Tailwind 类的合并,不负责解决任意 CSS 的层叠。自定义材质类不应依赖className的书写先后来决定优先级,也不靠持续增加选择器权重或!important定制外观。 - 显式颜色仅用于主题定义、图表与地图 API、资源固有颜色和必要的动态值;业务 JSX 优先引用语义变量。
import { Button } from "@/shared/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/shared/ui/card";
// 独立地图浮层;放入已有 Acrylic 外壳时改用内部内容表面。
<Card className="acrylic-panel w-full max-w-sm">
<CardHeader className="p-3">
<CardTitle className="text-sm">分析结果</CardTitle>
</CardHeader>
<CardContent className="surface-reading space-y-3 p-3">
<p className="text-sm text-foreground">展示已有结论与证据。</p>
<Button variant="outline" size="sm">查看依据</Button>
</CardContent>
</Card>
3. 颜色与状态
地图与工作台 Acrylic 界面的视觉方向为宝石蓝操作、银灰外壳、冷瓷阅读面和少量香槟提示。完整色阶见 宝石蓝配色。下表为其材质基线,实际使用通过变量引用;Agent 弹窗与面板沿用已配置的 shadcn/ui 主题变量,不从下表另建局部色板。
| 角色 | 语义变量 | 基线 |
|---|---|---|
| 主操作 | --action-blue |
#4263C7 |
| 主操作 hover / 按压 | --action-blue-hover / --action-blue-pressed |
#3653B0 / #2B469C |
| 外壳色调 | --surface-panel |
银霜 #E6E9F2 |
| 常驻底板、普通控件 | --surface-dock / --surface-subtle |
#EBEEF5 |
| 正文与表单 | --surface-reading |
冷瓷 #F5F7FA,按阅读场景保持高遮蔽度 |
| 选中背景 | --action-selection-soft |
#DAE5FD |
| 正文 / 辅助文字 | --ink / --ink-muted |
#232935 / #4E5566 |
| 边框 / 分隔线 | --surface-border / --surface-divider |
#BEC2CD / #D5D9E1 |
| 警告与确认提示 | --status-warning-* |
香槟色系,小面积使用 |
状态使用 status-tone-neutral/info/success/warning/danger 与共享 StatusBadge、StatusIcon、StatusDot,同时提供文字或图标。业务状态、交互选中和数据系列颜色各自独立;material-tone-agent 只标记 Agent 解释或建议,原始监测值和人工资料继续使用普通阅读面。
地图中的管线一起显示,以管径对应的颜色和线宽体现差异。水库、泵站、水箱和水质监测点保持清晰;阀门、普通节点与常规 SCADA 使用随缩放连续变化的大小和透明度。密集设施的工程符号自动避让,底层保留轻量圆点以表达位置和支持点选。选中与异常分析标记单独突出,普通设施以连续变化为主;普通节点从 12 级、阀门从 13 级开始显示,图标、标注与命中范围同步限制。
Agent、调查展示和 Dev 本地预览的要素定位复用地图调试的选中样式,按原业务源保留线宽、边框、圆环半径、设备类型过滤和缩放规则。展示覆盖层从当前地图样式派生,独立管理高亮与清理范围;闪烁只改变强调透明度,结束后恢复静态样式。
管道透明度不随缩放变化,缩放渐变体现在管线与描边的宽度上,远看纤细、放大清晰;图层开关时仍使用透明度淡入淡出。
图层开关统一使用约 320ms 的透明度淡入淡出,覆盖管线、设施、监测点、GIS 原始数据和模拟结果。矢量瓦片可绘制后才开始淡入计时,避免加载期间耗尽过渡时间。淡入淡出只临时叠加透明度系数,结束后恢复图层原有样式;快速反向切换从当前进度继续。隐藏时立即关闭命中层与交互强调层,淡入结束后恢复;减少动态效果偏好下直接切换。管线用过滤器区分开关状态,透明度保持统一数值,避免逐帧重写属性表达式触发瓦片重算。
重要设施也使用连续缩放插值,但图标的最低透明度保持较高,衬底更轻,保证概览可辨识。按需开启的数值标签随缩放渐变字号与透明度;使用者设置的字号作为放大后的目标字号。
水质、压力和流量监测点统一从 11 级开始显示,图标、圆点、交互层和图层面板提示共用缩放起点。水质与压力监测点使用一致的圆点、衬底尺寸和图标屏幕像素宽度。图标缩放系数需结合原图尺寸换算,水质图标 128px、压力图标 96px,不直接使用相同系数。
GIS 原始图层与对应业务类型共用起始级别:GIS 管线与 DN100+ 台账从 8.5 级显示,流量仪从 11 级显示,消火栓、接水点、用户及非居民水表从 12 级显示,GIS 阀门与排水阀从 13 级显示。图层提示、图形和点击范围保持一致。
Agent 使用 shadcn/ui 的实体表面和现有主题色,不将这种外观列为待迁移到 Acrylic 的差异。已有 Agent 专用配色、材质和控件 CSS 覆盖应在对应组件调整时收敛到本地 shadcn/ui 样式;是否完成以运行界面验收为准。
4. 材质与层级
本节的 Acrylic 材质规则适用于地图与其他工作台界面;Agent、Dev 测试、外围系统、调查与本地展示面板按前述 shadcn/ui 规则执行。Acrylic 通过半透明色调、背景模糊、混合层和细噪点建立层级,边缘高光与阴影保持克制。常驻、参与布局的业务区域使用实体底板;Mica 仅作为这一底板角色的设计参考,Web CSS 实体色不等同于原生系统 Mica。
| 表面类 | 用途 |
|---|---|
acrylic-navigation |
透出地图背景的顶部导航 |
acrylic-panel |
图层、图例、工况、要素详情和菜单等独立地图浮层 |
acrylic-panel-white |
与 acrylic-panel 配合的白色变体,如项目切换对话框 |
acrylic-control |
工具栏、缩放、比例尺和底图入口 |
glass-transient |
活动任务浮条和地图临时通知 |
surface-dock |
非 Agent 的常驻业务面板、分析成果及业务报告外壳与标题区 |
surface-control |
内部按钮、筛选器和紧凑操作区 |
surface-well |
低密度分组、空白支撑区和内部凹槽 |
surface-reading |
消息、报告、表格、属性、证据和表单 |
一个浮动区域只由最外层承担背景模糊,内部使用内容表面。同一区域的工具面板相互替换,避免叠加 Acrylic。常驻底板可以承载独立临时浮层,标题栏按背景关系选择材质。
地图纹理可影响外壳空白区,不能穿透密集文字。透明度、模糊和阴影由全局变量及 data-basemap-tone 适配;具体参数以 CSS 为准,不在多份文档重复维护固定数值。入场动画与定位容器需保证背景采样正常,结束后不保留不必要的合成提示。
减少透明度偏好或不支持 backdrop-filter 时,切换高遮蔽度背景并关闭模糊;强制颜色模式使用系统色,关闭纹理与阴影。项目已有浅色主题是当前基线,暗色类名不代表已完成暗色验收。
地图组件继续复用 map-control-styles.ts:
| 共享常量 | 材质类 |
|---|---|
MAP_CONTROL_SURFACE_CLASS_NAME |
acrylic-control border |
MAP_TOOL_PANEL_SURFACE_CLASS_NAME |
acrylic-panel border |
MAP_FOCUS_SURFACE_CLASS_NAME |
acrylic-panel border |
MAP_READABLE_SURFACE_CLASS_NAME |
surface-well border |
MAP_READABLE_SURFACE_STRONG_CLASS_NAME |
surface-control border |
5. 排版、密度与布局
沿用 Noto Sans SC,中文正文自然换行,不额外拉开字距。编号、时间和数值使用等宽数字,标签左对齐,数值列右对齐。
| 场景 | 排版约定 |
|---|---|
| 侧栏标题、业务分组标题 | 分别为 14px、13px |
| 紧凑正文与字段标签、辅助信息 | 分别为 12px、11px |
| Agent 消息正文 | 14px,行高 24px |
| 欢迎提示与展开报告标题 | 20px,行高 28px |
| 指标值、单位 | 分别为 24px、12px,数值使用等宽数字 |
业务区间距为 12px 至 14px,Agent 消息之间保留 24px。地图与业务面板的普通控件和内部区域沿用 8px、12px 圆角,独立大面板使用共享 16px 圆角;具体值复用组件变体和地图圆角常量。Agent 弹窗、面板和表单控件沿用本地 shadcn/ui 的默认圆角、间距及尺寸变体。
地图与业务表单的主要按钮目标高度为 40px;基础 Input 当前默认 36px,这些业务场景通过 h-10 或适配后的字段组件统一。Agent 控件优先沿用 shadcn/ui 默认尺寸和 size 变体。紧凑控件保留至少 40px 的互不重叠命中区域,可通过周边留白适配触屏。
地图保持主工作区。浮层、导航、时间轴和正文预留各自安全区,地图背景可延伸到 56px 顶部导航背后。业务内容按“定位、状态、下一步、证据”排列,原始对象与历史按需展开;移动端单列,表格只在自己的容器内横向滚动。
Agent 与主工作区、地图与报告使用共享 Resizable 分栏;连续调宽不增加布局过渡。报告展开保留同一组件实例、草稿、筛选与阅读位置。具体尺寸、切换条件和任务交互由 Agent 交互与报告设计 维护。
6. 组件与交互规则
| 用途 | 优先组件 |
|---|---|
| 操作 | Button,复用 default、outline、secondary、ghost、link 和 destructive 变体 |
| 输入与选择 | Input、Textarea、InputGroup、FieldSelect、Select、Checkbox、Radio、DateTimeField |
| 分组、状态、数据 | Card、Separator、共享状态组件、Table、Tabs |
| 证据与过程 | Disclosure、Accordion、Collapsible |
| 菜单、弹层、解释 | DropdownMenu、Dialog、Tooltip、HoverCard |
| 可调工作区 | ResizablePanelGroup、ResizablePanel、ResizableHandle |
WorkbenchSection 统一标题、说明、状态和操作;WorkbenchNotice 使用局部状态线;WorkbenchEmptyState 只说明为空原因与下一步。以分隔线、留白和浅色差组织内容,避免重复嵌套同级卡片。
每个业务区最多一个醒目的主操作。按钮覆盖默认、hover、按压、焦点、禁用和加载态;hover 仅用于支持 hover 的设备,加载时阻止重复提交并保留可读状态。地图与业务控件沿用共享按压反馈,Agent 控件保留本地 shadcn/ui 交互状态;具有专用资源交互的 AgentPersona 保留原版悬停,不额外缩放或变暗。
地图与业务表单字段复用 .form-field,聚焦只改变原有 1px 边框;组合输入由外层承担焦点边界,无边框输入使用内描边。Agent 字段保留本地 shadcn/ui 输入组件的边框、焦点和错误样式。错误通过文字、aria-invalid 和关联说明表达,失败后保留输入。选中与焦点不改变控件尺寸,底图选择卡片使用主题边框和勾选标记,键盘焦点使用共享内描边。
弹层保留标题、关闭入口、焦点管理及触发控件的焦点返回。表单弹窗显式将初始焦点放在首要业务字段,选择框获焦不自动展开。Esc 从内到外处理,外层尊重已消费事件;弹窗容器可承接程序焦点,业务控件仍保留可见焦点。模态遮罩阻断底层地图操作。
状态必须区分无数据、加载中、失败、无权限、未配置与结果未知;保留完整证据、修订及请求号的可读入口。演练数据明确标记,前端展示不能暗示已经完成业务执行或写入。
7. 验证与维护
文档修改检查引用路径、示例中的本地组件与属性、命令及 git diff --check。运行代码变更执行 pnpm lint、pnpm typecheck、pnpm test;可见 UI 变化增加聚焦的 pnpm test:browser,依赖、构建或运行集成变化增加 pnpm build。
界面验收覆盖 1280px 及以上桌面和 320px、375px 窄屏,检查长内容、按钮与命中区域、弹层边界、Tab、方向键、Esc、焦点返回及减少动态效果。普通文字与实际合成背景对比度至少 4.5:1,焦点与必要非文字状态至少 3:1,并验证强制颜色、减少透明度与模糊不可用时的回退。
Agent 界面另检查所有弹窗、面板及其子菜单是否沿用本地 shadcn/ui 设计,是否存在地图材质类、额外模糊和阴影、独立 Agent 配色或重绘基础控件的 CSS。尺寸和层级适配不能改变这些组件的视觉规范。
设计规则只在本文维护;业务协议与动作留在功能文档,历史测试结果留在交付记录,不作为当前全量验收结论。