refactor(styles): 建立统一的生产级样式体系 (#4)
## 变更内容 - 将全局样式拆分为设计令牌、基础规则和语义组件层 - 集中管理 Naive UI 主题配置 - 迁移页面容器、表单、信息面板和按钮等重复样式 - 增加样式体系文档与自动契约检查 ## 验证 - `npm run check:styles` - `npm run build`Reviewed-on: #4
This commit was merged in pull request #4.
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
# OpenCloud 样式体系
|
||||
|
||||
这套体系用于让视觉规则集中、Vue 模板可读,同时保留 Tailwind 对一次性布局的灵活性。它不是“所有样式都写成全局类”,而是把会跨页面复用、带有产品语义或必须一致的规则集中管理。
|
||||
|
||||
## 分层
|
||||
|
||||
| 层级 | 文件 | 职责 |
|
||||
| --- | --- | --- |
|
||||
| 设计令牌 | `src/styles/tokens.css` | 颜色、字体、渐变、阴影、动效时长等稳定决策 |
|
||||
| 基础规则 | `src/styles/base.css` | 页面基线、选中文本、全局圆角策略 |
|
||||
| 组件规则 | `src/styles/components.css` | 页面 Hero、容器、表单、面板、按钮等共享语义类 |
|
||||
| 第三方主题 | `src/lib/theme.ts` | Naive UI 的全局主题契约;值应与设计令牌保持一致 |
|
||||
| 单组件样式 | Vue 文件的 `<style scoped>` | 只属于一个功能的滑杆、动画、地图或媒体细节 |
|
||||
| 一次性布局 | Vue 模板中的 Tailwind 类 | flex/grid、间距、响应式排列及确实只出现一次的视觉调整 |
|
||||
|
||||
`src/style.css` 只负责按以上顺序装配全局样式,不再直接堆放组件规则。
|
||||
|
||||
## 命名规则
|
||||
|
||||
- 所有共享类使用 `oc-` 前缀,避免与 Naive UI、AMap 和 Tailwind 冲突。
|
||||
- 组件使用 `.oc-block`,内部结构使用 `.oc-block__element`,变体使用 `.oc-block--modifier`。
|
||||
- 变体不能脱离基础类使用,例如 `oc-panel-button oc-panel-button--sky`。
|
||||
- 类名描述用途,不描述当前颜色。例如使用 `oc-field-error`,而不是 `oc-red-text`。
|
||||
- 只有至少跨两个页面复用,或承载全局产品规则时才新增共享类。仅服务单一功能的代码留在组件内。
|
||||
|
||||
## 常用契约
|
||||
|
||||
### 页面结构
|
||||
|
||||
```html
|
||||
<section class="oc-page-hero">
|
||||
<div class="oc-container oc-container--content oc-page-hero__inner">
|
||||
<p class="oc-page-eyebrow">Cloud Upload</p>
|
||||
<h1 class="oc-page-title">上传云图</h1>
|
||||
<p class="oc-page-description">页面描述</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<main class="oc-container oc-container--content oc-page-content">
|
||||
<!-- 页面内容 -->
|
||||
</main>
|
||||
```
|
||||
|
||||
容器宽度只有三个语义档位:`oc-container--narrow`、`oc-container--content`、`oc-container--wide`。不要在同类页面重复手写 `max-w-* mx-auto px-*`。
|
||||
|
||||
### 表单
|
||||
|
||||
```html
|
||||
<label class="oc-field-label">
|
||||
拍摄时间 <span class="oc-field-required">*</span>
|
||||
</label>
|
||||
<input class="oc-field-control" />
|
||||
<p class="oc-field-help">补充说明</p>
|
||||
<p class="oc-field-error">错误信息</p>
|
||||
```
|
||||
|
||||
原生 `input`、`select` 和 `textarea` 共用 `oc-field-control`。尺寸或布局差异可以追加少量 Tailwind 类,例如 `class="oc-field-control mt-2 resize-none"`。
|
||||
|
||||
### 信息与面板
|
||||
|
||||
- `oc-section-label`:详情面板中的字段标题。
|
||||
- `oc-stat-label` / `oc-stat-value`:统计数据的标签和值。
|
||||
- `oc-inset-panel`:详情中的浅色信息块。
|
||||
- `oc-panel-card` / `oc-panel-card-soft`:Naive UI 卡片的硬阴影。
|
||||
- `oc-surface`:普通 HTML 容器的标准白色表面。
|
||||
- `oc-empty-card`:空状态表面。
|
||||
|
||||
### 按钮
|
||||
|
||||
Naive UI 按钮继续使用 `type="default"`,视觉语义由共享类控制:
|
||||
|
||||
```html
|
||||
<NButton class="oc-panel-button oc-panel-button--neutral" type="default">
|
||||
取消
|
||||
</NButton>
|
||||
<NButton class="oc-panel-button oc-panel-button--sky" type="default">
|
||||
保存
|
||||
</NButton>
|
||||
```
|
||||
|
||||
页面级主操作使用 `oc-primary-button`;面板内操作使用 `oc-panel-button`。可用变体为 `neutral`、`sky`、`teal`、`amber`、`danger`,不要临时创建新的强调色。
|
||||
|
||||
## 新增或修改样式的决策顺序
|
||||
|
||||
1. 先确认现有 `oc-*` 类能否表达该语义。
|
||||
2. 一次性布局使用 Tailwind,不为单次 `flex`、`gap` 或响应式网格创建共享类。
|
||||
3. 跨页面重复或属于产品视觉契约时,在 `components.css` 增加语义类;涉及稳定视觉值时先在 `tokens.css` 增加令牌。
|
||||
4. 只属于一个交互或组件的规则放在对应 Vue 文件的 `<style scoped>` 中。
|
||||
5. 修改 Naive UI 全局值时同步检查 `theme.ts` 与 `tokens.css`。
|
||||
|
||||
## 验证
|
||||
|
||||
提交前运行:
|
||||
|
||||
```bash
|
||||
npm run check:styles
|
||||
npm run build
|
||||
```
|
||||
|
||||
`check:styles` 会阻止已经淘汰的重复 class、非项目调色板以及缺少基础类的按钮修饰类回流;`build` 同时执行 Vue/TypeScript 类型检查和生产构建。
|
||||
Reference in New Issue
Block a user