@icen.ai/ui 0.4.0 → 0.8.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.
Files changed (155) hide show
  1. package/AGENTS.md +256 -0
  2. package/README.md +47 -13
  3. package/dist/base.css +31 -4
  4. package/dist/behaviors/accordion.d.mts +4 -0
  5. package/dist/behaviors/accordion.mjs +4 -3
  6. package/dist/behaviors/ai-chat.d.mts +57 -0
  7. package/dist/behaviors/ai-chat.mjs +557 -0
  8. package/dist/behaviors/ai-composer.d.mts +112 -0
  9. package/dist/behaviors/ai-composer.mjs +2032 -0
  10. package/dist/behaviors/ai-core.d.mts +151 -0
  11. package/dist/behaviors/ai-core.mjs +491 -0
  12. package/dist/behaviors/ai-diff.d.mts +53 -0
  13. package/dist/behaviors/ai-diff.mjs +282 -0
  14. package/dist/behaviors/ai-panel.d.mts +98 -0
  15. package/dist/behaviors/ai-panel.mjs +1012 -0
  16. package/dist/behaviors/ai-provider.d.mts +198 -0
  17. package/dist/behaviors/ai-provider.mjs +1055 -0
  18. package/dist/behaviors/ai-tool.d.mts +18 -0
  19. package/dist/behaviors/ai-tool.mjs +2125 -0
  20. package/dist/behaviors/ai-tools.d.mts +81 -0
  21. package/dist/behaviors/ai-tools.mjs +1658 -0
  22. package/dist/behaviors/back-top.d.mts +20 -0
  23. package/dist/behaviors/back-top.mjs +101 -0
  24. package/dist/behaviors/carousel.d.mts +4 -0
  25. package/dist/behaviors/carousel.mjs +34 -16
  26. package/dist/behaviors/charts.d.mts +250 -0
  27. package/dist/behaviors/charts.mjs +1301 -448
  28. package/dist/behaviors/command-palette.d.mts +8 -0
  29. package/dist/behaviors/command-palette.mjs +189 -0
  30. package/dist/behaviors/context-menu.d.mts +36 -0
  31. package/dist/behaviors/context-menu.mjs +6 -2
  32. package/dist/behaviors/copy.d.mts +4 -0
  33. package/dist/behaviors/copy.mjs +7 -6
  34. package/dist/behaviors/datatable.d.mts +78 -0
  35. package/dist/behaviors/datatable.mjs +54 -11
  36. package/dist/behaviors/date-picker.d.mts +4 -0
  37. package/dist/behaviors/date-picker.mjs +296 -0
  38. package/dist/behaviors/dropdown.d.mts +4 -0
  39. package/dist/behaviors/dropdown.mjs +7 -3
  40. package/dist/behaviors/input.d.mts +4 -0
  41. package/dist/behaviors/input.mjs +184 -8
  42. package/dist/behaviors/modal.d.mts +11 -0
  43. package/dist/behaviors/modal.mjs +11 -6
  44. package/dist/behaviors/nav.d.mts +7 -0
  45. package/dist/behaviors/nav.mjs +25 -9
  46. package/dist/behaviors/notification.d.mts +172 -0
  47. package/dist/behaviors/notification.mjs +908 -0
  48. package/dist/behaviors/popover.d.mts +46 -0
  49. package/dist/behaviors/popover.mjs +2 -1
  50. package/dist/behaviors/select.d.mts +4 -0
  51. package/dist/behaviors/select.mjs +268 -34
  52. package/dist/behaviors/sidebar.d.mts +4 -0
  53. package/dist/behaviors/sidebar.mjs +4 -3
  54. package/dist/behaviors/slider.d.mts +4 -0
  55. package/dist/behaviors/slider.mjs +4 -3
  56. package/dist/behaviors/split-pane.d.mts +4 -0
  57. package/dist/behaviors/split-pane.mjs +102 -0
  58. package/dist/behaviors/tabs.d.mts +8 -0
  59. package/dist/behaviors/tabs.mjs +44 -19
  60. package/dist/behaviors/tag-input.d.mts +4 -0
  61. package/dist/behaviors/tag-input.mjs +12 -3
  62. package/dist/behaviors/theme.d.mts +25 -0
  63. package/dist/behaviors/theme.mjs +3 -1
  64. package/dist/behaviors/toast.d.mts +26 -0
  65. package/dist/behaviors/toast.mjs +24 -18
  66. package/dist/behaviors/tree.d.mts +4 -0
  67. package/dist/behaviors/tree.mjs +4 -3
  68. package/dist/behaviors/upload.d.mts +4 -0
  69. package/dist/behaviors/upload.mjs +205 -17
  70. package/dist/components/ai-chat.css +1037 -0
  71. package/dist/components/ai-chat.mjs +3 -0
  72. package/dist/components/ai-composer.mjs +3 -0
  73. package/dist/components/ai-context.mjs +2 -0
  74. package/dist/components/ai-diff.css +311 -0
  75. package/dist/components/ai-diff.mjs +3 -0
  76. package/dist/components/ai-files.mjs +3 -0
  77. package/dist/components/ai-message.mjs +3 -0
  78. package/dist/components/ai-panel.css +682 -0
  79. package/dist/components/ai-reasoning.mjs +3 -0
  80. package/dist/components/ai-subagent.mjs +2 -0
  81. package/dist/components/ai-todo.mjs +2 -0
  82. package/dist/components/ai-tool-call.mjs +2 -0
  83. package/dist/components/ai-tool.css +532 -0
  84. package/dist/components/ai-usage.mjs +3 -0
  85. package/dist/components/back-top.css +88 -0
  86. package/dist/components/back-top.mjs +3 -0
  87. package/dist/components/badge.css +127 -0
  88. package/dist/components/badge.mjs +2 -0
  89. package/dist/components/breadcrumb.css +53 -0
  90. package/dist/components/btn.css +4 -7
  91. package/dist/components/card.css +66 -1
  92. package/dist/components/chart-bar.css +10 -0
  93. package/dist/components/chart-calendar.mjs +5 -0
  94. package/dist/components/chart-gauge.css +1 -1
  95. package/dist/components/chart-heatmap.css +40 -0
  96. package/dist/components/chart-scatter.css +24 -0
  97. package/dist/components/chart-scatter.mjs +4 -0
  98. package/dist/components/charts.css +86 -1
  99. package/dist/components/charts.mjs +1 -0
  100. package/dist/components/command-palette.css +246 -0
  101. package/dist/components/command-palette.mjs +3 -0
  102. package/dist/components/content.css +221 -8
  103. package/dist/components/copy.css +93 -0
  104. package/dist/components/copy.mjs +3 -0
  105. package/dist/components/datatable.css +4 -8
  106. package/dist/components/date-picker.css +240 -0
  107. package/dist/components/date-picker.mjs +3 -0
  108. package/dist/components/empty.css +69 -3
  109. package/dist/components/feedback.css +241 -10
  110. package/dist/components/form.css +129 -11
  111. package/dist/components/form.mjs +2 -0
  112. package/dist/components/input.css +25 -2
  113. package/dist/components/layout.css +36 -36
  114. package/dist/components/media.css +153 -6
  115. package/dist/components/menu.css +2 -2
  116. package/dist/components/modal.css +1 -1
  117. package/dist/components/nav.css +106 -2
  118. package/dist/components/notification.css +387 -0
  119. package/dist/components/notification.mjs +3 -0
  120. package/dist/components/pagination.css +1 -1
  121. package/dist/components/panel.css +104 -9
  122. package/dist/components/pill.css +82 -12
  123. package/dist/components/scroll-area.css +112 -0
  124. package/dist/components/scroll-area.mjs +2 -0
  125. package/dist/components/segmented.css +80 -5
  126. package/dist/components/segmented.mjs +1 -0
  127. package/dist/components/select.css +104 -17
  128. package/dist/components/sidebar.css +119 -1
  129. package/dist/components/slider.css +113 -0
  130. package/dist/components/split-pane.css +111 -0
  131. package/dist/components/split-pane.mjs +3 -0
  132. package/dist/components/stat.css +131 -12
  133. package/dist/components/steps.css +98 -1
  134. package/dist/components/switch.css +145 -7
  135. package/dist/components/table.css +111 -29
  136. package/dist/components/tabs.css +132 -22
  137. package/dist/components/tag-input.css +4 -4
  138. package/dist/components/tag.css +164 -0
  139. package/dist/components/tag.mjs +2 -0
  140. package/dist/components/toast.css +122 -5
  141. package/dist/components/toolbar.css +101 -0
  142. package/dist/components/toolbar.mjs +2 -0
  143. package/dist/components/tooltip.css +2 -2
  144. package/dist/components/upload.css +61 -4
  145. package/dist/index.d.mts +37 -0
  146. package/dist/index.mjs +9409 -929
  147. package/dist/registry.json +176 -4
  148. package/dist/retro-effects.css +21 -17
  149. package/dist/tokens/colors.css +4 -1
  150. package/dist/tokens/retro-effects.css +21 -17
  151. package/dist/tokens/style-profiles.css +21 -0
  152. package/dist/tokens.css +25 -1
  153. package/dist/ui.css +9616 -2839
  154. package/docs/spec/ai-native.md +659 -0
  155. package/package.json +15 -5
