@icen.ai/ui 0.10.0 → 0.11.1

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.
Files changed (362) hide show
  1. package/AGENTS.md +79 -309
  2. package/LICENSE +21 -0
  3. package/README.md +43 -54
  4. package/dist/base.css +68 -22
  5. package/dist/behaviors/accordion.mjs +1 -1
  6. package/dist/behaviors/ai-branch.mjs +14 -0
  7. package/dist/behaviors/ai-chat.d.mts +2 -2
  8. package/dist/behaviors/ai-chat.mjs +66 -10
  9. package/dist/behaviors/ai-composer.d.mts +5 -5
  10. package/dist/behaviors/ai-composer.mjs +34 -10
  11. package/dist/behaviors/ai-core.mjs +14 -0
  12. package/dist/behaviors/ai-diff.mjs +14 -0
  13. package/dist/behaviors/ai-feedback.mjs +14 -0
  14. package/dist/behaviors/ai-panel.d.mts +2 -2
  15. package/dist/behaviors/ai-panel.mjs +14 -0
  16. package/dist/behaviors/ai-provider.d.mts +1 -1
  17. package/dist/behaviors/ai-provider.mjs +14 -0
  18. package/dist/behaviors/ai-threads.mjs +14 -0
  19. package/dist/behaviors/ai-tool.d.mts +1 -1
  20. package/dist/behaviors/ai-tool.mjs +299 -24
  21. package/dist/behaviors/ai-tools.mjs +1179 -28
  22. package/dist/behaviors/autocomplete.d.mts +1 -1
  23. package/dist/behaviors/autocomplete.mjs +14 -0
  24. package/dist/behaviors/back-top.mjs +14 -0
  25. package/dist/behaviors/carousel.mjs +21 -1
  26. package/dist/behaviors/cascader.mjs +27 -0
  27. package/dist/behaviors/charts.d.mts +12 -1
  28. package/dist/behaviors/charts.mjs +298 -20
  29. package/dist/behaviors/code-block.mjs +22 -1
  30. package/dist/behaviors/command-palette.mjs +3 -3
  31. package/dist/behaviors/context-menu.d.mts +2 -2
  32. package/dist/behaviors/context-menu.mjs +14 -0
  33. package/dist/behaviors/controls.d.mts +8 -8
  34. package/dist/behaviors/controls.mjs +50 -6
  35. package/dist/behaviors/copy.mjs +14 -0
  36. package/dist/behaviors/datatable.d.mts +3 -3
  37. package/dist/behaviors/datatable.mjs +89 -11
  38. package/dist/behaviors/date-picker.mjs +14 -0
  39. package/dist/behaviors/events.d.mts +10 -10
  40. package/dist/behaviors/events.mjs +11 -1
  41. package/dist/behaviors/form-validate.d.mts +10 -1
  42. package/dist/behaviors/form-validate.mjs +279 -4611
  43. package/dist/behaviors/i18n.d.mts +14 -0
  44. package/dist/behaviors/i18n.mjs +28 -0
  45. package/dist/behaviors/input.mjs +16 -0
  46. package/dist/behaviors/kb-access.d.mts +2 -2
  47. package/dist/behaviors/kb-access.mjs +21 -2
  48. package/dist/behaviors/kb-acl.d.mts +2 -2
  49. package/dist/behaviors/kb-acl.mjs +14 -0
  50. package/dist/behaviors/kb-answer.d.mts +2 -2
  51. package/dist/behaviors/kb-answer.mjs +298 -23
  52. package/dist/behaviors/kb-audit.d.mts +2 -2
  53. package/dist/behaviors/kb-audit.mjs +14 -0
  54. package/dist/behaviors/kb-canvas.d.mts +3 -3
  55. package/dist/behaviors/kb-canvas.mjs +14 -0
  56. package/dist/behaviors/kb-chain.d.mts +2 -2
  57. package/dist/behaviors/kb-chain.mjs +14 -0
  58. package/dist/behaviors/kb-checkpoint.d.mts +2 -2
  59. package/dist/behaviors/kb-checkpoint.mjs +14 -0
  60. package/dist/behaviors/kb-chunks.d.mts +2 -2
  61. package/dist/behaviors/kb-chunks.mjs +14 -0
  62. package/dist/behaviors/kb-citation.d.mts +2 -2
  63. package/dist/behaviors/kb-citation.mjs +33 -6
  64. package/dist/behaviors/kb-clarify.d.mts +2 -2
  65. package/dist/behaviors/kb-clarify.mjs +14 -0
  66. package/dist/behaviors/kb-conflict.d.mts +2 -2
  67. package/dist/behaviors/kb-conflict.mjs +14 -0
  68. package/dist/behaviors/kb-connector.d.mts +2 -2
  69. package/dist/behaviors/kb-connector.mjs +14 -0
  70. package/dist/behaviors/kb-core.d.mts +1 -1
  71. package/dist/behaviors/kb-core.mjs +14 -0
  72. package/dist/behaviors/kb-eval.d.mts +2 -2
  73. package/dist/behaviors/kb-eval.mjs +21 -2
  74. package/dist/behaviors/kb-explain.d.mts +2 -2
  75. package/dist/behaviors/kb-explain.mjs +26 -2
  76. package/dist/behaviors/kb-filter.d.mts +2 -2
  77. package/dist/behaviors/kb-filter.mjs +21 -2
  78. package/dist/behaviors/kb-gap.d.mts +2 -2
  79. package/dist/behaviors/kb-gap.mjs +14 -0
  80. package/dist/behaviors/kb-hittest.d.mts +2 -2
  81. package/dist/behaviors/kb-hittest.mjs +15 -1
  82. package/dist/behaviors/kb-metadata.mjs +19 -0
  83. package/dist/behaviors/kb-passage.d.mts +2 -2
  84. package/dist/behaviors/kb-passage.mjs +14 -0
  85. package/dist/behaviors/kb-pipeline.d.mts +2 -2
  86. package/dist/behaviors/kb-pipeline.mjs +14 -0
  87. package/dist/behaviors/kb-qa.mjs +14 -0
  88. package/dist/behaviors/kb-rerank.d.mts +2 -2
  89. package/dist/behaviors/kb-rerank.mjs +14 -0
  90. package/dist/behaviors/kb-retrieval.d.mts +2 -2
  91. package/dist/behaviors/kb-retrieval.mjs +31 -4
  92. package/dist/behaviors/kb-review.d.mts +2 -2
  93. package/dist/behaviors/kb-review.mjs +21 -2
  94. package/dist/behaviors/kb-sandbox.d.mts +2 -2
  95. package/dist/behaviors/kb-sandbox.mjs +20 -1
  96. package/dist/behaviors/kb-segment.d.mts +2 -2
  97. package/dist/behaviors/kb-segment.mjs +15 -1
  98. package/dist/behaviors/kb-select.mjs +21 -2
  99. package/dist/behaviors/kb-sources.d.mts +2 -2
  100. package/dist/behaviors/kb-sources.mjs +14 -0
  101. package/dist/behaviors/kb-sql.d.mts +2 -2
  102. package/dist/behaviors/kb-sql.mjs +14 -0
  103. package/dist/behaviors/kb-trace.d.mts +2 -2
  104. package/dist/behaviors/kb-trace.mjs +22 -3
  105. package/dist/behaviors/kb-visibility.d.mts +2 -2
  106. package/dist/behaviors/kb-visibility.mjs +14 -0
  107. package/dist/behaviors/kb-who-can.d.mts +2 -2
  108. package/dist/behaviors/kb-who-can.mjs +21 -2
  109. package/dist/behaviors/mentions.d.mts +1 -1
  110. package/dist/behaviors/mentions.mjs +14 -0
  111. package/dist/behaviors/modal.d.mts +1 -1
  112. package/dist/behaviors/modal.mjs +14 -0
  113. package/dist/behaviors/motion.d.mts +16 -0
  114. package/dist/behaviors/motion.mjs +39 -0
  115. package/dist/behaviors/notification.d.mts +2 -2
  116. package/dist/behaviors/notification.mjs +27 -3
  117. package/dist/behaviors/panel.mjs +14 -0
  118. package/dist/behaviors/scroll-area.d.mts +17 -0
  119. package/dist/behaviors/scroll-area.mjs +59 -0
  120. package/dist/behaviors/select.mjs +21 -2
  121. package/dist/behaviors/slider.mjs +3 -3
  122. package/dist/behaviors/split-pane.mjs +2 -0
  123. package/dist/behaviors/suggestions.mjs +14 -0
  124. package/dist/behaviors/tabs.mjs +10 -0
  125. package/dist/behaviors/tag-input.mjs +14 -0
  126. package/dist/behaviors/theme-switcher.d.mts +2 -2
  127. package/dist/behaviors/theme-switcher.mjs +30 -2
  128. package/dist/behaviors/theme.mjs +16 -2
  129. package/dist/behaviors/toast.d.mts +2 -2
  130. package/dist/behaviors/toast.mjs +14 -0
  131. package/dist/behaviors/tree-select.mjs +27 -0
  132. package/dist/behaviors/tree.mjs +4 -4
  133. package/dist/behaviors/upload.mjs +14 -0
  134. package/dist/behaviors/url-safety.d.mts +8 -0
  135. package/dist/behaviors/url-safety.mjs +11 -0
  136. package/dist/components/accordion.d.mts +2 -0
  137. package/dist/components/ai-branch.d.mts +2 -0
  138. package/dist/components/ai-chat.css +40 -33
  139. package/dist/components/ai-chat.d.mts +2 -0
  140. package/dist/components/ai-composer.d.mts +2 -0
  141. package/dist/components/ai-context.d.mts +2 -0
  142. package/dist/components/ai-context.mjs +1 -0
  143. package/dist/components/ai-diff.css +6 -6
  144. package/dist/components/ai-diff.d.mts +2 -0
  145. package/dist/components/ai-feedback.d.mts +2 -0
  146. package/dist/components/ai-files.d.mts +2 -0
  147. package/dist/components/ai-message.d.mts +2 -0
  148. package/dist/components/ai-panel.css +12 -10
  149. package/dist/components/ai-reasoning.d.mts +2 -0
  150. package/dist/components/ai-subagent.d.mts +2 -0
  151. package/dist/components/ai-subagent.mjs +1 -0
  152. package/dist/components/ai-threads.d.mts +2 -0
  153. package/dist/components/ai-todo.d.mts +2 -0
  154. package/dist/components/ai-todo.mjs +1 -0
  155. package/dist/components/ai-tool-call.d.mts +2 -0
  156. package/dist/components/ai-tool-call.mjs +1 -0
  157. package/dist/components/ai-tool.css +16 -16
  158. package/dist/components/ai-usage.d.mts +2 -0
  159. package/dist/components/alert.d.mts +2 -0
  160. package/dist/components/autocomplete.css +12 -12
  161. package/dist/components/autocomplete.d.mts +2 -0
  162. package/dist/components/avatar.d.mts +2 -0
  163. package/dist/components/back-top.css +47 -16
  164. package/dist/components/back-top.d.mts +2 -0
  165. package/dist/components/badge.css +1 -1
  166. package/dist/components/badge.d.mts +2 -0
  167. package/dist/components/breadcrumb.css +26 -8
  168. package/dist/components/breadcrumb.d.mts +2 -0
  169. package/dist/components/btn.css +67 -62
  170. package/dist/components/btn.d.mts +2 -0
  171. package/dist/components/card.css +22 -22
  172. package/dist/components/card.d.mts +2 -0
  173. package/dist/components/carousel.d.mts +2 -0
  174. package/dist/components/cascader.css +56 -35
  175. package/dist/components/cascader.d.mts +2 -0
  176. package/dist/components/chart-area.css +46 -0
  177. package/dist/components/chart-area.d.mts +2 -0
  178. package/dist/components/chart-bar.css +66 -19
  179. package/dist/components/chart-bar.d.mts +2 -0
  180. package/dist/components/chart-calendar.d.mts +2 -0
  181. package/dist/components/chart-gauge.css +23 -3
  182. package/dist/components/chart-gauge.d.mts +2 -0
  183. package/dist/components/chart-graph.css +15 -3
  184. package/dist/components/chart-graph.d.mts +2 -0
  185. package/dist/components/chart-heatmap.css +117 -95
  186. package/dist/components/chart-heatmap.d.mts +2 -0
  187. package/dist/components/chart-line.css +54 -0
  188. package/dist/components/chart-line.d.mts +2 -0
  189. package/dist/components/chart-map.d.mts +2 -0
  190. package/dist/components/chart-pie.css +29 -0
  191. package/dist/components/chart-pie.d.mts +2 -0
  192. package/dist/components/chart-radar.css +50 -1
  193. package/dist/components/chart-radar.d.mts +2 -0
  194. package/dist/components/chart-scatter.css +39 -2
  195. package/dist/components/chart-scatter.d.mts +2 -0
  196. package/dist/components/chart-sparkline.css +20 -0
  197. package/dist/components/chart-sparkline.d.mts +2 -0
  198. package/dist/components/chart-stack.css +16 -5
  199. package/dist/components/chart-stack.d.mts +2 -0
  200. package/dist/components/charts.css +109 -35
  201. package/dist/components/charts.d.mts +2 -0
  202. package/dist/components/code-block.css +10 -8
  203. package/dist/components/code-block.d.mts +2 -0
  204. package/dist/components/command-palette.css +45 -38
  205. package/dist/components/command-palette.d.mts +2 -0
  206. package/dist/components/content.css +62 -57
  207. package/dist/components/context-menu.d.mts +2 -0
  208. package/dist/components/copy.css +10 -10
  209. package/dist/components/copy.d.mts +2 -0
  210. package/dist/components/datatable.css +72 -59
  211. package/dist/components/datatable.d.mts +2 -0
  212. package/dist/components/date-picker.css +26 -26
  213. package/dist/components/date-picker.d.mts +2 -0
  214. package/dist/components/desc.d.mts +2 -0
  215. package/dist/components/dropdown.d.mts +2 -0
  216. package/dist/components/empty.css +16 -16
  217. package/dist/components/empty.d.mts +2 -0
  218. package/dist/components/feedback.css +31 -29
  219. package/dist/components/form-validate.css +20 -6
  220. package/dist/components/form-validate.d.mts +2 -0
  221. package/dist/components/form.css +17 -14
  222. package/dist/components/form.d.mts +2 -0
  223. package/dist/components/icon.css +21 -10
  224. package/dist/components/icon.d.mts +2 -0
  225. package/dist/components/input.css +22 -22
  226. package/dist/components/input.d.mts +2 -0
  227. package/dist/components/kb-access.d.mts +2 -0
  228. package/dist/components/kb-acl.d.mts +2 -0
  229. package/dist/components/kb-agent.css +134 -55
  230. package/dist/components/kb-answer.d.mts +2 -0
  231. package/dist/components/kb-audit.d.mts +2 -0
  232. package/dist/components/kb-canvas.d.mts +2 -0
  233. package/dist/components/kb-chain.d.mts +2 -0
  234. package/dist/components/kb-checkpoint.d.mts +2 -0
  235. package/dist/components/kb-chunks.d.mts +2 -0
  236. package/dist/components/kb-citation.d.mts +2 -0
  237. package/dist/components/kb-clarify.d.mts +2 -0
  238. package/dist/components/kb-conflict.d.mts +2 -0
  239. package/dist/components/kb-connector.d.mts +2 -0
  240. package/dist/components/kb-data.css +192 -80
  241. package/dist/components/kb-eval.d.mts +2 -0
  242. package/dist/components/kb-explain.d.mts +2 -0
  243. package/dist/components/kb-filter.d.mts +2 -0
  244. package/dist/components/kb-gap.d.mts +2 -0
  245. package/dist/components/kb-ground.css +165 -73
  246. package/dist/components/kb-hittest.d.mts +2 -0
  247. package/dist/components/kb-ingest.css +308 -113
  248. package/dist/components/kb-metadata.d.mts +2 -0
  249. package/dist/components/kb-ops.css +189 -75
  250. package/dist/components/kb-passage.d.mts +2 -0
  251. package/dist/components/kb-perm.css +158 -87
  252. package/dist/components/kb-pipeline.d.mts +2 -0
  253. package/dist/components/kb-qa.d.mts +2 -0
  254. package/dist/components/kb-rerank.d.mts +2 -0
  255. package/dist/components/kb-retrieval.d.mts +2 -0
  256. package/dist/components/kb-review.d.mts +2 -0
  257. package/dist/components/kb-sandbox.d.mts +2 -0
  258. package/dist/components/kb-search.css +353 -116
  259. package/dist/components/kb-segment.d.mts +2 -0
  260. package/dist/components/kb-sources.d.mts +2 -0
  261. package/dist/components/kb-sql.d.mts +2 -0
  262. package/dist/components/kb-trace.d.mts +2 -0
  263. package/dist/components/kb-visibility.d.mts +2 -0
  264. package/dist/components/kb-who-can.d.mts +2 -0
  265. package/dist/components/kb.css +60 -36
  266. package/dist/components/kb.d.mts +2 -0
  267. package/dist/components/kbd.d.mts +2 -0
  268. package/dist/components/layout.css +10 -10
  269. package/dist/components/layout.d.mts +2 -0
  270. package/dist/components/list.d.mts +2 -0
  271. package/dist/components/material-chinese.css +10 -0
  272. package/dist/components/material-soviet.css +10 -0
  273. package/dist/components/material.css +61 -18
  274. package/dist/components/media-card.d.mts +2 -0
  275. package/dist/components/media.css +22 -27
  276. package/dist/components/mentions.css +18 -17
  277. package/dist/components/mentions.d.mts +2 -0
  278. package/dist/components/menu.css +32 -28
  279. package/dist/components/modal.css +30 -27
  280. package/dist/components/modal.d.mts +2 -0
  281. package/dist/components/nav.css +48 -44
  282. package/dist/components/nav.d.mts +2 -0
  283. package/dist/components/notification.css +31 -25
  284. package/dist/components/notification.d.mts +2 -0
  285. package/dist/components/pagination.css +15 -13
  286. package/dist/components/pagination.d.mts +2 -0
  287. package/dist/components/panel.css +19 -20
  288. package/dist/components/panel.d.mts +2 -0
  289. package/dist/components/pill.css +8 -7
  290. package/dist/components/pill.d.mts +2 -0
  291. package/dist/components/popover.css +32 -23
  292. package/dist/components/popover.d.mts +2 -0
  293. package/dist/components/progress.d.mts +2 -0
  294. package/dist/components/rating.d.mts +2 -0
  295. package/dist/components/result.d.mts +2 -0
  296. package/dist/components/scroll-area.css +84 -112
  297. package/dist/components/scroll-area.d.mts +2 -0
  298. package/dist/components/scroll-area.mjs +1 -0
  299. package/dist/components/segmented.css +47 -29
  300. package/dist/components/segmented.d.mts +2 -0
  301. package/dist/components/select.css +80 -41
  302. package/dist/components/select.d.mts +2 -0
  303. package/dist/components/sidebar.css +42 -38
  304. package/dist/components/sidebar.d.mts +2 -0
  305. package/dist/components/skeleton.d.mts +2 -0
  306. package/dist/components/slider.css +26 -22
  307. package/dist/components/slider.d.mts +2 -0
  308. package/dist/components/spinner.d.mts +2 -0
  309. package/dist/components/split-pane.css +16 -7
  310. package/dist/components/split-pane.d.mts +2 -0
  311. package/dist/components/stat.css +17 -16
  312. package/dist/components/stat.d.mts +2 -0
  313. package/dist/components/steps.css +26 -26
  314. package/dist/components/steps.d.mts +2 -0
  315. package/dist/components/switch.css +78 -39
  316. package/dist/components/switch.d.mts +2 -0
  317. package/dist/components/table.css +54 -32
  318. package/dist/components/table.d.mts +2 -0
  319. package/dist/components/tabs.css +53 -32
  320. package/dist/components/tabs.d.mts +2 -0
  321. package/dist/components/tag-input.css +12 -8
  322. package/dist/components/tag-input.d.mts +2 -0
  323. package/dist/components/tag.css +20 -12
  324. package/dist/components/tag.d.mts +2 -0
  325. package/dist/components/theme-switcher.css +7 -7
  326. package/dist/components/theme-switcher.d.mts +2 -0
  327. package/dist/components/timeline.d.mts +2 -0
  328. package/dist/components/toast.css +34 -30
  329. package/dist/components/toast.d.mts +2 -0
  330. package/dist/components/toolbar.css +19 -18
  331. package/dist/components/toolbar.d.mts +2 -0
  332. package/dist/components/tooltip.css +9 -8
  333. package/dist/components/tooltip.d.mts +2 -0
  334. package/dist/components/tree-select.css +63 -40
  335. package/dist/components/tree-select.d.mts +2 -0
  336. package/dist/components/tree.d.mts +2 -0
  337. package/dist/components/upload.css +9 -11
  338. package/dist/components/upload.d.mts +2 -0
  339. package/dist/index.d.mts +85 -84
  340. package/dist/index.mjs +14644 -13935
  341. package/dist/react.d.mts +18 -18
  342. package/dist/react.mjs +377 -36
  343. package/dist/registry.json +797 -64
  344. package/dist/tokens/colors.css +6 -0
  345. package/dist/tokens/design.css +137 -31
  346. package/dist/tokens/dtcg.json +9592 -2008
  347. package/dist/tokens/figma.variables.json +7451 -2141
  348. package/dist/tokens/motion.css +51 -0
  349. package/dist/tokens/pixel.css +10 -0
  350. package/dist/tokens/scrollbars.css +40 -0
  351. package/dist/tokens/tokens-studio.json +8390 -1142
  352. package/dist/tokens/typography.css +33 -0
  353. package/dist/tokens.css +402 -82
  354. package/dist/ui.css +4196 -2163
  355. package/dist/vue.d.mts +17 -17
  356. package/dist/vue.mjs +371 -34
  357. package/docs/spec/charts-scale-a11y.md +115 -0
  358. package/docs/spec/design-philosophy.md +5 -5
  359. package/docs/spec/design-primitives.md +10 -10
  360. package/docs/spec/motion-typography.md +105 -0
  361. package/docs/spec/scrollbars.md +46 -0
  362. package/package.json +17 -3
