153 lines
9.8 KiB
Markdown
153 lines
9.8 KiB
Markdown
# 前端 UI 开发规范(给 Gemini)
|
||
|
||
> 你(Gemini)**只负责前端 UI**。这份文档是你动手前的唯一须知,请**先完整读一遍再改任何代码**。
|
||
> 本项目是 **Kanboard 1.2.52**(开源 PHP 看板)的二次开发,分支 `fix-newUI`。
|
||
> 代码根目录:`W:\kanban\kanboard-1.2.52\`(下文所有相对路径都以此为基准)。
|
||
> 文档里说的"屎山"指:同一样式散落多处互相打架、死代码、内联样式乱塞、写死颜色/宽度。**本规范的全部目的就是不让它再变成屎山。**
|
||
|
||
---
|
||
|
||
## 0. 三条铁律(违反任何一条 = 制造屎山)
|
||
|
||
1. **所有 CSS 只写在 `assets/css/custom_dashboard.css`,并放进正确的编号区块。** 严禁在 `.php` 模板里内联 `<style>`,严禁新建别的 css 文件。
|
||
2. **同一个东西只允许有一处样式来源。** 改样式先去对应区块找现成的改,别另起一段重复定义(重复 = 下次没人知道哪段生效)。
|
||
3. **改颜色一律用变量,不准写死色值。** 主题色变量在 `assets/css/custom_login.css` 的 `:root` 里(如 `--login-bg`、`--login-card-bg`、`--color-primary`)。
|
||
|
||
---
|
||
|
||
## 1. 怎么运行 / 怎么看到你的改动
|
||
|
||
- 应用跑在 **`http://127.0.0.1:8000`**,由本地 PHP 实时读磁盘文件提供服务(双击 `W:\kanban\start-kanban.bat` 启动;那个黑窗口要一直开着)。
|
||
- 改完文件**不需要清缓存**:框架会给 css/js 的 URL 自动加 `?文件修改时间` 戳,存盘即换新。
|
||
- ⚠️ **弹窗(modal)内容是 AJAX 加载的,不是随页面一起来的。** 所以看弹窗的改动要:
|
||
1. 先 **F5 刷新整个页面**(让 `<head>` 里的新 CSS 重新加载)
|
||
2. **再重新打开那个弹窗**(光 F5 不重开弹窗,看到的还是旧弹窗 DOM)
|
||
|
||
### 「改了看不见」自查清单(按顺序排查,别瞎猜缓存)
|
||
1. 改的是不是 `custom_dashboard.css` 的**正确区块**?(不是某个模板里的内联样式 / 不是 `.min.css`)
|
||
2. 有没有 **F5 + 重新打开弹窗**?
|
||
3. 服务器还在跑吗?(浏览器 `ERR_CONNECTION_REFUSED` = 8000 端口的服务进程被关了,重开 `start-kanban.bat`,**这跟你的代码无关**)
|
||
4. 是不是被**核心写死的样式用更高特异性盖住了**?见第 5 节。
|
||
|
||
---
|
||
|
||
## 2. 你能碰 / 绝对不能碰的文件
|
||
|
||
### ✅ 允许修改(前端 UI 全在这几处)
|
||
| 文件 | 作用 |
|
||
|---|---|
|
||
| `assets/css/custom_dashboard.css` | **全站自定义样式总入口**(登录页除外)。你 95% 的工作在这里 |
|
||
| `assets/css/custom_login.css` | 登录页样式 + **全站主题色变量 `:root`** |
|
||
| `assets/js/custom_dashboard.js` | UI 行为脚本(label 转 placeholder、定位"指派给我"等) |
|
||
| `app/Template/` 下的自定义模板(见第 4 节) | 弹窗/页面的 HTML 结构 |
|
||
|
||
### ⛔ 绝对不要改(改了要么白改,要么炸)
|
||
- `assets/js/app.min.js`、`assets/js/vendor.min.js` —— **压缩文件,没有源码,无法维护**。Kanboard 弹窗的结构和行为就藏在 `app.min.js` 里,**别手改它**;要调 UI 行为就写在 `custom_dashboard.js`。
|
||
- `assets/css/*.min.css`(`vendor` / `light` / `dark` / `auto` / `print`)—— 核心主题,只读。
|
||
- `vendor/`、`app/Model/`、`app/Controller/`、`app/Core/`、`data/db.sqlite` —— 后端/数据,不归你管。
|
||
|
||
---
|
||
|
||
## 3. `custom_dashboard.css` 的结构(必须维护好目录)
|
||
|
||
文件**顶部有一个编号目录(TOC)**,正文按编号分区块。**新增样式时:放进对应编号区块;如果开了新主题,更新顶部 TOC。**
|
||
|
||
```
|
||
1. 全局背景
|
||
2. 顶栏 Header(logo / 标题 / 项目切换器)
|
||
3. 侧边栏 Sidebar
|
||
4. 页面头部标签 Page header
|
||
5. 列表 / 卡片 / 提示 / 搜索框
|
||
6. 顶栏注入组件(视图切换 / 过滤)
|
||
7. 项目概览仪表盘(KPI + 标签页)
|
||
8. 看板 Kanban board
|
||
9. 任务【编辑】弹窗表单布局 (.task-form-*)
|
||
10. 任务【新建】弹窗表单布局 (.custom-task-form-*)
|
||
11. 弹窗通用外观(所有 #modal-box)
|
||
```
|
||
|
||
### 「改什么 → 改哪里」速查
|
||
| 你想改 | 去这里 |
|
||
|---|---|
|
||
| 任意弹窗的外壳(宽度/圆角/遮罩/关闭按钮/通用按钮) | `custom_dashboard.css` **§11** |
|
||
| **新建任务**弹窗的表单布局 | `custom_dashboard.css` **§10** |
|
||
| **编辑任务**弹窗的表单布局 | `custom_dashboard.css` **§9** |
|
||
| 主题色 | `custom_login.css` 的 `:root`(亮色)和 `@media (prefers-color-scheme: dark)`(暗色) |
|
||
| 弹窗内字段的行为(隐藏 label、占位符等) | `custom_dashboard.js` |
|
||
| 弹窗的 HTML 结构(加/删字段、换列) | 对应模板(第 4 节),**样式仍写回 css** |
|
||
|
||
---
|
||
|
||
## 4. 关键模板 & 一个必须知道的"两套表单"陷阱
|
||
|
||
| 模板 | 是什么 |
|
||
|---|---|
|
||
| `app/Template/layout.php` | 全站骨架,负责加载 css/js(一般别动) |
|
||
| `app/Template/header/title.php` | 顶栏标题区 |
|
||
| `app/Template/header/custom_board_selector.php` | 项目切换下拉 |
|
||
| `app/Template/project_overview/show.php` | 项目概览(KPI 卡 + 纯 CSS 标签页) |
|
||
| `app/Template/task_creation/show.php` | **新建任务**弹窗(已去内联样式,只剩 HTML) |
|
||
| `app/Template/task_modification/show.php` | **编辑任务**弹窗 |
|
||
|
||
### ⚠️ 陷阱:新建 和 编辑 是两套不同的类名,别搞混!
|
||
- **新建任务**(`task_creation/show.php`)用 `.custom-task-form-container` / `.custom-task-form-main` / `.custom-task-form-secondary` / `.custom-task-form-tertiary`,样式在 **§10**。
|
||
- **编辑任务**(`task_modification/show.php`)用 `.task-form-container` / `.task-form-main-column` / `.task-form-secondary-column` / `.task-form-bottom`,样式在 **§9**。
|
||
- 改其中一个弹窗,**只动它对应那套类名**;想两个一起改,两节都要改。**别把 `.task-form-*` 的规则套到新建弹窗上(反之亦然),那是无效的死代码。**
|
||
|
||
---
|
||
|
||
## 5. Kanboard 核心避坑大全(不知道这些 = 改半天找不到原因)
|
||
|
||
### 5.1 核心给很多控件写死了像素宽度 —— 放进网格/弹窗会撑爆或太窄
|
||
在三列网格里,这些写死宽度会把整张表撑出**横向滚动条**。已知清单:
|
||
|
||
| 选择器 | 核心写死的宽度 | 出现在 |
|
||
|---|---|---|
|
||
| `.text-editor textarea` / `.text-editor .text-editor-preview-area` | **700px** | 描述(markdown 编辑器) |
|
||
| `input[type="text"]:not(.input-addon-field)` | 300px | 普通文本框 |
|
||
| `.form-date` / `.form-datetime` | 150px | 到期/开始时间 |
|
||
| `.form-input-small` | 150px | 参考 |
|
||
| `.form-input-large` / `.tag-autocomplete` | 400px | 标签等 |
|
||
| `.color-picker` | 220px | 颜色下拉 |
|
||
| `.task-form-main-column input[type="text"]` | 700px | 编辑弹窗标题 |
|
||
|
||
**处理原则:在表单容器里把它们强制改成 `width:100% !important; max-width:100% !important`,让它随所在列自适应。** §10 已经对编辑器和这些字段做了覆盖,照着那个写法加即可,**不要去改核心 `.min.css`**。
|
||
|
||
### 5.2 弹窗的"滚动层"是 `#modal-box`,不是 `#modal-content`
|
||
核心:`#modal-box { overflow:auto }`。所以想处理弹窗的横向溢出,要针对 `#modal-box`,针对 `#modal-content` **没用**(这是上次踩了很久的坑)。
|
||
- 已有一条**精准收口**:`#modal-box:has(.custom-task-form-container)`(用 `:has()` 只作用于任务表单弹窗,不影响其它可能需要横向滚动的弹窗)。**收溢出前要先确认右侧没有真内容被藏起来**,否则就是"裁掉内容糊弄",不允许。
|
||
|
||
### 5.3 CSS 特异性:你的规则可能被核心更高特异性的规则盖住
|
||
例:核心 `input[type="text"]:not(.input-addon-field).form-date{width:150px}` 的特异性是 (0,3,1),会**压过**你写的 `.custom-task-form-container input[type="text"]{...}`(0,2,1)。
|
||
- 现象就是"我明明写了 width 却不生效"。
|
||
- 解决:把选择器写得更具体(带上具体类名,如 `.custom-task-form-container input.form-date`)或在该属性上加 `!important`。**`!important` 只在确实被核心盖住时用,不要全文乱撒。**
|
||
|
||
### 5.4 样式加载顺序(`layout.php`)
|
||
`vendor/theme.min.css` → `custom_login.css` → **`custom_dashboard.css`** → DB 自定义 CSS(目前为空)。
|
||
你的 `custom_dashboard.css` 在主题之后加载,同特异性下能赢核心。变量来自 `custom_login.css`(在它之前加载,所以变量可用)。
|
||
|
||
---
|
||
|
||
## 6. 标准改动流程(每次都这样做)
|
||
|
||
1. **定位**:先按第 3 节速查表找到该改的区块/文件,去看现有规则,**在原处改**。
|
||
2. **不破坏现状**:尽量不动其它区块;删任何东西前,先确认它没被别的模板/页面引用(两套表单类名见 4 节)。
|
||
3. **用变量**:颜色用 `:root` 变量,不写死。
|
||
4. **验证**:F5 + 重新打开弹窗,亲眼确认效果;顺手看一眼别的页面/弹窗没被你连累。
|
||
5. **保持整洁**:新增区块要在 TOC 登记;写一句注释说明"这段管什么"。
|
||
6. **括号配平**:CSS 大括号要成对,别留半截规则。
|
||
|
||
---
|
||
|
||
## 7. 当前已知待办(都是 JS 行为,CSS 改不动它们)
|
||
这些在新建任务弹窗里,属于 `custom_dashboard.js` / 核心 JS 的行为问题,**别试图用 CSS 硬怼**:
|
||
- 游离的"我"(指派给我链接)定位错乱 → `custom_dashboard.js` 第 58–79 行
|
||
- 标题下红色 `*` 没被隐藏 → `custom_dashboard.js` 第 46–47 行
|
||
- 部分字段 label→占位符转换不干净 → `custom_dashboard.js` 第 6–44 行
|
||
- 颜色选择器弹层定位 → 核心 `app.min.js`(最难,建议最后碰)
|
||
|
||
---
|
||
|
||
## 8. 一句话总结
|
||
**CSS 全进 `custom_dashboard.css` 的对应编号区块;颜色用变量;别碰 `.min.js`/`.min.css`;新建和编辑是两套类名别混;核心写死的宽度要在表单里覆盖成 100%;改完 F5+重开弹窗验证。** 守住这些,就不会再变屎山,也不会再出"改了看不见"的怪事。
|