agentcss 0.0.0-stage → 0.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/01-tokens/README.md +236 -0
- package/01-tokens/behavior/dismissable.js +132 -0
- package/01-tokens/behavior/emit.js +76 -0
- package/01-tokens/behavior/focus-return.js +81 -0
- package/01-tokens/behavior/roving.js +152 -0
- package/01-tokens/behavior/typeahead.js +124 -0
- package/01-tokens/focus-ring-demo.html +133 -0
- package/01-tokens/focus-ring.css +102 -0
- package/01-tokens/page.css +244 -0
- package/01-tokens/polyfill.js +116 -0
- package/01-tokens/responsive-demo.html +171 -0
- package/01-tokens/scrollbar-demo.html +194 -0
- package/01-tokens/scrollbar.css +179 -0
- package/01-tokens/theme-toggle.js +103 -0
- package/01-tokens/tokens.css +972 -0
- package/01-tokens/typography.css +156 -0
- package/02-primitives/badge/README.md +71 -0
- package/02-primitives/badge/badge.css +141 -0
- package/02-primitives/badge/demo.html +101 -0
- package/02-primitives/button/README.md +99 -0
- package/02-primitives/button/button.css +353 -0
- package/02-primitives/button/demo.html +200 -0
- package/02-primitives/card/README.md +145 -0
- package/02-primitives/card/card.css +246 -0
- package/02-primitives/card/demo.html +170 -0
- package/02-primitives/choice/README.md +161 -0
- package/02-primitives/choice/choice.css +395 -0
- package/02-primitives/choice/demo.html +277 -0
- package/02-primitives/combobox/README.md +79 -0
- package/02-primitives/combobox/combobox.css +223 -0
- package/02-primitives/combobox/combobox.js +485 -0
- package/02-primitives/combobox/demo.html +109 -0
- package/02-primitives/date-range/README.md +100 -0
- package/02-primitives/date-range/date-range.css +206 -0
- package/02-primitives/date-range/date-range.js +301 -0
- package/02-primitives/date-range/demo.html +104 -0
- package/02-primitives/input/README.md +170 -0
- package/02-primitives/input/demo.html +246 -0
- package/02-primitives/input/input.css +239 -0
- package/02-primitives/popover/README.md +80 -0
- package/02-primitives/popover/demo.html +150 -0
- package/02-primitives/popover/popover.css +187 -0
- package/02-primitives/popover/popover.js +331 -0
- package/02-primitives/progress/README.md +82 -0
- package/02-primitives/progress/demo.html +154 -0
- package/02-primitives/progress/progress.css +172 -0
- package/02-primitives/select/README.md +95 -0
- package/02-primitives/select/demo.html +121 -0
- package/02-primitives/select/select.css +151 -0
- package/02-primitives/select/select.js +549 -0
- package/02-primitives/separator/README.md +63 -0
- package/02-primitives/separator/demo.html +84 -0
- package/02-primitives/separator/separator.css +73 -0
- package/02-primitives/skeleton/README.md +69 -0
- package/02-primitives/skeleton/demo.html +110 -0
- package/02-primitives/skeleton/skeleton.css +96 -0
- package/02-primitives/switch/README.md +65 -0
- package/02-primitives/switch/demo.html +115 -0
- package/02-primitives/switch/switch.css +370 -0
- package/03-patterns/accordion/README.md +121 -0
- package/03-patterns/accordion/accordion.css +453 -0
- package/03-patterns/accordion/accordion.js +369 -0
- package/03-patterns/accordion/demo.html +223 -0
- package/03-patterns/content/README.md +103 -0
- package/03-patterns/content/content.css +286 -0
- package/03-patterns/content/demo.html +88 -0
- package/03-patterns/drawer/README.md +79 -0
- package/03-patterns/drawer/demo.html +101 -0
- package/03-patterns/drawer/drawer.css +129 -0
- package/03-patterns/drawer/drawer.js +258 -0
- package/03-patterns/dropdown/README.md +78 -0
- package/03-patterns/dropdown/demo.html +101 -0
- package/03-patterns/dropdown/dropdown.css +135 -0
- package/03-patterns/dropdown/dropdown.js +451 -0
- package/03-patterns/form-validation/README.md +147 -0
- package/03-patterns/form-validation/demo.html +280 -0
- package/03-patterns/form-validation/form-validation.css +263 -0
- package/03-patterns/list/README.md +150 -0
- package/03-patterns/list/demo.html +225 -0
- package/03-patterns/list/flip.js +201 -0
- package/03-patterns/list/list.css +162 -0
- package/03-patterns/nav/README.md +225 -0
- package/03-patterns/nav/demo.html +131 -0
- package/03-patterns/nav/nav.css +314 -0
- package/03-patterns/nav/nav.js +430 -0
- package/03-patterns/nav/toc.js +111 -0
- package/03-patterns/overlay/README.md +196 -0
- package/03-patterns/overlay/demo.html +241 -0
- package/03-patterns/overlay/overlay.css +319 -0
- package/03-patterns/overlay/overlay.js +563 -0
- package/03-patterns/pagination/README.md +114 -0
- package/03-patterns/pagination/demo.html +165 -0
- package/03-patterns/pagination/pagination.css +195 -0
- package/03-patterns/pagination/pagination.js +395 -0
- package/03-patterns/reveal/README.md +91 -0
- package/03-patterns/reveal/demo.html +106 -0
- package/03-patterns/reveal/reveal.css +93 -0
- package/03-patterns/reveal/reveal.js +172 -0
- package/03-patterns/states/README.md +141 -0
- package/03-patterns/states/demo.html +240 -0
- package/03-patterns/states/states.css +252 -0
- package/03-patterns/tabs/README.md +84 -0
- package/03-patterns/tabs/demo.html +139 -0
- package/03-patterns/tabs/tabs.css +172 -0
- package/03-patterns/tabs/tabs.js +307 -0
- package/03-patterns/tooltip/README.md +96 -0
- package/03-patterns/tooltip/demo.html +78 -0
- package/03-patterns/tooltip/tooltip.css +89 -0
- package/03-patterns/tooltip/tooltip.js +288 -0
- package/03-patterns/tree/README.md +94 -0
- package/03-patterns/tree/demo.html +138 -0
- package/03-patterns/tree/tree.css +113 -0
- package/03-patterns/tree/tree.js +456 -0
- package/04-recipes/analysis-report/README.md +80 -0
- package/04-recipes/analysis-report/analysis-report.css +187 -0
- package/04-recipes/analysis-report/demo.html +274 -0
- package/04-recipes/data-showcase/README.md +45 -0
- package/04-recipes/data-showcase/demo.html +247 -0
- package/04-recipes/detail-page/README.md +93 -0
- package/04-recipes/detail-page/demo.html +55 -0
- package/04-recipes/detail-page/detail-page.css +190 -0
- package/04-recipes/detail-page/full.html +60 -0
- package/04-recipes/detail-page/null.html +60 -0
- package/04-recipes/detail-page/partial.html +60 -0
- package/04-recipes/detail-page/verify-skeleton.py +19 -0
- package/04-recipes/longform/README.md +93 -0
- package/04-recipes/longform/agc-memory.svg +4 -0
- package/04-recipes/longform/content.html +610 -0
- package/04-recipes/longform/content.md +51 -0
- package/04-recipes/longform/longform.html +627 -0
- package/04-recipes/report/README.md +176 -0
- package/04-recipes/report/demo.html +355 -0
- package/04-recipes/report/report.css +364 -0
- package/04-recipes/table/README.md +103 -0
- package/04-recipes/table/demo.html +455 -0
- package/04-recipes/table/table.css +372 -0
- package/04-recipes/tierA-tokens.css +189 -0
- package/09-assets/README.md +74 -0
- package/09-assets/bar/README.md +94 -0
- package/09-assets/bar/bar.css +166 -0
- package/09-assets/bar/bar.js +320 -0
- package/09-assets/bar/demo.html +176 -0
- package/09-assets/echarts-adapter/demo.html +192 -0
- package/09-assets/echarts-adapter/echarts-adapter.js +277 -0
- package/09-assets/model-viewer/README.md +155 -0
- package/09-assets/model-viewer/demo.html +105 -0
- package/09-assets/model-viewer/model-viewer.css +143 -0
- package/09-assets/model-viewer/model-viewer.js +423 -0
- package/09-assets/scientific-plot/README.md +94 -0
- package/09-assets/scientific-plot/demo.html +252 -0
- package/09-assets/scientific-plot/scientific-plot.css +141 -0
- package/09-assets/scientific-plot/scientific-plot.js +610 -0
- package/09-assets/sparkline/README.md +153 -0
- package/09-assets/sparkline/demo.html +163 -0
- package/09-assets/sparkline/sparkline.css +158 -0
- package/09-assets/sparkline/sparkline.js +508 -0
- package/API.md +332 -0
- package/CHANGELOG.md +3116 -0
- package/CODE_OF_CONDUCT.md +64 -0
- package/CONTRIBUTING.md +89 -0
- package/ERRORS.md +1658 -0
- package/LICENSE +21 -0
- package/README.md +491 -2
- package/SECURITY.md +72 -0
- package/START-HERE.md +164 -0
- package/SUPPORT.md +109 -0
- package/adapters/presentation/README.md +113 -0
- package/adapters/presentation/check.js +101 -0
- package/adapters/presentation/deck.schema.json +74 -0
- package/adapters/presentation/to-doc.js +138 -0
- package/ai/START-HERE.md +104 -0
- package/ai/behaviors.json +380 -0
- package/ai/behaviors.schema.json +61 -0
- package/ai/capabilities.json +56 -0
- package/ai/cli.js +387 -0
- package/ai/components.json +1944 -0
- package/ai/components.meta.json +168 -0
- package/ai/components.schema.json +220 -0
- package/ai/contract.schema.json +147 -0
- package/ai/deprecations.json +55 -0
- package/ai/deprecations.schema.json +85 -0
- package/ai/motion-policy.json +22 -0
- package/ai/patch.js +323 -0
- package/ai/patch.schema.json +63 -0
- package/ai/profiles.json +92 -0
- package/ai/tokens.audience.json +55 -0
- package/ai/tokens.audience.schema.json +73 -0
- package/ai/tokens.json +762 -0
- package/ai/tokens.schema.json +58 -0
- package/ai/tokens.tree.json +752 -0
- package/ai/tokens.tree.schema.json +56 -0
- package/ai/validate.js +383 -0
- package/dist/01-tokens/behavior/dismissable.js +60 -0
- package/dist/01-tokens/behavior/emit.js +21 -0
- package/dist/01-tokens/behavior/focus-return.js +31 -0
- package/dist/01-tokens/behavior/roving.js +77 -0
- package/dist/01-tokens/behavior/typeahead.js +61 -0
- package/dist/01-tokens/focus-ring.css +1 -0
- package/dist/01-tokens/page.css +1 -0
- package/dist/01-tokens/polyfill.js +78 -0
- package/dist/01-tokens/scrollbar.css +1 -0
- package/dist/01-tokens/theme-toggle.js +61 -0
- package/dist/01-tokens/tokens.css +1 -0
- package/dist/01-tokens/typography.css +1 -0
- package/dist/02-primitives/badge/badge.css +1 -0
- package/dist/02-primitives/button/button.css +1 -0
- package/dist/02-primitives/card/card.css +1 -0
- package/dist/02-primitives/choice/choice.css +1 -0
- package/dist/02-primitives/combobox/combobox.css +1 -0
- package/dist/02-primitives/combobox/combobox.js +439 -0
- package/dist/02-primitives/date-range/date-range.css +1 -0
- package/dist/02-primitives/date-range/date-range.js +267 -0
- package/dist/02-primitives/input/input.css +1 -0
- package/dist/02-primitives/popover/popover.css +1 -0
- package/dist/02-primitives/popover/popover.js +257 -0
- package/dist/02-primitives/progress/progress.css +1 -0
- package/dist/02-primitives/select/select.css +1 -0
- package/dist/02-primitives/select/select.js +449 -0
- package/dist/02-primitives/separator/separator.css +1 -0
- package/dist/02-primitives/skeleton/skeleton.css +1 -0
- package/dist/02-primitives/switch/switch.css +1 -0
- package/dist/03-patterns/accordion/accordion.css +1 -0
- package/dist/03-patterns/accordion/accordion.js +219 -0
- package/dist/03-patterns/content/content.css +1 -0
- package/dist/03-patterns/drawer/drawer.css +1 -0
- package/dist/03-patterns/drawer/drawer.js +229 -0
- package/dist/03-patterns/dropdown/dropdown.css +1 -0
- package/dist/03-patterns/dropdown/dropdown.js +365 -0
- package/dist/03-patterns/form-validation/form-validation.css +1 -0
- package/dist/03-patterns/list/flip.js +117 -0
- package/dist/03-patterns/list/list.css +1 -0
- package/dist/03-patterns/nav/nav.css +1 -0
- package/dist/03-patterns/nav/nav.js +322 -0
- package/dist/03-patterns/nav/toc.js +76 -0
- package/dist/03-patterns/overlay/overlay.css +1 -0
- package/dist/03-patterns/overlay/overlay.js +398 -0
- package/dist/03-patterns/pagination/pagination.css +1 -0
- package/dist/03-patterns/pagination/pagination.js +273 -0
- package/dist/03-patterns/reveal/reveal.css +1 -0
- package/dist/03-patterns/reveal/reveal.js +138 -0
- package/dist/03-patterns/states/states.css +1 -0
- package/dist/03-patterns/tabs/tabs.css +1 -0
- package/dist/03-patterns/tabs/tabs.js +242 -0
- package/dist/03-patterns/tooltip/tooltip.css +1 -0
- package/dist/03-patterns/tooltip/tooltip.js +213 -0
- package/dist/03-patterns/tree/tree.css +1 -0
- package/dist/03-patterns/tree/tree.js +383 -0
- package/dist/04-recipes/analysis-report/analysis-report.css +1 -0
- package/dist/04-recipes/detail-page/detail-page.css +1 -0
- package/dist/04-recipes/report/report.css +1 -0
- package/dist/04-recipes/table/table.css +1 -0
- package/dist/04-recipes/tierA-tokens.css +1 -0
- package/dist/09-assets/bar/bar.css +1 -0
- package/dist/09-assets/bar/bar.js +222 -0
- package/dist/09-assets/echarts-adapter/echarts-adapter.js +185 -0
- package/dist/09-assets/model-viewer/model-viewer.css +1 -0
- package/dist/09-assets/model-viewer/model-viewer.js +320 -0
- package/dist/09-assets/scientific-plot/scientific-plot.css +1 -0
- package/dist/09-assets/scientific-plot/scientific-plot.js +568 -0
- package/dist/09-assets/sparkline/sparkline.css +1 -0
- package/dist/09-assets/sparkline/sparkline.js +265 -0
- package/dist/COSTS.md +56 -0
- package/docs/AI-CONTRACT.md +197 -0
- package/docs/BACKLOG.md +127 -0
- package/docs/BENCHMARK.md +252 -0
- package/docs/GUIDANCE.md +154 -0
- package/docs/INVARIANT.md +372 -0
- package/docs/LAYER-BASELINE.md +158 -0
- package/docs/RELEASING.md +275 -0
- package/docs/RFC-THEME-SCOPE.md +141 -0
- package/docs/ROADMAP.md +182 -0
- package/index.html +82 -0
- package/package.json +107 -4
- package/types/index.d.ts +310 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 frontend-lib contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,492 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frontend-lib
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
移动 Web 组件库。CSS 样式 + 可选行为脚本,**零第三方运行时依赖**。
|
|
4
|
+
|
|
5
|
+
> **npm 包名是 `agentcss`**(`npm install agentcss`)。
|
|
6
|
+
> 仓库名沿用 `frontend-lib`。两者不是一回事:包名是安装标识,仓库名是主页地址。
|
|
7
|
+
|
|
8
|
+
**它同时是给 AI 读的**:`ai/components.json` 里每个组件都有机器可解析的契约
|
|
9
|
+
——可用的类名、状态怎么表达、哪些行为不能漏、成熟度到哪一步。
|
|
10
|
+
人可以直接复制 CSS 用;AI 可以读契约避免凭空猜组件怎么写。
|
|
11
|
+
|
|
12
|
+
## 它解决什么问题
|
|
13
|
+
|
|
14
|
+
移动端页面的三个反复出现的问题:
|
|
15
|
+
|
|
16
|
+
1. **暗色模式**要自己写两套色值 → 这里一套令牌自动适配
|
|
17
|
+
2. **弹层行为**(Esc 关闭、焦点归还、点击外部关闭)每个项目重写一遍 → 这里是可复用的组件
|
|
18
|
+
3. **无障碍**(焦点环、读屏标签、对比度)容易漏 → 这里每个组件都有契约守着
|
|
19
|
+
|
|
20
|
+
## 不是什么
|
|
21
|
+
|
|
22
|
+
- ❌ **不是 UI kit** —— 不做 calendar / upload 那些大而全的东西。
|
|
23
|
+
(`date-range` 是轻量的起止日期选择,不是完整的日历 / 日期选择器;
|
|
24
|
+
完整的 date-picker 请用专门的库)
|
|
25
|
+
- ❌ **不是构建工具** —— 不需要打包器,复制文件就能用
|
|
26
|
+
- ❌ **不是零依赖的 JS 框架** —— 交互组件是**可选**的,纯样式场景不用加载任何 JS
|
|
27
|
+
|
|
28
|
+
## 怎么用它 —— 有选择地用
|
|
29
|
+
|
|
30
|
+
**这是一个可选的工具箱,不是所有页面都必须遵守的规范。**
|
|
31
|
+
|
|
32
|
+
- 挑组件时看**实际实现、demo 和适用场景**,不要只看组件名和成熟度字段。
|
|
33
|
+
- 本库不覆盖你的场景时,**直接用别的做法** —— 不要为了迁就本库而把任务做坏。
|
|
34
|
+
- 改一个**已有网站**时,先看它原有的框架、组件和样式体系,能沿用就沿用;
|
|
35
|
+
本库只在你确实缺一块时补上去。
|
|
36
|
+
- 输出形态不是网页(PPT / 文档 / 邮件)时,本库的网页布局规则**不适用**。
|
|
37
|
+
|
|
38
|
+
`ai/START-HERE.md` 是给 AI 用的短入口(约 90 行),`START-HERE.md`(根目录)是给
|
|
39
|
+
人类复用者的三步清单(组件表由脚本生成,不会漂移)。
|
|
40
|
+
|
|
41
|
+
## 安装
|
|
42
|
+
|
|
43
|
+
**当前状态:npm registry 上没有可安装版本。** 包名 `agentcss` 归本账号
|
|
44
|
+
(0.9.0 曾发布成功、两分钟后被误删,见 `ERRORS.md` E55;0.11.2 的发布卡在
|
|
45
|
+
账号 2FA 的一次性验证码上,见 `docs/RELEASING.md`「发布受阻时」)。
|
|
46
|
+
所以现在有两条**真实可用**的路:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# ① 装**和我们验证过的那一份逐字节一致**的包(GitHub Release 附件,v0.11.2)
|
|
50
|
+
npm install https://github.com/owain323/frontend-lib/releases/download/v0.11.2/agentcss-0.11.2.tgz
|
|
51
|
+
|
|
52
|
+
# ①b 想跟着 master 走
|
|
53
|
+
npm install github:owain323/frontend-lib
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
装出来的目录名仍是 `agentcss`,导入写法与将来发 npm 后**完全一致** ——
|
|
57
|
+
换回 `npm install agentcss` 时不用改任何代码。
|
|
58
|
+
|
|
59
|
+
**② 源码复制**(不想装依赖):把 `01-tokens/` 和需要的组件目录复制进你的项目。
|
|
60
|
+
⚠️ 复制 `dist/` 里的版本,**别复制源码版** —— 源码版有一半以上是给人和 AI 读的注释
|
|
61
|
+
(理由见下面「体积」一节)。
|
|
62
|
+
|
|
63
|
+
> 为什么这里不提前写 `npm install agentcss`:
|
|
64
|
+
> 写了而 registry 上还没有,照做的人会拿到 404,然后以为是自己的环境问题 ——
|
|
65
|
+
> 这与本库曾经踩过的「README 教人装、装到的是别人 2017 年的包」是同一类坑。
|
|
66
|
+
> 发布成功之后这一行才会换上。
|
|
67
|
+
|
|
68
|
+
## 组件一览
|
|
69
|
+
|
|
70
|
+
共 **35** 个(stable 31 / beta 4)。每个组件目录下有 `README.md`(为什么这么做)和 `demo.html`(能直接抄的结构)。
|
|
71
|
+
|
|
72
|
+
### primitives · 基础件(13)
|
|
73
|
+
|
|
74
|
+
| 组件 | 根类名 | 用途 |
|
|
75
|
+
|---|---|---|
|
|
76
|
+
| `badge` | `badge` | 状态标签:计数、分类、结果标记 |
|
|
77
|
+
| `button` | `btn` | 动作触发:主/次/危险/纯文字四档 |
|
|
78
|
+
| `card` | `card` | 内容容器:媒体+正文+操作区三段 |
|
|
79
|
+
| `choice` | `choice` | 单选/多选/原生 select 外观的统一控件 |
|
|
80
|
+
| `combobox` | `combo` | 可搜索 + 可多选标签的输入控件 |
|
|
81
|
+
| `date-range` | `drange` | 日期区间选择,含预设快捷范围 |
|
|
82
|
+
| `input` | `field` | 文本输入及其标签/帮助/错误三件套 |
|
|
83
|
+
| `popover` | `popover` | 锚定到触发元素的浮层 |
|
|
84
|
+
| `progress` | `progress` | 进度条与进度环 |
|
|
85
|
+
| `select` | `select` | 自定义下拉选择(非原生) |
|
|
86
|
+
| `separator` | `separator` | 分隔线,可带中间文字 |
|
|
87
|
+
| `skeleton` | `skeleton` | 加载占位骨架 |
|
|
88
|
+
| `switch` | `switch` | 开关切换 |
|
|
89
|
+
|
|
90
|
+
### patterns · 组合模式(14)
|
|
91
|
+
|
|
92
|
+
| 组件 | 根类名 | 用途 |
|
|
93
|
+
|---|---|---|
|
|
94
|
+
| `accordion` | `accordion` | 可折叠分组 |
|
|
95
|
+
| `content` | `prose` | 长文排版容器(标题/段落/列表/引用/代码) |
|
|
96
|
+
| `drawer` | `drawer` | 侧边抽屉,含遮罩 |
|
|
97
|
+
| `dropdown` | `dd` | 下拉菜单 |
|
|
98
|
+
| `form-validation` | `form` | 表单校验反馈与错误汇总 |
|
|
99
|
+
| `list` | `list` | 键值列表/条目列表 |
|
|
100
|
+
| `nav` | `nav` | 顶部导航与目录 |
|
|
101
|
+
| `overlay` | `toast` | 吐司提示与模态遮罩 |
|
|
102
|
+
| `pagination` | `pagination` | 分页控件 |
|
|
103
|
+
| `reveal` | `reveal` | 入场动效:一个 `data-reveal` 属性管六个方向,**零 JS 也能看** |
|
|
104
|
+
| `states` | `state` | 空/加载/错误/成功四种整块状态 |
|
|
105
|
+
| `tabs` | `tabs` | 选项卡切换 |
|
|
106
|
+
| `tooltip` | `tooltip` | 悬停/聚焦提示 |
|
|
107
|
+
| `tree` | `tree` | 可展开树形结构 |
|
|
108
|
+
|
|
109
|
+
### recipes · 整页配方(4)
|
|
110
|
+
|
|
111
|
+
| 组件 | 根类名 | 用途 |
|
|
112
|
+
|---|---|---|
|
|
113
|
+
| `analysis-report` | `report` | 组合型研究报告页面:正文与辅助栏并排,窄屏自然退回单栏 |
|
|
114
|
+
| `detail-page` | `detail-page` | 实体详情页骨架:字段齐全 / 部分缺失 / 一条数据都没有,三态共用同一套 DOM |
|
|
115
|
+
| `report` | `rep` | 报告版式系统 v1:共享基础 + 三套版式(杂志/科研技术/金融研究),只换一个 … |
|
|
116
|
+
| `table` | `table` | 数据表格:排序/加载/空/错误四态;三种用途预设(财务/学术/统计) |
|
|
117
|
+
|
|
118
|
+
### assets · 可视化(4)
|
|
119
|
+
|
|
120
|
+
| 组件 | 根类名 | 用途 |
|
|
121
|
+
|---|---|---|
|
|
122
|
+
| `bar` | `bar` | 柱状图(charter 13 图表规范):堆叠/分组两种语义、超量程裁剪、图例 |
|
|
123
|
+
| `model-viewer` | `mv` | 3D 模型查看器:令牌驱动样式,不含渲染库本体 |
|
|
124
|
+
| `scientific-plot` | `splot` | 二维科学绘图:折线/区间带/对数轴,纯令牌驱动、零依赖 |
|
|
125
|
+
| `sparkline` | `sparkline` | 迷你趋势图:无坐标轴、纯形状,适合表格内嵌的一行走势 |
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## 用法
|
|
129
|
+
|
|
130
|
+
**1 · 引入样式**(用你的打包器)
|
|
131
|
+
|
|
132
|
+
```js
|
|
133
|
+
import 'agentcss/tokens.css';
|
|
134
|
+
import 'agentcss/typography.css';
|
|
135
|
+
import 'agentcss/primitives/button/button.css';
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**2 · 需要交互组件时**,引入行为脚本
|
|
139
|
+
|
|
140
|
+
行为脚本是 IIFE,挂到 `window` 上(如 `window.Overlay`)。
|
|
141
|
+
|
|
142
|
+
用打包器:
|
|
143
|
+
|
|
144
|
+
```js
|
|
145
|
+
import 'agentcss/patterns/overlay/overlay.js';
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
用 `<script>` 标签(**注意路径是包内的真实目录**):
|
|
149
|
+
|
|
150
|
+
```html
|
|
151
|
+
<!-- npm 不会把 patterns/ 建成目录,必须按 03-patterns/ 写 -->
|
|
152
|
+
<script src="node_modules/agentcss/03-patterns/overlay/overlay.js"></script>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
包内的目录结构与仓库一致:`01-tokens` `02-primitives` `03-patterns`
|
|
156
|
+
`04-recipes` `09-assets`。上例等价于 `import 'agentcss/patterns/overlay/overlay.js'`。
|
|
157
|
+
|
|
158
|
+
**3 · 直接复制**(不想装依赖)
|
|
159
|
+
|
|
160
|
+
复制 `dist/` 里对应的文件进你的项目即可 —— `dist/` 是**去注释但保留格式**的,
|
|
161
|
+
拷过去不会有大段注释挡着。想读取舍理由再回源码目录看。
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
dist/01-tokens/tokens.css ← 拷这个
|
|
165
|
+
01-tokens/tokens.css ← 源码(带 31.6 KB 注释),用于阅读
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
- **别拷源码目录**除非你要读它:全库 CSS 有 66% 是注释(字节口径;字符口径会低报 12 个百分点),`page.css` 一个文件
|
|
169
|
+
12.4 KB 里 10.8 KB 是注释。
|
|
170
|
+
- **JS 也拷 `dist/`**:那一份去了注释但没压缩(理由见「体积」一节)。
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
### 最小可运行页面(纯 HTML,不用打包器)
|
|
175
|
+
|
|
176
|
+
把下面整段存成 `index.html`,放在 `node_modules/` 同级目录,双击打开就是对的:
|
|
177
|
+
|
|
178
|
+
```html
|
|
179
|
+
<!doctype html>
|
|
180
|
+
<html lang="zh-CN">
|
|
181
|
+
<head>
|
|
182
|
+
<meta charset="utf-8">
|
|
183
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
184
|
+
<title>示例</title>
|
|
185
|
+
<link rel="stylesheet" href="node_modules/agentcss/dist/01-tokens/tokens.css">
|
|
186
|
+
<link rel="stylesheet" href="node_modules/agentcss/dist/01-tokens/typography.css">
|
|
187
|
+
<link rel="stylesheet" href="node_modules/agentcss/dist/01-tokens/page.css">
|
|
188
|
+
<link rel="stylesheet" href="node_modules/agentcss/dist/02-primitives/card/card.css">
|
|
189
|
+
<link rel="stylesheet" href="node_modules/agentcss/dist/02-primitives/badge/badge.css">
|
|
190
|
+
<link rel="stylesheet" href="node_modules/agentcss/dist/02-primitives/button/button.css">
|
|
191
|
+
<link rel="stylesheet" href="node_modules/agentcss/dist/02-primitives/input/input.css">
|
|
192
|
+
</head>
|
|
193
|
+
<body class="page">
|
|
194
|
+
<main class="wrap">
|
|
195
|
+
|
|
196
|
+
<h1>我的订单</h1>
|
|
197
|
+
<p class="lede">最近 30 天 · 共 1 笔</p>
|
|
198
|
+
|
|
199
|
+
<div class="card card--interactive">
|
|
200
|
+
<div class="card__body">
|
|
201
|
+
<h3>茅台 2026 年一季报</h3>
|
|
202
|
+
<p class="small">订单号 20261017001</p>
|
|
203
|
+
<span class="badge badge--success">已披露</span>
|
|
204
|
+
</div>
|
|
205
|
+
</div>
|
|
206
|
+
|
|
207
|
+
<div class="field">
|
|
208
|
+
<label class="field__label" for="q">订单号</label>
|
|
209
|
+
<input class="field__input" id="q" type="search" placeholder="输入订单号" inputmode="numeric">
|
|
210
|
+
<span class="field__hint">支持后四位模糊匹配</span>
|
|
211
|
+
</div>
|
|
212
|
+
|
|
213
|
+
<button class="btn btn--md btn--primary">导出</button>
|
|
214
|
+
|
|
215
|
+
</main>
|
|
216
|
+
</body>
|
|
217
|
+
</html>
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
三处最容易写错的地方,模板里已经避开了:
|
|
221
|
+
|
|
222
|
+
| 如果这样写 | 会发生什么 |
|
|
223
|
+
|---|---|
|
|
224
|
+
| `<input class="input">` | **`.input` 不存在**。不报错、不警告,高度变成 21px |
|
|
225
|
+
| 内容直接放 `.card` 里 | `.card` 自身 `padding: 0`,文字**贴边** |
|
|
226
|
+
| 漏掉 `page.css` | `.wrap` / `.lede` 不生效,整页宽度失去约束 |
|
|
227
|
+
|
|
228
|
+
**上生产时**:把 `node_modules/agentcss/dist/` 整个复制到静态目录(比如 `vendor/agentcss/`),
|
|
229
|
+
把上面 7 个 `href` 的前缀换掉。`node_modules` 不会随部署上线。
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## 体积:默认给你的已经是干净产物
|
|
234
|
+
|
|
235
|
+
源码目录(`01-tokens/` `02-primitives/` …)里的 CSS **带着全部注释** —— 实测全库 CSS
|
|
236
|
+
有 **66% 是注释**(354.7 KB 原始里 235.2 KB),`page.css` 单个就有 87%。
|
|
237
|
+
|
|
238
|
+
那些注释是写给你看的取舍理由(为什么这么定、踩过什么坑),不是写给你浏览器看的。
|
|
239
|
+
**注释让你看代码时处处撞墙,构建工具还会把 66% 的字节原样传下去。**
|
|
240
|
+
|
|
241
|
+
⇒ 所以 `import 'agentcss/tokens.css'` **默认给你去注释后的产物**,
|
|
242
|
+
源码版放在 `agentcss/src/*`:
|
|
243
|
+
|
|
244
|
+
| 你写的 | 实际拿到 | tokens 那一项的体积 |
|
|
245
|
+
|---|---|---|
|
|
246
|
+
| `import 'agentcss/tokens.css'` | `dist/01-tokens/tokens.css`(去注释、留格式) | **8.0 KB**(源码是 39.6 KB) |
|
|
247
|
+
| `import 'agentcss/typography.css'` | `dist/01-tokens/typography.css` | **1.1 KB**(源码是 7.1 KB) |
|
|
248
|
+
| `import 'agentcss/src/01-tokens/tokens.css'` | 源码(**带全部注释**) | 39.6 KB |
|
|
249
|
+
|
|
250
|
+
**规则一句话**:默认拿干净的;想读"为什么这么定"就去 `src/`。
|
|
251
|
+
|
|
252
|
+
### 产物只有一份(压缩)+ 源码可读
|
|
253
|
+
|
|
254
|
+
| 产物 | 内容 | 什么时候用 |
|
|
255
|
+
|---|---|---|
|
|
256
|
+
| `dist/**/*.css` | **去注释 + 压缩** | 生产,默认就用这个 |
|
|
257
|
+
| `dist/**/*.js` | 只去注释,**不压缩** | 生产(JS 不压缩的理由见下) |
|
|
258
|
+
| `01-tokens/**` `02-primitives/**` … | 源码,注释齐全 | 想读"为什么这么定"、要 diff |
|
|
259
|
+
|
|
260
|
+
```js
|
|
261
|
+
import 'agentcss/dist/01-tokens/tokens.css'; // 压缩版
|
|
262
|
+
import 'agentcss/dist/02-primitives/button/button.css';
|
|
263
|
+
// 要可读版:import 'agentcss/01-tokens/tokens.css';
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
> ⚠️ **不再有 `*.min.css`**。此前 `dist/` 同时产出 `x.css`(去注释)与 `x.min.css`(压缩),
|
|
267
|
+
> 而源码也在包里 ⇒ 同一批 CSS 出现三次(未压缩 564.4 kB,占解包 19.3%)。
|
|
268
|
+
> 现在 `dist/x.css` **就是压缩版**,路径不变、内容更小;
|
|
269
|
+
> 写死 `x.min.css` 的地方去掉 `.min` 即可。
|
|
270
|
+
|
|
271
|
+
- **`dist/` 是导出物**,可以整个删掉重建(`npm run dist`)。真值永远是源码目录。
|
|
272
|
+
- **JS 不做压缩**:手写压缩器会引入破坏 ES5 语义的风险,收益不抵风险 —— 这一点如实写在这里,
|
|
273
|
+
不假装 min 过。
|
|
274
|
+
- **一致性有门禁守着**:`dist-parity` 把每个产物与源码喂给浏览器的 CSSOM,
|
|
275
|
+
必须解析出**同一份规则集**;`dist-fresh` 防"源码改了但 dist 没重建"。
|
|
276
|
+
|
|
277
|
+
**采纳一个组件到底要付多少**:见 `dist/COSTS.md`(由脚本生成,每个数字都能复算)。
|
|
278
|
+
`tokens` 的 min 版 **2.1 KB gzip**,比任何一个组件自己都贵 —— 那就是"只用一个组件"的真实起步价。
|
|
279
|
+
|
|
280
|
+
**4 · 要成套的页面(可选)** —— 页面骨架
|
|
281
|
+
|
|
282
|
+
`01-tokens/page.css` 是**页面级**的骨架:页面框、内容列宽、标题阶梯、
|
|
283
|
+
行内代码、说明块。**它是选配的**,只有写了 `class="page"` 的页面才生效:
|
|
284
|
+
|
|
285
|
+
```html
|
|
286
|
+
<link rel="stylesheet" href="01-tokens/tokens.css">
|
|
287
|
+
<link rel="stylesheet" href="01-tokens/typography.css">
|
|
288
|
+
<link rel="stylesheet" href="01-tokens/page.css">
|
|
289
|
+
<!-- 骨架要放在组件 CSS 之前:组件靠"后来者同特异性胜出"覆盖骨架,不用 !important -->
|
|
290
|
+
<link rel="stylesheet" href="02-primitives/button/button.css">
|
|
291
|
+
...
|
|
292
|
+
<body class="page">
|
|
293
|
+
<main class="wrap"> <!-- 内容列,宽度 = var(--measure-page) -->
|
|
294
|
+
<h1>标题</h1>
|
|
295
|
+
<p class="lede">导语</p>
|
|
296
|
+
<h2 class="rule-top">带分隔线的小节</h2>
|
|
297
|
+
</main>
|
|
298
|
+
</body>
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
为什么是 `class="page"` 而不是直接给 `body` / `h1` 写规则:
|
|
302
|
+
裸标签选择器的作用域是**整个文档**,会改掉宿主页面自己的同名元素。
|
|
303
|
+
挂一个类名是**显式选配** —— 不写就不生效,库对宿主页面零副作用。
|
|
304
|
+
|
|
305
|
+
要改全局观感,改这几处就够了,**不要在页面里再写一遍**:
|
|
306
|
+
|
|
307
|
+
| 想改什么 | 改哪里 |
|
|
308
|
+
|---|---|
|
|
309
|
+
| 内容列宽 | `--measure-page`(所有 `.wrap` 一起变) |
|
|
310
|
+
| 标题字号 / 字距 | `--fs-2xl` / `--tracking-title` |
|
|
311
|
+
| 页面内边距 | `--sp-6`(页面框)、`--sp-4`(左右下限) |
|
|
312
|
+
| 行内代码底色 | `--surface-sunken` |
|
|
313
|
+
| 说明块 | `--surface-sunken`(`.note--warn` 用 `--warning-bg`) |
|
|
314
|
+
|
|
315
|
+
页面里重写这些选择器**不会报错,但也不会生效**(会被 `.page` 前缀的定义
|
|
316
|
+
以更高特异性静默盖掉,成为死声明)⇒ `05-audit/shell-gate.py` 会拦住它。
|
|
317
|
+
|
|
318
|
+
## 目录
|
|
319
|
+
|
|
320
|
+
| 路径 | 内容 |
|
|
321
|
+
|---|---|
|
|
322
|
+
| `01-tokens/` | 设计令牌(颜色 / 间距 / 字号 / 圆角)、排版基线、页面骨架(`page.css`,选配)、`behavior/` 微行为核 |
|
|
323
|
+
| `02-primitives/` | 基础组件:button / input / select / combobox / date-range 等 |
|
|
324
|
+
| `03-patterns/` | 复合模式:nav / tabs / overlay / list / tree / table 等 |
|
|
325
|
+
| `04-recipes/` | 页面级示例:`longform`(长文排版)· `analysis-report`(组合型研究报告)· `table`(专业数据表格)· `data-showcase`(数据展示能力对照) |
|
|
326
|
+
| `09-assets/` | 图表资产:`sparkline`(迷你趋势线)· `scientific-plot`(二维科学绘图:坐标轴/误差棒/置信区间带/对数轴)· `echarts-adapter`(把令牌喂给 ECharts,按需,本库不含 ECharts) |
|
|
327
|
+
| `ai/` | **机器可读契约**:`components.json` / `tokens.json` / schema / 校验器 / 命令行 |
|
|
328
|
+
| `adapters/` | 场景适配层(如演示文稿),**不进核心** |
|
|
329
|
+
| `benchmark/` | 兼容性基准(10 类编辑意图,当前无模型实测记录) |
|
|
330
|
+
| `docs/` | `INVARIANT.md`(不变式)· `GUIDANCE.md`(建议)· `BENCHMARK.md`(对标) |
|
|
331
|
+
| `types/` | TypeScript 类型定义(描述 `window` 上的全局对象) |
|
|
332
|
+
|
|
333
|
+
## 示例与验证状态
|
|
334
|
+
|
|
335
|
+
### 怎么跑示例
|
|
336
|
+
|
|
337
|
+
```bash
|
|
338
|
+
npm ci
|
|
339
|
+
python -m http.server 8000 # 在仓库根起静态服务
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
| 示例 | 地址 | 展示什么 |
|
|
343
|
+
|---|---|---|
|
|
344
|
+
| 长文排版 | `/04-recipes/longform/longform.html` | 单栏长文的阅读节奏 |
|
|
345
|
+
| 组合型报告 | `/04-recipes/analysis-report/demo.html` | 正文 + 辅助栏并排,窄屏自然退回单栏 |
|
|
346
|
+
| 专业数据表格 | `/04-recipes/table/demo.html` | 列级格式与单位、三种预设、多级表头 |
|
|
347
|
+
| 数据展示对照 | `/04-recipes/data-showcase/demo.html` | 四种数据表达方式各自回答什么问题 |
|
|
348
|
+
| 科学绘图 | `/09-assets/scientific-plot/demo.html` | 坐标轴、误差棒、置信区间带、对数轴 |
|
|
349
|
+
|
|
350
|
+
### 怎么自己验证(不想只信我们的话)
|
|
351
|
+
|
|
352
|
+
```bash
|
|
353
|
+
python -m http.server 8000 & # 🔴 必须先起静态服务:一部分门禁要真浏览器渲染
|
|
354
|
+
bash 05-audit/check-all.sh # 全量门禁约 130 项,本机约 8 分钟
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
每一项的输出是 `PASS` / `FAIL` / `SKIP`,末尾给出失败条数与退出码(全绿为 0)。
|
|
358
|
+
|
|
359
|
+
- **`SKIP` 是真话,不是通过。** 缺依赖的项会明确写"装了才会跑",
|
|
360
|
+
例如 `visual`(逐张比对视觉基线)需要 Pillow:`pip install pillow`。
|
|
361
|
+
真浏览器类门禁需要 `npm ci`。
|
|
362
|
+
- **环境不全时它不会给你假绿。** 忘了起静态服务,真浏览器类门禁会直接报:
|
|
363
|
+
「基线跑不起来(一条 FAIL 都没有):多半是崩了或 8000 端口没有静态服务」。
|
|
364
|
+
—— 这正是本库对"门禁报通过却什么也没查"的处置:**宁可红,不假装绿。**
|
|
365
|
+
- 只跑一项:`python 05-audit/deprecation-gate.py`、`node 05-audit/table-check.js`、
|
|
366
|
+
`node 05-audit/scientific-plot-check.js`。
|
|
367
|
+
- 想看每道门禁**自己有没有牙**:`bash 05-audit/behavior-reverse.sh`
|
|
368
|
+
(对门禁做突变,验证它会红、且只红该红的那一条)。
|
|
369
|
+
- 想知道**我们踩过哪些坑**:`ERRORS.md`。只记真的红过的门禁和真的做错过的事,
|
|
370
|
+
每条写清症状 → 根因 → 纠正规则,规则都能照着执行。
|
|
371
|
+
|
|
372
|
+
### 经过实际验证的
|
|
373
|
+
|
|
374
|
+
- 桌面 Chrome / Edge / Firefox,跑过全量门禁(含真浏览器渲染与无障碍扫描)。
|
|
375
|
+
- 视觉基线在 `10-review/shots/_baseline/`,由 `shot-baseline` 门禁逐张比对。
|
|
376
|
+
- 每个组件的键盘路径 / ARIA / 对比度都有契约守着(`05-audit/` 下百余道检查)。
|
|
377
|
+
- 数据语义有机械断言:例如科学绘图的「缺失值不被当作零」、
|
|
378
|
+
表格的「不按数值大小猜百分比」,都有**反例对照**证明判据有效。
|
|
379
|
+
|
|
380
|
+
### 明确不承诺的
|
|
381
|
+
|
|
382
|
+
- **未在 iOS / Android 真机 WebView 上验证**(见下一节)。
|
|
383
|
+
- 不做虚拟滚动:大表格的行数上限交给调用方判断。
|
|
384
|
+
- 不提供 React / Vue 组件,只提供 CSS 类与可选的行为脚本。
|
|
385
|
+
- `scientific-plot` 不做插值、回归或任何统计计算,也不宣称显著性。
|
|
386
|
+
- 示例页里的数据**全部是演示数据**,不是真实实验结果或业务数据。
|
|
387
|
+
|
|
388
|
+
## 浏览器支持
|
|
389
|
+
|
|
390
|
+
| 环境 | 状态 |
|
|
391
|
+
|---|---|
|
|
392
|
+
| Chrome / Edge(桌面) | 已验证 |
|
|
393
|
+
| Firefox(桌面) | 已验证 |
|
|
394
|
+
| iOS Safari / WKWebView | **未在真机验证** |
|
|
395
|
+
| Android WebView | **未在真机验证** |
|
|
396
|
+
|
|
397
|
+
⚠️ 定位里写「移动 Web」指的是**设计取向**(触控优先、命中区不小于 44px),
|
|
398
|
+
不代表已在真机 WebView 上跑过完整测试。生产前请在自己的目标环境验证。
|
|
399
|
+
|
|
400
|
+
## 主题定制
|
|
401
|
+
|
|
402
|
+
覆盖 CSS 变量即可,不需要重新编译:
|
|
403
|
+
|
|
404
|
+
```css
|
|
405
|
+
:root {
|
|
406
|
+
--accent: #0a7c5a; /* 品牌主色 */
|
|
407
|
+
--r-md: 10px; /* 圆角 */
|
|
408
|
+
--sp-3: 12px; /* 间距 */
|
|
409
|
+
}
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### 明暗模式
|
|
413
|
+
|
|
414
|
+
**CSS 自己表达,不需要 JS**:
|
|
415
|
+
|
|
416
|
+
| 你想要 | 做法 |
|
|
417
|
+
|---|---|
|
|
418
|
+
| 跟随系统 | 什么都不做(默认) |
|
|
419
|
+
| 强制暗 | `<html data-theme="dark">` |
|
|
420
|
+
| 强制亮 | `<html data-theme="light">` |
|
|
421
|
+
|
|
422
|
+
三种都**不加载任何 JS 就成立** —— 这点由 `theme-css` 门禁在真浏览器里守着。
|
|
423
|
+
|
|
424
|
+
想要一个可点的开关时,才加载 `01-tokens/theme-toggle.js`。
|
|
425
|
+
它**只翻属性,不含任何色值**(色值的真值只有一份:`tokens.css`)。
|
|
426
|
+
支持三态:跟随系统 / 亮 / 暗,`window.Theme.set('dark' | 'light' | 'auto')`。
|
|
427
|
+
|
|
428
|
+
⚠️ 因为暗色是纯 CSS 表达的,你的覆盖**不会**被 inline style 压掉
|
|
429
|
+
(旧版靠 JS 写 30 条 inline 属性,那是本库曾经最大的一处设计代价)。
|
|
430
|
+
|
|
431
|
+
## 机器可读契约(给自动化工具用)
|
|
432
|
+
|
|
433
|
+
组件与令牌不只有文档,还有**结构化数据**:
|
|
434
|
+
|
|
435
|
+
```bash
|
|
436
|
+
node ai/cli.js components --maturity=stable # 列出达到 stable 的组件
|
|
437
|
+
node ai/cli.js tokens --mode=dark # 列出暗色令牌
|
|
438
|
+
node ai/cli.js check doc.json # 校验一份**契约文档**(读 JSON)
|
|
439
|
+
node ai/cli.js diff a.json b.json # 两份契约文档按语义 id 比对
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
> ⚠️ `check` / `diff` 吃的是 **JSON 契约文档**,**不解析原始 HTML**。
|
|
443
|
+
> 想校验一个真实页面,请先用契约格式描述它,或直接跑 `npm run gate`
|
|
444
|
+
> (那里有真浏览器,能验的是渲染结果而不是源文件文本)。
|
|
445
|
+
|
|
446
|
+
- `ai/components.json` / `ai/tokens.json` 由源码**生成**(`--check` 已接门禁)
|
|
447
|
+
⇒ 改了源码忘记重新生成就红。真值只有一份,不靠"记得同步"。
|
|
448
|
+
- 组件**成熟度是算出来的**,不是人写的(没人会主动把自己的组件标成 beta)。
|
|
449
|
+
- 档位 `creative / standard / strict` 决定校验严格程度。
|
|
450
|
+
门禁会证明它有鉴别力:同一份文档在 `strict` 下的报错数必须**多于** `creative`。
|
|
451
|
+
- 文档里带未知 `extensions` 时旧版校验器只忽略、不判非法(前向兼容)。
|
|
452
|
+
|
|
453
|
+
## 规范分三层
|
|
454
|
+
|
|
455
|
+
改动本库或写扩展之前,先知道该动哪一层:
|
|
456
|
+
|
|
457
|
+
| 层 | 文件 | 性质 |
|
|
458
|
+
|---|---|---|
|
|
459
|
+
| **不变式** | `docs/INVARIANT.md` | 客观事实,永不变。有门禁守边界 |
|
|
460
|
+
| **契约** | `ai/*.json` + `API.md` | 约定,随版本变 |
|
|
461
|
+
| **建议** | `docs/GUIDANCE.md` | 工作建议,可整份推翻 |
|
|
462
|
+
|
|
463
|
+
约束要放宽时动的是**建议层**,不变式一个字都不用动。
|
|
464
|
+
对标了谁、故意不学谁,见 `docs/BENCHMARK.md`。
|
|
465
|
+
|
|
466
|
+
## 可访问性
|
|
467
|
+
|
|
468
|
+
- 每个组件都有行为契约(键盘路径、ARIA 属性、对比度)
|
|
469
|
+
- 焦点环遵循系统设置,高对比度模式下浏览器会加强
|
|
470
|
+
- 尊重 `prefers-reduced-motion`
|
|
471
|
+
|
|
472
|
+
## 开发
|
|
473
|
+
|
|
474
|
+
```bash
|
|
475
|
+
npm ci # 按锁文件安装
|
|
476
|
+
npm test # 单元测试(约 100ms)
|
|
477
|
+
npm run test:types # 类型契约:正例必过 + 反例必挂
|
|
478
|
+
npm run gate:fast # 静态检查(约 45 秒)
|
|
479
|
+
npm run gate # 全量检查(含浏览器)
|
|
480
|
+
npm run ai -- check path/to/doc.json # 机器可读契约的命令行(读 JSON 文档)
|
|
481
|
+
npm run benchmark # 兼容性基准
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
改代码时跑 `gate:fast` 即可;**提交前**再跑一次 `gate`。
|
|
485
|
+
|
|
486
|
+
类型声明在 `types/index.d.ts`。改动它之前先看
|
|
487
|
+
[docs/ROADMAP.md](docs/ROADMAP.md) 里的「契约类事项」——
|
|
488
|
+
那几项没做完之前,本库还不适合作为长期依赖引入。
|
|
489
|
+
|
|
490
|
+
## 许可
|
|
491
|
+
|
|
492
|
+
MIT
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# 安全策略
|
|
2
|
+
|
|
3
|
+
## 报告漏洞
|
|
4
|
+
|
|
5
|
+
**请不要在 GitHub 上开公开 issue 报告漏洞。**
|
|
6
|
+
|
|
7
|
+
发到私有渠道:[security advisory](https://github.com/owain323/frontend-lib/security/advisories/new)
|
|
8
|
+
|
|
9
|
+
## 我们会怎么回应
|
|
10
|
+
|
|
11
|
+
| 阶段 | 时限 |
|
|
12
|
+
|---|---|
|
|
13
|
+
| 确认收到 | 3 个工作日内 |
|
|
14
|
+
| 初步判断(是否受影响、影响多大) | 10 个工作日内 |
|
|
15
|
+
| 修复发布 | 确认后 30 天内;有人在用且危害高则更快 |
|
|
16
|
+
|
|
17
|
+
超过时限没有回应,你可以直接在 advisory 里催。
|
|
18
|
+
|
|
19
|
+
## 这个库的攻击面有多大
|
|
20
|
+
|
|
21
|
+
说实话很小,但不为零:
|
|
22
|
+
|
|
23
|
+
- **运行时依赖:0 个。** 本库是纯 CSS + 可选行为脚本,`package.json` 的
|
|
24
|
+
`dependencies` 是空的。这意味着常见的供应链攻击(依赖被投毒)在这里没有入口。
|
|
25
|
+
- **构建期依赖**:`package-lock.json` 里是 devDependencies(typescript、puppeteer-core、
|
|
26
|
+
axe-core 等),只在开发和跑门禁时用。它们**不会被使用者安装**。
|
|
27
|
+
- **真实面**:
|
|
28
|
+
- **`combobox` 用 `innerHTML` 渲染,但变量都过了转义** ——
|
|
29
|
+
实测约 235 / 240 / 264 三处,插值全部走本文件内的 `esc()`
|
|
30
|
+
(转义 `& < > "`)。
|
|
31
|
+
⇒ 结论:**传不可信内容进 combobox 是安全的**。
|
|
32
|
+
但这条正确性**只靠这一处 `esc()` 调用撑着,没有门禁守着**
|
|
33
|
+
(`bleed-gate` 查的是内部机制泄漏,不是 XSS)——
|
|
34
|
+
将来谁插一个新字段忘了 `esc()`,没有任何东西会拦住他。这在路线图上。
|
|
35
|
+
- **CSS 注入** —— 把不可信内容插进 `class` 属性时同理(本库不读 `class` 里的值,
|
|
36
|
+
所以这不是可利用路径,只是习惯问题)。
|
|
37
|
+
- **DOM 监听泄漏** —— 组件反复挂载/卸载时可能累积监听(部分组件的 `destroy()`
|
|
38
|
+
正在补齐中,见 CHANGELOG)
|
|
39
|
+
|
|
40
|
+
⇒ 也就是说:**本库不太可能成为供应链攻击的一环**,
|
|
41
|
+
combobox 那处 `innerHTML` 当前是安全的(已转义),但缺一道门禁兜底。
|
|
42
|
+
|
|
43
|
+
## 支持的版本
|
|
44
|
+
|
|
45
|
+
| 版本 | 支持 |
|
|
46
|
+
|---|---|
|
|
47
|
+
| `master` 分支最新 | ✅ |
|
|
48
|
+
| 打过的 tag(`v0.8.8` 起) | ✅ 修安全相关缺陷并回移植 |
|
|
49
|
+
| `v0.8.8` 之前 | ❌ 无 tag、无锚点,无法可靠回溯 |
|
|
50
|
+
|
|
51
|
+
**本库尚未发布到 npm**(`agentcss` 这个名字已实测未被占用,但还没占住)。
|
|
52
|
+
安装方式见 `README.md` 的「安装」一节 —— 里面写的是当前**真实可用**的路径。
|
|
53
|
+
|
|
54
|
+
### 版本与提交点的锚点
|
|
55
|
+
|
|
56
|
+
`v0.8.8` 起每个版本都打 **annotated tag**,由 `release-gate` 的
|
|
57
|
+
`[10] git tag 锚点` 判据守着(它还会核对 tag 指向的提交里 `VERSION`
|
|
58
|
+
就是那个版本 —— 只查"tag 存在"的话,给任意提交打个 tag 也能过)。
|
|
59
|
+
|
|
60
|
+
`v0.8.8` 之前的版本**不补打**:那些提交不在本仓库的可达历史里
|
|
61
|
+
(历史被 squash 过),按日期猜锚点会造出假锚点 —— 比没有锚点更糟。
|
|
62
|
+
|
|
63
|
+
## 关于「无障碍」这个卖点
|
|
64
|
+
|
|
65
|
+
本库把无障碍写进了门禁(焦点可见、读屏标签、对比度)。如果你发现:
|
|
66
|
+
|
|
67
|
+
- 某个组件在键盘下走不通
|
|
68
|
+
- 焦点环看不见
|
|
69
|
+
- 对比度实测不达标
|
|
70
|
+
|
|
71
|
+
这**既是 bug 也是安全问题**(对依赖读屏的用户是阻断性的),请按上面的渠道报告,
|
|
72
|
+
并在标题里写 `a11y`,会优先处理。
|