@@ -116,6 +116,7 @@ var ICEN_LOCALE_ZH_CN = {
116
116
  "aiChat.roleTool": "\u5DE5",
117
117
  "aiChat.roleUser": "\u6211",
118
118
  "aiChat.thinking": "\u601D\u8003 {p0}",
119
+ "aiChat.thinkingNow": "\u6B63\u5728\u601D\u8003\u2026",
119
120
  /* ── aiComposer ── */
120
121
  "aiComposer.attachAgent": "\u4EE3\u7406",
121
122
  "aiComposer.library": "\u6DFB\u52A0\u4E0A\u4E0B\u6587\u4E0E\u547D\u4EE4",
@@ -298,6 +299,19 @@ var ICEN_LOCALE_ZH_CN = {
298
299
  "charts.noData": "\u6682\u65E0\u6570\u636E",
299
300
  "charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
300
301
  "charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
302
+ "charts.a11y.keyboardHint": "\u65B9\u5411\u952E\u9010\u70B9\u6D4F\u89C8\uFF0CHome/End \u8DF3\u9996\u5C3E\uFF0CEsc \u91CD\u7F6E\u7F29\u653E",
303
+ "charts.a11y.max": "\u6700\u5927 {p0}\uFF08{p1}\uFF09",
304
+ "charts.a11y.min": "\u6700\u5C0F {p0}\uFF08{p1}\uFF09",
305
+ "charts.a11y.point": "{p0}\uFF1A{p1}\uFF0C\u7B2C {p2}/{p3} \u70B9",
306
+ "charts.a11y.pointSeries": "{p0} \xB7 {p1}\uFF1A{p2}\uFF0C\u7B2C {p3}/{p4} \u70B9",
307
+ "charts.a11y.range": "\u7C7B\u76EE {p0} \u81F3 {p1}",
308
+ "charts.a11y.scatterRange": "x \u8303\u56F4 {p0}\u2013{p1}\uFF0Cy \u8303\u56F4 {p2}\u2013{p3}",
309
+ "charts.a11y.seriesCount": "{p0} \u4E2A\u7CFB\u5217",
310
+ "charts.a11y.tableCaption": "{p0} \u6570\u636E\u8868",
311
+ "charts.a11y.trend": "\u9996\u7CFB\u5217\u8D8B\u52BF{p0}",
312
+ "charts.a11y.trendDown": "\u4E0B\u964D",
313
+ "charts.a11y.trendFlat": "\u6301\u5E73",
314
+ "charts.a11y.trendUp": "\u4E0A\u5347",
301
315
  "charts.type.area": "\u9762\u79EF\u56FE",
302
316
  "charts.type.donut": "\u73AF\u5F62\u56FE",
303
317
  "charts.type.gauge": "\u4EEA\u8868\u76D8",
@@ -1167,7 +1181,8 @@ function withChrome(el, opts, hasLegend, paint, state, extras) {
1167
1181
  emitIcen(el, "icen:chart-legend-visibility", { visible: hidden ? false : true });
1168
1182
  });
1169
1183
  syncEye();
1170
- head.append(title, eye);
1184
+ if (hasLegend) head.append(title, eye);
1185
+ else head.append(title);
1171
1186
  el.append(head, body);
1172
1187
  paint(body);
1173
1188
  }
