Files
Starlight_Lancher/.agents/skills/oil-frontend/references/component-contract.md

113 lines
7.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 组件、代码组织与视觉系统规则
> 当任务涉及模块、组件、Hook、函数、类型、数据来源、样式归属或旧实现清理时读取。
## 决策顺序
遇到视觉或交互问题时依次检查:
1. 项目是否已有相同含义且符合本规范的组件、函数、统一设计变量或样式;
2. 页面是否用了错误组件;
3. 父级布局是否给了错误尺寸、对齐或定位;
4. 组件默认样式或状态逻辑是否错误;
5. 现有组件变体是否足够;
6. 是否存在稳定的重复职责,足以新增共享实现;
7. 所有使用位置和旧实现是否需要同步处理。
未完成搜索,也未检查组件选择、父布局和默认行为前,不新增组件、函数、样式或组件变体。
## 系统分工
- 统一设计变量负责跨产品复用的颜色、字号、间距、圆角、阴影和动效含义。
- 基础与共享组件负责自身视觉、交互反馈和完整状态,不由页面逐项重画。
- 业务组件负责组合稳定的业务对象和交互,不把业务差异塞进基础组件。
- 格式化、校验和数据转换等逻辑使用输入相同就返回相同结果的函数;请求、保存和导航由负责业务操作的代码处理,不藏进只负责展示的组件。
- 页面负责取得当前数据和路由信息、安排区域并组合组件,不复制组件内部逻辑。
同一含义只保留一个实现来源。结构相似不等于职责相同;只有职责、输入输出和行为都稳定一致时才共享。
## 模块与代码组织
- 按业务对象或功能模块组织代码,不按文件类型把整个项目拆散。
- 只服务一个模块的组件、Hook、函数、类型、样式和测试放在该模块附近多个模块稳定复用后才移入共享层。
- Hook 负责状态和副作用组合;无副作用的格式化、校验和转换使用普通函数;请求和持久化由数据访问或业务操作代码负责。
- 业务类型由拥有该数据的模块定义,组件输入类型放在组件附近,接口请求与响应类型放在接口层;相同含义不重复声明。
- 共享层不得依赖具体业务模块;跨模块使用公开入口,不直接引用对方内部文件。
- 既有目录混乱时,不继续复制错误模式。为当前改动确定正确归属,迁移相关代码、更新引用并删除旧文件;无法一次完成时明确剩余范围。
## 数据来源
- 同一业务数据只保留一个权威来源;服务端结果、缓存、全局状态、表单草稿和派生视图各自只承担明确职责,不维护能够独立修改的重复副本。
- 能从权威来源计算的值直接派生。只有未提交编辑确实需要时才保留本地草稿,并明确初始化、提交和丢弃边界。
## 既有实现与历史包袱
- 既有实现只有在职责、行为、数据和样式归属正确时才值得复用;存在时间长、使用页面多或位于共享目录,都不能证明它是正确模式。
- 既有实现持续产生局部补丁、重复状态、影响无关页面的样式、业务开关或不一致行为时,停止在新位置继续使用它。
- 在授权范围内优先修复或替换真正出错的共享实现,处理所有受影响的使用位置后删除旧实现;为纠正问题,可以有计划地改变旧接口、结构或样式组织。
- 新实现已经接管且使用位置完成迁移后删除旧分支、fallback、legacy 适配层、旧类型、旧状态和失效开关。只有仍有真实兼容对象时才暂时保留,并明确删除条件。
- 无法在当前范围内全部改完时,不得继续复制错误模式;明确记录还剩哪些旧使用位置、这次改到哪里以及后续如何清理,不靠长期保留两套实现来掩盖问题。
## 允许
- 在共享组件内部维护视觉样式。
- 使用含义明确的组件属性,例如 `variant``size``state``loading``destructive`
- 由布局容器控制网格、排列、区域间距和响应式结构。
- 使用正式组件属性或 `data-state` 表达状态。
- 为重复交互建立共享组件。
- 复用已有的格式化、校验和数据转换函数。
- 弹窗内部结构由共享组件和按用途命名的组件变体负责;只有任务实际改变弹窗尺寸、滚动或结构时,才读取 [视口与弹窗规则](viewport-and-dialog-contract.md#弹窗结构)。
- 在交互组件内部统一维护 pointer、hover、active 和 disabled 状态。
## 禁止
- 在使用组件的位置直接写只服务于当前页面的视觉样式。
- 为共享组件传入视觉型 `className` 后覆盖颜色、尺寸、圆角、阴影或内部布局。
- `!important` 修补组件实例。
- 页面专属选择器侵入共享组件内部。
- 使用任意数值绕过统一设计变量。
- 用页面名、业务对象名或视觉结果命名组件变体。
- 为一个实例增加没有稳定含义的组件变体。
- 复制组件后只改一点样式。
- 复制函数后改名,或在多个组件中分别维护相同转换和校验。
- 用大量页面名称、业务布尔开关和条件分支制造万能组件。
- 把请求、保存或导航藏进纯展示组件。
- 在 CSS 修复前不检查页面结构、父级布局和组件调用。
- 在使用弹窗的页面重排共享弹窗的标题区、内容区和操作区,或重新定义其高度和滚动方式。
- 在使用共享组件的页面为单个组件补固定宽高。
- 让业务组件样式无边界地累积在一个全局样式文件中。
## 视觉一致性
- 新页面沿用项目中符合本规范的统一设计变量、组件、布局模式和状态表达,不建立页面专属的设计语言。
- 一致性同时包括颜色、字号、间距、信息密度、动作层级、状态位置、图标含义和交互反馈,不能只统一其中一项。
- 业务差异通过内容、组合和稳定含义表达;不要通过任意视觉值制造差异。
## 样式归属与清理
- 每段样式必须归属于基础规则、共享组件或明确的业务模块;页面只负责区域布局,不接管组件内部视觉。
- 项目已有的样式组织方式符合归属边界时才沿用;如果业务样式无边界集中、互相覆盖或无法随组件删除,就停止扩大全局文件,重新建立组件或业务模块的样式归属。
- 删除或改名页面结构、样式类、状态或组件变体时,同步删除不再生效的选择器、状态样式、响应式规则、引用和样式文件。
- 新实现能够运行不代表改动完成;旧组件、旧函数和旧样式已经清理,所有受影响的使用位置已经检查,才算完成。
## 新增组件变体的门槛
同时满足以下条件才新增:
- 差异表达稳定含义,不是页面身份;
- 存在多个使用位置,或明确属于组件公共状态;
- 属性名称能说明使用原因,而非视觉结果;
- 默认行为仍适用于多数场景;
- 能用组件级验证覆盖。
组件变体应说明“为什么存在差异”,不能只说明颜色、数值、页面或业务对象。
## 尺寸由谁负责
- 页面布局容器负责区域分配,共享组件负责自身稳定尺寸。
- 使用共享组件的页面不得为单个组件补固定宽高;只有任务实际改变固定尺寸、滚动或视口边界时,才读取 [视口与弹窗规则](viewport-and-dialog-contract.md#内容驱动尺寸)。
## 修改后的审查
修改共享组件、函数或样式后,搜索全部使用位置,检查默认方式、受影响的使用场景和旧实现,并报告未验证项。