@@ -0,0 +1,3 @@
1
+ // @icen.ai/ui — kit: ai-chat(CSS + behavior 一行入口;构建产物,勿手改)
2
+ import './ai-chat.css';
3
+ export * from '../behaviors/ai-chat.mjs';
@@ -0,0 +1,3 @@
1
+ // @icen.ai/ui — kit: ai-composer(CSS + behavior 一行入口;构建产物,勿手改)
2
+ import './ai-chat.css';
3
+ export * from '../behaviors/ai-composer.mjs';
@@ -0,0 +1,2 @@
1
+ // @icen.ai/ui — kit: ai-context(CSS + behavior 一行入口;构建产物,勿手改)
2
+ import './ai-panel.css';
@@ -0,0 +1,311 @@
1
+ /*
2
+ * @icen.ai/ui — Component: ai-diff(AI 差异审阅 + 文件 chips,与 behaviors/ai-diff.ts 配套)
3
+ *
4
+ * 完整 DOM 契约(类名与规格 §4.6/§4.7 一致):
5
+ * <div class="ai-diff">
6
+ * <div class="ai-diff-file is-added|is-modified|is-deleted|is-renamed
7
+ * [.is-accepted|.is-rejected]" data-path="src/foo.ts">
8
+ * <div class="ai-diff-head" role="button" tabindex="0" aria-expanded="false">
9
+ * <span class="ai-diff-path">src/foo.ts</span> <!-- renamed:旧路径 → 新路径 -->
10
+ * <span class="ai-diff-stat"><b class="ai-diff-add">+12</b> <b class="ai-diff-del">−4</b></span>
11
+ * <span class="ai-diff-actions">
12
+ * <button type="button" data-ai-diff-accept>接受</button>
13
+ * <button type="button" data-ai-diff-reject>拒绝</button>
14
+ * </span>
15
+ * <span class="ai-diff-verdict" hidden>已接受|已拒绝</span> <!-- 状态章(JS 决策后显示) -->
16
+ * </div>
17
+ * <div class="ai-diff-body" hidden>
18
+ * <table class="ai-diff-table">
19
+ * <tr class="ai-diff-line--hunk"><td colspan="3">@@ -10,6 +10,8 @@ …</td></tr>
20
+ * <tr class="ai-diff-line--ctx|ai-diff-line--add|ai-diff-line--del">
21
+ * <td class="ai-diff-ln" aria-hidden="true">10</td>
22
+ * <td class="ai-diff-ln" aria-hidden="true">10</td>
23
+ * <td class="ai-diff-code">内容(行首符号由 ::before 提供)</td>
24
+ * </tr>
25
+ * </table>
26
+ * </div>
27
+ * </div>
28
+ * </div>
29
+ *
30
+ * 文件 chips(纯 CSS 族,无 behavior;文件图标由消费方/ai-panel.ts 注入 svg):
31
+ * <div class="ai-files">
32
+ * <span class="ai-file-chip is-added|is-modified|is-deleted
33
+ * ai-file-chip--ts|js|css|json|md|img|other">
34
+ * <span class="ai-file-icon">…svg…</span>src/foo.ts
35
+ * </span>
36
+ * </div>
37
+ *
38
+ * 状态视觉:
39
+ * add 行 = success 底 / del 行 = error 底 / hunk 行 = info 文字(bg-soft 底)
40
+ * 文件头状态色边(inset 左色条):added=success / modified=accent / deleted=error / renamed=info
41
+ * .is-accepted / .is-rejected = 整体淡化 + .ai-diff-verdict 状态章,actions 由 JS hidden
42
+ *
43
+ * 依赖:base.css(--icen-tx-* / --icen-ring / keyframes icen-pop-in)。
44
+ * 只消费 --token-* / --density-* / --radius-*;动画时长全部走组件局部变量。
45
+ */
46
+
47
+ /* ══════════════ ai-diff · 差异审阅 ══════════════ */
48
+
49
+ .ai-diff {
50
+ display: flex;
51
+ flex-direction: column;
52
+ gap: var(--density-space-sm);
53
+ font-size: var(--density-font-size-sm);
54
+ min-width: 0;
55
+ align-self: stretch; /* 输出容器宽度自稳定:宿主 flex/grid 居中时不 shrink-wrap */
56
+ }
57
+
58
+ .ai-diff-file {
59
+ border: 1px solid var(--token-line-soft);
60
+ border-radius: var(--radius-md);
61
+ background: var(--token-surface);
62
+ overflow: hidden;
63
+ min-width: 0;
64
+ animation: icen-pop-in var(--ai-diff-pop-duration, var(--icen-tx-fast));
65
+ }
66
+
67
+ /* 文件头状态色边(inset 色条避免 border 宽差导致布局抖动) */
68
+ .ai-diff-file.is-added { box-shadow: inset 3px 0 0 var(--token-success); }
69
+ .ai-diff-file.is-modified { box-shadow: inset 3px 0 0 var(--token-accent); }
70
+ .ai-diff-file.is-deleted { box-shadow: inset 3px 0 0 var(--token-error); }
71
+ .ai-diff-file.is-renamed { box-shadow: inset 3px 0 0 var(--token-info); }
72
+
73
+ /* 决策后淡化(状态章配色见 .ai-diff-verdict) */
74
+ .ai-diff-file.is-accepted,
75
+ .ai-diff-file.is-rejected {
76
+ opacity: 0.66;
77
+ transition: opacity var(--ai-diff-fade-duration, var(--icen-tx-normal));
78
+ }
79
+
80
+ /* ── head ── */
81
+
82
+ .ai-diff-head {
83
+ display: flex;
84
+ align-items: center;
85
+ gap: var(--density-space-sm);
86
+ padding: var(--density-space-xs) var(--density-space-sm);
87
+ min-width: 0;
88
+ cursor: pointer;
89
+ user-select: none;
90
+ transition: background-color var(--icen-tx-fast);
91
+ }
92
+ .ai-diff-head:hover {
93
+ background: var(--token-fill-1);
94
+ }
95
+ .ai-diff-head:focus-visible {
96
+ outline: none;
97
+ box-shadow: var(--icen-ring);
98
+ }
99
+
100
+ .ai-diff-path {
101
+ flex: 1;
102
+ min-width: 0;
103
+ overflow: hidden;
104
+ text-overflow: ellipsis;
105
+ white-space: nowrap;
106
+ font-family: var(--font-mono);
107
+ font-size: var(--density-font-size-xs);
108
+ color: var(--token-text);
109
+ }
110
+
111
+ .ai-diff-stat {
112
+ flex-shrink: 0;
113
+ display: inline-flex;
114
+ gap: var(--density-space-xs);
115
+ font-size: var(--density-font-size-xs);
116
+ font-variant-numeric: tabular-nums;
117
+ }
118
+ .ai-diff-add { color: var(--token-success); font-weight: 600; }
119
+ .ai-diff-del { color: var(--token-error); font-weight: 600; }
120
+
121
+ /* accept / reject 行内小钮(DOM 无固定类,按 data 属性定位) */
122
+ .ai-diff-actions {
123
+ flex-shrink: 0;
124
+ display: inline-flex;
125
+ gap: var(--density-space-xs);
126
+ }
127
+ .ai-diff-actions button {
128
+ padding: 3px 10px;
129
+ border: 1px solid var(--token-line-soft);
130
+ border-radius: var(--radius-full);
131
+ background: var(--token-surface);
132
+ color: var(--token-text-muted);
133
+ font-size: var(--density-font-size-xs);
134
+ line-height: 1.4;
135
+ cursor: pointer;
136
+ transition:
137
+ background-color var(--icen-tx-fast),
138
+ border-color var(--icen-tx-fast),
139
+ color var(--icen-tx-fast);
140
+ }
141
+ .ai-diff-actions button:focus-visible {
142
+ outline: none;
143
+ box-shadow: var(--icen-ring);
144
+ }
145
+ .ai-diff-actions [data-ai-diff-accept]:hover {
146
+ color: var(--token-success);
147
+ border-color: color-mix(in srgb, var(--token-success) 45%, transparent);
148
+ background: var(--token-success-muted);
149
+ }
150
+ .ai-diff-actions [data-ai-diff-reject]:hover {
151
+ color: var(--token-error);
152
+ border-color: color-mix(in srgb, var(--token-error) 45%, transparent);
153
+ background: var(--token-error-muted);
154
+ }
155
+
156
+ /* 状态章:决策后 JS 置 text + 去 hidden */
157
+ .ai-diff-verdict {
158
+ flex-shrink: 0;
159
+ padding: 2px 8px;
160
+ border: 1px solid currentColor;
161
+ border-radius: var(--radius-full);
162
+ font-size: var(--density-font-size-xs);
163
+ font-weight: 500;
164
+ line-height: 1.4;
165
+ }
166
+ .ai-diff-file.is-accepted .ai-diff-verdict { color: var(--token-success); background: var(--token-success-muted); }
167
+ .ai-diff-file.is-rejected .ai-diff-verdict { color: var(--token-error); background: var(--token-error-muted); }
168
+
169
+ /* ── body / 表格 ── */
170
+
171
+ .ai-diff-body {
172
+ border-top: 1px solid var(--token-line-soft);
173
+ overflow-x: auto;
174
+ }
175
+
176
+ .ai-diff-table {
177
+ width: 100%;
178
+ border-collapse: collapse;
179
+ font-family: var(--font-mono);
180
+ font-size: var(--density-font-size-xs);
181
+ line-height: 1.6;
182
+ }
183
+ .ai-diff-table td {
184
+ padding: 0 var(--density-space-xs);
185
+ vertical-align: top;
186
+ }
187
+
188
+ /* hunk 头:info 文字 */
189
+ .ai-diff-line--hunk td {
190
+ padding: 2px var(--density-space-sm);
191
+ background: var(--token-bg-soft);
192
+ color: var(--token-info);
193
+ user-select: none;
194
+ white-space: nowrap;
195
+ }
196
+
197
+ .ai-diff-ln {
198
+ width: 1%;
199
+ min-width: 3.5ch;
200
+ text-align: right;
201
+ color: var(--token-text-faint);
202
+ font-variant-numeric: tabular-nums;
203
+ user-select: none;
204
+ }
205
+ /* 行号区与代码区的分隔线画在第二列右侧 */
206
+ .ai-diff-ln + .ai-diff-ln {
207
+ border-right: 1px solid var(--token-line-soft);
208
+ }
209
+
210
+ /* add = success 底 / del = error 底 */
211
+ .ai-diff-line--add { background: var(--token-success-muted); }
212
+ .ai-diff-line--del { background: var(--token-error-muted); }
213
+
214
+ .ai-diff-code {
215
+ white-space: pre-wrap;
216
+ word-break: break-all;
217
+ padding-left: var(--density-space-sm);
218
+ }
219
+ /* 行首符号(选择 diff 内容时不带符号) */
220
+ .ai-diff-code::before {
221
+ user-select: none;
222
+ }
223
+ .ai-diff-line--add .ai-diff-code::before {
224
+ content: '+ ';
225
+ color: var(--token-success);
226
+ }
227
+ .ai-diff-line--del .ai-diff-code::before {
228
+ content: '− ';
229
+ color: var(--token-error);
230
+ }
231
+ .ai-diff-line--ctx .ai-diff-code::before {
232
+ content: ' ';
233
+ }
234
+
235
+ /* ══════════════ ai-files · 文件 chips(纯 CSS 族) ══════════════ */
236
+
237
+ .ai-files {
238
+ display: flex;
239
+ flex-wrap: wrap;
240
+ gap: var(--density-space-xs);
241
+ align-self: stretch; /* 容器自稳定;chip 自身保持内容宽 */
242
+ }
243
+
244
+ .ai-file-chip {
245
+ display: inline-flex;
246
+ align-items: center;
247
+ gap: 5px;
248
+ max-width: 100%;
249
+ padding: 2px 8px;
250
+ border: 1px solid var(--token-line-soft);
251
+ border-radius: var(--radius-full);
252
+ background: var(--token-surface);
253
+ color: var(--token-text-muted);
254
+ font-family: var(--font-mono);
255
+ font-size: var(--density-font-size-xs);
256
+ line-height: 1.6;
257
+ overflow: hidden;
258
+ text-overflow: ellipsis;
259
+ white-space: nowrap;
260
+ transition:
261
+ background-color var(--icen-tx-fast),
262
+ border-color var(--icen-tx-fast);
263
+ }
264
+ .ai-file-chip:hover {
265
+ background: var(--token-fill-1);
266
+ border-color: var(--token-line);
267
+ }
268
+
269
+ /* 状态色点(尾点,纯 CSS) */
270
+ .ai-file-chip::after {
271
+ content: '';
272
+ flex-shrink: 0;
273
+ width: 6px;
274
+ height: 6px;
275
+ border-radius: var(--radius-full);
276
+ background: var(--token-text-faint);
277
+ }
278
+ .ai-file-chip.is-added::after { background: var(--token-success); }
279
+ .ai-file-chip.is-modified::after { background: var(--token-accent); }
280
+ .ai-file-chip.is-deleted::after { background: var(--token-error); }
281
+
282
+ .ai-file-chip.is-deleted {
283
+ text-decoration: line-through;
284
+ opacity: 0.75;
285
+ }
286
+
287
+ .ai-file-icon {
288
+ flex-shrink: 0;
289
+ display: inline-flex;
290
+ color: var(--token-text-faint);
291
+ }
292
+ .ai-file-icon svg {
293
+ width: 13px;
294
+ height: 13px;
295
+ }
296
+
297
+ /* 文件类型色(语义 token):ts/js=冷调 accent-cold,css=accent,json=warning,md=info,img=success */
298
+ .ai-file-chip--ts .ai-file-icon,
299
+ .ai-file-chip--js .ai-file-icon { color: var(--token-accent-cold); }
300
+ .ai-file-chip--css .ai-file-icon { color: var(--token-accent); }
301
+ .ai-file-chip--json .ai-file-icon { color: var(--token-warning); }
302
+ .ai-file-chip--md .ai-file-icon { color: var(--token-info); }
303
+ .ai-file-chip--img .ai-file-icon { color: var(--token-success); }
304
+
305
+ /* ── 动效守卫 ── */
306
+
307
+ @media (prefers-reduced-motion: reduce) {
308
+ .ai-diff-file { animation: none; }
309
+ .ai-diff-file.is-accepted,
310
+ .ai-diff-file.is-rejected { transition: none; }
311
+ }
@@ -0,0 +1,3 @@
1
+ // @icen.ai/ui — kit: ai-diff(CSS + behavior 一行入口;构建产物,勿手改)
2
+ import './ai-diff.css';
3
+ export * from '../behaviors/ai-diff.mjs';
@@ -0,0 +1,3 @@
1
+ // @icen.ai/ui — kit: ai-files(CSS + behavior 一行入口;构建产物,勿手改)
2
+ import './ai-diff.css';
3
+ export { renderAiDiff } from '../behaviors/ai-diff.mjs';
@@ -0,0 +1,3 @@
1
+ // @icen.ai/ui — kit: ai-message(CSS + behavior 一行入口;构建产物,勿手改)
2
+ import './ai-chat.css';
3
+ export { renderAiMessage, createAiStream, initAiChat } from '../behaviors/ai-chat.mjs';