agentcss 0.25.3 → 0.25.5

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.
@@ -68,8 +68,14 @@ this.btn.addEventListener('click', function () { self.load(); });
68
68
  this.ui.appendChild(this.btn);
69
69
 
70
70
  this.hint = el('p', 'mv__hint');
71
- this.hint.innerHTML = '模型 <code>' + (this.src.split('/').pop() || '—') +
72
- '</code> 会<b>点击后才下载</b>,首屏不占流量。';
71
+
72
+ var fname = el('code', null, this.src.split('/').pop() || '—');
73
+ var strong = el('b', null, '点击后才下载');
74
+ this.hint.appendChild(document.createTextNode('模型 '));
75
+ this.hint.appendChild(fname);
76
+ this.hint.appendChild(document.createTextNode(' 会'));
77
+ this.hint.appendChild(strong);
78
+ this.hint.appendChild(document.createTextNode(',首屏不占流量。'));
73
79
  this.ui.appendChild(this.hint);
74
80
 
75
81
  if (!hasWebGL()) {
@@ -260,6 +266,7 @@ self.raf = requestAnimationFrame(loop);
260
266
  self.ui.innerHTML = '';
261
267
  var cap = el('p', 'mv__cap');
262
268
  var dt = Math.round(((window.performance && performance.now) ? performance.now() : Date.now()) - t0);
269
+
263
270
  cap.innerHTML = '模型 <b>' + fmtKB(bytes || self.lastBytes || 0) + '</b> · 引擎就绪耗时 <b>' + dt + 'ms</b>' +
264
271
  (controls ? ' · 拖动可旋转,滚轮/双指可缩放' : ' · 未加载控制器,无法拖动');
265
272
  self.node.appendChild(cap);
@@ -501,6 +501,7 @@ return String(s == null ? '' : s)
501
501
  legendHtml = '<ul class="splot__legend">' + items.join('') + '</ul>';
502
502
  }
503
503
 
504
+ /* @html-sink internal — svg 由本文件生成,图例名字已过 esc() */
504
505
  el.innerHTML = svg + legendHtml;
