agentcss 0.25.6 → 0.27.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/README.md +1 -1
- package/01-tokens/behavior/labels.js +44 -0
- package/01-tokens/responsive-demo.html +1 -1
- package/01-tokens/tokens.core.css +1 -1
- package/01-tokens/tokens.css +2 -2
- package/02-primitives/combobox/combobox.js +26 -3
- package/02-primitives/date-range/date-range.js +28 -6
- package/02-primitives/popover/popover.js +22 -2
- package/02-primitives/select/select.js +23 -2
- package/02-primitives/timeline/demo.html +1 -1
- 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/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.css +1 -1
- package/03-patterns/overlay/overlay.js +39 -2
- package/03-patterns/pagination/pagination.js +37 -10
- package/03-patterns/states/states.css +1 -1
- 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/app-shell/README.md +1 -1
- package/04-recipes/app-shell/demo.html +1 -1
- package/04-recipes/data-showcase/demo.html +2 -2
- package/04-recipes/longform/content.html +993 -78
- package/04-recipes/longform/longform.html +3 -3
- package/04-recipes/report/demo.html +3 -3
- package/04-recipes/table/README.md +23 -1
- package/04-recipes/table/demo.html +7 -7
- package/09-assets/bar/bar.css +1 -1
- package/09-assets/bar/bar.js +28 -4
- package/09-assets/model-viewer/model-viewer.js +45 -13
- package/09-assets/scientific-plot/demo.html +6 -6
- package/AGENTS.md +3 -1
- package/API.md +32 -0
- package/CHANGELOG.md +174 -5
- package/CONTRIBUTING.md +44 -3
- package/README.md +19 -0
- package/README.zh-CN.md +18 -0
- package/SECURITY.md +16 -4
- package/START-HERE.md +25 -18
- package/ai/START-HERE.md +40 -6
- package/ai/check-html.js +658 -0
- package/ai/cli.js +557 -67
- package/ai/components.json +9 -4
- package/ai/pdf.js +52 -10
- package/ai/recipes.json +86 -0
- package/ai/scaffold.js +195 -0
- package/ai/shot.js +345 -0
- package/ai/validate.js +65 -6
- 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 +20 -20
- package/docs/ACCESSIBILITY.md +3 -3
- package/docs/ARCHITECTURE.md +116 -0
- package/docs/L10N.md +92 -0
- package/docs/LAYER-BASELINE.md +2 -2
- package/docs/PRINT.md +3 -3
- package/docs/RELEASE-PROCESS.md +59 -3
- package/docs/STABILITY.md +1 -1
- package/docs/VERIFY-RELEASE.md +24 -2
- package/index.html +3 -3
- package/llms-full.txt +18 -4
- package/llms.txt +26 -5
- package/package.json +4 -2
- package/types/index.d.ts +218 -13
|
@@ -10,8 +10,9 @@
|
|
|
10
10
|
demo 可以用现代语法(跑在用户浏览器上),库代码不行。
|
|
11
11
|
|
|
12
12
|
API:
|
|
13
|
-
Overlay.toast({ title, desc, variant, duration })
|
|
13
|
+
Overlay.toast({ title, desc, variant, duration, maxVisible, labels })
|
|
14
14
|
Overlay.dialog({ title, desc, actions, danger, initialFocus })
|
|
15
|
+
labels: 读屏文案覆盖(默认中文,不传时行为不变)
|
|
15
16
|
→ 返回 { el, close }
|
|
16
17
|
========================================================================= */
|
|
17
18
|
(function (global) {
|
|
@@ -265,8 +266,36 @@
|
|
|
265
266
|
warning: 'toast--warning'
|
|
266
267
|
};
|
|
267
268
|
|
|
269
|
+
/* 读屏文案的**默认值**与合并规则(F2 / 0.26.0)。
|
|
270
|
+
🔴 只覆盖"会被读屏念出来或用户看得见"的文案;`throw new Error(...)`
|
|
271
|
+
这类是给调用方看的开发期信息,不在这里 —— 它们不经过 UI。
|
|
272
|
+
值可以是字符串,也可以是函数(动态文案,如 `第 N 页`)。
|
|
273
|
+
不传 `labels` 时行为与之前**逐字相同**(默认中文)。 */
|
|
274
|
+
var DEFAULT_LABELS = {
|
|
275
|
+
closeToast: '关闭提示'
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
/* ==== BEHAVIOR INJECT BEGIN: labels ==== */
|
|
279
|
+
var flLabels = function (defaults, src) {
|
|
280
|
+
src = src || {};
|
|
281
|
+
var out = {};
|
|
282
|
+
var k;
|
|
283
|
+
for (k in defaults) {
|
|
284
|
+
if (Object.prototype.hasOwnProperty.call(defaults, k)) {
|
|
285
|
+
out[k] = (src[k] === undefined || src[k] === null) ? defaults[k] : src[k];
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return out;
|
|
289
|
+
};
|
|
290
|
+
/* ==== BEHAVIOR INJECT END: labels ==== */
|
|
291
|
+
/* 同屏最多几条 toast。超了就把**最旧的**直接摘掉 ——
|
|
292
|
+
否则 20 条并发提示会把屏幕铺满,且最后一条永远读不到。
|
|
293
|
+
0 / 负数表示不限制(调用方自己负责)。 */
|
|
294
|
+
var TOAST_LIMIT = 4;
|
|
295
|
+
|
|
268
296
|
function toast(opts) {
|
|
269
297
|
opts = opts || {};
|
|
298
|
+
var L = flLabels(DEFAULT_LABELS, opts && opts.labels);
|
|
270
299
|
|
|
271
300
|
var region = document.querySelector('.toast-region');
|
|
272
301
|
if (!region) {
|
|
@@ -314,7 +343,7 @@
|
|
|
314
343
|
var closeBtn = document.createElement('button');
|
|
315
344
|
closeBtn.className = 'toast__close';
|
|
316
345
|
closeBtn.type = 'button';
|
|
317
|
-
closeBtn.setAttribute('aria-label',
|
|
346
|
+
closeBtn.setAttribute('aria-label', L.closeToast);
|
|
318
347
|
closeBtn.textContent = '×';
|
|
319
348
|
el.appendChild(closeBtn);
|
|
320
349
|
|
|
@@ -331,6 +360,14 @@
|
|
|
331
360
|
}
|
|
332
361
|
|
|
333
362
|
closeBtn.addEventListener('click', close);
|
|
363
|
+
/* 同屏上限:先摘最旧的,再挂新的。
|
|
364
|
+
🔴 摘的时候**不走 close()** —— 它带 220ms 退场动画,
|
|
365
|
+
动画期间节点仍在 DOM 里,children.length 不减 ⇒ 这里会空转。
|
|
366
|
+
被摘掉的那条已经在屏幕外了,动画没有意义。 */
|
|
367
|
+
var max = (opts.maxVisible === undefined) ? TOAST_LIMIT : opts.maxVisible;
|
|
368
|
+
while (max > 0 && region.children.length >= max) {
|
|
369
|
+
region.removeChild(region.firstChild);
|
|
370
|
+
}
|
|
334
371
|
region.appendChild(el);
|
|
335
372
|
|
|
336
373
|
var timerId = auto > 0 ? setTimeout(close, auto) : null;
|
|
@@ -137,12 +137,39 @@
|
|
|
137
137
|
|
|
138
138
|
/* ---------------------------------------------------------------------- */
|
|
139
139
|
|
|
140
|
-
|
|
140
|
+
/* 读屏文案默认值(F2 / 0.26.0)。值是字符串或函数;
|
|
141
|
+
不传 `labels` 时输出与之前逐字相同。 */
|
|
142
|
+
var DEFAULT_LABELS = {
|
|
143
|
+
nav: '分页',
|
|
144
|
+
prev: '上一页',
|
|
145
|
+
next: '下一页',
|
|
146
|
+
page: function (p, isCurrent) {
|
|
147
|
+
return '第 ' + p + ' 页' + (isCurrent ? '(当前页)' : '');
|
|
148
|
+
},
|
|
149
|
+
status: function (page, pages) { return '第 ' + page + ' 页 / 共 ' + pages + ' 页'; },
|
|
150
|
+
live: function (page, pages) { return '第 ' + page + ' 页,共 ' + pages + ' 页'; }
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
/* ==== BEHAVIOR INJECT BEGIN: labels ==== */
|
|
154
|
+
var flLabels = function (defaults, src) {
|
|
155
|
+
src = src || {};
|
|
156
|
+
var out = {};
|
|
157
|
+
var k;
|
|
158
|
+
for (k in defaults) {
|
|
159
|
+
if (Object.prototype.hasOwnProperty.call(defaults, k)) {
|
|
160
|
+
out[k] = (src[k] === undefined || src[k] === null) ? defaults[k] : src[k];
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return out;
|
|
164
|
+
};
|
|
165
|
+
/* ==== BEHAVIOR INJECT END: labels ==== */
|
|
166
|
+
function Pagination(node, opts) {
|
|
141
167
|
this.node = node;
|
|
168
|
+
this.labels = flLabels(DEFAULT_LABELS, opts && opts.labels);
|
|
142
169
|
this.total = Math.max(1, parseInt(node.getAttribute('data-total') || '1', 10));
|
|
143
170
|
this.size = Math.max(1, parseInt(node.getAttribute('data-page-size') || '20', 10));
|
|
144
171
|
this.page = Math.max(1, parseInt(node.getAttribute('data-page') || '1', 10));
|
|
145
|
-
this.label = node.getAttribute('aria-label') ||
|
|
172
|
+
this.label = node.getAttribute('aria-label') || this.labels.nav;
|
|
146
173
|
this.pages = Math.max(1, Math.ceil(this.total / this.size));
|
|
147
174
|
this.onChange = null;
|
|
148
175
|
|
|
@@ -301,7 +328,7 @@
|
|
|
301
328
|
/** ⭐ 播报(依据第 2 条:改 textContent,不换元素) */
|
|
302
329
|
Pagination.prototype.announce = function () {
|
|
303
330
|
if (!this.liveNode) return;
|
|
304
|
-
this.liveNode.textContent =
|
|
331
|
+
this.liveNode.textContent = this.labels.live(this.page, this.pages);
|
|
305
332
|
};
|
|
306
333
|
|
|
307
334
|
Pagination.prototype.render = function () {
|
|
@@ -309,6 +336,7 @@
|
|
|
309
336
|
var L = this.listNode;
|
|
310
337
|
while (L.firstChild) L.removeChild(L.firstChild);
|
|
311
338
|
var self = this;
|
|
339
|
+
var T = this.labels;
|
|
312
340
|
|
|
313
341
|
function addBtn(text, ariaLabel, goto, disabled) {
|
|
314
342
|
var li = el('li', 'pagination__item');
|
|
@@ -325,7 +353,7 @@
|
|
|
325
353
|
}
|
|
326
354
|
|
|
327
355
|
/* --- 上一页 / 首页 --- */
|
|
328
|
-
addBtn('‹',
|
|
356
|
+
addBtn('‹', T.prev, 'prev', self.page <= 1);
|
|
329
357
|
/* --- 页码 --- */
|
|
330
358
|
var win = pageWindow(self.page, self.pages, SLOTS);
|
|
331
359
|
for (var i = 0; i < win.length; i++) {
|
|
@@ -347,7 +375,7 @@
|
|
|
347
375
|
var b2 = el('button', 'pagination__link', String(p));
|
|
348
376
|
b2.type = 'button';
|
|
349
377
|
b2.setAttribute('data-goto', String(p));
|
|
350
|
-
b2.setAttribute('aria-label',
|
|
378
|
+
b2.setAttribute('aria-label', T.page(p, isCur));
|
|
351
379
|
if (isCur) {
|
|
352
380
|
b2.setAttribute('aria-current', 'page');
|
|
353
381
|
b2.setAttribute('aria-disabled', 'true');
|
|
@@ -356,22 +384,21 @@
|
|
|
356
384
|
L.appendChild(li2);
|
|
357
385
|
}
|
|
358
386
|
/* --- 下一页 / 末页 --- */
|
|
359
|
-
addBtn('›',
|
|
387
|
+
addBtn('›', T.next, 'next', self.page >= self.pages);
|
|
360
388
|
|
|
361
389
|
/* --- 可见状态("第 2 页 / 共 12 页") --- */
|
|
362
390
|
if (this.statusNode) {
|
|
363
|
-
this.statusNode.textContent =
|
|
364
|
-
'第 ' + self.page + ' 页 / 共 ' + self.pages + ' 页';
|
|
391
|
+
this.statusNode.textContent = T.status(self.page, self.pages);
|
|
365
392
|
}
|
|
366
393
|
};
|
|
367
394
|
|
|
368
395
|
/* ---------------------------------------------------------------------- */
|
|
369
396
|
var API = {
|
|
370
397
|
/** 创建一个分页实例(返回实例以便绑定 onChange) */
|
|
371
|
-
create: function (node) {
|
|
398
|
+
create: function (node, opts) {
|
|
372
399
|
if (!node) return null;
|
|
373
400
|
if (node.__pg) return node.__pg;
|
|
374
|
-
node.__pg = new Pagination(node);
|
|
401
|
+
node.__pg = new Pagination(node, opts);
|
|
375
402
|
return node.__pg;
|
|
376
403
|
},
|
|
377
404
|
/** 页面内所有 [data-pagination] */
|
|
@@ -137,7 +137,7 @@
|
|
|
137
137
|
⇒ 减少动态效果的用户照样看到闪烁的微光;
|
|
138
138
|
· 与 `02-primitives/skeleton/skeleton.css` 同特异性 ⇒ 谁后加载谁定生死。
|
|
139
139
|
|
|
140
|
-
即"要不要尊重减少动态效果"取决于 CSS
|
|
140
|
+
即"要不要尊重减少动态效果"取决于 CSS 顺序。与同类。
|
|
141
141
|
⚠️ 这里与 skeleton.css 是**两份实现**(已登记在 css-ownership.json),
|
|
142
142
|
修的时候两边都要看。 */
|
|
143
143
|
@media (prefers-reduced-motion: no-preference) {
|
|
@@ -125,6 +125,21 @@ var flDismissable = function (opts) {
|
|
|
125
125
|
|
|
126
126
|
var uid = 0;
|
|
127
127
|
|
|
128
|
+
/* 读屏文案默认值(F2 / 0.26.0)。
|
|
129
|
+
本组件是 `attach(el, text)` 形式、没有逐实例 opts,
|
|
130
|
+
所以文案用**模块级**设置:`Tooltip.setLabels({ region: 'Tooltip' })`。 */
|
|
131
|
+
var LABELS = { region: '组件提示' };
|
|
132
|
+
|
|
133
|
+
function setLabels(patch) {
|
|
134
|
+
if (!patch) return;
|
|
135
|
+
for (var k in LABELS) {
|
|
136
|
+
if (Object.prototype.hasOwnProperty.call(LABELS, k)
|
|
137
|
+
&& patch[k] !== undefined && patch[k] !== null) {
|
|
138
|
+
LABELS[k] = patch[k];
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
128
143
|
function ensureStyle() {
|
|
129
144
|
if (document.getElementById('tooltip-css')) return;
|
|
130
145
|
/* 说明:样式由页面通过 <link> 引入;这里只做"有没有"的提示,
|
|
@@ -149,7 +164,7 @@ var flDismissable = function (opts) {
|
|
|
149
164
|
而在读屏用户"到达"它之前它通常是空的
|
|
150
165
|
⇒ 光靠内容拿不到名字 ⇒ 必须显式给 aria-label。
|
|
151
166
|
label 用通用措辞,具体内容由 aria-live 负责播报。 */
|
|
152
|
-
r.setAttribute('aria-label',
|
|
167
|
+
r.setAttribute('aria-label', LABELS.region);
|
|
153
168
|
r.style.cssText =
|
|
154
169
|
'position:absolute;width:1px;height:1px;padding:0;margin:-1px;' +
|
|
155
170
|
'overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0';
|
|
@@ -280,5 +295,5 @@ var flDismissable = function (opts) {
|
|
|
280
295
|
el.setAttribute('data-tooltip', text);
|
|
281
296
|
}
|
|
282
297
|
|
|
283
|
-
global.Tooltip = { attach: attach };
|
|
298
|
+
global.Tooltip = { attach: attach, setLabels: setLabels };
|
|
284
299
|
})(typeof window !== 'undefined' ? window : globalThis);
|
package/03-patterns/tree/tree.js
CHANGED
|
@@ -231,11 +231,31 @@
|
|
|
231
231
|
var uid = 0;
|
|
232
232
|
|
|
233
233
|
function create(root, opt) {
|
|
234
|
+
/* 读屏文案默认值(F2 / 0.26.0)。不传 `labels` 时输出逐字不变。 */
|
|
235
|
+
var DEFAULT_LABELS = {
|
|
236
|
+
tree: '树形视图'
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
/* ==== BEHAVIOR INJECT BEGIN: labels ==== */
|
|
240
|
+
var flLabels = function (defaults, src) {
|
|
241
|
+
src = src || {};
|
|
242
|
+
var out = {};
|
|
243
|
+
var k;
|
|
244
|
+
for (k in defaults) {
|
|
245
|
+
if (Object.prototype.hasOwnProperty.call(defaults, k)) {
|
|
246
|
+
out[k] = (src[k] === undefined || src[k] === null) ? defaults[k] : src[k];
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return out;
|
|
250
|
+
};
|
|
251
|
+
/* ==== BEHAVIOR INJECT END: labels ==== */
|
|
252
|
+
var L = flLabels(DEFAULT_LABELS, opt && opt.labels);
|
|
253
|
+
|
|
234
254
|
opt = opt || {};
|
|
235
255
|
root.classList.add('tree');
|
|
236
256
|
if (!root.getAttribute('role')) root.setAttribute('role', 'tree');
|
|
237
257
|
if (!root.getAttribute('aria-label') && !root.getAttribute('aria-labelledby')) {
|
|
238
|
-
root.setAttribute('aria-label', opt.label ||
|
|
258
|
+
root.setAttribute('aria-label', opt.label || L.tree);
|
|
239
259
|
}
|
|
240
260
|
|
|
241
261
|
/* ---------- 初始化结构 ---------- */
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
每组成 2 个平行样,取算术平均。
|
|
99
99
|
</p>
|
|
100
100
|
|
|
101
|
-
<pre class="report__code">电解液 1 M LiPF6 in EC:EMC:DMC = 3:5:2 (v/v) + 2 wt% VC
|
|
101
|
+
<pre class="report__code" tabindex="0">电解液 1 M LiPF6 in EC:EMC:DMC = 3:5:2 (v/v) + 2 wt% VC
|
|
102
102
|
截止电压 3.0 – 4.4 V (vs. Li/Li+)
|
|
103
103
|
倍率 0.5C 充电 / 1.0C 放电
|
|
104
104
|
温度 25 ± 1 °C
|
|
@@ -243,7 +243,7 @@ rail 下硬塞一个 `.shell__side-label` 会被 CSS 藏掉(兜底,防止它
|
|
|
243
243
|
|
|
244
244
|
- **❌ 侧栏 `position: fixed` + 主区 `margin-inline-start`** —— 看起来能用,但侧栏被摘出
|
|
245
245
|
grid 流,主区宽度靠**手抄的数字**维持(改侧栏宽就要改两处);`inset-inline-start`
|
|
246
|
-
与 `margin-inline-start` 只要有一处漏改,RTL
|
|
246
|
+
与 `margin-inline-start` 只要有一处漏改,RTL 下侧栏跑到右边、主区仍在右边留白。
|
|
247
247
|
|
|
248
248
|
正确的做法见上面「侧栏为什么是 `sticky` 而不是 `fixed`」。
|
|
249
249
|
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
多级表头用 <code>scope</code> 标明层级。
|
|
113
113
|
</p>
|
|
114
114
|
|
|
115
|
-
<div class="table table--academic">
|
|
115
|
+
<div class="table table--academic" tabindex="0" role="region" aria-label="三种干燥工艺的成品性能对比(可横向滚动)">
|
|
116
116
|
<table>
|
|
117
117
|
<caption class="table__cap">表 1 · 三种干燥工艺的成品性能对比(示例数据)</caption>
|
|
118
118
|
<thead>
|
|
@@ -157,7 +157,7 @@
|
|
|
157
157
|
不能用同一个数字格式化函数打发。<strong>本表不推断显著性,也不计算统计量。</strong>
|
|
158
158
|
</p>
|
|
159
159
|
|
|
160
|
-
<div class="table table--stats">
|
|
160
|
+
<div class="table table--stats" tabindex="0" role="region" aria-label="干燥工艺对含水率的影响(可横向滚动)">
|
|
161
161
|
<table>
|
|
162
162
|
<caption class="table__cap">表 2 · 干燥工艺对含水率的影响(OLS 估计,示例数据,n = 60)</caption>
|
|
163
163
|
<thead>
|