agentcss 0.11.13 → 0.11.16
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/page.css +4 -2
- package/02-primitives/badge/demo.html +6 -3
- package/02-primitives/choice/demo.html +32 -16
- package/02-primitives/combobox/combobox.js +1 -1
- package/02-primitives/date-range/date-range.js +1 -1
- package/02-primitives/popover/demo.html +1 -1
- package/02-primitives/popover/popover.js +1 -1
- package/02-primitives/select/select.js +1 -1
- package/02-primitives/separator/demo.html +28 -10
- package/02-primitives/switch/demo.html +28 -14
- package/03-patterns/accordion/accordion.js +25 -5
- package/03-patterns/accordion/demo.html +65 -26
- package/03-patterns/drawer/drawer.js +1 -1
- package/03-patterns/dropdown/dropdown.js +1 -1
- package/03-patterns/form-validation/demo.html +2 -3
- package/03-patterns/list/flip.js +1 -1
- package/03-patterns/nav/nav.js +6 -3
- package/03-patterns/nav/toc.js +1 -1
- package/03-patterns/overlay/demo.html +1 -2
- package/03-patterns/overlay/overlay.js +1 -1
- package/03-patterns/pagination/demo.html +1 -1
- package/03-patterns/pagination/pagination.js +9 -3
- package/03-patterns/reveal/reveal.js +4 -1
- package/03-patterns/tabs/demo.html +71 -27
- package/03-patterns/tabs/tabs.js +12 -3
- package/03-patterns/tooltip/tooltip.js +1 -1
- package/03-patterns/tree/tree.js +1 -1
- package/04-recipes/report/demo.html +2 -2
- package/09-assets/echarts-adapter/demo.html +6 -7
- package/09-assets/model-viewer/demo.html +2 -2
- package/09-assets/sparkline/demo.html +1 -2
- package/API.md +37 -3
- package/CHANGELOG.md +309 -0
- package/CONTRIBUTING.md +9 -3
- package/README.zh-CN.md +1 -1
- package/START-HERE.md +5 -5
- package/ai/components.json +8 -4
- package/ai/deprecations.schema.json +2 -2
- package/dist/02-primitives/combobox/combobox.js +1 -1
- package/dist/02-primitives/date-range/date-range.js +1 -1
- package/dist/02-primitives/popover/popover.js +1 -1
- package/dist/02-primitives/select/select.js +1 -1
- package/dist/03-patterns/accordion/accordion.js +10 -4
- package/dist/03-patterns/drawer/drawer.js +1 -1
- package/dist/03-patterns/dropdown/dropdown.js +1 -1
- package/dist/03-patterns/list/flip.js +1 -1
- package/dist/03-patterns/nav/nav.js +4 -3
- package/dist/03-patterns/nav/toc.js +1 -1
- package/dist/03-patterns/overlay/overlay.js +1 -1
- package/dist/03-patterns/pagination/pagination.js +4 -3
- package/dist/03-patterns/reveal/reveal.js +2 -1
- package/dist/03-patterns/tabs/tabs.js +8 -3
- package/dist/03-patterns/tooltip/tooltip.js +1 -1
- package/dist/03-patterns/tree/tree.js +1 -1
- package/dist/COSTS.md +10 -10
- package/docs/ACCESSIBILITY.md +3 -3
- package/docs/DEPRECATIONS.md +128 -0
- package/esm/accordion.mjs +7 -0
- package/esm/combobox.mjs +7 -0
- package/esm/date-range.mjs +7 -0
- package/esm/drawer.mjs +7 -0
- package/esm/dropdown.mjs +7 -0
- package/esm/flip.mjs +7 -0
- package/esm/index.mjs +38 -0
- package/esm/nav.mjs +7 -0
- package/esm/overlay.mjs +7 -0
- package/esm/pagination.mjs +7 -0
- package/esm/popover.mjs +7 -0
- package/esm/reveal.mjs +7 -0
- package/esm/select.mjs +7 -0
- package/esm/tabs.mjs +7 -0
- package/esm/toc.mjs +7 -0
- package/esm/tooltip.mjs +7 -0
- package/esm/tree.mjs +7 -0
- package/index.html +1 -1
- package/package.json +10 -3
- package/types/index.d.ts +131 -1
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
</head>
|
|
18
18
|
<body class="page page">
|
|
19
19
|
<main class="wrap">
|
|
20
|
-
<!-- demo-claim:skip 两块都可量(button 的个数、tabindex="0" 的个数),但这一页仍是单栏结构,升级成 cmp 要重排整页 —— 本轮没做,已知欠账 -->
|
|
21
20
|
<h1>tabs · 标签页</h1>
|
|
22
21
|
<p class="lede">
|
|
23
22
|
标签页用于在同一位置切换<strong>同层级的几块内容</strong>。
|
|
@@ -103,37 +102,82 @@
|
|
|
103
102
|
</p>
|
|
104
103
|
</div>
|
|
105
104
|
|
|
106
|
-
<h2 class="rule-top"
|
|
107
|
-
<div class="
|
|
108
|
-
<
|
|
109
|
-
|
|
110
|
-
<div class="
|
|
111
|
-
<div class="
|
|
112
|
-
|
|
105
|
+
<h2 class="rule-top">对照:两处最容易写错的地方</h2>
|
|
106
|
+
<div class="cmp">
|
|
107
|
+
<div class="cmp__pane cmp__bad" data-bad="[role=tab]|focus|=0">
|
|
108
|
+
<h3>❌ 用 div 当 tab</h3>
|
|
109
|
+
<div class="tabs">
|
|
110
|
+
<div class="tabs__list" role="tablist" aria-label="错例:div 当 tab">
|
|
111
|
+
<div class="tabs__tab" role="tab" aria-selected="true">基本信息</div>
|
|
112
|
+
<div class="tabs__tab" role="tab" aria-selected="false">高级设置</div>
|
|
113
|
+
</div>
|
|
113
114
|
</div>
|
|
115
|
+
<p class="cmp__why">
|
|
116
|
+
这两个 tab <strong>看起来完全正常</strong>,但
|
|
117
|
+
<code><div role="tab"></code> 根本 Tab 不到(除非手写
|
|
118
|
+
<code>tabindex</code>),也不响应 Enter/Space。
|
|
119
|
+
APG 要求 tab 是 <code><button role="tab"></code>。
|
|
120
|
+
</p>
|
|
121
|
+
</div>
|
|
122
|
+
|
|
123
|
+
<div class="cmp__pane cmp__good" data-good="[role=tab]|focus|=2">
|
|
124
|
+
<h3>✅ button role="tab"</h3>
|
|
125
|
+
<div class="tabs">
|
|
126
|
+
<div class="tabs__list" role="tablist" aria-label="正例:button 当 tab">
|
|
127
|
+
<button class="tabs__tab" role="tab" aria-selected="true">基本信息</button>
|
|
128
|
+
<button class="tabs__tab" role="tab" aria-selected="false">高级设置</button>
|
|
129
|
+
</div>
|
|
130
|
+
</div>
|
|
131
|
+
<p class="cmp__why">
|
|
132
|
+
同一个外观,键盘行为免费且必然正确。
|
|
133
|
+
(这里只演示"能不能聚焦",roving 见下面那块。)
|
|
134
|
+
</p>
|
|
114
135
|
</div>
|
|
115
|
-
<p class="small">
|
|
116
|
-
上面这两个 tab <strong>看起来完全正常</strong>,但
|
|
117
|
-
<code><div role="tab"></code> 键盘上根本<strong>Tab 不到</strong>
|
|
118
|
-
(除非手写 <code>tabindex</code>),也不会响应 Enter/Space。
|
|
119
|
-
APG 明确要求 tab 是 <code><button role="tab"></code> ——
|
|
120
|
-
用原生 button,键盘行为免费且必然正确。
|
|
121
|
-
</p>
|
|
122
136
|
</div>
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
<div class="
|
|
126
|
-
<
|
|
127
|
-
|
|
128
|
-
<
|
|
129
|
-
|
|
137
|
+
|
|
138
|
+
<div class="cmp">
|
|
139
|
+
<div class="cmp__pane cmp__bad" data-bad="[role=tab]|focus|=3">
|
|
140
|
+
<h3>❌ 每个 tab 都写 tabindex="0"</h3>
|
|
141
|
+
<div class="tabs">
|
|
142
|
+
<div class="tabs__list" role="tablist" aria-label="错例:三个 tab 全是 0">
|
|
143
|
+
<button class="tabs__tab" role="tab" tabindex="0" aria-selected="true">基本信息</button>
|
|
144
|
+
<button class="tabs__tab" role="tab" tabindex="0" aria-selected="false">高级设置</button>
|
|
145
|
+
<button class="tabs__tab" role="tab" tabindex="0" aria-selected="false">日志</button>
|
|
146
|
+
</div>
|
|
130
147
|
</div>
|
|
148
|
+
<p class="cmp__why">
|
|
149
|
+
看起来"都能 Tab 到",但一排 3 个 tab 就要按 <strong>3 次 Tab</strong>
|
|
150
|
+
才能进内容区。Tab 键应该是<strong>进出</strong>控件的,
|
|
151
|
+
组内移动是方向键的活。
|
|
152
|
+
</p>
|
|
153
|
+
</div>
|
|
154
|
+
|
|
155
|
+
<div class="cmp__pane cmp__good" data-good="[role=tab]|focus|=1">
|
|
156
|
+
<h3>✅ roving tabindex:整组只有一个 0</h3>
|
|
157
|
+
<div class="tabs" data-tabs>
|
|
158
|
+
<div class="tabs__list" role="tablist" aria-orientation="horizontal" aria-label="正例:roving">
|
|
159
|
+
<button class="tabs__tab" role="tab" id="rt1" aria-controls="rp1"
|
|
160
|
+
aria-selected="true">基本信息</button>
|
|
161
|
+
<button class="tabs__tab" role="tab" id="rt2" aria-controls="rp2"
|
|
162
|
+
aria-selected="false">高级设置</button>
|
|
163
|
+
<button class="tabs__tab" role="tab" id="rt3" aria-controls="rp3"
|
|
164
|
+
aria-selected="false">日志</button>
|
|
165
|
+
</div>
|
|
166
|
+
<div class="tabs__panel" role="tabpanel" id="rp1" aria-labelledby="rt1">
|
|
167
|
+
<p>一次 Tab 就进来,方向键在组内移动。</p>
|
|
168
|
+
</div>
|
|
169
|
+
<div class="tabs__panel" role="tabpanel" id="rp2" aria-labelledby="rt2" hidden>
|
|
170
|
+
<p>方向键到这里。</p>
|
|
171
|
+
</div>
|
|
172
|
+
<div class="tabs__panel" role="tabpanel" id="rp3" aria-labelledby="rt3" hidden>
|
|
173
|
+
<p>方向键到这里。</p>
|
|
174
|
+
</div>
|
|
175
|
+
</div>
|
|
176
|
+
<p class="cmp__why">
|
|
177
|
+
那个 <code>0</code> 跟着选中项走 —— 由 <code>roving.js</code> 在切换时搬,
|
|
178
|
+
不是初始化时设一次。只设一次是最常见的 bug。
|
|
179
|
+
</p>
|
|
131
180
|
</div>
|
|
132
|
-
<p class="small">
|
|
133
|
-
看起来"都能 Tab 到",但一排 3 个 tab 就要按 <strong>3 次 Tab</strong>
|
|
134
|
-
才能进内容区(真到 5 个 tab 的页面上只会更糟)。Tab 键应该是<strong>进出</strong>控件的,
|
|
135
|
-
组内移动是方向键的活。
|
|
136
|
-
</p>
|
|
137
181
|
</div>
|
|
138
182
|
</main>
|
|
139
183
|
<script src="tabs.js"></script>
|
package/03-patterns/tabs/tabs.js
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
* 只在初始化时设一次是最常见的 bug:用户激活第 3 个 tab 后,
|
|
27
27
|
* Tab 键还是会回到第 1 个。
|
|
28
28
|
*/
|
|
29
|
-
(function () {
|
|
29
|
+
(function (global) {
|
|
30
30
|
'use strict';
|
|
31
31
|
|
|
32
32
|
/* ==== BEHAVIOR INJECT BEGIN: emit ==== */
|
|
@@ -165,6 +165,9 @@
|
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
function Tabs(root, opts) {
|
|
168
|
+
/* 🔴 同一 root 只允许一个实例 —— 理由同 accordion.js。
|
|
169
|
+
重复构造会让 keydown 监听叠两份:方向键按一次跳两格。 */
|
|
170
|
+
if (root && root.tabsInstance) return root.tabsInstance;
|
|
168
171
|
this.root = root;
|
|
169
172
|
this.opts = opts || {};
|
|
170
173
|
this.list = root.querySelector('[role="tablist"]');
|
|
@@ -281,7 +284,7 @@
|
|
|
281
284
|
};
|
|
282
285
|
|
|
283
286
|
// 暴露
|
|
284
|
-
|
|
287
|
+
global.Tabs = Tabs;
|
|
285
288
|
|
|
286
289
|
// 自动初始化:<div class="tabs" data-tabs>
|
|
287
290
|
//
|
|
@@ -294,14 +297,20 @@
|
|
|
294
297
|
function init() {
|
|
295
298
|
var nodes = document.querySelectorAll('[data-tabs]');
|
|
296
299
|
for (var i = 0; i < nodes.length; i++) {
|
|
300
|
+
/* 🔴 幂等:同 accordion.js 里的理由。重复 new 会让 keydown / click
|
|
301
|
+
监听叠在同一个 root 上 ⇒ 方向键按一次跳两格。 */
|
|
302
|
+
if (nodes[i].tabsInstance) continue;
|
|
297
303
|
nodes[i].tabsInstance = new Tabs(nodes[i], {});
|
|
298
304
|
}
|
|
299
305
|
}
|
|
300
306
|
|
|
301
307
|
// @autoinit: [data-tabs] —— 扫属性自动建实例(详见 API.md「自动初始化」)
|
|
308
|
+
// ⚠️ 无 DOM 环境(SSR / 构建期 / Node 里 import)不自动初始化。
|
|
309
|
+
// 之前这里直接摸 document ⇒ Next.js 等 SSR 里 import 即 ReferenceError。
|
|
310
|
+
if (typeof document === 'undefined') return;
|
|
302
311
|
if (document.readyState === 'loading') {
|
|
303
312
|
document.addEventListener('DOMContentLoaded', init);
|
|
304
313
|
} else {
|
|
305
314
|
init();
|
|
306
315
|
}
|
|
307
|
-
})();
|
|
316
|
+
})(typeof window !== 'undefined' ? window : globalThis);
|
package/03-patterns/tree/tree.js
CHANGED
|
@@ -181,7 +181,7 @@
|
|
|
181
181
|
写死数字的话,插入一张新图后面全会错位。
|
|
182
182
|
同一句标记放在 financial 版里不会出编号 —— 那是 profile 决定的,不是标记决定的。 -->
|
|
183
183
|
<figure class="rep__fig">
|
|
184
|
-
<div class="table"><table>
|
|
184
|
+
<div class="table"><table aria-label="关键读数:包覆方案与保持率">
|
|
185
185
|
<thead><tr>
|
|
186
186
|
<th scope="col">方案</th>
|
|
187
187
|
<th scope="col">保持率</th>
|
|
@@ -248,7 +248,7 @@
|
|
|
248
248
|
<h3>关键假设</h3>
|
|
249
249
|
<!-- 同一句标记放在 finance 版:没有编号,因为 financial profile 不开 counter -->
|
|
250
250
|
<figure class="rep__fig">
|
|
251
|
-
<div class="table"><table>
|
|
251
|
+
<div class="table"><table aria-label="关键假设:三种情形下的良率与毛利率">
|
|
252
252
|
<thead><tr>
|
|
253
253
|
<th scope="col">情形</th>
|
|
254
254
|
<th scope="col">良率</th>
|
|
@@ -35,7 +35,6 @@ td.num { text-align: right; font-family: var(--mono); font-variant-numeric: tabu
|
|
|
35
35
|
</head>
|
|
36
36
|
<body class="page page">
|
|
37
37
|
<div class="wrap">
|
|
38
|
-
<!-- demo-claim:skip 反例是一张「不要做」清单表;3D、双 Y 轴这些错法都要真的渲染一张图才立得住,本页没有图表实例可摆 -->
|
|
39
38
|
<h1>图表规范</h1>
|
|
40
39
|
<p class="lede">
|
|
41
40
|
<strong>下次画图照这里做就行</strong>,不用再反复微调。
|
|
@@ -45,7 +44,7 @@ td.num { text-align: right; font-family: var(--mono); font-variant-numeric: tabu
|
|
|
45
44
|
</p>
|
|
46
45
|
|
|
47
46
|
<h2 class="rule-top">0 · 边界:什么该用本库,什么该用 ECharts</h2>
|
|
48
|
-
<table>
|
|
47
|
+
<table aria-label="能力边界:什么场景用本库、什么用 ECharts">
|
|
49
48
|
<tr><th>场景</th><th>用什么</th><th>谁维护</th></tr>
|
|
50
49
|
<tr><td>列表右侧的<strong>迷你趋势</strong>(看走势)</td>
|
|
51
50
|
<td class="ok">本库 <code>sparkline</code>(1.5KB,零依赖)</td><td>我们</td></tr>
|
|
@@ -95,7 +94,7 @@ td.num { text-align: right; font-family: var(--mono); font-variant-numeric: tabu
|
|
|
95
94
|
<div class="flex">
|
|
96
95
|
<div class="box">
|
|
97
96
|
<h3 style="margin-top:0">✅ 规范:柱状图(分类轴从 0)</h3>
|
|
98
|
-
<table>
|
|
97
|
+
<table aria-label="示例数据:柱状图的分季度营收">
|
|
99
98
|
<tr><th>季度</th><th class="num">营收(亿)</th><th class="num">同比</th></tr>
|
|
100
99
|
<tr><td>Q1</td><td class="num">128.4</td><td class="num up">+12.4%</td></tr>
|
|
101
100
|
<tr><td>Q2</td><td class="num">136.1</td><td class="num up">+8.1%</td></tr>
|
|
@@ -110,7 +109,7 @@ td.num { text-align: right; font-family: var(--mono); font-variant-numeric: tabu
|
|
|
110
109
|
|
|
111
110
|
<div class="box">
|
|
112
111
|
<h3 style="margin-top:0">✅ 规范:多系列(≤ 5 条)</h3>
|
|
113
|
-
<table>
|
|
112
|
+
<table aria-label="示例数据:A / B / C 三支股票的逐年对比">
|
|
114
113
|
<tr><th>年份</th>
|
|
115
114
|
<th class="num"><span class="swatch" style="background:var(--accent)"></span>A 股</th>
|
|
116
115
|
<th class="num"><span class="swatch" style="background:var(--danger)"></span>B 股</th>
|
|
@@ -134,7 +133,7 @@ td.num { text-align: right; font-family: var(--mono); font-variant-numeric: tabu
|
|
|
134
133
|
</div>
|
|
135
134
|
|
|
136
135
|
<h2 class="rule-top">3 · 数字格式(已经在用)</h2>
|
|
137
|
-
<table>
|
|
136
|
+
<table aria-label="数字格式规则与例子">
|
|
138
137
|
<tr><th>类型</th><th>规则</th><th>例子</th></tr>
|
|
139
138
|
<tr><td>千分位</td><td>每三位加逗号</td><td class="num">1,234,567</td></tr>
|
|
140
139
|
<tr><td>百分比</td><td>固定 1–2 位小数</td><td class="num">42.6%</td></tr>
|
|
@@ -148,8 +147,8 @@ td.num { text-align: right; font-family: var(--mono); font-variant-numeric: tabu
|
|
|
148
147
|
</p>
|
|
149
148
|
|
|
150
149
|
<h2 class="rule-top">4 · 明确禁止(这些是"看起来专业但会骗人"的)</h2>
|
|
151
|
-
<div class="box bad">
|
|
152
|
-
<table>
|
|
150
|
+
<div class="box bad" data-claim-skip="这一块是「不要做」清单本身(一张表),不是某个组件的错写法 —— 要给它配正例栏,得先真的渲染一张 3D 图与一张 2D 图做对照,而本页没有图表实例可摆;表格尺寸量出来的是排版,不是观点">
|
|
151
|
+
<table aria-label="明确禁止的做法与原因">
|
|
153
152
|
<tr><th>不要做</th><th>为什么</th></tr>
|
|
154
153
|
<tr><td class="no">3D 图表</td><td>透视扭曲会<b>误导读数</b>(Tufte 的核心结论)</td></tr>
|
|
155
154
|
<tr><td class="no">双 Y 轴</td><td>两轴的交叉点可以被随意搬动 ⇒ <b>视觉在说谎</b></td></tr>
|
|
@@ -59,7 +59,7 @@ td.num { text-align: right; font-family: var(--mono); font-variant-numeric: tabu
|
|
|
59
59
|
data-mv-orbit="vendor/OrbitControls.js"></div>
|
|
60
60
|
|
|
61
61
|
<h2 class="rule-top">为什么是这样设计的</h2>
|
|
62
|
-
<table>
|
|
62
|
+
<table aria-label="3D 模型页的设计要求与做法">
|
|
63
63
|
<tr><th>要求</th><th>做法</th></tr>
|
|
64
64
|
<tr><td>首屏要快</td>
|
|
65
65
|
<td>3D 引擎<strong>点击后</strong>才 <code><script></code> 注入,
|
|
@@ -85,7 +85,7 @@ td.num { text-align: right; font-family: var(--mono); font-variant-numeric: tabu
|
|
|
85
85
|
</ul>
|
|
86
86
|
|
|
87
87
|
<h2 class="rule-top">体积现状</h2>
|
|
88
|
-
<table>
|
|
88
|
+
<table aria-label="各文件的体积与加载时机">
|
|
89
89
|
<tr><th>文件</th><th class="num">体积</th><th>何时加载</th></tr>
|
|
90
90
|
<tr><td><code>model-viewer.js</code>(本库)</td><td class="num">~9 KB</td><td><span class="ok">首屏</span></td></tr>
|
|
91
91
|
<tr><td><code>models/fox.glb</code></td><td class="num">159 KB</td><td>点击后(可 XHR 显示进度)</td></tr>
|
|
@@ -34,7 +34,6 @@
|
|
|
34
34
|
</head>
|
|
35
35
|
<body class="page page">
|
|
36
36
|
<main class="wrap">
|
|
37
|
-
<!-- demo-claim:skip 两块反例(读屏念什么、reduced-motion 动画)都是运行时或读屏输出,没有可量的元素属性 -->
|
|
38
37
|
<h1>sparkline · 迷你趋势图</h1>
|
|
39
38
|
<p class="lede">
|
|
40
39
|
在一行里显示"最近走势"。它是<strong>辅助</strong>不是图表 ——
|
|
@@ -124,7 +123,7 @@
|
|
|
124
123
|
</div>
|
|
125
124
|
|
|
126
125
|
<h2 class="rule-top">反例</h2>
|
|
127
|
-
<div class="box bad">
|
|
126
|
+
<div class="box bad" data-claim-skip="两栏画的是同一条走势线,差别只在旁边有没有一个数字 —— 而「该不该配数字」本页上文明写取决于数值重不重要(纯装饰小图可以不配),没有一条能划的界线;断言只能去数一个我自己编出来的选择器,那证明的是我编的标记,不是这件事">
|
|
128
127
|
<h3>反例:只放 sparkline,没有数字</h3>
|
|
129
128
|
<p class="small">
|
|
130
129
|
视觉上"很有信息",但读屏用户<strong>什么都不知道</strong> ——
|
package/API.md
CHANGED
|
@@ -24,6 +24,30 @@
|
|
|
24
24
|
各有各的调用方式。下表由`05-audit/global-api-probe.js`在真实浏览器里
|
|
25
25
|
探测生成,门禁 `api-doc` 会核对本文与实现是否一致。
|
|
26
26
|
|
|
27
|
+
### 模块化引入(ESM)
|
|
28
|
+
|
|
29
|
+
除了 `<script src>`,16 个交互组件的脚本还有一个 ESM 入口:
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
// 只要一个
|
|
33
|
+
import { Accordion } from 'agentcss/esm/accordion.mjs';
|
|
34
|
+
|
|
35
|
+
// 或者一次拿全(体积更大,Vite/Rollup 会按需摇树)
|
|
36
|
+
import { Accordion, Tabs, Select } from 'agentcss/esm';
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
三条容易踩的:
|
|
40
|
+
|
|
41
|
+
1. **入口是包装,不是第二份实现**。`esm/*.mjs` 只做
|
|
42
|
+
「导入副作用 + 把全局上那个对象 re-export」,所以
|
|
43
|
+
`Accordion === window.Accordion` 恒成立(门禁 `behavior-api` 断言这一点)。
|
|
44
|
+
它由 `05-audit/gen-esm.py` 生成,改源码后要重新生成,`esm-gen` 门禁会拦住漂移。
|
|
45
|
+
2. **无 DOM 环境可以直接 import**(SSR 安全)。但自动初始化会被跳过 ——
|
|
46
|
+
服务端没有 DOM 可扫,到浏览器里再调 `init()`/构造函数。16 个脚本
|
|
47
|
+
在 Node 里 `require` 全部成功(门禁的判据 A)。
|
|
48
|
+
3. **重复初始化是安全的**。`init()` 与构造函数都做了幂等处理:
|
|
49
|
+
同一 root 只会有一个实例,不会出现「点一次切换两次」。
|
|
50
|
+
|
|
27
51
|
### 四种接入形态
|
|
28
52
|
|
|
29
53
|
| 形态 | 调用方式 | 适合 |
|
|
@@ -327,6 +351,16 @@ python3 05-audit/prefix-build.py --prefix fl
|
|
|
327
351
|
|
|
328
352
|
## 破坏性变更怎么走
|
|
329
353
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
-
|
|
354
|
+
公开**名字**(令牌名 / 类名 / 全局与类型成员 / 事件名)的移除走**登记制**:
|
|
355
|
+
|
|
356
|
+
- 先在 `ai/deprecations.json` 里登记,写清 `deprecatedIn`、`removeIn`、`reason`
|
|
357
|
+
- 迁移窗口**至少跨一个次版本**:`0.7.x` 里标弃用 ⇒ 最早 `0.8.0` 才允许消失
|
|
358
|
+
- 到期才删。**提前删**和**到期不删**都会被门禁拦下(`05-audit/deprecation-gate.py`)
|
|
359
|
+
- 对外说明在 `docs/DEPRECATIONS.md`,那份文档与登记册由门禁**双向**比对,
|
|
360
|
+
漏告知(登记了没写进文档)与假承诺(文档写了、登记册没有)都会红
|
|
361
|
+
|
|
362
|
+
> 🔴 本节此前写的是「只在**大版本**移除」「弃用项先加警告并保留一个完整版本周期」——
|
|
363
|
+
> 两句都是错的:本库在 `0.7.x → 0.8.0` 就删过名字(`state--delayed`),
|
|
364
|
+
> 而且组件脚本从不打印运行时警告(移动端 WebView 里那是纯噪音)。
|
|
365
|
+
> `0.x` 期间按 semver 本就允许破坏性变更,把话说满比说清更伤人。
|
|
366
|
+
> 现在这两句被上面四条取代,覆盖范围与抓不到哪些名字见 `docs/DEPRECATIONS.md`。
|