@@ -1268,7 +1283,7 @@ function renderVBar(el, opts) {
1268
1283
  wrap.appendChild(track);
1269
1284
  }
1270
1285
  body.append(wrap, labelsRow(labelsUsed));
1271
- if (seriesList.length > 1) body.appendChild(toggleLegend(seriesList.map((s, si) => ({ key: s.name, label: s.name, tone: s.tone ?? (si === 0 ? opts.tone : void 0), si })), wrap));
1286
+ if (seriesList.length > 1) body.appendChild(toggleLegend(seriesList.map((s, si) => ({ key: `${si}:${s.name}`, label: s.name, tone: s.tone ?? (si === 0 ? opts.tone : void 0), si })), wrap));
1272
1287
  });
1273
1288
  attachChartInteraction(el, "vbar");
1274
1289
  return el;
@@ -1363,8 +1378,10 @@ function renderDonut(el, opts) {
1363
1378
  "stroke-width": "14"
1364
1379
  }));
1365
1380
  let offset = 0;
1381
+ const gap = opts.segments.length > 1 ? 2.5 : 0;
1366
1382
  opts.segments.forEach((seg, segIndex) => {
1367
- const dash = seg.value / total * circumference;
1383
+ const arcLength = Math.max(0, seg.value / total * circumference);
1384
+ const dash = arcLength - Math.min(gap, arcLength * 0.1);
1368
1385
  const arc = svgEl("circle", {
1369
1386
  cx: "60",
1370
1387
  cy: "60",
@@ -1378,7 +1395,7 @@ function renderDonut(el, opts) {
1378
1395
  });
1379
1396
  setMarkData(arc, { index: segIndex, label: seg.label, value: seg.value });
1380
1397
  svg.appendChild(arc);
1381
- offset += dash;
1398
+ offset += arcLength;
1382
1399
  });
1383
1400
  const legend = document.createElement("div");
1384
1401
  legend.className = "icen-chart-legend";
@@ -1413,8 +1430,9 @@ function renderLine(el, opts) {
1413
1430
  const svg = svgEl("svg", { viewBox: `0 0 ${width} ${height}`, role: "img", "aria-label": chartAriaLabel(opts.title, t("charts.type.line")) });
1414
1431
  const defs = svgEl("defs", {});
1415
1432
  for (let i = 0; i < 4; i++) {
1416
- const y = pad + i * (height - pad * 2) / 3;
1433
+ const y = Math.round(pad + i * (height - pad * 2) / 3) + 0.5;
1417
1434
  svg.appendChild(svgEl("line", {
1435
+ class: i === 3 ? "icen-chart-grid icen-chart-baseline" : "icen-chart-grid",
1418
1436
  x1: String(pad),
1419
1437
  x2: String(width - pad),
1420
1438
  y1: String(y),
@@ -1498,7 +1516,7 @@ function renderLine(el, opts) {
1498
1516
  if (defs.firstChild) svg.insertBefore(defs, svg.firstChild);
1499
1517
  wrap.append(svg, pointLabelsRow(labelsUsed, width, pad));
1500
1518
  body.appendChild(wrap);
1501
- if (seriesList.length > 1) body.appendChild(toggleLegend(seriesList.map((s, si) => ({ key: s.name, label: s.name, tone: s.tone ?? (si === 0 ? opts.tone : void 0), si })), wrap));
1519
+ if (seriesList.length > 1) body.appendChild(toggleLegend(seriesList.map((s, si) => ({ key: `${si}:${s.name}`, label: s.name, tone: s.tone ?? (si === 0 ? opts.tone : void 0), si })), wrap));
1502
1520
  });
1503
1521
  if (el.dataset.icenChartBody == null) observeFluidWidth(el, () => renderLine(el, opts));
1504
1522
  attachChartInteraction(el, "line");
@@ -1520,8 +1538,10 @@ function renderArea(el, opts) {
1520
1538
  const max = maxOf(values);
1521
1539
  const tone = toneVar(opts.tone);
1522
1540
  const points = values.map((value, i) => ({
1541
+ i,
1523
1542
  x: values.length <= 1 ? width / 2 : pad + i / (values.length - 1) * (width - pad * 2),
1524
- y: height - pad - value / max * (height - pad * 2),
1543
+ /* 负值钳到基线(与折线图同口径):容器 overflow:visible,反向射出会压住下方内容 */
1544
+ y: height - pad - Math.max(0, value) / max * (height - pad * 2),
1525
1545
  value,
1526
1546
  label: labels[i] ?? ""
1527
1547
  }));
@@ -1540,8 +1560,9 @@ function renderArea(el, opts) {
1540
1560
  defs.appendChild(gradient);
1541
1561
  svg.appendChild(defs);
1542
1562
  for (let i = 0; i < 4; i++) {
1543
- const y = pad + i * (height - pad * 2) / 3;
1563
+ const y = Math.round(pad + i * (height - pad * 2) / 3) + 0.5;
1544
1564
  svg.appendChild(svgEl("line", {
1565
+ class: i === 3 ? "icen-chart-grid icen-chart-baseline" : "icen-chart-grid",
1545
1566
  x1: String(pad),
1546
1567
  x2: String(width - pad),
1547
1568
  y1: String(y),
@@ -1562,14 +1583,26 @@ function renderArea(el, opts) {
1562
1583
  for (const p of points) {
1563
1584
  const title = svgEl("title", {});
1564
1585
  title.textContent = `${p.label}: ${fmt(opts, p.value)}`;
1565
- const inv = svgEl("circle", {
1586
+ const dot = svgEl("circle", {
1566
1587
  cx: p.x.toFixed(1),
1567
1588
  cy: p.y.toFixed(1),
1568
- r: "2",
1569
- fill: "transparent"
1589
+ r: "2.6",
1590
+ fill: "var(--icen-token-card)",
1591
+ stroke: tone,
1592
+ "stroke-width": "1.6"
1593
+ });
1594
+ dot.appendChild(title);
1595
+ setMarkData(dot, { index: p.i, label: p.label, value: p.value });
1596
+ svg.appendChild(dot);
1597
+ const hit = svgEl("circle", {
1598
+ cx: p.x.toFixed(1),
1599
+ cy: p.y.toFixed(1),
1600
+ r: "9",
1601
+ fill: "transparent",
1602
+ "data-icen-chart-hit": "1"
1570
1603
  });
1571
- inv.appendChild(title);
1572
- svg.appendChild(inv);
1604
+ copyMarkData(hit, dot);
1605
+ svg.appendChild(hit);
1573
1606
  }
1574
1607
  wrap.append(svg, pointLabelsRow(labels, width, pad));
1575
1608
  body.appendChild(wrap);
@@ -1679,7 +1712,7 @@ function renderRadar(el, opts) {
1679
1712
  setMarkData(dot, { index: i, seriesIndex: si, seriesName: s.name || void 0, label: axes[i] ?? "", value: s.values[i] ?? 0 });
1680
1713
  svg.appendChild(dot);
1681
1714
  }
1682
- legendItems.push({ key: s.name || t("charts.seriesName", { p0: si + 1 }), label: s.name || t("charts.seriesName", { p0: si + 1 }), tone: s.tone, si });
1715
+ legendItems.push({ key: `${si}:${s.name || t("charts.seriesName", { p0: si + 1 })}`, label: s.name || t("charts.seriesName", { p0: si + 1 }), tone: s.tone, si });
1683
1716
  });
1684
1717
  wrap.appendChild(svg);
1685
1718
  body.appendChild(wrap);
@@ -1701,6 +1734,11 @@ function niceCeil(v) {
1701
1734
  else nice = 10;
1702
1735
  return nice * base;
1703
1736
  }
1737
+ function tickPrecision(min, max, steps) {
1738
+ const span = Math.abs(max - min);
1739
+ if (!Number.isFinite(span) || span <= 0) return 0;
1740
+ return Math.max(0, Math.ceil(-Math.log10(span / steps)));
1741
+ }
1704
1742
  function isoDate(d) {
1705
1743
  const m = String(d.getMonth() + 1).padStart(2, "0");
1706
1744
  const day = String(d.getDate()).padStart(2, "0");
@@ -1796,7 +1834,8 @@ function renderSparkline(el, opts) {
1796
1834
  const tone = toneVar(opts.tone);
1797
1835
  const points = values.map((value, i) => ({
1798
1836
  x: values.length <= 1 ? width / 2 : pad + i / (values.length - 1) * (width - pad * 2),
1799
- y: height - pad - value / max * (height - pad * 2),
1837
+ /* 负值钳到基线(与折线图同口径):viewBox 仅 28 高,反向射出更刺眼 */
1838
+ y: height - pad - Math.max(0, value) / max * (height - pad * 2),
1800
1839
  value
1801
1840
  }));
1802
1841
  const line = points.map((p, i) => `${i === 0 ? "M" : "L"}${p.x.toFixed(1)},${p.y.toFixed(1)}`).join(" ");
@@ -1921,6 +1960,7 @@ function renderCalendar(el, opts) {
1921
1960
  weekdayRow.appendChild(s);
1922
1961
  });
1923
1962
  const max = maxOf(entries.map((e) => e.value));
1963
+ entries.sort((a, b) => a.date.localeCompare(b.date));
1924
1964
  const pad = padFirstWeek(grid, entries[0].date, weekStart);
1925
1965
  let lastMonth = -1;
1926
1966
  entries.forEach((entry, i) => {
@@ -1979,8 +2019,9 @@ function renderScatter(el, opts) {
1979
2019
  const xAt = (x) => pad + (x - xMin) / (xMax - xMin) * (width - pad * 2);
1980
2020
  const yAt = (y) => height - pad - (y - yMin) / (yMax - yMin) * (height - pad * 2);
1981
2021
  for (let i = 0; i <= 3; i++) {
1982
- const y = pad + i * (height - pad * 2) / 3;
2022
+ const y = Math.round(pad + i * (height - pad * 2) / 3) + 0.5;
1983
2023
  svg.appendChild(svgEl("line", {
2024
+ class: i === 3 ? "icen-chart-grid icen-chart-baseline" : "icen-chart-grid",
1984
2025
  x1: String(pad),
1985
2026
  x2: String(width - pad),
1986
2027
  y1: String(y),
@@ -1996,12 +2037,13 @@ function renderScatter(el, opts) {
1996
2037
  "font-size": "8",
1997
2038
  fill: "var(--icen-token-text-faint)"
1998
2039
  });
1999
- txt.textContent = fmt(opts, Math.round(tv * 10) / 10);
2040
+ txt.textContent = fmt(opts, +tv.toFixed(tickPrecision(yMin, yMax, 3)));
2000
2041
  svg.appendChild(txt);
2001
2042
  }
2002
2043
  for (let i = 0; i <= 4; i++) {
2003
- const x = pad + i * (width - pad * 2) / 4;
2044
+ const x = Math.round(pad + i * (width - pad * 2) / 4) + 0.5;
2004
2045
  svg.appendChild(svgEl("line", {
2046
+ class: i === 0 ? "icen-chart-grid icen-chart-grid--v icen-chart-axis" : "icen-chart-grid icen-chart-grid--v",
2005
2047
  x1: String(x),
2006
2048
  x2: String(x),
2007
2049
  y1: String(pad),
@@ -2018,7 +2060,7 @@ function renderScatter(el, opts) {
2018
2060
  "font-size": "8",
2019
2061
  fill: "var(--icen-token-text-faint)"
2020
2062
  });
2021
- txt.textContent = fmt(opts, Math.round(tv * 10) / 10);
2063
+ txt.textContent = fmt(opts, +tv.toFixed(tickPrecision(xMin, xMax, 4)));
2022
2064
  svg.appendChild(txt);
2023
2065
  }
2024
2066
  if (opts.yLabel) {
@@ -2255,6 +2297,14 @@ function normalizeChartSpec(raw) {
2255
2297
  }
2256
2298
  if (s.zoom === "x" || s.zoom === "brush") spec.zoom = s.zoom;
2257
2299
  if (typeof s.loading === "boolean") spec.loading = s.loading;
2300
+ if (s.a11y && typeof s.a11y === "object") {
2301
+ const a = s.a11y;
2302
+ const a11y = {};
2303
+ if (typeof a.summary === "boolean") a11y.summary = a.summary;
2304
+ if (typeof a.table === "boolean") a11y.table = a.table;
2305
+ if (typeof a.keyboard === "boolean") a11y.keyboard = a.keyboard;
2306
+ if (Object.keys(a11y).length > 0) spec.a11y = a11y;
2307
+ }
2258
2308
  if (Array.isArray(s.marks)) {
2259
2309
  const marks = [];
2260
2310
  for (const raw2 of s.marks) {
@@ -2382,6 +2432,7 @@ function renderChartSkeleton(body) {
2382
2432
  body.appendChild(box);
2383
2433
  }
2384
2434
  var CHART_MARK_ACCENT = "var(--icen-token-accent)";
2435
+ var CHART_MARK_ACCENT_TEXT = "var(--icen-token-accent-text)";
2385
2436
  function markToneVar(tone) {
2386
2437
  switch (tone) {
2387
2438
  case "success":
@@ -2517,7 +2568,7 @@ function paintSvgChartMarks(root, view, marks, formatValue, warned) {
2517
2568
  y: String(clampNum(y - 10, 8, CHART_LINE_H - 4)),
2518
2569
  "text-anchor": "middle",
2519
2570
  "font-size": "8",
2520
- fill: CHART_MARK_ACCENT
2571
+ fill: CHART_MARK_ACCENT_TEXT
2521
2572
  });
2522
2573
  label.textContent = mark.text ?? mark.label;
2523
2574
  g.appendChild(label);
@@ -2609,6 +2660,81 @@ function paintVBarChartMarks(root, view, spec, marks, formatValue, warned) {
2609
2660
  function chartAriaLabel(title, typeName) {
2610
2661
  return title ? `${typeName}\uFF1A${title}` : typeName;
2611
2662
  }
2663
+ function summarizeChart(view, type, fmt2) {
2664
+ const series = view.series && view.series.length > 0 ? view.series : [{ name: "", values: view.values ?? [] }];
2665
+ const parts = [];
2666
+ if (series.length > 1) parts.push(t("charts.a11y.seriesCount", { p0: series.length }));
2667
+ if (type === "scatter") {
2668
+ const pts = view.points ?? [];
2669
+ if (pts.length > 0) {
2670
+ const xs = pts.map((p) => p.x);
2671
+ const ys = pts.map((p) => p.y);
2672
+ parts.push(t("charts.a11y.scatterRange", { p0: fmt2(Math.min(...xs)), p1: fmt2(Math.max(...xs)), p2: fmt2(Math.min(...ys)), p3: fmt2(Math.max(...ys)) }));
2673
+ }
2674
+ return parts.join("\uFF1B");
2675
+ }
2676
+ const labels = view.labels ?? [];
2677
+ if (labels.length > 1) parts.push(t("charts.a11y.range", { p0: labels[0], p1: labels[labels.length - 1] }));
2678
+ let min = Infinity;
2679
+ let max = -Infinity;
2680
+ let minAt = "";
2681
+ let maxAt = "";
2682
+ for (const s of series) {
2683
+ s.values.forEach((v, i) => {
2684
+ if (v < min) {
2685
+ min = v;
2686
+ minAt = labels[i] ?? String(i + 1);
2687
+ }
2688
+ if (v > max) {
2689
+ max = v;
2690
+ maxAt = labels[i] ?? String(i + 1);
2691
+ }
2692
+ });
2693
+ }
2694
+ if (Number.isFinite(min) && Number.isFinite(max)) {
2695
+ parts.push(t("charts.a11y.min", { p0: fmt2(min), p1: minAt }));
2696
+ parts.push(t("charts.a11y.max", { p0: fmt2(max), p1: maxAt }));
2697
+ }
2698
+ const first = series[0]?.values ?? [];
2699
+ if (first.length > 1) {
2700
+ const d = first[first.length - 1] - first[0];
2701
+ const key = Math.abs(d) < 1e-9 ? "charts.a11y.trendFlat" : d > 0 ? "charts.a11y.trendUp" : "charts.a11y.trendDown";
2702
+ parts.push(t("charts.a11y.trend", { p0: t(key) }));
2703
+ }
2704
+ return parts.join("\uFF1B");
2705
+ }
2706
+ function buildChartTable(view, spec, type, fmt2) {
2707
+ const table = document.createElement("table");
2708
+ table.className = "icen-chart-table";
2709
+ const caption = document.createElement("caption");
2710
+ caption.textContent = t("charts.a11y.tableCaption", { p0: spec.title ?? String(type) });
2711
+ table.appendChild(caption);
2712
+ const addRow = (target, cells, head) => {
2713
+ const tr = document.createElement("tr");
2714
+ for (const c of cells) {
2715
+ const cell = document.createElement(head ? "th" : "td");
2716
+ if (head) cell.scope = target.tagName === "THEAD" ? "col" : "row";
2717
+ cell.textContent = c;
2718
+ tr.appendChild(cell);
2719
+ }
2720
+ target.appendChild(tr);
2721
+ };
2722
+ const thead = table.createTHead();
2723
+ const tbody = table.createTBody();
2724
+ if (type === "scatter") {
2725
+ addRow(thead, ["x", "y"], true);
2726
+ for (const p of view.points ?? []) addRow(tbody, [fmt2(p.x), fmt2(p.y)], false);
2727
+ return table;
2728
+ }
2729
+ const series = view.series && view.series.length > 0 ? view.series : [{ name: "", values: view.values ?? [] }];
2730
+ const labels = view.labels ?? [];
2731
+ addRow(thead, ["", ...series.map((s, i) => s.name || String(i + 1))], true);
2732
+ const n = Math.max(labels.length, ...series.map((s) => s.values.length));
2733
+ for (let i = 0; i < n; i++) {
2734
+ addRow(tbody, [labels[i] ?? String(i + 1), ...series.map((s) => fmt2(s.values[i] ?? 0))], false);
2735
+ }
2736
+ return table;
2737
+ }
2612
2738
  function svgDimsOf(svg) {
2613
2739
  const vb = (svg.getAttribute("viewBox") ?? "").split(/\s+/).map(Number);
2614
2740
  const w = Number.isFinite(vb[2]) && (vb[2] ?? 0) > 0 ? vb[2] : CHART_LINE_W;
@@ -2949,6 +3075,7 @@ function renderChart(el, raw) {
2949
3075
  if (!isZoomableType(t2) || fullLength() < 2) return;
2950
3076
  const plot = t2 === "vbar" ? root.querySelector(".icen-chart-vbar") : root.querySelector(".icen-chart-line svg");
2951
3077
  if (!plot) return;
3078
+ plot.style.touchAction = current2.zoom === "x" ? "pan-y" : "none";
2952
3079
  const on = (type, fn) => {
2953
3080
  plot.addEventListener(type, fn);
2954
3081
  };
@@ -3004,6 +3131,149 @@ function renderChart(el, raw) {
3004
3131
  render();
3005
3132
  });
3006
3133
  };
3134
+ const KB_TYPES = /* @__PURE__ */ new Set(["line", "area", "vbar", "hbar", "scatter"]);
3135
+ const kbCursor = { si: 0, i: 0, active: false };
3136
+ let liveRegion = null;
3137
+ let a11ySeq = 0;
3138
+ const a11yOf = () => ({
3139
+ summary: current2.a11y?.summary !== false,
3140
+ table: current2.a11y?.table === true,
3141
+ keyboard: current2.a11y?.keyboard !== false
3142
+ });
3143
+ const seriesViewOf = (view) => view.series && view.series.length > 0 ? view.series : [{ name: "", values: view.values ?? [] }];
3144
+ const kbPointCount = (view) => typeOf() === "scatter" ? view.points?.length ?? 0 : Math.max(0, ...seriesViewOf(view).map((s) => s.values.length), view.labels?.length ?? 0);
3145
+ const kbCursorEl = () => {
3146
+ const t2 = typeOf();
3147
+ const view = viewOf();
3148
+ const series = seriesViewOf(view);
3149
+ const n = kbPointCount(view);
3150
+ if (n < 1) return null;
3151
+ const si = clampNum(kbCursor.si, 0, Math.max(0, series.length - 1));
3152
+ const i = clampNum(kbCursor.i, 0, n - 1);
3153
+ if (t2 === "line" || t2 === "area") {
3154
+ const svg = root.querySelector(".icen-chart-line svg");
3155
+ if (!svg) return null;
3156
+ const dots = svg.querySelectorAll("circle");
3157
+ let base = 0;
3158
+ for (let k = 0; k < si; k++) base += Math.min(series[k].values.length, n);
3159
+ return dots.item(base + i) ?? null;
3160
+ }
3161
+ if (t2 === "scatter") return root.querySelector(".icen-chart-scatter svg")?.querySelectorAll("circle").item(i) ?? null;
3162
+ if (t2 === "vbar") return root.querySelectorAll(".icen-chart-vbar-bar").item(series.length > 1 ? i * series.length + si : i) ?? null;
3163
+ if (t2 === "hbar") return root.querySelectorAll(".icen-chart-hbar-bar").item(i) ?? null;
3164
+ return null;
3165
+ };
3166
+ const announceKb = (text) => {
3167
+ if (!liveRegion || !liveRegion.isConnected) {
3168
+ liveRegion = document.createElement("div");
3169
+ liveRegion.className = "icen-chart-live";
3170
+ liveRegion.setAttribute("aria-live", "polite");
3171
+ root.appendChild(liveRegion);
3172
+ }
3173
+ liveRegion.textContent = "";
3174
+ liveRegion.textContent = text;
3175
+ };
3176
+ const applyKbCursor = () => {
3177
+ for (const el2 of root.querySelectorAll(".icen-chart-kb-focus")) el2.classList.remove("icen-chart-kb-focus");
3178
+ if (!kbCursor.active) return;
3179
+ kbCursorEl()?.classList.add("icen-chart-kb-focus");
3180
+ };
3181
+ const announceCursor = () => {
3182
+ const view = viewOf();
3183
+ const series = seriesViewOf(view);
3184
+ const n = kbPointCount(view);
3185
+ if (n < 1) return;
3186
+ const si = clampNum(kbCursor.si, 0, Math.max(0, series.length - 1));
3187
+ const i = clampNum(kbCursor.i, 0, Math.max(0, n - 1));
3188
+ const fmt2 = chartFormatValue(current2.format);
3189
+ if (typeOf() === "scatter") {
3190
+ const p = view.points?.[i];
3191
+ if (!p) return;
3192
+ announceKb(t("charts.a11y.point", { p0: `x ${fmt2(p.x)}`, p1: `y ${fmt2(p.y)}`, p2: i + 1, p3: n }));
3193
+ return;
3194
+ }
3195
+ const label = view.labels?.[i] ?? String(i + 1);
3196
+ const value = series[si]?.values[i] ?? 0;
3197
+ if (series.length > 1) announceKb(t("charts.a11y.pointSeries", { p0: series[si].name || String(si + 1), p1: label, p2: fmt2(value), p3: i + 1, p4: n }));
3198
+ else announceKb(t("charts.a11y.point", { p0: label, p1: fmt2(value), p2: i + 1, p3: n }));
3199
+ };
3200
+ const onKbKeydown = (e) => {
3201
+ const conf = a11yOf();
3202
+ if (!conf.keyboard || !KB_TYPES.has(typeOf())) return;
3203
+ const g = root.querySelector("[data-icen-chart-kb]");
3204
+ if (!g || e.target !== g) return;
3205
+ if (e.key === "Escape") {
3206
+ if (zoomWindow) {
3207
+ zoomWindow = null;
3208
+ kbCursor.active = false;
3209
+ render();
3210
+ }
3211
+ return;
3212
+ }
3213
+ const view = viewOf();
3214
+ const series = seriesViewOf(view);
3215
+ const n = kbPointCount(view);
3216
+ if (n < 1) return;
3217
+ const siMax = Math.max(0, series.length - 1);
3218
+ let moved = true;
3219
+ switch (e.key) {
3220
+ case "ArrowRight":
3221
+ kbCursor.i = clampNum(kbCursor.i + 1, 0, n - 1);
3222
+ break;
3223
+ case "ArrowLeft":
3224
+ kbCursor.i = clampNum(kbCursor.i - 1, 0, n - 1);
3225
+ break;
3226
+ case "ArrowDown":
3227
+ kbCursor.si = clampNum(kbCursor.si + 1, 0, siMax);
3228
+ break;
3229
+ case "ArrowUp":
3230
+ kbCursor.si = clampNum(kbCursor.si - 1, 0, siMax);
3231
+ break;
3232
+ case "Home":
3233
+ kbCursor.i = 0;
3234
+ break;
3235
+ case "End":
3236
+ kbCursor.i = n - 1;
3237
+ break;
3238
+ default:
3239
+ moved = false;
3240
+ }
3241
+ if (!moved) return;
3242
+ e.preventDefault();
3243
+ kbCursor.active = true;
3244
+ applyKbCursor();
3245
+ announceCursor();
3246
+ };
3247
+ root.addEventListener("keydown", onKbKeydown);
3248
+ const applyChartA11yPlus = (view, spec, type, formatValue) => {
3249
+ const conf = a11yOf();
3250
+ const graphic = root.querySelector('[role="img"]');
3251
+ if (!graphic) return;
3252
+ const body = root.querySelector(".icen-chart-body") ?? graphic.parentElement ?? root;
3253
+ const summaryParts = [];
3254
+ if (conf.summary) summaryParts.push(summarizeChart(view, type, formatValue));
3255
+ if (conf.keyboard && KB_TYPES.has(type)) summaryParts.push(t("charts.a11y.keyboardHint"));
3256
+ const summaryText = summaryParts.filter(Boolean).join("\uFF1B");
3257
+ if (summaryText) {
3258
+ const p = document.createElement("p");
3259
+ p.className = "icen-chart-summary";
3260
+ p.id = `icen-chart-a11y-${++a11ySeq}`;
3261
+ p.textContent = summaryText;
3262
+ body.appendChild(p);
3263
+ graphic.setAttribute("aria-describedby", p.id);
3264
+ } else {
3265
+ graphic.removeAttribute("aria-describedby");
3266
+ }
3267
+ if (conf.keyboard && KB_TYPES.has(type)) {
3268
+ graphic.setAttribute("tabindex", "0");
3269
+ graphic.setAttribute("data-icen-chart-kb", "");
3270
+ } else {
3271
+ graphic.removeAttribute("tabindex");
3272
+ graphic.removeAttribute("data-icen-chart-kb");
3273
+ }
3274
+ if (conf.table) body.appendChild(buildChartTable(view, spec, type, formatValue));
3275
+ applyKbCursor();
3276
+ };
3007
3277
  const render = () => {
3008
3278
  if (!current2.type) current2 = { ...current2, type: inferChartType(current2) };
3009
3279
  const spec = current2;
@@ -3075,9 +3345,16 @@ function renderChart(el, raw) {
3075
3345
  const graphic = root.querySelector('[role="img"]');
3076
3346
  if (graphic && !graphic.getAttribute("aria-label")) {
3077
3347
  graphic.setAttribute("aria-label", spec.title ? `${spec.title}\uFF08${type}\uFF09` : type);
3348
+ } else if (!graphic) {
3349
+ const dom = root.querySelector(".icen-chart-vbar, .icen-chart-hbar");
3350
+ if (dom) {
3351
+ dom.setAttribute("role", "img");
3352
+ dom.setAttribute("aria-label", spec.title ? `${spec.title}\uFF08${type}\uFF09` : type);
3353
+ }
3078
3354
  }
3079
3355
  }
3080
3356
  if (loading) return;
3357
+ applyChartA11yPlus(view, spec, type, formatValue);
3081
3358
  paintChartMarks(root, view, spec, formatValue, warnedMarks);
3082
3359
  bindZoomGesture();
3083
3360
  };
@@ -3159,6 +3436,7 @@ function renderChart(el, raw) {
3159
3436
  releaseFluidWidth(root);
3160
3437
  hiddenLegendKeys.delete(root);
3161
3438
  zoomDragCleanup?.();
3439
+ root.removeEventListener("keydown", onKbKeydown);
3162
3440
  root.textContent = "";
3163
3441
  root.classList.remove("is-loading");
3164
3442
  unbindEvents();
@@ -230,6 +230,7 @@ var ICEN_LOCALE_ZH_CN = {
230
230
  "aiChat.roleTool": "\u5DE5",
231
231
  "aiChat.roleUser": "\u6211",
232
232
  "aiChat.thinking": "\u601D\u8003 {p0}",
233
+ "aiChat.thinkingNow": "\u6B63\u5728\u601D\u8003\u2026",
233
234
  /* ── aiComposer ── */
234
235
  "aiComposer.attachAgent": "\u4EE3\u7406",
235
236
  "aiComposer.library": "\u6DFB\u52A0\u4E0A\u4E0B\u6587\u4E0E\u547D\u4EE4",
@@ -412,6 +413,19 @@ var ICEN_LOCALE_ZH_CN = {
412
413
  "charts.noData": "\u6682\u65E0\u6570\u636E",
413
414
  "charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
414
415
  "charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
416
+ "charts.a11y.keyboardHint": "\u65B9\u5411\u952E\u9010\u70B9\u6D4F\u89C8\uFF0CHome/End \u8DF3\u9996\u5C3E\uFF0CEsc \u91CD\u7F6E\u7F29\u653E",
417
+ "charts.a11y.max": "\u6700\u5927 {p0}\uFF08{p1}\uFF09",
418
+ "charts.a11y.min": "\u6700\u5C0F {p0}\uFF08{p1}\uFF09",
419
+ "charts.a11y.point": "{p0}\uFF1A{p1}\uFF0C\u7B2C {p2}/{p3} \u70B9",
420
+ "charts.a11y.pointSeries": "{p0} \xB7 {p1}\uFF1A{p2}\uFF0C\u7B2C {p3}/{p4} \u70B9",
421
+ "charts.a11y.range": "\u7C7B\u76EE {p0} \u81F3 {p1}",
422
+ "charts.a11y.scatterRange": "x \u8303\u56F4 {p0}\u2013{p1}\uFF0Cy \u8303\u56F4 {p2}\u2013{p3}",
423
+ "charts.a11y.seriesCount": "{p0} \u4E2A\u7CFB\u5217",
424
+ "charts.a11y.tableCaption": "{p0} \u6570\u636E\u8868",
425
+ "charts.a11y.trend": "\u9996\u7CFB\u5217\u8D8B\u52BF{p0}",
426
+ "charts.a11y.trendDown": "\u4E0B\u964D",
427
+ "charts.a11y.trendFlat": "\u6301\u5E73",
428
+ "charts.a11y.trendUp": "\u4E0A\u5347",
415
429
  "charts.type.area": "\u9762\u79EF\u56FE",
416
430
  "charts.type.donut": "\u73AF\u5F62\u56FE",
417
431
  "charts.type.gauge": "\u4EEA\u8868\u76D8",
@@ -1435,12 +1449,19 @@ function prepareFigure(fig) {
1435
1449
  if (!pre) return;
1436
1450
  pre.tabIndex = 0;
1437
1451
  pre.setAttribute("role", "region");
1438
- if (!pre.hasAttribute("aria-label")) pre.setAttribute("aria-label", fig.querySelector(".icen-code-block-file,.icen-code-block-title,.icen-code-block-lang")?.textContent || t("codeBlock.region"));
1439
1452
  if (!pre.id) {
1440
1453
  do {
1441
1454
  pre.id = "icen-code-region-" + ++regionSequence;
1442
1455
  } while (document.getElementById(pre.id) && document.getElementById(pre.id) !== pre);
1443
1456
  }
1457
+ {
1458
+ const base = (pre.getAttribute("aria-label") || fig.querySelector(".icen-code-block-file,.icen-code-block-title,.icen-code-block-lang")?.textContent || t("codeBlock.region")).trim();
1459
+ const used = /* @__PURE__ */ new Set();
1460
+ for (const region of document.querySelectorAll('pre[role="region"][aria-label]')) if (region !== pre) used.add(region.getAttribute("aria-label") ?? "");
1461
+ let label = base, n = 2;
1462
+ while (used.has(label)) label = `${base} ${n++}`;
1463
+ if (label !== base || !pre.hasAttribute("aria-label")) pre.setAttribute("aria-label", label);
1464
+ }
1444
1465
  fig.querySelectorAll("[data-icen-code-block-num],[data-icen-code-block-wrap],[data-icen-code-block-fold],.icen-code-block-tail").forEach((control) => control.setAttribute("aria-controls", pre.id));
1445
1466
  syncFold(fig, fig.classList.contains("is-folded"));
1446
1467
  }
@@ -244,6 +244,7 @@ function openCommandPalette(id, opts) {
244
244
  window.clearTimeout(closingState.timer);
245
245
  closingState.backdrop.removeEventListener("transitionend", closingState.onEnd);
246
246
  delete closingState.backdrop.dataset.icenState;
247
+ if (closingState.backdrop !== backdrop) closingState.backdrop.hidden = true;
247
248
  closingState = null;
248
249
  }
249
250
  backdrop.hidden = false;
@@ -286,7 +287,6 @@ function openCommandPalette(id, opts) {
286
287
  const active = panel.querySelector(".icen-command-palette-item.is-active");
287
288
  if (active && !isDisabledItem(active)) {
288
289
  e.preventDefault();
289
- if (!programmaticCommands.has(active)) emitMenuSelect(panel, active);
290
290
  active.click();
291
291
  }
292
292
  return;
@@ -300,7 +300,7 @@ function openCommandPalette(id, opts) {
300
300
  els[next]?.focus();
301
301
  }
302
302
  };
303
- window.addEventListener("keydown", keyHandler);
303
+ window.addEventListener("keydown", keyHandler, true);
304
304
  emitIcen(document, "icen:command-palette-open", {});
305
305
  }
306
306
  function closeCommandPalette(id, opts) {
@@ -313,7 +313,7 @@ function closeCommandPalette(id, opts) {
313
313
  if (openId !== id) return;
314
314
  openId = null;
315
315
  if (keyHandler) {
316
- window.removeEventListener("keydown", keyHandler);
316
+ window.removeEventListener("keydown", keyHandler, true);
317
317
  keyHandler = null;
318
318
  }
319
319
  document.body.style.overflow = prevBodyOverflow;
@@ -1,5 +1,5 @@
1
- import { IconName } from './icons.js';
2
- import { PanelSizing } from './popover.js';
1
+ import { IconName } from './icons.mjs';
2
+ import { PanelSizing } from './popover.mjs';
3
3
 
4
4
  interface ContextMenuEntry {
5
5
  label: string;
@@ -222,6 +222,7 @@ var ICEN_LOCALE_ZH_CN = {
222
222
  "aiChat.roleTool": "\u5DE5",
223
223
  "aiChat.roleUser": "\u6211",
224
224
  "aiChat.thinking": "\u601D\u8003 {p0}",
225
+ "aiChat.thinkingNow": "\u6B63\u5728\u601D\u8003\u2026",
225
226
  /* ── aiComposer ── */
226
227
  "aiComposer.attachAgent": "\u4EE3\u7406",
227
228
  "aiComposer.library": "\u6DFB\u52A0\u4E0A\u4E0B\u6587\u4E0E\u547D\u4EE4",
@@ -404,6 +405,19 @@ var ICEN_LOCALE_ZH_CN = {
404
405
  "charts.noData": "\u6682\u65E0\u6570\u636E",
405
406
  "charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
406
407
  "charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
408
+ "charts.a11y.keyboardHint": "\u65B9\u5411\u952E\u9010\u70B9\u6D4F\u89C8\uFF0CHome/End \u8DF3\u9996\u5C3E\uFF0CEsc \u91CD\u7F6E\u7F29\u653E",
409
+ "charts.a11y.max": "\u6700\u5927 {p0}\uFF08{p1}\uFF09",
410
+ "charts.a11y.min": "\u6700\u5C0F {p0}\uFF08{p1}\uFF09",
411
+ "charts.a11y.point": "{p0}\uFF1A{p1}\uFF0C\u7B2C {p2}/{p3} \u70B9",
412
+ "charts.a11y.pointSeries": "{p0} \xB7 {p1}\uFF1A{p2}\uFF0C\u7B2C {p3}/{p4} \u70B9",
413
+ "charts.a11y.range": "\u7C7B\u76EE {p0} \u81F3 {p1}",
414
+ "charts.a11y.scatterRange": "x \u8303\u56F4 {p0}\u2013{p1}\uFF0Cy \u8303\u56F4 {p2}\u2013{p3}",
415
+ "charts.a11y.seriesCount": "{p0} \u4E2A\u7CFB\u5217",
416
+ "charts.a11y.tableCaption": "{p0} \u6570\u636E\u8868",
417
+ "charts.a11y.trend": "\u9996\u7CFB\u5217\u8D8B\u52BF{p0}",
418
+ "charts.a11y.trendDown": "\u4E0B\u964D",
419
+ "charts.a11y.trendFlat": "\u6301\u5E73",
420
+ "charts.a11y.trendUp": "\u4E0A\u5347",
407
421
  "charts.type.area": "\u9762\u79EF\u56FE",
408
422
  "charts.type.donut": "\u73AF\u5F62\u56FE",
409
423
  "charts.type.gauge": "\u4EEA\u8868\u76D8",