505
506
  return {
506
507
  svg: el.firstChild,
package/dist/COSTS.md CHANGED
@@ -22,12 +22,12 @@
22
22
  | primitive | `button` | 2.9 KB | 1.0 KB | — | **3.9 KB** | 28.3 KB | −24.4 KB |
23
23
  | primitive | `card` | 2.9 KB | 0.9 KB | — | **3.9 KB** | 26.0 KB | −22.1 KB |
24
24
  | primitive | `choice` | 2.9 KB | 1.1 KB | — | **4.1 KB** | 28.1 KB | −24.0 KB |
25
- | primitive | `combobox` | 2.9 KB | 1.0 KB | 5.4 KB | **9.3 KB** | 31.4 KB | −22.2 KB |
26
- | primitive | `date-range` | 2.9 KB | 0.8 KB | 2.5 KB | **6.3 KB** | 28.4 KB | −22.1 KB |
25
+ | primitive | `combobox` | 2.9 KB | 1.0 KB | 5.5 KB | **9.4 KB** | 31.5 KB | −22.1 KB |
26
+ | primitive | `date-range` | 2.9 KB | 0.8 KB | 2.6 KB | **6.3 KB** | 28.6 KB | −22.3 KB |
27
27
  | primitive | `delta` | 2.9 KB | 0.3 KB | — | **3.2 KB** | 24.7 KB | −21.5 KB |
28
28
  | primitive | `input` | 2.9 KB | 1.0 KB | — | **4.0 KB** | 25.8 KB | −21.9 KB |
29
29
  | primitive | `metric` | 2.9 KB | 0.5 KB | — | **3.4 KB** | 25.1 KB | −21.7 KB |
30
- | primitive | `popover` | 2.9 KB | 0.8 KB | 2.2 KB | **5.9 KB** | 29.2 KB | −23.3 KB |
30
+ | primitive | `popover` | 2.9 KB | 0.8 KB | 2.2 KB | **5.9 KB** | 29.3 KB | −23.4 KB |
31
31
  | primitive | `progress` | 2.9 KB | 0.8 KB | — | **3.7 KB** | 26.2 KB | −22.5 KB |
32
32
  | primitive | `select` | 2.9 KB | 0.8 KB | 4.1 KB | **7.9 KB** | 32.9 KB | −24.9 KB |
33
33
  | primitive | `separator` | 2.9 KB | 0.2 KB | — | **3.2 KB** | 23.2 KB | −20.0 KB |
@@ -37,7 +37,7 @@
37
37
  | primitive | `upload` | 2.9 KB | 1.4 KB | 4.2 KB | **8.5 KB** | 39.3 KB | −30.8 KB |
38
38
  | pattern | `accordion` | 2.9 KB | 1.3 KB | 1.8 KB | **6.0 KB** | 36.4 KB | −30.4 KB |
39
39
  | pattern | `content` | 2.9 KB | 1.0 KB | — | **4.0 KB** | 26.5 KB | −22.5 KB |
40
- | pattern | `drawer` | 2.9 KB | 0.8 KB | 2.6 KB | **6.3 KB** | 30.1 KB | −23.8 KB |
40
+ | pattern | `drawer` | 2.9 KB | 0.8 KB | 2.6 KB | **6.3 KB** | 30.2 KB | −23.9 KB |
41
41
  | pattern | `dropdown` | 2.9 KB | 0.8 KB | 3.5 KB | **7.2 KB** | 31.6 KB | −24.4 KB |
42
42
  | pattern | `form-validation` | 2.9 KB | 0.8 KB | — | **3.7 KB** | 26.8 KB | −23.1 KB |
43
43
  | pattern | `list` | 2.9 KB | 0.6 KB | — | **3.5 KB** | 24.3 KB | −20.8 KB |
@@ -52,8 +52,8 @@
52
52
 
53
53
  ## 三、全库
54
54
 
55
- - 全部组件都用上(min,含 tokens 一份):**70.4 KB**
56
- - 源码版(带注释)全库 gzip:358.8 KB
55
+ - 全部组件都用上(min,含 tokens 一份):**70.6 KB**
56
+ - 源码版(带注释)全库 gzip:380.1 KB
57
57
 
58
58
  > ⚠️ 源码版那个数字**不是**要付的钱:它包含我们的注释(全库 CSS 有 69% 是注释,字节口径)。
59
59
  > 它的用途只有一个 —— 让人看清"dist 到底省了多少"。
@@ -5,8 +5,8 @@
5
5
 
6
6
  | 项目 | 值 |
7
7
  |---|---|
8
- | 声明适用版本 | agentcss `0.25.3` |
9
- | 声明日期 | 2026-11-03 |
8
+ | 声明适用版本 | agentcss `0.25.5` |
9
+ | 声明日期 | 2026-11-04 |
10
10
  | 复核节奏 | 每次发版前重跑(`npm run gate` 内含全部证据) |
11
11
  | 范围 | 本库交付的 CSS / JS、全部 `demo.html`(组件页 + 图表页 + 组合页)、以及文档站生成的页面 |
12
12
  | 不在范围 | 使用者拿这些组件拼出来的业务页面(那是你的无障碍责任,不是库的) |
@@ -139,14 +139,26 @@
139
139
  所以"未分层"是当前唯一安全的选择。`cascade-layer-gate.py` 把这条变成可判状态:
140
140
  一旦出现第一条 `@layer`,就要求三条前提的实测记录已落档,否则红。
141
141
 
142
- `!important` 现有 10 处,**每一处都必须能被归类**:
142
+ `!important` **每一处都必须能被归类**,归不了类的 ⇒ 红。判据不是"清零" ——
143
+ 清零会逼人删掉无障碍兜底。
143
144
 
144
- | 类别 | 处数 | 为什么必须赢 |
145
- |---|---|---|
146
- | 无障碍偏好(`prefers-reduced-motion`) | 9 | 操作系统级偏好,组件无权推翻 |
147
- | 正确性(`[hidden] { display: none }`) | 1 | 不赢就会"藏不住" |
145
+ | 类别 | 为什么必须赢 |
146
+ |---|---|
147
+ | 无障碍偏好(`prefers-reduced-motion: reduce`) | 操作系统级偏好,组件无权推翻 |
148
+ | 正确性(`[hidden] { display: none }`) | 不赢就会"藏不住" |
149
+ | 打印媒体(`@media print` + `display: none`) | 纸张上没有交互,屏幕专属元素必须真的不出现 |
150
+
151
+ **这里刻意不写"现在有几处"**(I-7:同一个数字有第二个出处,就必然漂移)。
152
+ 要数字就跑门禁,它会把每一类的处数打出来:
153
+
154
+ ```bash
155
+ python 05-audit/cascade-layer-gate.py
156
+ ```
148
157
 
149
- 分不了类的 `!important` ⇒ 红。判据不是"清零"——清零会逼人删掉无障碍兜底。
158
+ > 曾经的教训:这份文档写"10 处(无障碍 9 + `[hidden]` 1)",而门禁当时实测
159
+ > **13 处**——多出来的 2 处是打印媒体,文档连这个类别都没列。
160
+ > 于是按文档去审计的人会把 2 处**判成"说不清"**,而那两处恰恰是正当的。
161
+ > 少写一个类别,比少写一个数字更坏。
150
162
 
151
163
  ## 八 · 对比度与触控的硬线
152
164
 
package/index.html CHANGED
@@ -97,7 +97,7 @@ li a:active { background: var(--surface-sunken); }
97
97
  </p>
98
98
  </main>
99
99
  <footer class="wrap">
100
- <p class="note">0.25.3 · 零第三方运行时依赖</p>
100
+ <p class="note">0.25.5 · 零第三方运行时依赖</p>
101
101
  </footer>
102
102
  </body>
103
103
  </html>
package/llms-full.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  # agentcss — full reference (one file)
2
2
 
3
- > Generated from `ai/components.json` + `ai/pitfalls*.json` + `ai/behaviors.json` at version **0.25.3**.
3
+ > Generated from `ai/components.json` + `ai/pitfalls*.json` + `ai/behaviors.json` at version **0.25.5**.
4
4
  > Do not edit by hand: run `python 05-audit/gen-llms.py` (freshness is gated).
5
5
  > Short version: `llms.txt`. Machine contract: `ai/*.json`.
6
6
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentcss",
3
- "version": "0.25.3",
3
+ "version": "0.25.5",
4
4
  "description": "移动 Web 组件库:CSS + 可选行为脚本,零第三方运行时依赖。样式用 bundler 引入,交互行为用 script 标签引入。",
5
5
  "keywords": [
6
6
  "css",
@@ -23,6 +23,8 @@
23
23
  "default": "./esm/index.mjs"
24
24
  },
25
25
  "./tokens.css": "./dist/01-tokens/tokens.css",
26
+ "./tokens.core.css": "./dist/01-tokens/tokens.core.css",
27
+ "./base.reset.css": "./dist/01-tokens/base.reset.css",
26
28
  "./typography.css": "./dist/01-tokens/typography.css",
27
29
  "./page.css": "./dist/01-tokens/page.css",
28
30
  "./esm": {
package/types/index.d.ts CHANGED
@@ -390,6 +390,114 @@ export interface FlipApi {
390
390
  remove(container: HTMLElement, el: HTMLElement, done?: () => void): void;
391
391
  }
392
392
 
393
+ /* ============================================================================
394
+ * 资产 / 主题:`01-tokens/`、`09-assets/`、`04-recipes/` 的公开对象
395
+ *
396
+ * 🔴 为什么单列一段(0.25.2 的缺陷,0.25.3 补):这 8 个对象都挂在 window 上,
397
+ * 但本文件里一个都没有 ⇒ `window.Theme.set('dark')` 在 TS 项目里直接报
398
+ * "属性不存在",用户只能写 `(window as any).Theme` —— 等于绕过类型系统。
399
+ * 其中 `Upload` 更明显:`esm/upload.mjs` 是**存在**的,运行时能 import,
400
+ * 类型里却看不见。
401
+ *
402
+ * ⚠️ 本文件从前在这里写过一句「behavior-api 门禁核对源码 / esm 入口 /
403
+ * 本文件声明三者集合相等」—— 那句话**不成立**:那道门禁只比源码与 esm/,
404
+ * 从不读本文件(0.25.3 核实过)。现在由 `05-audit/types-globals-gate.py` 判:
405
+ * 源码里每个 `window.X =` / `global.X =` 都必须在这里有声明,
406
+ * 反过来每条声明也必须有源码依据。
407
+ *
408
+ * 为什么这 7 个不给 `export declare const`:`esm/` 里没有它们的包装模块
409
+ * (只有 16 个行为脚本 + upload)。声明一个运行时取不到的具名导出,
410
+ * 正是本库最反对的「幻觉 API」。它们只能走 `window.X`。
411
+ * ========================================================================== */
412
+ export type ThemeMode = 'light' | 'dark' | 'auto';
413
+
414
+ export interface ThemeApi {
415
+ /** 读当前**模式**(不是"现在是深还是浅"):auto 也算一种模式 */
416
+ get(): ThemeMode;
417
+ /** 当前实际渲染是不是深色(auto 模式下由系统决定) */
418
+ isDark(): boolean;
419
+ set(mode: ThemeMode): void;
420
+ toggle(): void;
421
+ /** 三态循环:auto → light → dark → auto */
422
+ cycle(): void;
423
+ }
424
+
425
+ export interface ChartApi {
426
+ draw(el: Element): void;
427
+ /** `draw` 的语义别名:数据变了,重画一次 */
428
+ emit(el: Element): void;
429
+ /** 画一个区域里所有 `.sparkline[data-spark]` */
430
+ update(root?: ParentNode): void;
431
+ /** ⚠️ 只有浏览器支持 ResizeObserver 时才存在(老 WebView 里是 undefined) */
432
+ observe?(el?: Element): void;
433
+ }
434
+
435
+ export interface ChartAdapterPalette {
436
+ accent: string;
437
+ danger: string;
438
+ success: string;
439
+ warn: string;
440
+ info: string;
441
+ [key: string]: string;
442
+ }
443
+
444
+ export interface ChartAdapterApi {
445
+ /** 读某个作用域下的 CSS 变量值(`ctx` 决定用哪套主题) */
446
+ cssVar(name: string, fallback?: string, ctx?: Element): string;
447
+ palette(ctx?: Element): ChartAdapterPalette;
448
+ seriesColors(n: number, p: ChartAdapterPalette): string[];
449
+ /** 生成 ECharts 主题对象;`name` 形如 `fe-light` / `fe-dark` */
450
+ theme(name: string, p?: ChartAdapterPalette | null, ctx?: Element): object;
451
+ themeName(ctx?: Element): string;
452
+ defaults(option?: object, ctx?: Element): object;
453
+ create(dom: HTMLElement, opt?: object): unknown;
454
+ /** 主题切换后重设;主题名变了会重建实例(ECharts 的主题在 init 时绑定) */
455
+ refresh(inst: unknown): unknown;
456
+ }
457
+
458
+ export interface ModelViewerInstance {
459
+ build(): void;
460
+ makeIdle(): void;
461
+ fail(msg?: string): void;
462
+ status(text: string): void;
463
+ load(): void;
464
+ boot(): void;
465
+ initScene(): void;
466
+ }
467
+
468
+ export interface BarApi {
469
+ draw(opt: {
470
+ host: HTMLElement;
471
+ /** 🔴 必填:本库铁律三,量程不得自动适配(漏了会抛错,不会悄悄自适应) */
472
+ max: number;
473
+ series?: unknown[];
474
+ height?: number;
475
+ mode?: 'group' | 'stack';
476
+ }): void;
477
+ }
478
+
479
+ export interface ScientificPlotApi {
480
+ render(el: Element, spec?: object): void;
481
+ /** 判据 / 单测用的真值入口;不承诺稳定,改版可能变 */
482
+ __internals: object;
483
+ }
484
+
485
+ export interface ShellNavInstance {
486
+ /** 已开着就直接返回现有句柄(重复点不该叠两层遮罩) */
487
+ open(): unknown;
488
+ close(): void;
489
+ destroy(): void;
490
+ }
491
+
492
+ export interface UploadInstance {
493
+ /** 收下一批文件(拖放入口,也是公开 API) */
494
+ add(incoming: FileList | File[], dirCount?: number): void;
495
+ render(): void;
496
+ setState(state: string): void;
497
+ setProgress(index: number, pct: number): void;
498
+ removeAt(index: number): void;
499
+ }
500
+
393
501
  /* ============================================================================
394
502
  * 全局命名空间(组件脚本是 IIFE,挂到 window)
395
503
  * ========================================================================== */
@@ -412,6 +520,18 @@ export interface FrontendLibGlobal {
412
520
  Toc: TocApi;
413
521
  Reveal: RevealApi;
414
522
  FLIP: FlipApi;
523
+ /* ---- 资产 / 主题(没有 esm 入口,只能走 window.X) ---- */
524
+ Theme: ThemeApi;
525
+ Chart: ChartApi;
526
+ ChartAdapter: ChartAdapterApi;
527
+ /** construct 形态:`new window.ModelViewer(node)` */
528
+ ModelViewer: new (node: HTMLElement) => ModelViewerInstance;
529
+ Bar: BarApi;
530
+ ScientificPlot: ScientificPlotApi;
531
+ /** construct 形态:`new window.ShellNav(root, opts)` */
532
+ ShellNav: new (root: HTMLElement, opts?: object) => ShellNavInstance;
533
+ /** construct 形态:`new window.Upload(root, opts)` */
534
+ Upload: new (root: HTMLElement, opts?: object) => UploadInstance;
415
535
  }
416
536
 
417
537
  declare global {
@@ -426,7 +546,8 @@ export declare const Dropdown: FrontendLibGlobal['Dropdown'];
426
546
  export declare const Tree: FrontendLibGlobal['Tree'];
427
547
  /* 与 `global.X = …` 一一对应(16 个行为脚本全部覆盖)。
428
548
  证据:`esm/` 下的 16 个 .mjs 由 `05-audit/gen-esm.py` 从源码生成,
429
- `behavior-api` 门禁核对「源码导出 / esm 入口 / 本文件声明」三者集合相等。 */
549
+ `behavior-api` 门禁核对「源码导出 ↔ esm 入口」两者集合相等
550
+ (⚠️ 它**不读本文件**;本文件的声明由 `types-globals-gate.py` 判)。 */
430
551
  export declare const Accordion: FrontendLibGlobal['Accordion'];
431
552
  export declare const Tabs: FrontendLibGlobal['Tabs'];
432
553
  export declare const Nav: FrontendLibGlobal['Nav'];
@@ -437,4 +558,7 @@ export declare const Tooltip: TooltipApi;
437
558
  export declare const Popover: PopoverApi;
438
559
  export declare const Toc: TocApi;
439
560
  export declare const Reveal: RevealApi;
440
- export declare const FLIP: FlipApi;
561
+ export declare const FLIP: FlipApi;
562
+ /* Upload 有 esm 入口(`esm/upload.mjs`)⇒ 可以具名导出;
563
+ 其余 7 个资产/主题对象没有包装模块,只在 FrontendLibGlobal 里声明。 */
564
+ export declare const Upload: FrontendLibGlobal['Upload'];