agentcss 0.25.6 → 0.26.0
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/behavior/labels.js +44 -0
- package/02-primitives/combobox/combobox.js +26 -3
- package/02-primitives/date-range/date-range.js +27 -5
- package/02-primitives/popover/popover.js +22 -2
- package/02-primitives/select/select.js +23 -2
- package/02-primitives/upload/upload.js +50 -17
- package/03-patterns/content/content.css +13 -1
- package/03-patterns/content/demo.html +1 -1
- package/03-patterns/drawer/drawer.js +44 -6
- package/03-patterns/dropdown/dropdown.js +21 -1
- package/03-patterns/overlay/overlay.js +39 -2
- package/03-patterns/pagination/pagination.js +37 -10
- package/03-patterns/tooltip/tooltip.js +17 -2
- package/03-patterns/tree/tree.js +21 -1
- package/04-recipes/analysis-report/demo.html +1 -1
- package/04-recipes/data-showcase/demo.html +2 -2
- package/04-recipes/longform/content.html +989 -74
- package/04-recipes/longform/longform.html +3 -3
- package/04-recipes/report/demo.html +1 -1
- package/04-recipes/table/README.md +22 -0
- package/04-recipes/table/demo.html +6 -6
- package/09-assets/bar/bar.js +28 -4
- package/09-assets/model-viewer/model-viewer.js +44 -12
- package/09-assets/scientific-plot/demo.html +6 -6
- package/API.md +32 -0
- package/CHANGELOG.md +71 -0
- package/README.md +17 -0
- package/README.zh-CN.md +16 -0
- package/SECURITY.md +16 -4
- package/START-HERE.md +14 -14
- package/ai/components.json +9 -4
- package/ai/pdf.js +50 -8
- package/dist/01-tokens/behavior/labels.js +11 -0
- package/dist/02-primitives/combobox/combobox.js +25 -3
- package/dist/02-primitives/date-range/date-range.js +26 -5
- package/dist/02-primitives/popover/popover.js +14 -1
- package/dist/02-primitives/select/select.js +22 -2
- package/dist/02-primitives/upload/upload.js +47 -17
- package/dist/03-patterns/content/content.css +1 -1
- package/dist/03-patterns/drawer/drawer.js +32 -4
- package/dist/03-patterns/dropdown/dropdown.js +20 -1
- package/dist/03-patterns/overlay/overlay.js +25 -1
- package/dist/03-patterns/pagination/pagination.js +34 -10
- package/dist/03-patterns/tooltip/tooltip.js +14 -2
- package/dist/03-patterns/tree/tree.js +20 -1
- package/dist/09-assets/bar/bar.js +23 -4
- package/dist/09-assets/model-viewer/model-viewer.js +38 -12
- package/dist/COSTS.md +14 -14
- package/docs/ACCESSIBILITY.md +2 -2
- package/docs/L10N.md +92 -0
- package/docs/RELEASE-PROCESS.md +7 -1
- package/docs/VERIFY-RELEASE.md +7 -2
- package/index.html +1 -1
- package/llms-full.txt +2 -2
- package/package.json +3 -2
- package/types/index.d.ts +218 -13
|
@@ -479,7 +479,7 @@ th {
|
|
|
479
479
|
哪怕会覆盖掉别人写的东西。
|
|
480
480
|
</p>
|
|
481
481
|
|
|
482
|
-
<div class="table-wrap">
|
|
482
|
+
<div class="table-wrap" tabindex="0" role="region" aria-label="对照表(可横向滚动)">
|
|
483
483
|
<table>
|
|
484
484
|
<colgroup>
|
|
485
485
|
<col style="width: 34%">
|
|
@@ -520,7 +520,7 @@ th {
|
|
|
520
520
|
这套机制加上"准入控制",让关键任务(姿态、点火)不会被普通计算饿死。
|
|
521
521
|
</p>
|
|
522
522
|
|
|
523
|
-
<pre><code><span class="c-cmt"># 不是原文,是按手册重述的伪代码</span>
|
|
523
|
+
<pre tabindex="0"><code><span class="c-cmt"># 不是原文,是按手册重述的伪代码</span>
|
|
524
524
|
if computer_overload():
|
|
525
525
|
issue(1202) <span class="c-cmt"># 告警编号写入 AGC 计数区</span>
|
|
526
526
|
<span class="c-cmt"># 不停机:停机会丢掉姿态信息,地面将失去唯一的实时数据源</span>
|
|
@@ -540,7 +540,7 @@ if computer_overload():
|
|
|
540
540
|
包括读取真实的操作数、写入真实的寄存器地址。
|
|
541
541
|
</p>
|
|
542
542
|
|
|
543
|
-
<pre><code><span class="c-cmt"># 一段能真正跑起来的最小例子</span>
|
|
543
|
+
<pre tabindex="0"><code><span class="c-cmt"># 一段能真正跑起来的最小例子</span>
|
|
544
544
|
<span class="c-out">$</span> python3 -m agc --help
|
|
545
545
|
<span class="c-out">$</span> ./yaAGC -t demo.agc <span class="c-cmt"># 载入磁带并执行</span>
|
|
546
546
|
<span class="c-out">AGC 0000 GO</span></code></pre>
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
<!-- ======================================================================== -->
|
|
33
33
|
<h2 class="rule-top">先看取舍:三套版式各自放弃了什么</h2>
|
|
34
34
|
|
|
35
|
-
<div class="table"><table>
|
|
35
|
+
<div class="table" tabindex="0" role="region" aria-label="三种 profile 的结构差异(可横向滚动)"><table>
|
|
36
36
|
<caption class="table__cap">表 A · 三种 profile 的结构差异(判据可验证,不是文案差异)</caption>
|
|
37
37
|
<thead><tr>
|
|
38
38
|
<th scope="col">profile</th>
|
|
@@ -65,6 +65,28 @@ var COLS = [
|
|
|
65
65
|
|
|
66
66
|
## 无障碍
|
|
67
67
|
|
|
68
|
+
- **滚动容器必须能用键盘进入。** `.table` 是 `overflow:auto` 的二维滚动区域,
|
|
69
|
+
窄屏下会横向滚动;**纯 CSS 无法让它被 Tab 到**,必须在标记上给入口:
|
|
70
|
+
|
|
71
|
+
```html
|
|
72
|
+
<div class="table table--financial" tabindex="0" role="region"
|
|
73
|
+
aria-label="A 股样例数据(可横向滚动)">
|
|
74
|
+
<table>…</table>
|
|
75
|
+
</div>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
三个属性缺一不可:`tabindex="0"`(进 Tab 序列)、`role="region"`(成为可命名地标)、
|
|
79
|
+
`aria-label`(读屏要念出"这是什么表")。少了它们的后果是:只用键盘的用户
|
|
80
|
+
和部分读屏用户**看不到超出可视区的列**(WCAG 2.1.1)。
|
|
81
|
+
名字里带上 **「(可横向滚动)」**:只说"什么表"不告诉用户这里能滚,
|
|
82
|
+
焦点停上来时读屏不会提示还有更多列 —— 那正是这条规则要解决的问题。
|
|
83
|
+
图/图表容器同理,但名字应来自图注(`aria-labelledby` 指向 `<figcaption>`),
|
|
84
|
+
不要再手写一份同名文案(同一事实不留第二出处)。
|
|
85
|
+
> 这条由两道门禁守着:`table-check.js` ⑮ 在 320px 下逐个量「会滚的容器有没有入口」,
|
|
86
|
+
> `a11y-scan.js` 在同一个页面上补跑 320px 的 `scrollable-region-focusable`。
|
|
87
|
+
> 桌面宽(1280)下表格不溢出,那条 axe 规则根本不会触发 —— 所以窄屏必须单独判。
|
|
88
|
+
> ⚠️ 只有**真的会滚**的容器需要 `tabindex`;不滚的容器加上去只是多一个空的 Tab 停靠点。
|
|
89
|
+
|
|
68
90
|
- 数据表用 `<th scope="col">` / `<th scope="row">`;多级表头第一层用 `scope="colgroup"`。
|
|
69
91
|
复杂表格可用 `id` + `headers` 建立显式关联(本示例未用到,但结构支持)。
|
|
70
92
|
- 排序状态放在 `<th aria-sort="ascending|descending">`,**不是**放在按钮上。
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
<strong>空格子和 0 是两件事</strong>:空格子读者分不清"没有数据"还是"漏了",
|
|
132
132
|
0 会被当成真实数值参与心算。
|
|
133
133
|
</p>
|
|
134
|
-
<div class="table table--compact">
|
|
134
|
+
<div class="table table--compact" tabindex="0" role="region" aria-label="银行对账明细(可横向滚动)">
|
|
135
135
|
<table>
|
|
136
136
|
<caption class="table__cap">表 G · 银行对账明细(示例,含缺失值)</caption>
|
|
137
137
|
<thead>
|
|
@@ -353,7 +353,7 @@
|
|
|
353
353
|
});
|
|
354
354
|
}
|
|
355
355
|
|
|
356
|
-
var h = '<div class="table table--financial"><table>' +
|
|
356
|
+
var h = '<div class="table table--financial" tabindex="0" role="region" aria-label="A 股样例数据(可横向滚动)"><table>' +
|
|
357
357
|
'<caption class="table__cap">A 股样例数据(非真实财报,量级参照公开年报)· ' +
|
|
358
358
|
'金额单位:万元 · 比率为比例值</caption>' +
|
|
359
359
|
'<thead><tr>';
|
|
@@ -425,7 +425,7 @@
|
|
|
425
425
|
{ label: '时效 (150 °C)', key: 'h150' }
|
|
426
426
|
];
|
|
427
427
|
|
|
428
|
-
var a = '<div class="table table--academic"><table>' +
|
|
428
|
+
var a = '<div class="table table--academic" tabindex="0" role="region" aria-label="时效温度对铝合金拉伸性能的影响(可横向滚动)"><table>' +
|
|
429
429
|
'<caption class="table__cap">表 1 · 不同时效温度下铝合金的拉伸性能(示例数据)</caption>' +
|
|
430
430
|
'<thead><tr><th scope="col" rowspan="2">合金牌号</th>';
|
|
431
431
|
GROUPS.forEach(function (g) {
|
|
@@ -472,7 +472,7 @@
|
|
|
472
472
|
return fixed(p, 3).replace(/^0\./, '.');
|
|
473
473
|
}
|
|
474
474
|
|
|
475
|
-
var s = '<div class="table table--stats"><table>' +
|
|
475
|
+
var s = '<div class="table table--stats" tabindex="0" role="region" aria-label="OLS 估计结果(可横向滚动)"><table>' +
|
|
476
476
|
'<caption class="table__cap">表 2 · 处理效应的 OLS 估计(示例数据,n = 412)</caption>' +
|
|
477
477
|
'<thead><tr>' +
|
|
478
478
|
'<th scope="col">项</th>' +
|
|
@@ -512,7 +512,7 @@
|
|
|
512
512
|
why: '缺失 ⇒ 显示 —,不是 0,也不带符号' }
|
|
513
513
|
];
|
|
514
514
|
|
|
515
|
-
var p = '<div class="table"><table>' +
|
|
515
|
+
var p = '<div class="table" tabindex="0" role="region" aria-label="同一个数在不同列定义下的显示(可横向滚动)"><table>' +
|
|
516
516
|
'<caption class="table__cap">同一个数、不同的列定义 ⇒ 不同的显示</caption>' +
|
|
517
517
|
'<thead><tr><th scope="col">列定义</th><th scope="col">输入</th>' +
|
|
518
518
|
'<th scope="col">渲染结果</th><th scope="col">为什么</th></tr></thead><tbody>';
|
|
@@ -547,7 +547,7 @@
|
|
|
547
547
|
expect: '显示为字面字符' }
|
|
548
548
|
];
|
|
549
549
|
|
|
550
|
-
var e2 = '<div class="table"><table>' +
|
|
550
|
+
var e2 = '<div class="table" tabindex="0" role="region" aria-label="转义演示:动态文本按文本渲染(可横向滚动)"><table>' +
|
|
551
551
|
'<caption class="table__cap">动态文本按**文本**渲染,不当 HTML 解释</caption>' +
|
|
552
552
|
'<thead><tr><th scope="col">列定义</th><th scope="col">原始数据</th>' +
|
|
553
553
|
'<th scope="col">渲染结果</th><th scope="col">验收点</th></tr></thead><tbody>';
|
package/09-assets/bar/bar.js
CHANGED
|
@@ -95,9 +95,35 @@
|
|
|
95
95
|
* 并且只画(画布内的那一部分),不能画到坐标系外面去
|
|
96
96
|
* ③ **标注跟着堆叠顶端走**:标签写的是**该列合计**,不是第一个系列的值
|
|
97
97
|
*/
|
|
98
|
+
/* 可见文案默认值(F2 / 0.26.0)。
|
|
99
|
+
⚠️ 这里用 `opt.text` 而不是 `labels` —— `bar.draw` 的 `labels`
|
|
100
|
+
早就是「X 轴标签」这个**数据**参数,改名是破坏性变更。
|
|
101
|
+
同类情况全库只此一处,已在 docs/L10N.md 写明。 */
|
|
102
|
+
var DEFAULT_TEXT = {
|
|
103
|
+
series: function (i) { return '系列 ' + i; },
|
|
104
|
+
clipped: function (n, isStack, max) {
|
|
105
|
+
return '有 ' + n + ' 个' + (isStack ? '类目的合计' : '数据')
|
|
106
|
+
+ '超出量程(上限 ' + max + '),已按上限截断显示。';
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
/* ==== BEHAVIOR INJECT BEGIN: labels ==== */
|
|
111
|
+
var flLabels = function (defaults, src) {
|
|
112
|
+
src = src || {};
|
|
113
|
+
var out = {};
|
|
114
|
+
var k;
|
|
115
|
+
for (k in defaults) {
|
|
116
|
+
if (Object.prototype.hasOwnProperty.call(defaults, k)) {
|
|
117
|
+
out[k] = (src[k] === undefined || src[k] === null) ? defaults[k] : src[k];
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return out;
|
|
121
|
+
};
|
|
122
|
+
/* ==== BEHAVIOR INJECT END: labels ==== */
|
|
98
123
|
function draw(opt) {
|
|
99
124
|
opt = opt || {};
|
|
100
125
|
var host = opt.host;
|
|
126
|
+
var T = flLabels(DEFAULT_TEXT, opt && opt.text);
|
|
101
127
|
if (!host) throw new Error('bar.draw: 缺少 host');
|
|
102
128
|
if (opt.max === undefined || opt.max === null) {
|
|
103
129
|
/* 🔴 铁律三:不替调用方决定量程。
|
|
@@ -286,7 +312,7 @@
|
|
|
286
312
|
/* 🔴 用 textContent,不用 innerHTML —— 系列名来自调用方的数据 */
|
|
287
313
|
li.appendChild(sw);
|
|
288
314
|
var tx = document.createElement('span');
|
|
289
|
-
tx.textContent = se.name || (
|
|
315
|
+
tx.textContent = se.name || T.series(si + 1);
|
|
290
316
|
li.appendChild(tx);
|
|
291
317
|
legendEl.appendChild(li);
|
|
292
318
|
});
|
|
@@ -302,9 +328,7 @@
|
|
|
302
328
|
} else if (clipped.length) {
|
|
303
329
|
var p2 = document.createElement('p');
|
|
304
330
|
p2.className = 'bar__note';
|
|
305
|
-
p2.textContent =
|
|
306
|
-
(mode === 'stack' ? '类目的合计' : '数据') +
|
|
307
|
-
'超出量程(上限 ' + max + '),已按上限截断显示。';
|
|
331
|
+
p2.textContent = T.clipped(clipped.length, mode === 'stack', max);
|
|
308
332
|
host.appendChild(p2);
|
|
309
333
|
}
|
|
310
334
|
|
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
n.appendChild(this.ui);
|
|
111
111
|
|
|
112
112
|
// 加载按钮
|
|
113
|
-
this.btn = el('button', 'mv__btn',
|
|
113
|
+
this.btn = el('button', 'mv__btn', LABELS.load);
|
|
114
114
|
this.btn.type = 'button';
|
|
115
115
|
this.btn.addEventListener('click', function () { self.load(); });
|
|
116
116
|
this.ui.appendChild(this.btn);
|
|
@@ -120,23 +120,23 @@
|
|
|
120
120
|
原来用 innerHTML 直接拼 ⇒ `<img onerror>` 这类值会被解析成节点。
|
|
121
121
|
改成 textContent 组装:`<code>` 与 `<b>` 仍然存在,但文本永远只是文本。 */
|
|
122
122
|
var fname = el('code', null, this.src.split('/').pop() || '—');
|
|
123
|
-
var strong = el('b', null,
|
|
124
|
-
this.hint.appendChild(document.createTextNode(
|
|
123
|
+
var strong = el('b', null, LABELS.hintStrong);
|
|
124
|
+
this.hint.appendChild(document.createTextNode(LABELS.hintBefore));
|
|
125
125
|
this.hint.appendChild(fname);
|
|
126
|
-
this.hint.appendChild(document.createTextNode(
|
|
126
|
+
this.hint.appendChild(document.createTextNode(LABELS.hintBetween));
|
|
127
127
|
this.hint.appendChild(strong);
|
|
128
|
-
this.hint.appendChild(document.createTextNode(
|
|
128
|
+
this.hint.appendChild(document.createTextNode(LABELS.hintTail));
|
|
129
129
|
this.ui.appendChild(this.hint);
|
|
130
130
|
|
|
131
131
|
if (!hasWebGL()) {
|
|
132
|
-
this.fail(
|
|
132
|
+
this.fail(LABELS.noWebGL);
|
|
133
133
|
this.btn.disabled = true;
|
|
134
134
|
}
|
|
135
135
|
};
|
|
136
136
|
|
|
137
137
|
Viewer.prototype.makeIdle = function () {
|
|
138
138
|
var box = el('div', 'mv__stage');
|
|
139
|
-
box.appendChild(el('div', 'mv__ph',
|
|
139
|
+
box.appendChild(el('div', 'mv__ph', LABELS.placeholder));
|
|
140
140
|
return box;
|
|
141
141
|
};
|
|
142
142
|
|
|
@@ -146,14 +146,14 @@
|
|
|
146
146
|
this.state = 'error';
|
|
147
147
|
this.ui.innerHTML = '';
|
|
148
148
|
var s = el('div', 'mv__stage mv__stage--err');
|
|
149
|
-
s.appendChild(el('div', 'mv__ph',
|
|
149
|
+
s.appendChild(el('div', 'mv__ph', LABELS.placeholder));
|
|
150
150
|
var p = el('p', 'mv__err', msg);
|
|
151
151
|
s.appendChild(p);
|
|
152
152
|
this.ui.appendChild(s);
|
|
153
153
|
if (this.btn) this.ui.appendChild(this.btn);
|
|
154
154
|
if (this.btn) {
|
|
155
155
|
this.btn.disabled = false;
|
|
156
|
-
this.btn.textContent =
|
|
156
|
+
this.btn.textContent = LABELS.retry;
|
|
157
157
|
}
|
|
158
158
|
};
|
|
159
159
|
|
|
@@ -169,12 +169,12 @@
|
|
|
169
169
|
|
|
170
170
|
this.ui.innerHTML = '';
|
|
171
171
|
var stage = el('div', 'mv__stage');
|
|
172
|
-
this.statusNode = el('p', 'mv__status',
|
|
172
|
+
this.statusNode = el('p', 'mv__status', LABELS.preparing);
|
|
173
173
|
stage.appendChild(this.statusNode);
|
|
174
174
|
this.ui.appendChild(stage);
|
|
175
175
|
|
|
176
176
|
var t0 = (window.performance && performance.now) ? performance.now() : Date.now();
|
|
177
|
-
this.status(
|
|
177
|
+
this.status(LABELS.preparingEngine);
|
|
178
178
|
this.boot(null, t0, 0);
|
|
179
179
|
|
|
180
180
|
/* 🔴🔴 **超时兜底**(实测:服务器上会卡死在 loading)
|
|
@@ -296,7 +296,7 @@
|
|
|
296
296
|
xhr.onprogress = function (e) {
|
|
297
297
|
if (e.lengthComputable && e.total) {
|
|
298
298
|
self1.lastBytes = e.total;
|
|
299
|
-
self1.status(
|
|
299
|
+
self1.status(LABELS.downloading(Math.round(e.loaded / e.total * 100)));
|
|
300
300
|
}
|
|
301
301
|
};
|
|
302
302
|
xhr.onload = function () {
|
|
@@ -396,6 +396,36 @@
|
|
|
396
396
|
|
|
397
397
|
/* ---------- 对外 API ---------- */
|
|
398
398
|
|
|
399
|
+
/* 可见 / 读屏文案(F2 / 0.26.0)。
|
|
400
|
+
本组件由 `[data-mv]` 自动初始化、没有逐实例 opts ⇒ 用**模块级**设置:
|
|
401
|
+
`ModelViewer.setLabels({ load: 'Load 3D model', ... })`
|
|
402
|
+
⚠️ 已知仍未覆盖的(列在 docs/L10N.md,不假装已做完):
|
|
403
|
+
`mv__cap` 的说明句、`fail()` 的几条错误句 ——
|
|
404
|
+
它们含 `<b>` 结构与多个动态量,要改成节点拼装才能安全本地化。 */
|
|
405
|
+
var LABELS = {
|
|
406
|
+
load: '加载 3D 模型',
|
|
407
|
+
placeholder: '3D 模型',
|
|
408
|
+
retry: '重试',
|
|
409
|
+
preparing: '正在准备…',
|
|
410
|
+
preparingEngine: '正在准备 3D 引擎…',
|
|
411
|
+
hintBefore: '模型 ',
|
|
412
|
+
hintBetween: ' 会',
|
|
413
|
+
hintStrong: '点击后才下载',
|
|
414
|
+
hintTail: ',首屏不占流量。',
|
|
415
|
+
downloading: function (pct) { return '正在下载模型 ' + pct + '%'; },
|
|
416
|
+
noWebGL: '这台设备的浏览器不支持 WebGL,无法显示 3D 模型。'
|
|
417
|
+
};
|
|
418
|
+
|
|
419
|
+
function setLabels(patch) {
|
|
420
|
+
if (!patch) return;
|
|
421
|
+
for (var k in LABELS) {
|
|
422
|
+
if (Object.prototype.hasOwnProperty.call(LABELS, k)
|
|
423
|
+
&& patch[k] !== undefined && patch[k] !== null) {
|
|
424
|
+
LABELS[k] = patch[k];
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
399
429
|
var ModelViewer = {
|
|
400
430
|
/** 扫描并初始化页面里的所有查看器 */
|
|
401
431
|
update: function (root) {
|
|
@@ -421,6 +451,8 @@
|
|
|
421
451
|
},
|
|
422
452
|
};
|
|
423
453
|
|
|
454
|
+
ModelViewer.setLabels = setLabels;
|
|
455
|
+
|
|
424
456
|
if (typeof window !== 'undefined') window.ModelViewer = ModelViewer;
|
|
425
457
|
|
|
426
458
|
// @autoinit: [data-mv] —— 扫属性自动 update()(详见 API.md「自动初始化」)
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
本模块<strong>不做表达式求值</strong>。
|
|
40
40
|
</p>
|
|
41
41
|
<figure class="fig">
|
|
42
|
-
<div class="fig__box" id="fig1"></div>
|
|
43
|
-
<figcaption class="fig__cap">
|
|
42
|
+
<div class="fig__box" id="fig1" tabindex="0" role="region" aria-labelledby="fig1-cap"></div>
|
|
43
|
+
<figcaption class="fig__cap" id="fig1-cap">
|
|
44
44
|
图 1 · 阻尼振荡位移随时间的变化。A = 1.00 m,λ = 0.35 s⁻¹,f = 1.20 Hz。
|
|
45
45
|
</figcaption>
|
|
46
46
|
</figure>
|
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
也不据此推断显著性 —— 这两件事必须由测量者说清楚。
|
|
53
53
|
</p>
|
|
54
54
|
<figure class="fig">
|
|
55
|
-
<div class="fig__box" id="fig2"></div>
|
|
56
|
-
<figcaption class="fig__cap">
|
|
55
|
+
<div class="fig__box" id="fig2" tabindex="0" role="region" aria-labelledby="fig2-cap"></div>
|
|
56
|
+
<figcaption class="fig__cap" id="fig2-cap">
|
|
57
57
|
图 2 · 五种催化剂在不同温度下的转化率(示例数据,误差棒为 ±1 个测量标准差)。
|
|
58
58
|
</figcaption>
|
|
59
59
|
</figure>
|
|
@@ -105,11 +105,11 @@
|
|
|
105
105
|
后者画出的是一段<strong>不存在的趋势</strong>。
|
|
106
106
|
</p>
|
|
107
107
|
<figure class="fig">
|
|
108
|
-
<div class="fig__box" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:var(--sp-3)">
|
|
108
|
+
<div class="fig__box" tabindex="0" role="region" aria-labelledby="figgap-cap" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:var(--sp-3)">
|
|
109
109
|
<div id="figGap"></div>
|
|
110
110
|
<div id="figZero"></div>
|
|
111
111
|
</div>
|
|
112
|
-
<figcaption class="fig__cap">
|
|
112
|
+
<figcaption class="fig__cap" id="figgap-cap">
|
|
113
113
|
图 5 · 同一组数据,两种缺失处理。左:缺失断开(正确)。右:缺失当 0(错误,仅用于对照)。
|
|
114
114
|
</figcaption>
|
|
115
115
|
</figure>
|
package/API.md
CHANGED
|
@@ -376,6 +376,38 @@ python3 05-audit/prefix-build.py --prefix fl
|
|
|
376
376
|
|
|
377
377
|
---
|
|
378
378
|
|
|
379
|
+
## 文案本地化(0.26.0 起)
|
|
380
|
+
|
|
381
|
+
**库默认输出中文;`labels` 可覆盖用户可见 / 读屏会念到的文案。**
|
|
382
|
+
|
|
383
|
+
```js
|
|
384
|
+
Pagination.create(node, { labels: { prev: 'Previous', next: 'Next' } });
|
|
385
|
+
Overlay.toast({ title: 'Saved', labels: { closeToast: 'Dismiss' } });
|
|
386
|
+
Tooltip.setLabels({ region: 'Tooltip' }); // 模块级(属性初始化,无逐实例 opts)
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
- 值可以是字符串或函数(动态量用函数:`page(p, isCurrent)`、`uploading(pct)`)。
|
|
390
|
+
- **不传时输出与 0.25.x 逐字相同** —— 升级补丁版本不会换掉界面语言。
|
|
391
|
+
- `bar.draw` 是唯一例外:`labels` 已是「X 轴标签」这个**数据**参数,
|
|
392
|
+
它的文案覆盖叫 `text`。
|
|
393
|
+
- 开发期错误信息(`throw new Error`)**不在覆盖范围**,它们不经过 UI。
|
|
394
|
+
|
|
395
|
+
逐组件的键名、以及**已知仍未覆盖**的几处,见 `docs/L10N.md`。
|
|
396
|
+
门禁:`05-audit/i18n-labels-gate.js`(静态禁硬编码 + 真浏览器验证覆盖生效、默认值不变)。
|
|
397
|
+
|
|
398
|
+
### HTML 净化钩子
|
|
399
|
+
|
|
400
|
+
`popover` / `drawer` 的字符串 HTML 入口可以接净化器:
|
|
401
|
+
|
|
402
|
+
```js
|
|
403
|
+
Popover.setSanitizer(function (html) { return DOMPurify.sanitize(html); });
|
|
404
|
+
Drawer.setSanitizer(function (html) { return DOMPurify.sanitize(html); });
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
默认**不改变行为**(仍按"调用方已净化"处理),理由与责任边界见 `SECURITY.md`。
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
379
411
|
## 破坏性变更怎么走
|
|
380
412
|
|
|
381
413
|
公开**名字**(令牌名 / 类名 / 全局与类型成员 / 事件名)的移除走**登记制**:
|
package/CHANGELOG.md
CHANGED
|
@@ -16,6 +16,77 @@
|
|
|
16
16
|
|
|
17
17
|
(无)
|
|
18
18
|
|
|
19
|
+
## [0.26.0] - 2026-11-04
|
|
20
|
+
|
|
21
|
+
这一版有两类改动:**修外部审计确认的缺陷**,以及**新增三个公开能力**
|
|
22
|
+
(文案覆盖、HTML 净化钩子、toast 上限)。升级不需要改代码 ——
|
|
23
|
+
新增能力都有默认值,且默认值与 0.25.6 行为一致。
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- **文案本地化**:`labels` 可以覆盖用户可见 / 读屏会念到的文案。
|
|
28
|
+
逐实例入口 `Overlay.toast({ labels })`、`Drawer.open({ labels })`、
|
|
29
|
+
`Pagination.create(node, { labels })`、`new Upload(root, { labels })`、
|
|
30
|
+
`Select/Combobox/Dropdown/Tree/DateRange.create(root, { labels })`;
|
|
31
|
+
属性自动初始化的 `Tooltip` / `ModelViewer` 用模块级 `setLabels()`。
|
|
32
|
+
**不传时输出与 0.25.6 逐字相同**。`bar.draw` 的文案覆盖叫 `text`
|
|
33
|
+
(它的 `labels` 早就是 X 轴标签这个数据参数)。清单与已知剩余项见 `docs/L10N.md`。
|
|
34
|
+
- **HTML 净化钩子**:`Popover.setSanitizer(fn)` / `Drawer.setSanitizer(fn)`,
|
|
35
|
+
也可逐次传 `sanitize`。默认**不改变行为**(仍按"调用方已净化"处理)——
|
|
36
|
+
静默自动净化会让既有页面里的 `<b>` / `<svg>` 突然消失。边界见 `SECURITY.md`。
|
|
37
|
+
- **toast 同屏上限**:`Overlay.toast({ maxVisible })`,默认 4,`0` = 不限。
|
|
38
|
+
超出时摘掉**最旧的**一条(此前无上限,20 条并发提示会把屏幕铺满)。
|
|
39
|
+
- `types/index.d.ts`:新增上列文案类型与 `ToastOptions` / `DialogOptions` /
|
|
40
|
+
`PopoverOptions` / `DrawerOpenOptions` / `UploadOptions` / `DropdownOptions` /
|
|
41
|
+
`NavOptions`;把 `ModelViewer` 从"构造函数"改正为 `{ update, refresh, setLabels }`
|
|
42
|
+
(按旧声明写 `new window.ModelViewer(el)` 会在运行时抛 TypeError)。
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
|
|
46
|
+
- `longform` 配方页:`.prose > img` 是**直接子代**选择器,而 Markdown 渲染出的图片
|
|
47
|
+
在 `<p>` 里 ⇒ `max-width:100%` 从未生效,600px 宽的图在 375px 视口横向溢出
|
|
48
|
+
246px、320px 溢出 301px。改为后代选择器(`> a` 在 0.9 踩过同一个坑,这次同一个坑换了标签)。
|
|
49
|
+
- 可滚动的 `.table` / `.table-wrap` / `<pre>` / 图框在窄屏下**键盘进不去**
|
|
50
|
+
(WCAG 2.1.1)。补 `tabindex="0"` + `role="region"` + 「内容名(可横向滚动)」为名的
|
|
51
|
+
可访问名;图类用 `aria-labelledby` 指向 `<figcaption>`,不手写第二份文案。
|
|
52
|
+
- 浏览器自动发现:Playwright 1.6x 的缓存目录名(`chrome-headless-shell-win64/` 等)
|
|
53
|
+
与代码里的候选**一个都不匹配**,此前靠系统 Chrome 兜底才跑得通。改为按可执行文件名
|
|
54
|
+
有界递归 + 读 `chromium.executablePath()`,并补 `%LOCALAPPDATA%` 路径。
|
|
55
|
+
- 三处判据把"文本里出现过的字样"当成"当前生效的现状":`contrast.py` 把注释里的旧色值
|
|
56
|
+
当真值、把 `@media dark` 块之后的浅色定义卷进暗色范围;`wiring-check.py` 把
|
|
57
|
+
`<style>` 里的 CSS 选择器当接线;`delta-check.js` 把 `<pre>` 里的用法示例当成
|
|
58
|
+
页面真的用了 `data-market`。三处都改成只看**会渲染 / 会执行**的结构。
|
|
59
|
+
|
|
60
|
+
### Changed
|
|
61
|
+
|
|
62
|
+
- 开发依赖 `puppeteer-core` 23 → 25(`npm audit` 从 9 high 到 0),CI 增加
|
|
63
|
+
`npm audit --omit=dev --audit-level=high`。
|
|
64
|
+
- 根导出补显式 `import` 条件;README 讲清"运行时是 ESM、`engines>=18` 只代表语法可用,
|
|
65
|
+
`require()` 需要 Node ≥ 22.12"。
|
|
66
|
+
|
|
67
|
+
### 新增 / 加强的门禁
|
|
68
|
+
|
|
69
|
+
- `i18n-labels`:静态禁止「中文字面量直接进 `aria-label` / `textContent` / `el()` 文本位」,
|
|
70
|
+
并在真浏览器里传 `labels` 断言 DOM 真的变了、不传时仍是中文。
|
|
71
|
+
- `md-inline-gate`:`md-render.py` 生成的单文件产物会把 `tokens.css` / `content.css`
|
|
72
|
+
整份内联成第二份副本,此前没有任何门禁守着它漂移(实测已落后 586 字符)。
|
|
73
|
+
- `chrome-discovery-gate`:七种 Playwright 目录布局 × 两个入口 + 空目录不回落 + 旧写法元反向。
|
|
74
|
+
- `a11y-scan` 增加 320px 的 `scrollable-region-focusable` 补扫 —— 一上线就抓出
|
|
75
|
+
`content` / `longform` / `analysis-report` / `scientific-plot` 四页真实违规。
|
|
76
|
+
- `zoom-reflow` 的页面清单改为从文件系统枚举 `04-recipes/**/*.html`(43 → 49 页)——
|
|
77
|
+
上面那个 `.prose` 缺陷就活在不属于任何组件的配方页里。
|
|
78
|
+
- `gen-behavior` 的扫描范围补上 `09-assets`:`bar` 的注入块否则是空的,
|
|
79
|
+
`flLabels is not defined` 只在浏览器门禁才炸。
|
|
80
|
+
|
|
81
|
+
### 关于外部审计报告里的三条
|
|
82
|
+
|
|
83
|
+
F8(demo 对比度)、F10(model-viewer 小溢出)、F12(缺 SemVer/废弃政策)经复核
|
|
84
|
+
**不成立**:`.bad-err` / `.btn--naive` 都在 `.cmp__bad` 豁免容器内;本机 320px
|
|
85
|
+
实测溢出 0;`STABILITY.md` / `DEPRECATIONS.md` / `deprecation-gate` 早已存在。
|
|
86
|
+
没有为"关闭报告项"去改这三处。
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
19
90
|
## [0.25.6] - 2026-11-04
|
|
20
91
|
|
|
21
92
|
这一版**没有改组件、令牌、CSS 或运行时 JS**。改的是「装到手里的包可不可信」:
|
package/README.md
CHANGED
|
@@ -10,6 +10,23 @@ npm install agentcss
|
|
|
10
10
|
|
|
11
11
|
The npm package is `agentcss`; the repository is `frontend-lib`. They are different things: the package name is what you install, the repository name is where the source lives.
|
|
12
12
|
|
|
13
|
+
### Module format: ESM-only
|
|
14
|
+
|
|
15
|
+
The JS entry points (`esm/*.mjs`) are **ESM only** — `exports` has no `require` condition.
|
|
16
|
+
|
|
17
|
+
| You write | Node **≥ 20.19 / ≥ 22.12** | Node 18 – 20.18 |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| `import 'agentcss'` | ✅ | ✅ |
|
|
20
|
+
| `require('agentcss')` | ✅ (Node's built-in require(ESM)) | ❌ `ERR_REQUIRE_ESM` |
|
|
21
|
+
|
|
22
|
+
- On older runtimes use `await import('agentcss')`, or consume the CSS entry points only
|
|
23
|
+
(`agentcss/tokens.css` etc. are not JS and work on any Node version).
|
|
24
|
+
- The shipped `*.js` files under `02-primitives/**` and `03-patterns/**` are **classic
|
|
25
|
+
scripts** for `<script>` tags, not CommonJS modules — they attach to `window.*`.
|
|
26
|
+
- `"type": "commonjs"` is deliberate: it describes how those classic scripts are
|
|
27
|
+
*parsed*. Flipping it to `module` would make bundlers re-interpret them as ESM,
|
|
28
|
+
which is a breaking change.
|
|
29
|
+
|
|
13
30
|
## Docs and live demos
|
|
14
31
|
|
|
15
32
|
- **Every demo page, one index** — https://owain323.github.io/frontend-lib/
|
package/README.zh-CN.md
CHANGED
|
@@ -60,6 +60,22 @@ npm install agentcss
|
|
|
60
60
|
|
|
61
61
|
装出来的目录名就是 `agentcss`,`dist-tags.latest` 指向当前版本。
|
|
62
62
|
|
|
63
|
+
### 模块格式:ESM-only(请先读这一条)
|
|
64
|
+
|
|
65
|
+
`agentcss` 的 JS 入口(`esm/*.mjs`)**只有 ESM**,`exports` 里没有 `require` 条件。
|
|
66
|
+
|
|
67
|
+
| 你的写法 | Node **≥ 20.19 / ≥ 22.12** | Node 18 ~ 20.18 |
|
|
68
|
+
|---|---|---|
|
|
69
|
+
| `import 'agentcss'` | ✅ | ✅ |
|
|
70
|
+
| `require('agentcss')` | ✅(Node 自带的 require(ESM)) | ❌ `ERR_REQUIRE_ESM` |
|
|
71
|
+
|
|
72
|
+
- 走 `require` 的旧环境请改用 `await import('agentcss')`,或只用 CSS 入口
|
|
73
|
+
(`agentcss/tokens.css` 这类**不是 JS**,任何 Node 版本都能直接引用)。
|
|
74
|
+
- 包里的 `*.js`(`02-primitives/**`、`03-patterns/**`)是给 `<script>` 用的**经典脚本**,
|
|
75
|
+
不是 CommonJS 模块 —— 它们挂 `window.*`,不需要 bundler。
|
|
76
|
+
- `type` 字段保持 `commonjs` 是**有意**的:它描述的是那批经典脚本的解析方式。
|
|
77
|
+
把它改成 `module` 会让 bundler 用 ESM 语义重新解析它们,属于破坏性变更。
|
|
78
|
+
|
|
63
79
|
另外两条**同样真实可用**的路(内容与 registry 上那一份同源):
|
|
64
80
|
|
|
65
81
|
```bash
|
package/SECURITY.md
CHANGED
|
@@ -44,10 +44,22 @@
|
|
|
44
44
|
下面两处会把字符串**当 HTML 解析**。它们是**有意的 API**,不是疏漏 ——
|
|
45
45
|
`popover` 要能放任意块级内容,`drawer` 要能放整页内容,只收文本就废了。
|
|
46
46
|
|
|
47
|
-
| 文件 | 入口 | 谁负责净化 |
|
|
48
|
-
|
|
49
|
-
| `02-primitives/popover/popover.js` | `opts.html` |
|
|
50
|
-
| `03-patterns/drawer/drawer.js` | `opt.content` |
|
|
47
|
+
| 文件 | 入口 | 净化钩子 | 谁负责净化 |
|
|
48
|
+
|---|---|---|---|
|
|
49
|
+
| `02-primitives/popover/popover.js` | `opts.html` | `opts.sanitize` / `Popover.setSanitizer(fn)` | 调用方(或接钩子) |
|
|
50
|
+
| `03-patterns/drawer/drawer.js` | `opt.content`(字符串) | `opt.sanitize` / `Drawer.setSanitizer(fn)` | 调用方(或接钩子) |
|
|
51
|
+
|
|
52
|
+
**0.26.0 起有钩子,但默认不改变行为**:不传 `sanitize`、也不调 `setSanitizer()`
|
|
53
|
+
时,两处仍然直接把字符串当 HTML 解析 —— 与 0.25.x 完全一致(静默"自动净化"
|
|
54
|
+
会让既有页面里的 `<b>` / `<svg>` 突然消失,那也是一种破坏)。
|
|
55
|
+
接 DOMPurify 只需一行:
|
|
56
|
+
|
|
57
|
+
```js
|
|
58
|
+
Popover.setSanitizer(function (html) { return DOMPurify.sanitize(html); });
|
|
59
|
+
Drawer.setSanitizer(function (html) { return DOMPurify.sanitize(html); });
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
逐次覆盖优先于模块级:`Popover.attach(el, { html: s, sanitize: fn })`。
|
|
51
63
|
|
|
52
64
|
**为什么本库不做净化**:净化需要一个 HTML 解析器或一份允许列表实现,而本库的目标是
|
|
53
65
|
零运行时依赖 + Chromium 97 可用。给一个"看起来安全"的半吊子净化,比明确说
|
package/START-HERE.md
CHANGED
|
@@ -39,39 +39,39 @@
|
|
|
39
39
|
| 标签 / 徽章 | `02-primitives/badge/badge.css` | 141 | — | 有状态标记就要("已披露""停牌") |
|
|
40
40
|
| 卡片 | `02-primitives/card/card.css` | 283 | — | 有分组内容就要 |
|
|
41
41
|
| 单选 / 多选 | `02-primitives/choice/choice.css` | 434 | — | 单选 / 多选就要 |
|
|
42
|
-
| 下拉选择 | `02-primitives/select/select.css` | 151 | **必需
|
|
43
|
-
| 可搜索选择 | `02-primitives/combobox/combobox.css` | 223 | **必需
|
|
42
|
+
| 下拉选择 | `02-primitives/select/select.css` | 151 | **必需 652** (`select.js`) | 原生 select 的外观或交互不够用就要 |
|
|
43
|
+
| 可搜索选择 | `02-primitives/combobox/combobox.css` | 223 | **必需 503** (`combobox.js`) | 选项多到要搜索,或要选多个并留成标签就要 |
|
|
44
44
|
| 开关 | `02-primitives/switch/switch.css` | 429 | — | 有"立即生效的设置"就要 |
|
|
45
45
|
| 分隔线 | `02-primitives/separator/separator.css` | 73 | — | 要分开内容块就要 |
|
|
46
46
|
| 加载骨架 | `02-primitives/skeleton/skeleton.css` | 114 | — | 数据还没到、先把版式占住就要 |
|
|
47
47
|
| 进度条 / 环 | `02-primitives/progress/progress.css` | 228 | — | 有耗时过程要给进度就要 |
|
|
48
|
-
| 浮层气泡 | `02-primitives/popover/popover.css` | 187 | **必需
|
|
49
|
-
| 日期区间 | `02-primitives/date-range/date-range.css` | 206 | **必需
|
|
48
|
+
| 浮层气泡 | `02-primitives/popover/popover.css` | 187 | **必需 345** (`popover.js`) | 要一段信息贴着触发元素浮出来就要 |
|
|
49
|
+
| 日期区间 | `02-primitives/date-range/date-range.css` | 206 | **必需 332** (`date-range.js`) | 要选起止日期就要 |
|
|
50
50
|
| 标签页 | `03-patterns/tabs/tabs.css` | 172 | **必需 316** (`tabs.js`) | 同层级内容切换就要 |
|
|
51
51
|
| 折叠面板 | `03-patterns/accordion/accordion.css` | 453 | **必需 389** (`accordion.js`) | 长表单分段就要 |
|
|
52
|
-
| 动作菜单 | `03-patterns/dropdown/dropdown.css` | 135 | **必需
|
|
53
|
-
| 文字提示 | `03-patterns/tooltip/tooltip.css` | 89 | **必需
|
|
54
|
-
| 分页 | `03-patterns/pagination/pagination.css` | 195 | **必需
|
|
55
|
-
| 树形 | `03-patterns/tree/tree.css` | 122 | **必需
|
|
56
|
-
| 侧边抽屉 | `03-patterns/drawer/drawer.css` | 145 | **必需
|
|
57
|
-
| 弹窗 / 吐司 | `03-patterns/overlay/overlay.css` | 338 | **必需
|
|
52
|
+
| 动作菜单 | `03-patterns/dropdown/dropdown.css` | 135 | **必需 575** (`dropdown.js`) | 要一组动作(新建 / 导出 / 删除)就要 |
|
|
53
|
+
| 文字提示 | `03-patterns/tooltip/tooltip.css` | 89 | **必需 299** (`tooltip.js`) | 图标按钮或缩写需要一句话解释就要 |
|
|
54
|
+
| 分页 | `03-patterns/pagination/pagination.css` | 195 | **必需 428** (`pagination.js`) | 数据多到要翻页就要 |
|
|
55
|
+
| 树形 | `03-patterns/tree/tree.css` | 122 | **必需 484** (`tree.js`) | 层级数据(文件 / 组织 / 分类)要展开就要 |
|
|
56
|
+
| 侧边抽屉 | `03-patterns/drawer/drawer.css` | 145 | **必需 416** (`drawer.js`) | 要从侧边滑出面板就要 |
|
|
57
|
+
| 弹窗 / 吐司 | `03-patterns/overlay/overlay.css` | 338 | **必需 734** (`overlay.js`) | 需要弹层(吐司 / 模态)就要 |
|
|
58
58
|
| 状态(空 / 加载 / 错 / 成功) | `03-patterns/states/states.css` | 269 | — | **凡是会异步取数就要** |
|
|
59
59
|
| 表单校验 | `03-patterns/form-validation/form-validation.css` | 274 | — | 提交前要校验就要 |
|
|
60
60
|
| 列表增删 | `03-patterns/list/list.css` | 162 | 可选 201 (`flip.js`,FLIP 增删动画,纯增强) | 列表会动态增删就要 |
|
|
61
61
|
| 导航 / 目录 | `03-patterns/nav/nav.css` | 314 | **必需 425** (`nav.js`) · 可选 111 (`toc.js`,自动生成目录,纯增强) | 顶部要导航,或长文要目录就要 |
|
|
62
|
-
| 长文排版 | `03-patterns/content/content.css` |
|
|
62
|
+
| 长文排版 | `03-patterns/content/content.css` | 298 | — | 写文档 / 长文就要 |
|
|
63
63
|
| delta | `02-primitives/delta/delta.css` | 113 | — | |
|
|
64
64
|
| metric | `02-primitives/metric/metric.css` | 157 | — | |
|
|
65
65
|
| timeline | `02-primitives/timeline/timeline.css` | 152 | — | 有一串按时间排的事件(公告 / 大事记 / 版本记录)就要 |
|
|
66
|
-
| upload | `02-primitives/upload/upload.css` | 490 | 可选
|
|
66
|
+
| upload | `02-primitives/upload/upload.css` | 490 | 可选 709 (`upload.js`,拖放 / 文件列表 / 校验;没有它基础形态照常工作) | |
|
|
67
67
|
| reveal | `03-patterns/reveal/reveal.css` | 93 | 可选 175 (`reveal.js`,入场动效,纯增强;没有它内容直接可见) | |
|
|
68
68
|
| analysis-report | `04-recipes/analysis-report/analysis-report.css` | 226 | — | |
|
|
69
69
|
| app-shell | `04-recipes/app-shell/app-shell.css` | 588 | **必需 289** (`shell-nav.js`) | |
|
|
70
70
|
| detail-page | `04-recipes/detail-page/detail-page.css` | 190 | — | |
|
|
71
71
|
| report | `04-recipes/report/report.css` | 369 | — | |
|
|
72
72
|
| table | `04-recipes/table/table.css` | 409 | — | |
|
|
73
|
-
| bar | `09-assets/bar/bar.css` | 181 | **必需
|
|
74
|
-
| model-viewer | `09-assets/model-viewer/model-viewer.css` | 143 | **必需
|
|
73
|
+
| bar | `09-assets/bar/bar.css` | 181 | **必需 348** (`bar.js`) | |
|
|
74
|
+
| model-viewer | `09-assets/model-viewer/model-viewer.css` | 143 | **必需 464** (`model-viewer.js`) | |
|
|
75
75
|
| scientific-plot | `09-assets/scientific-plot/scientific-plot.css` | 141 | **必需 604** (`scientific-plot.js`) | |
|
|
76
76
|
| sparkline | `09-assets/sparkline/sparkline.css` | 158 | **必需 508** (`sparkline.js`) | |
|
|
77
77
|
|
package/ai/components.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": "1.0.0",
|
|
3
3
|
"generatedBy": "05-audit/gen-ai-contract.py",
|
|
4
|
-
"libraryVersion": "0.
|
|
4
|
+
"libraryVersion": "0.26.0",
|
|
5
5
|
"$comment": "机器可读的组件契约。slots = BEM 元素名(在本库里元素名就是插槽名),states.enum = 组件会在 DOM 上写出的 data-* 取值,states.legacyClass = 仍未收敛到 data 属性的历史状态类(INVARIANT I-8 未达标)。printPolicy = 这个组件在纸上会发生什么(空数组 = 原样保留);pagination = 内容是否被分页裁过(server 不许与 expand 同时出现,否则展开的只是当前一页)。",
|
|
6
6
|
"maturityCriteria": {
|
|
7
7
|
"alpha": "缺 demo.html 或缺 05-audit 下的专属门禁 ⇒ 还没被机器验证过,不要用",
|
|
@@ -249,11 +249,13 @@
|
|
|
249
249
|
},
|
|
250
250
|
"aria": {
|
|
251
251
|
"roles": [
|
|
252
|
-
"img"
|
|
252
|
+
"img",
|
|
253
|
+
"region"
|
|
253
254
|
],
|
|
254
255
|
"attrs": [
|
|
255
256
|
"hidden",
|
|
256
|
-
"label"
|
|
257
|
+
"label",
|
|
258
|
+
"labelledby"
|
|
257
259
|
]
|
|
258
260
|
},
|
|
259
261
|
"usesOtherNamespaces": [],
|
|
@@ -2411,7 +2413,9 @@
|
|
|
2411
2413
|
"legacyClass": []
|
|
2412
2414
|
},
|
|
2413
2415
|
"aria": {
|
|
2414
|
-
"roles": [
|
|
2416
|
+
"roles": [
|
|
2417
|
+
"region"
|
|
2418
|
+
],
|
|
2415
2419
|
"attrs": [
|
|
2416
2420
|
"hidden",
|
|
2417
2421
|
"label"
|
|
@@ -2475,6 +2479,7 @@
|
|
|
2475
2479
|
"aria": {
|
|
2476
2480
|
"roles": [
|
|
2477
2481
|
"alert",
|
|
2482
|
+
"region",
|
|
2478
2483
|
"status"
|
|
2479
2484
|
],
|
|
2480
2485
|
"attrs": [
|