@k8ordo/ui 1.0.0 → 2.1.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 (651) hide show
  1. package/README.md +206 -171
  2. package/dist/_virtual/_rolldown/runtime.mjs +13 -0
  3. package/dist/components/_internal/focus-ring.css +37 -0
  4. package/dist/components/_internal/focus-ring.module.mjs +9 -0
  5. package/dist/components/_internal/form-value.d.mts +33 -0
  6. package/dist/components/_internal/form-value.mjs +91 -0
  7. package/dist/components/_internal/high-contrast.css +18 -0
  8. package/dist/components/_internal/high-contrast.module.mjs +5 -0
  9. package/dist/components/_internal/ignore-changes.d.mts +20 -0
  10. package/dist/components/_internal/ignore-changes.mjs +37 -0
  11. package/dist/components/_internal/nav-link.css +78 -0
  12. package/dist/components/_internal/nav-link.d.mts +5 -0
  13. package/dist/components/_internal/nav-link.mjs +8 -0
  14. package/dist/components/_internal/nav-link.module.mjs +14 -0
  15. package/dist/components/_internal/sr-only.css +17 -0
  16. package/dist/components/_internal/sr-only.module.mjs +5 -0
  17. package/dist/components/_internal/status-tone.css +37 -0
  18. package/dist/components/_internal/status-tone.d.mts +20 -0
  19. package/dist/components/_internal/status-tone.mjs +22 -0
  20. package/dist/components/_internal/status-tone.module.mjs +14 -0
  21. package/dist/components/ai/_internal/attachment-preview.css +75 -0
  22. package/dist/components/ai/_internal/attachment-preview.d.mts +14 -0
  23. package/dist/components/ai/_internal/attachment-preview.mjs +50 -0
  24. package/dist/components/ai/_internal/attachment-preview.module.mjs +14 -0
  25. package/dist/components/ai/_internal/collapsible.css +62 -0
  26. package/dist/components/ai/_internal/collapsible.d.mts +4 -3
  27. package/dist/components/ai/_internal/collapsible.mjs +42 -33
  28. package/dist/components/ai/_internal/collapsible.module.mjs +12 -0
  29. package/dist/components/ai/_internal/icons.d.mts +7 -0
  30. package/dist/components/ai/_internal/icons.mjs +14 -0
  31. package/dist/components/ai/_internal/streaming-cursor.css +28 -0
  32. package/dist/components/ai/_internal/streaming-cursor.d.mts +2 -3
  33. package/dist/components/ai/_internal/streaming-cursor.mjs +2 -1
  34. package/dist/components/ai/_internal/streaming-cursor.module.mjs +8 -0
  35. package/dist/components/ai/attachment/attachment.css +17 -0
  36. package/dist/components/ai/attachment/attachment.d.mts +14 -0
  37. package/dist/components/ai/attachment/attachment.mjs +25 -0
  38. package/dist/components/ai/attachment/attachment.module.mjs +8 -0
  39. package/dist/components/ai/attachment/index.d.mts +13 -0
  40. package/dist/components/ai/attachment/index.mjs +8 -0
  41. package/dist/components/ai/conversation/conversation.css +71 -0
  42. package/dist/components/ai/conversation/conversation.d.mts +8 -11
  43. package/dist/components/ai/conversation/conversation.mjs +39 -40
  44. package/dist/components/ai/conversation/conversation.module.mjs +11 -0
  45. package/dist/components/ai/conversation/index.d.mts +15 -2
  46. package/dist/components/ai/conversation/index.mjs +8 -1
  47. package/dist/components/ai/index.d.mts +8 -10
  48. package/dist/components/ai/index.mjs +7 -5
  49. package/dist/components/ai/message/index.d.mts +39 -2
  50. package/dist/components/ai/message/index.mjs +12 -1
  51. package/dist/components/ai/message/message.css +71 -0
  52. package/dist/components/ai/message/message.d.mts +33 -5
  53. package/dist/components/ai/message/message.mjs +98 -12
  54. package/dist/components/ai/message/message.module.mjs +18 -0
  55. package/dist/components/ai/prompt-input/index.d.mts +31 -2
  56. package/dist/components/ai/prompt-input/index.mjs +10 -1
  57. package/dist/components/ai/prompt-input/prompt-input.css +101 -0
  58. package/dist/components/ai/prompt-input/prompt-input.d.mts +15 -8
  59. package/dist/components/ai/prompt-input/prompt-input.mjs +152 -42
  60. package/dist/components/ai/prompt-input/prompt-input.module.mjs +15 -0
  61. package/dist/components/ai/reasoning/reasoning.css +16 -0
  62. package/dist/components/ai/reasoning/reasoning.d.mts +2 -3
  63. package/dist/components/ai/reasoning/reasoning.mjs +5 -5
  64. package/dist/components/ai/reasoning/reasoning.module.mjs +8 -0
  65. package/dist/components/ai/response/response.css +453 -0
  66. package/dist/components/ai/response/response.d.mts +4 -6
  67. package/dist/components/ai/response/response.mjs +20 -15
  68. package/dist/components/ai/response/response.module.mjs +8 -0
  69. package/dist/components/ai/source/index.d.mts +12 -0
  70. package/dist/components/ai/source/index.mjs +8 -0
  71. package/dist/components/ai/source/source.css +54 -0
  72. package/dist/components/ai/source/source.d.mts +13 -0
  73. package/dist/components/ai/source/source.mjs +51 -0
  74. package/dist/components/ai/source/source.module.mjs +12 -0
  75. package/dist/components/ai/suggestion/index.d.mts +13 -2
  76. package/dist/components/ai/suggestion/index.mjs +7 -1
  77. package/dist/components/ai/suggestion/suggestion.css +32 -0
  78. package/dist/components/ai/suggestion/suggestion.d.mts +3 -6
  79. package/dist/components/ai/suggestion/suggestion.mjs +8 -11
  80. package/dist/components/ai/suggestion/suggestion.module.mjs +8 -0
  81. package/dist/components/ai/tool-invocation/approval-bar.css +26 -0
  82. package/dist/components/ai/tool-invocation/approval-bar.d.mts +11 -0
  83. package/dist/components/ai/tool-invocation/approval-bar.mjs +59 -0
  84. package/dist/components/ai/tool-invocation/approval-bar.module.mjs +9 -0
  85. package/dist/components/ai/tool-invocation/tool-invocation.css +55 -0
  86. package/dist/components/ai/tool-invocation/tool-invocation.d.mts +5 -5
  87. package/dist/components/ai/tool-invocation/tool-invocation.mjs +39 -18
  88. package/dist/components/ai/tool-invocation/tool-invocation.module.mjs +15 -0
  89. package/dist/components/ai/types.d.mts +21 -4
  90. package/dist/components/buttons/button/button.css +158 -0
  91. package/dist/components/buttons/button/button.d.mts +32 -9
  92. package/dist/components/buttons/button/button.mjs +46 -36
  93. package/dist/components/buttons/button/button.module.mjs +23 -0
  94. package/dist/components/buttons/button/index.d.mts +2 -2
  95. package/dist/components/buttons/copy-button/copy-button.css +15 -0
  96. package/dist/components/buttons/copy-button/copy-button.d.mts +10 -0
  97. package/dist/components/buttons/copy-button/copy-button.mjs +70 -0
  98. package/dist/components/buttons/copy-button/copy-button.module.mjs +8 -0
  99. package/dist/components/buttons/copy-button/index.d.mts +2 -0
  100. package/dist/components/buttons/copy-button/index.mjs +2 -0
  101. package/dist/components/buttons/icon-button/icon-button.css +81 -0
  102. package/dist/components/buttons/icon-button/icon-button.d.mts +39 -12
  103. package/dist/components/buttons/icon-button/icon-button.mjs +71 -58
  104. package/dist/components/buttons/icon-button/icon-button.module.mjs +15 -0
  105. package/dist/components/buttons/icon-button/index.d.mts +2 -2
  106. package/dist/components/buttons/toolbar/index.d.mts +14 -0
  107. package/dist/components/buttons/toolbar/index.mjs +9 -0
  108. package/dist/components/buttons/toolbar/toolbar.css +30 -0
  109. package/dist/components/buttons/toolbar/toolbar.d.mts +18 -0
  110. package/dist/components/buttons/toolbar/toolbar.mjs +111 -0
  111. package/dist/components/buttons/toolbar/toolbar.module.mjs +9 -0
  112. package/dist/components/data-display/accordion/accordion-button.css +48 -0
  113. package/dist/components/data-display/accordion/accordion-button.d.mts +2 -3
  114. package/dist/components/data-display/accordion/accordion-button.mjs +5 -4
  115. package/dist/components/data-display/accordion/accordion-button.module.mjs +9 -0
  116. package/dist/components/data-display/accordion/accordion-item.css +11 -0
  117. package/dist/components/data-display/accordion/accordion-item.d.mts +2 -3
  118. package/dist/components/data-display/accordion/accordion-item.mjs +2 -1
  119. package/dist/components/data-display/accordion/accordion-item.module.mjs +5 -0
  120. package/dist/components/data-display/accordion/accordion-panel.css +9 -0
  121. package/dist/components/data-display/accordion/accordion-panel.d.mts +2 -3
  122. package/dist/components/data-display/accordion/accordion-panel.mjs +2 -2
  123. package/dist/components/data-display/accordion/accordion-panel.module.mjs +5 -0
  124. package/dist/components/data-display/accordion/accordion.css +19 -0
  125. package/dist/components/data-display/accordion/accordion.d.mts +2 -3
  126. package/dist/components/data-display/accordion/accordion.mjs +2 -1
  127. package/dist/components/data-display/accordion/accordion.module.mjs +5 -0
  128. package/dist/components/data-display/accordion/context.d.mts +3 -3
  129. package/dist/components/data-display/accordion/index.d.mts +2 -3
  130. package/dist/components/data-display/avatar/avatar.css +95 -0
  131. package/dist/components/data-display/avatar/avatar.d.mts +2 -3
  132. package/dist/components/data-display/avatar/avatar.mjs +22 -6
  133. package/dist/components/data-display/avatar/avatar.module.mjs +18 -0
  134. package/dist/components/data-display/badge/badge.css +160 -0
  135. package/dist/components/data-display/badge/badge.d.mts +2 -3
  136. package/dist/components/data-display/badge/badge.mjs +30 -5
  137. package/dist/components/data-display/badge/badge.module.mjs +21 -0
  138. package/dist/components/data-display/card/card.css +44 -0
  139. package/dist/components/data-display/card/card.d.mts +2 -3
  140. package/dist/components/data-display/card/card.mjs +12 -2
  141. package/dist/components/data-display/card/card.module.mjs +12 -0
  142. package/dist/components/data-display/carousel/carousel.css +83 -0
  143. package/dist/components/data-display/carousel/carousel.d.mts +11 -0
  144. package/dist/components/data-display/carousel/carousel.mjs +186 -0
  145. package/dist/components/data-display/carousel/carousel.module.mjs +18 -0
  146. package/dist/components/data-display/carousel/index.d.mts +11 -0
  147. package/dist/components/data-display/carousel/index.mjs +8 -0
  148. package/dist/components/data-display/code/code.css +37 -0
  149. package/dist/components/data-display/code/code.d.mts +2 -3
  150. package/dist/components/data-display/code/code.mjs +7 -6
  151. package/dist/components/data-display/code/code.module.mjs +9 -0
  152. package/dist/components/data-display/code/find-all-colors.d.mts +2 -3
  153. package/dist/components/data-display/code/find-all-colors.mjs +0 -161
  154. package/dist/components/data-display/code-block/code-block.css +161 -0
  155. package/dist/components/data-display/code-block/code-block.d.mts +12 -0
  156. package/dist/components/data-display/code-block/code-block.mjs +44 -0
  157. package/dist/components/data-display/code-block/code-block.module.mjs +11 -0
  158. package/dist/components/data-display/code-block/highlight.d.mts +9 -0
  159. package/dist/components/data-display/code-block/highlight.mjs +54 -0
  160. package/dist/components/data-display/code-block/index.d.mts +2 -0
  161. package/dist/components/data-display/code-block/index.mjs +2 -0
  162. package/dist/components/data-display/data-table/data-table.css +74 -0
  163. package/dist/components/data-display/data-table/data-table.d.mts +31 -0
  164. package/dist/components/data-display/data-table/data-table.mjs +155 -0
  165. package/dist/components/data-display/data-table/data-table.module.mjs +14 -0
  166. package/dist/components/data-display/data-table/index.d.mts +2 -0
  167. package/dist/components/data-display/data-table/index.mjs +2 -0
  168. package/dist/components/data-display/heading/heading.css +99 -0
  169. package/dist/components/data-display/heading/heading.d.mts +2 -3
  170. package/dist/components/data-display/heading/heading.mjs +15 -14
  171. package/dist/components/data-display/heading/heading.module.mjs +20 -0
  172. package/dist/components/data-display/kbd/index.d.mts +2 -0
  173. package/dist/components/data-display/kbd/index.mjs +2 -0
  174. package/dist/components/data-display/kbd/kbd.css +21 -0
  175. package/dist/components/data-display/kbd/kbd.d.mts +8 -0
  176. package/dist/components/data-display/kbd/kbd.mjs +17 -0
  177. package/dist/components/data-display/kbd/kbd.module.mjs +5 -0
  178. package/dist/components/data-display/prose/index.d.mts +2 -0
  179. package/dist/components/data-display/prose/index.mjs +2 -0
  180. package/dist/components/data-display/prose/prose.css +253 -0
  181. package/dist/components/data-display/prose/prose.d.mts +5 -0
  182. package/dist/components/data-display/prose/prose.mjs +10 -0
  183. package/dist/components/data-display/prose/prose.module.mjs +5 -0
  184. package/dist/components/data-display/table/table.css +107 -0
  185. package/dist/components/data-display/table/table.d.mts +10 -9
  186. package/dist/components/data-display/table/table.mjs +26 -15
  187. package/dist/components/data-display/table/table.module.mjs +22 -0
  188. package/dist/components/data-display/tree/index.d.mts +2 -0
  189. package/dist/components/data-display/tree/index.mjs +2 -0
  190. package/dist/components/data-display/tree/tree.css +84 -0
  191. package/dist/components/data-display/tree/tree.d.mts +20 -0
  192. package/dist/components/data-display/tree/tree.mjs +151 -0
  193. package/dist/components/data-display/tree/tree.module.mjs +15 -0
  194. package/dist/components/feedback/alert/alert.css +42 -0
  195. package/dist/components/feedback/alert/alert.d.mts +3 -4
  196. package/dist/components/feedback/alert/alert.mjs +20 -23
  197. package/dist/components/feedback/alert/alert.module.mjs +14 -0
  198. package/dist/components/feedback/callout/callout.css +38 -0
  199. package/dist/components/feedback/callout/callout.d.mts +10 -0
  200. package/dist/components/feedback/callout/callout.mjs +38 -0
  201. package/dist/components/feedback/callout/callout.module.mjs +11 -0
  202. package/dist/components/feedback/callout/index.d.mts +2 -0
  203. package/dist/components/feedback/callout/index.mjs +2 -0
  204. package/dist/components/feedback/empty-state/empty-state.css +36 -0
  205. package/dist/components/feedback/empty-state/empty-state.d.mts +10 -0
  206. package/dist/components/feedback/empty-state/empty-state.mjs +27 -0
  207. package/dist/components/feedback/empty-state/empty-state.module.mjs +11 -0
  208. package/dist/components/feedback/empty-state/index.d.mts +2 -0
  209. package/dist/components/feedback/empty-state/index.mjs +2 -0
  210. package/dist/components/feedback/progress/progress.css +78 -0
  211. package/dist/components/feedback/progress/progress.d.mts +5 -5
  212. package/dist/components/feedback/progress/progress.mjs +17 -3
  213. package/dist/components/feedback/progress/progress.module.mjs +12 -0
  214. package/dist/components/feedback/skeleton/skeleton.css +64 -0
  215. package/dist/components/feedback/skeleton/skeleton.d.mts +2 -3
  216. package/dist/components/feedback/skeleton/skeleton.mjs +19 -2
  217. package/dist/components/feedback/skeleton/skeleton.module.mjs +17 -0
  218. package/dist/components/feedback/spinner/spinner.css +40 -0
  219. package/dist/components/feedback/spinner/spinner.d.mts +2 -3
  220. package/dist/components/feedback/spinner/spinner.mjs +13 -7
  221. package/dist/components/feedback/spinner/spinner.module.mjs +12 -0
  222. package/dist/components/feedback/toast/context.d.mts +8 -9
  223. package/dist/components/feedback/toast/provider.css +69 -0
  224. package/dist/components/feedback/toast/provider.d.mts +2 -3
  225. package/dist/components/feedback/toast/provider.mjs +17 -13
  226. package/dist/components/feedback/toast/provider.module.mjs +12 -0
  227. package/dist/components/feedback/toast/toast.d.mts +2 -3
  228. package/dist/components/form/autocomplete/autocomplete.css +154 -0
  229. package/dist/components/form/autocomplete/autocomplete.d.mts +2 -3
  230. package/dist/components/form/autocomplete/autocomplete.mjs +70 -46
  231. package/dist/components/form/autocomplete/autocomplete.module.mjs +21 -0
  232. package/dist/components/form/calendar/calendar.css +98 -0
  233. package/dist/components/form/calendar/calendar.d.mts +14 -0
  234. package/dist/components/form/calendar/calendar.mjs +182 -0
  235. package/dist/components/form/calendar/calendar.module.mjs +18 -0
  236. package/dist/components/form/calendar/index.d.mts +2 -0
  237. package/dist/components/form/calendar/index.mjs +2 -0
  238. package/dist/components/form/checkbox/checkbox.css +90 -0
  239. package/dist/components/form/checkbox/checkbox.d.mts +5 -3
  240. package/dist/components/form/checkbox/checkbox.mjs +30 -27
  241. package/dist/components/form/checkbox/checkbox.module.mjs +13 -0
  242. package/dist/components/form/checkbox-card/checkbox-card.css +138 -0
  243. package/dist/components/form/checkbox-card/checkbox-card.d.mts +3 -4
  244. package/dist/components/form/checkbox-card/checkbox-card.mjs +17 -23
  245. package/dist/components/form/checkbox-card/checkbox-card.module.mjs +17 -0
  246. package/dist/components/form/checkbox-group/checkbox-group.css +15 -0
  247. package/dist/components/form/checkbox-group/checkbox-group.d.mts +7 -5
  248. package/dist/components/form/checkbox-group/checkbox-group.mjs +12 -16
  249. package/dist/components/form/checkbox-group/checkbox-group.module.mjs +8 -0
  250. package/dist/components/form/checkbox-group/index.d.mts +5 -3
  251. package/dist/components/form/color-picker/color-picker.css +172 -0
  252. package/dist/components/form/color-picker/color-picker.d.mts +28 -0
  253. package/dist/components/form/color-picker/color-picker.mjs +239 -0
  254. package/dist/components/form/color-picker/color-picker.module.mjs +20 -0
  255. package/dist/components/form/color-picker/index.d.mts +2 -0
  256. package/dist/components/form/color-picker/index.mjs +2 -0
  257. package/dist/components/form/combobox/combobox.css +143 -0
  258. package/dist/components/form/combobox/combobox.d.mts +32 -0
  259. package/dist/components/form/combobox/combobox.mjs +278 -0
  260. package/dist/components/form/combobox/combobox.module.mjs +19 -0
  261. package/dist/components/form/combobox/index.d.mts +2 -0
  262. package/dist/components/form/combobox/index.mjs +2 -0
  263. package/dist/components/form/date-field/date-field.css +31 -0
  264. package/dist/components/form/date-field/date-field.d.mts +8 -0
  265. package/dist/components/form/date-field/date-field.mjs +20 -0
  266. package/dist/components/form/date-field/date-field.module.mjs +5 -0
  267. package/dist/components/form/date-field/index.d.mts +2 -0
  268. package/dist/components/form/date-field/index.mjs +2 -0
  269. package/dist/components/form/date-picker/date-picker.css +90 -0
  270. package/dist/components/form/date-picker/date-picker.d.mts +12 -0
  271. package/dist/components/form/date-picker/date-picker.mjs +77 -0
  272. package/dist/components/form/date-picker/date-picker.module.mjs +14 -0
  273. package/dist/components/form/date-picker/index.d.mts +2 -0
  274. package/dist/components/form/date-picker/index.mjs +2 -0
  275. package/dist/components/form/file-field/file-field.css +88 -0
  276. package/dist/components/form/file-field/file-field.d.mts +18 -19
  277. package/dist/components/form/file-field/file-field.mjs +130 -42
  278. package/dist/components/form/file-field/file-field.module.mjs +17 -0
  279. package/dist/components/form/file-field/index.d.mts +20 -2
  280. package/dist/components/form/file-field/index.mjs +9 -1
  281. package/dist/components/form/form/form.css +11 -0
  282. package/dist/components/form/form/form.d.mts +4 -4
  283. package/dist/components/form/form/form.mjs +2 -1
  284. package/dist/components/form/form/form.module.mjs +5 -0
  285. package/dist/components/form/form-control/form-control.css +43 -0
  286. package/dist/components/form/form-control/form-control.d.mts +2 -3
  287. package/dist/components/form/form-control/form-control.mjs +11 -10
  288. package/dist/components/form/form-control/form-control.module.mjs +12 -0
  289. package/dist/components/form/number-field/cast.d.mts +2 -3
  290. package/dist/components/form/number-field/cast.mjs +3 -22
  291. package/dist/components/form/number-field/number-field.css +122 -0
  292. package/dist/components/form/number-field/number-field.d.mts +10 -10
  293. package/dist/components/form/number-field/number-field.mjs +126 -54
  294. package/dist/components/form/number-field/number-field.module.mjs +10 -0
  295. package/dist/components/form/password-input/password-input.css +88 -0
  296. package/dist/components/form/password-input/password-input.d.mts +2 -3
  297. package/dist/components/form/password-input/password-input.mjs +15 -12
  298. package/dist/components/form/password-input/password-input.module.mjs +12 -0
  299. package/dist/components/form/radio/radio.css +89 -0
  300. package/dist/components/form/radio/radio.d.mts +4 -3
  301. package/dist/components/form/radio/radio.mjs +16 -19
  302. package/dist/components/form/radio/radio.module.mjs +16 -0
  303. package/dist/components/form/radio-card/radio-card.css +147 -0
  304. package/dist/components/form/radio-card/radio-card.d.mts +4 -4
  305. package/dist/components/form/radio-card/radio-card.mjs +17 -23
  306. package/dist/components/form/radio-card/radio-card.module.mjs +19 -0
  307. package/dist/components/form/range-slider/index.d.mts +2 -0
  308. package/dist/components/form/range-slider/index.mjs +2 -0
  309. package/dist/components/form/range-slider/range-slider.css +67 -0
  310. package/dist/components/form/range-slider/range-slider.d.mts +30 -0
  311. package/dist/components/form/range-slider/range-slider.mjs +135 -0
  312. package/dist/components/form/range-slider/range-slider.module.mjs +14 -0
  313. package/dist/components/form/select/select.css +74 -0
  314. package/dist/components/form/select/select.d.mts +2 -3
  315. package/dist/components/form/select/select.mjs +25 -8
  316. package/dist/components/form/select/select.module.mjs +12 -0
  317. package/dist/components/form/slider/range-input-class.css +97 -0
  318. package/dist/components/form/slider/range-input-class.d.mts +7 -0
  319. package/dist/components/form/slider/range-input-class.mjs +10 -0
  320. package/dist/components/form/slider/range-input-class.module.mjs +8 -0
  321. package/dist/components/form/slider/slider.css +55 -0
  322. package/dist/components/form/slider/slider.d.mts +6 -7
  323. package/dist/components/form/slider/slider.mjs +44 -11
  324. package/dist/components/form/slider/slider.module.mjs +12 -0
  325. package/dist/components/form/switch/switch.css +103 -0
  326. package/dist/components/form/switch/switch.d.mts +2 -3
  327. package/dist/components/form/switch/switch.mjs +14 -17
  328. package/dist/components/form/switch/switch.module.mjs +16 -0
  329. package/dist/components/form/text-field/text-field.css +41 -0
  330. package/dist/components/form/text-field/text-field.d.mts +4 -5
  331. package/dist/components/form/text-field/text-field.mjs +2 -3
  332. package/dist/components/form/text-field/text-field.module.mjs +5 -0
  333. package/dist/components/form/textarea/textarea.css +50 -0
  334. package/dist/components/form/textarea/textarea.d.mts +3 -3
  335. package/dist/components/form/textarea/textarea.mjs +6 -20
  336. package/dist/components/form/textarea/textarea.module.mjs +9 -0
  337. package/dist/components/icons/base.css +40 -0
  338. package/dist/components/icons/base.d.mts +4 -5
  339. package/dist/components/icons/base.mjs +10 -10
  340. package/dist/components/icons/base.module.mjs +13 -0
  341. package/dist/components/icons/browsers.d.mts +5 -6
  342. package/dist/components/icons/color-scale.d.mts +2 -3
  343. package/dist/components/icons/github-mark.d.mts +2 -3
  344. package/dist/components/icons/logo.css +17 -0
  345. package/dist/components/icons/logo.d.mts +3 -4
  346. package/dist/components/icons/logo.mjs +4 -3
  347. package/dist/components/icons/logo.module.mjs +9 -0
  348. package/dist/components/icons/lucide-deep.d.mts +3 -1
  349. package/dist/components/icons/lucide-imports.d.mts +3 -1
  350. package/dist/components/icons/lucide-imports.mjs +3 -1
  351. package/dist/components/icons/lucide.d.mts +60 -61
  352. package/dist/components/icons/qiita.d.mts +2 -3
  353. package/dist/components/icons/twitter.css +9 -0
  354. package/dist/components/icons/twitter.d.mts +2 -3
  355. package/dist/components/icons/twitter.mjs +2 -1
  356. package/dist/components/icons/twitter.module.mjs +5 -0
  357. package/dist/components/icons/vertical-writing.d.mts +2 -3
  358. package/dist/components/index.d.mts +62 -29
  359. package/dist/components/index.mjs +36 -14
  360. package/dist/components/layout/_shared/gap.css +25 -0
  361. package/dist/components/layout/_shared/gap.d.mts +8 -9
  362. package/dist/components/layout/_shared/gap.mjs +6 -5
  363. package/dist/components/layout/_shared/gap.module.mjs +11 -0
  364. package/dist/components/layout/_shared/padding.css +25 -0
  365. package/dist/components/layout/_shared/padding.d.mts +8 -9
  366. package/dist/components/layout/_shared/padding.mjs +6 -5
  367. package/dist/components/layout/_shared/padding.module.mjs +11 -0
  368. package/dist/components/layout/grid/grid.css +93 -0
  369. package/dist/components/layout/grid/grid.d.mts +5 -6
  370. package/dist/components/layout/grid/grid.mjs +21 -20
  371. package/dist/components/layout/grid/grid.module.mjs +25 -0
  372. package/dist/components/layout/resizable-panels/index.d.mts +18 -0
  373. package/dist/components/layout/resizable-panels/index.mjs +9 -0
  374. package/dist/components/layout/resizable-panels/resizable-panels.css +77 -0
  375. package/dist/components/layout/resizable-panels/resizable-panels.d.mts +21 -0
  376. package/dist/components/layout/resizable-panels/resizable-panels.mjs +164 -0
  377. package/dist/components/layout/resizable-panels/resizable-panels.module.mjs +16 -0
  378. package/dist/components/layout/separator/separator.css +37 -0
  379. package/dist/components/layout/separator/separator.d.mts +2 -3
  380. package/dist/components/layout/separator/separator.mjs +12 -9
  381. package/dist/components/layout/separator/separator.module.mjs +12 -0
  382. package/dist/components/layout/stack/stack.css +49 -0
  383. package/dist/components/layout/stack/stack.d.mts +3 -4
  384. package/dist/components/layout/stack/stack.mjs +11 -10
  385. package/dist/components/layout/stack/stack.module.mjs +17 -0
  386. package/dist/components/navigation/anchor/anchor.css +29 -0
  387. package/dist/components/navigation/anchor/anchor.d.mts +2 -3
  388. package/dist/components/navigation/anchor/anchor.mjs +5 -2
  389. package/dist/components/navigation/anchor/anchor.module.mjs +8 -0
  390. package/dist/components/navigation/breadcrumb/breadcrumb.css +72 -0
  391. package/dist/components/navigation/breadcrumb/breadcrumb.d.mts +5 -6
  392. package/dist/components/navigation/breadcrumb/breadcrumb.mjs +15 -9
  393. package/dist/components/navigation/breadcrumb/breadcrumb.module.mjs +14 -0
  394. package/dist/components/navigation/breadcrumb/index.d.mts +2 -3
  395. package/dist/components/navigation/pagination/pagination.css +36 -0
  396. package/dist/components/navigation/pagination/pagination.d.mts +2 -3
  397. package/dist/components/navigation/pagination/pagination.mjs +9 -8
  398. package/dist/components/navigation/pagination/pagination.module.mjs +11 -0
  399. package/dist/components/navigation/side-nav/index.d.mts +16 -0
  400. package/dist/components/navigation/side-nav/index.mjs +10 -0
  401. package/dist/components/navigation/side-nav/side-nav.css +73 -0
  402. package/dist/components/navigation/side-nav/side-nav.d.mts +31 -0
  403. package/dist/components/navigation/side-nav/side-nav.mjs +62 -0
  404. package/dist/components/navigation/side-nav/side-nav.module.mjs +11 -0
  405. package/dist/components/navigation/stepper/index.d.mts +2 -0
  406. package/dist/components/navigation/stepper/index.mjs +2 -0
  407. package/dist/components/navigation/stepper/stepper.css +151 -0
  408. package/dist/components/navigation/stepper/stepper.d.mts +19 -0
  409. package/dist/components/navigation/stepper/stepper.mjs +87 -0
  410. package/dist/components/navigation/stepper/stepper.module.mjs +29 -0
  411. package/dist/components/navigation/table-of-contents/index.d.mts +2 -0
  412. package/dist/components/navigation/table-of-contents/index.mjs +2 -0
  413. package/dist/components/navigation/table-of-contents/table-of-contents.css +17 -0
  414. package/dist/components/navigation/table-of-contents/table-of-contents.d.mts +12 -0
  415. package/dist/components/navigation/table-of-contents/table-of-contents.mjs +94 -0
  416. package/dist/components/navigation/table-of-contents/table-of-contents.module.mjs +8 -0
  417. package/dist/components/navigation/tabs/index.d.mts +19 -2
  418. package/dist/components/navigation/tabs/index.mjs +9 -1
  419. package/dist/components/navigation/tabs/tabs.css +70 -0
  420. package/dist/components/navigation/tabs/tabs.d.mts +16 -19
  421. package/dist/components/navigation/tabs/tabs.mjs +52 -49
  422. package/dist/components/navigation/tabs/tabs.module.mjs +12 -0
  423. package/dist/components/observers/fragment-instance.d.mts +1 -0
  424. package/dist/components/observers/in-view/in-view.d.mts +11 -0
  425. package/dist/components/observers/in-view/in-view.mjs +60 -0
  426. package/dist/components/observers/in-view/index.d.mts +2 -0
  427. package/dist/components/observers/in-view/index.mjs +2 -0
  428. package/dist/components/observers/resize/index.d.mts +2 -0
  429. package/dist/components/observers/resize/index.mjs +2 -0
  430. package/dist/components/observers/resize/resize.d.mts +7 -0
  431. package/dist/components/observers/resize/resize.mjs +25 -0
  432. package/dist/components/overlays/_internal/modal-dialog-context.d.mts +4 -5
  433. package/dist/components/overlays/_internal/use-can-hover.d.mts +2 -3
  434. package/dist/components/overlays/_internal/use-hover-intent.d.mts +3 -4
  435. package/dist/components/overlays/_internal/use-list-navigation.d.mts +17 -11
  436. package/dist/components/overlays/_internal/use-list-navigation.mjs +42 -26
  437. package/dist/components/overlays/command-palette/command-palette.css +91 -0
  438. package/dist/components/overlays/command-palette/command-palette.d.mts +24 -0
  439. package/dist/components/overlays/command-palette/command-palette.mjs +139 -0
  440. package/dist/components/overlays/command-palette/command-palette.module.mjs +14 -0
  441. package/dist/components/overlays/command-palette/index.d.mts +2 -0
  442. package/dist/components/overlays/command-palette/index.mjs +2 -0
  443. package/dist/components/overlays/context-menu/context-menu.d.mts +13 -0
  444. package/dist/components/overlays/context-menu/context-menu.mjs +79 -0
  445. package/dist/components/overlays/context-menu/index.d.mts +21 -0
  446. package/dist/components/overlays/context-menu/index.mjs +13 -0
  447. package/dist/components/overlays/dialog/dialog.css +31 -0
  448. package/dist/components/overlays/dialog/dialog.d.mts +12 -17
  449. package/dist/components/overlays/dialog/dialog.mjs +11 -13
  450. package/dist/components/overlays/dialog/dialog.module.mjs +10 -0
  451. package/dist/components/overlays/dialog/index.d.mts +17 -2
  452. package/dist/components/overlays/dialog/index.mjs +8 -1
  453. package/dist/components/overlays/drawer/drawer.css +48 -0
  454. package/dist/components/overlays/drawer/drawer.d.mts +2 -3
  455. package/dist/components/overlays/drawer/drawer.mjs +11 -10
  456. package/dist/components/overlays/drawer/drawer.module.mjs +13 -0
  457. package/dist/components/overlays/dropdown-menu/dropdown-menu.d.mts +19 -26
  458. package/dist/components/overlays/dropdown-menu/dropdown-menu.mjs +12 -20
  459. package/dist/components/overlays/dropdown-menu/hooks.d.mts +7 -7
  460. package/dist/components/overlays/dropdown-menu/hooks.mjs +3 -3
  461. package/dist/components/overlays/dropdown-menu/index.d.mts +30 -2
  462. package/dist/components/overlays/dropdown-menu/index.mjs +12 -1
  463. package/dist/components/overlays/dropdown-menu/shared.css +51 -0
  464. package/dist/components/overlays/dropdown-menu/shared.d.mts +3 -6
  465. package/dist/components/overlays/dropdown-menu/shared.mjs +4 -6
  466. package/dist/components/overlays/dropdown-menu/shared.module.mjs +8 -0
  467. package/dist/components/overlays/dropdown-menu/sub-menu.css +28 -0
  468. package/dist/components/overlays/dropdown-menu/sub-menu.d.mts +3 -6
  469. package/dist/components/overlays/dropdown-menu/sub-menu.mjs +16 -16
  470. package/dist/components/overlays/dropdown-menu/sub-menu.module.mjs +9 -0
  471. package/dist/components/overlays/dropdown-menu/use-safe-triangle.d.mts +2 -3
  472. package/dist/components/overlays/list-box/hooks.d.mts +6 -5
  473. package/dist/components/overlays/list-box/hooks.mjs +5 -4
  474. package/dist/components/overlays/list-box/index.d.mts +27 -2
  475. package/dist/components/overlays/list-box/index.mjs +9 -1
  476. package/dist/components/overlays/list-box/list-box.css +74 -0
  477. package/dist/components/overlays/list-box/list-box.d.mts +20 -23
  478. package/dist/components/overlays/list-box/list-box.mjs +17 -21
  479. package/dist/components/overlays/list-box/list-box.module.mjs +10 -0
  480. package/dist/components/overlays/modal/modal.css +119 -0
  481. package/dist/components/overlays/modal/modal.d.mts +2 -3
  482. package/dist/components/overlays/modal/modal.mjs +14 -11
  483. package/dist/components/overlays/modal/modal.module.mjs +11 -0
  484. package/dist/components/overlays/popover/anchor-positioning.d.mts +4 -5
  485. package/dist/components/overlays/popover/escape-stack.d.mts +2 -3
  486. package/dist/components/overlays/popover/hooks.d.mts +7 -8
  487. package/dist/components/overlays/popover/index.d.mts +25 -2
  488. package/dist/components/overlays/popover/index.mjs +8 -1
  489. package/dist/components/overlays/popover/popover.css +51 -0
  490. package/dist/components/overlays/popover/popover.d.mts +18 -20
  491. package/dist/components/overlays/popover/popover.mjs +13 -12
  492. package/dist/components/overlays/popover/popover.module.mjs +11 -0
  493. package/dist/components/overlays/tooltip/bridge.css +68 -0
  494. package/dist/components/overlays/tooltip/bridge.d.mts +2 -3
  495. package/dist/components/overlays/tooltip/bridge.mjs +7 -21
  496. package/dist/components/overlays/tooltip/bridge.module.mjs +11 -0
  497. package/dist/components/overlays/tooltip/index.d.mts +22 -2
  498. package/dist/components/overlays/tooltip/index.mjs +8 -1
  499. package/dist/components/overlays/tooltip/tooltip.css +15 -0
  500. package/dist/components/overlays/tooltip/tooltip.d.mts +19 -24
  501. package/dist/components/overlays/tooltip/tooltip.mjs +5 -9
  502. package/dist/components/overlays/tooltip/tooltip.module.mjs +5 -0
  503. package/dist/components/providers/index.d.mts +1 -2
  504. package/dist/components/providers/portal-root.d.mts +9 -7
  505. package/dist/components/providers/portal-root.mjs +7 -7
  506. package/dist/components/providers/ui-provider.d.mts +2 -6
  507. package/dist/components/providers/ui-provider.mjs +1 -5
  508. package/dist/helpers/chain.d.mts +2 -3
  509. package/dist/helpers/chain.mjs +0 -23
  510. package/dist/helpers/create-safe-context.d.mts +2 -3
  511. package/dist/helpers/create-safe-context.mjs +0 -17
  512. package/dist/helpers/index.d.mts +1 -2
  513. package/dist/helpers/index.mjs +2 -3
  514. package/dist/helpers/merge-props.d.mts +2 -3
  515. package/dist/helpers/merge-props.mjs +2 -37
  516. package/dist/helpers/merge-refs.d.mts +2 -3
  517. package/dist/helpers/merge-refs.mjs +0 -32
  518. package/dist/hooks/click-away/index.d.mts +2 -3
  519. package/dist/hooks/controllable-state/index.d.mts +2 -3
  520. package/dist/hooks/controllable-state/index.mjs +9 -11
  521. package/dist/hooks/index.d.mts +2 -23
  522. package/dist/hooks/index.mjs +2 -22
  523. package/dist/hooks/writing-mode/index.d.mts +15 -5
  524. package/dist/hooks/writing-mode/index.mjs +21 -14
  525. package/dist/i18n/current.d.mts +23 -0
  526. package/dist/i18n/current.mjs +43 -0
  527. package/dist/i18n/en.d.mts +2 -3
  528. package/dist/i18n/en.mjs +46 -0
  529. package/dist/i18n/index.d.mts +3 -2
  530. package/dist/i18n/index.mjs +4 -3
  531. package/dist/i18n/ja.d.mts +2 -3
  532. package/dist/i18n/ja.mjs +46 -0
  533. package/dist/i18n/messages.d.mts +81 -3
  534. package/dist/i18n/usage.d.mts +8 -0
  535. package/dist/i18n/usage.mjs +131 -0
  536. package/dist/index.d.mts +40 -47
  537. package/dist/index.mjs +36 -42
  538. package/dist/integrations/_shared/openui-defs.d.mts +3 -4
  539. package/dist/integrations/_shared/openui-defs.mjs +123 -54
  540. package/dist/integrations/_shared/renderers.css +50 -0
  541. package/dist/integrations/_shared/renderers.d.mts +71 -52
  542. package/dist/integrations/_shared/renderers.mjs +292 -34
  543. package/dist/integrations/_shared/renderers.module.mjs +14 -0
  544. package/dist/integrations/_shared/schemas.d.mts +388 -104
  545. package/dist/integrations/_shared/schemas.mjs +165 -27
  546. package/dist/integrations/ai-sdk/index.d.mts +2 -2
  547. package/dist/integrations/ai-sdk/map-parts.d.mts +25 -7
  548. package/dist/integrations/ai-sdk/map-parts.mjs +28 -3
  549. package/dist/integrations/json-render/catalog.d.mts +336 -18
  550. package/dist/integrations/json-render/catalog.mjs +120 -57
  551. package/dist/integrations/json-render/registry.d.mts +3 -4
  552. package/dist/integrations/json-render/registry.mjs +38 -4
  553. package/dist/integrations/openui/form-views.d.mts +23 -18
  554. package/dist/integrations/openui/form-views.mjs +27 -3
  555. package/dist/integrations/openui/library.d.mts +59 -7
  556. package/dist/integrations/openui/library.mjs +18 -3
  557. package/dist/integrations/openui/prompt.d.mts +2 -3
  558. package/dist/internal/accepts-file.d.mts +8 -0
  559. package/dist/internal/accepts-file.mjs +19 -0
  560. package/dist/internal/carries-files.d.mts +3 -0
  561. package/dist/internal/carries-files.mjs +4 -0
  562. package/dist/internal/clamp.d.mts +2 -3
  563. package/dist/internal/clamp.mjs +0 -11
  564. package/dist/internal/commit-input-value.d.mts +10 -0
  565. package/dist/internal/commit-input-value.mjs +15 -0
  566. package/dist/internal/dropped-files.d.mts +3 -0
  567. package/dist/internal/dropped-files.mjs +8 -0
  568. package/dist/{hooks/focus-trap/index.d.mts → internal/focus-trap.d.mts} +6 -7
  569. package/dist/{hooks/focus-trap/index.mjs → internal/focus-trap.mjs} +5 -5
  570. package/dist/internal/hex-color.d.mts +22 -0
  571. package/dist/internal/hex-color.mjs +53 -0
  572. package/dist/internal/iso-date.d.mts +39 -0
  573. package/dist/internal/iso-date.mjs +98 -0
  574. package/dist/internal/to-precision.d.mts +2 -3
  575. package/dist/internal/to-precision.mjs +0 -8
  576. package/dist/styles/index.css +513 -2534
  577. package/dist/styles/tailwind.css +217 -17
  578. package/dist/styles/tokens.d.mts +1 -2
  579. package/dist/styles/tokens.mjs +1 -2
  580. package/dist/types/variables.d.mts +7 -9
  581. package/docs/GUIDE.md +340 -158
  582. package/docs/llms.txt +18 -10
  583. package/docs/props.generated.json +2157 -292
  584. package/docs/references/ai-chat.md +396 -113
  585. package/docs/references/color.md +258 -113
  586. package/docs/references/components.md +1891 -461
  587. package/docs/references/generative-ui.md +163 -34
  588. package/docs/references/interaction-design.md +103 -73
  589. package/docs/references/spatial-design.md +112 -90
  590. package/docs/references/types.md +101 -0
  591. package/docs/references/typography.md +182 -73
  592. package/package.json +71 -70
  593. package/dist/components/_internal/focus-ring.d.mts +0 -8
  594. package/dist/components/_internal/focus-ring.mjs +0 -8
  595. package/dist/components/layout/scroll-linked/index.d.mts +0 -2
  596. package/dist/components/layout/scroll-linked/index.mjs +0 -2
  597. package/dist/components/layout/scroll-linked/scroll-linked.d.mts +0 -14
  598. package/dist/components/layout/scroll-linked/scroll-linked.mjs +0 -59
  599. package/dist/helpers/cn.d.mts +0 -5
  600. package/dist/helpers/cn.mjs +0 -27
  601. package/dist/hooks/breakpoint/index.d.mts +0 -5
  602. package/dist/hooks/breakpoint/index.mjs +0 -24
  603. package/dist/hooks/client/index.d.mts +0 -4
  604. package/dist/hooks/client/index.mjs +0 -6
  605. package/dist/hooks/clipboard/index.d.mts +0 -7
  606. package/dist/hooks/clipboard/index.mjs +0 -15
  607. package/dist/hooks/debounced-transition/index.d.mts +0 -5
  608. package/dist/hooks/debounced-transition/index.mjs +0 -49
  609. package/dist/hooks/deferred-debounce/index.d.mts +0 -4
  610. package/dist/hooks/deferred-debounce/index.mjs +0 -9
  611. package/dist/hooks/disclosure/index.d.mts +0 -10
  612. package/dist/hooks/disclosure/index.mjs +0 -20
  613. package/dist/hooks/hash/index.d.mts +0 -4
  614. package/dist/hooks/hash/index.mjs +0 -25
  615. package/dist/hooks/hover/index.d.mts +0 -12
  616. package/dist/hooks/hover/index.mjs +0 -19
  617. package/dist/hooks/intersection-observer/index.d.mts +0 -3
  618. package/dist/hooks/intersection-observer/index.mjs +0 -3
  619. package/dist/hooks/intersection-observer/use-in-view.d.mts +0 -11
  620. package/dist/hooks/intersection-observer/use-in-view.mjs +0 -18
  621. package/dist/hooks/intersection-observer/use-intersection-observer.d.mts +0 -11
  622. package/dist/hooks/intersection-observer/use-intersection-observer.mjs +0 -33
  623. package/dist/hooks/interval/index.d.mts +0 -4
  624. package/dist/hooks/interval/index.mjs +0 -19
  625. package/dist/hooks/local-storage/index.d.mts +0 -4
  626. package/dist/hooks/local-storage/index.mjs +0 -46
  627. package/dist/hooks/resize/index.d.mts +0 -8
  628. package/dist/hooks/resize/index.mjs +0 -24
  629. package/dist/hooks/scroll-direction/index.d.mts +0 -13
  630. package/dist/hooks/scroll-direction/index.mjs +0 -67
  631. package/dist/hooks/scroll-lock/index.d.mts +0 -9
  632. package/dist/hooks/scroll-lock/index.mjs +0 -59
  633. package/dist/hooks/session-storage/index.d.mts +0 -4
  634. package/dist/hooks/session-storage/index.mjs +0 -46
  635. package/dist/hooks/step/index.d.mts +0 -15
  636. package/dist/hooks/step/index.mjs +0 -39
  637. package/dist/hooks/timeout/index.d.mts +0 -4
  638. package/dist/hooks/timeout/index.mjs +0 -19
  639. package/dist/hooks/window-resize/index.d.mts +0 -11
  640. package/dist/hooks/window-resize/index.mjs +0 -21
  641. package/dist/hooks/window-size/index.d.mts +0 -8
  642. package/dist/hooks/window-size/index.mjs +0 -31
  643. package/dist/i18n/context.d.mts +0 -9
  644. package/dist/i18n/context.mjs +0 -19
  645. package/dist/styles/base.css +0 -315
  646. package/dist/styles/tokens.css +0 -380
  647. package/dist/styles/tokens.generated.d.mts +0 -840
  648. package/dist/styles/tokens.generated.mjs +0 -813
  649. package/dist/styles/utilities.css +0 -62
  650. package/docs/references/helpers.md +0 -120
  651. package/docs/references/hooks.md +0 -314
@@ -1,67 +1,68 @@
1
- # k8ordo UI AI チャットコンポーネント
1
+ # @k8ordo/ui AI chat components
2
2
 
3
- AI チャット UI(会話ログ・メッセージ・入力欄・推論表示・ツール実行表示)を構築するコンポーネント群。ルートではなく専用サブパスからインポートする。
3
+ Components for building an AI chat UI: the conversation log, messages and their actions, the input box with attachments, reasoning display, tool-invocation display with approval, attachments, and sources. Import them from their dedicated subpaths rather than from the root.
4
4
 
5
- ## インポート方法
5
+ ## Importing
6
6
 
7
7
  ```tsx
8
- // 基本コンポーネント(追加の依存なし)
8
+ // Core components (no extra dependencies)
9
9
  import {
10
+ Attachment,
10
11
  Conversation,
11
12
  Message,
12
13
  PromptInput,
13
14
  Reasoning,
15
+ Source,
14
16
  Suggestion,
15
17
  ToolInvocation,
16
18
  } from '@k8ordo/ui/ai';
17
-
18
- // ストリーミング対応 Markdown 描画(optional peer: streamdown)
19
- import { Response } from '@k8ordo/ui/ai/response';
20
-
21
- // AI SDK 連携(optional peer: ai)
19
+ // AI SDK integration (optional peer: ai)
22
20
  import { mapMessageParts } from '@k8ordo/ui/ai-sdk';
21
+ // Streaming-aware Markdown rendering (optional peer: streamdown)
22
+ import { Response } from '@k8ordo/ui/ai/response';
23
23
  ```
24
24
 
25
- 型も `@k8ordo/ui/ai` から export される:
25
+ The types are exported from `@k8ordo/ui/ai` too:
26
26
 
27
- - `ChatStatus`: `'ready' | 'submitted' | 'streaming' | 'error'`(AI SDK の `status` と互換)
28
- - `ToolState`: `'input-streaming' | 'input-available' | 'approval-requested' | 'approval-responded' | 'output-available' | 'output-error' | 'output-denied'`(AI SDK v7 のツール状態と 1:1)
27
+ - `ChatStatus`: `'ready' | 'submitted' | 'streaming' | 'error'` (compatible with the AI SDK's `status`)
28
+ - `ToolState`: `'input-streaming' | 'input-available' | 'approval-requested' | 'approval-responded' | 'output-available' | 'output-error' | 'output-denied'` (1:1 with the AI SDK v7 tool states)
29
+ - `ToolApproval`: `{ id: string; approved?: boolean; reason?: string; requestReason?: string; isAutomatic?: boolean }` (the shape of the AI SDK's `part.approval`, so the part's own object can be passed as is)
30
+ - `ToolApprovalResponse`: `{ id: string; approved: boolean }` (what `ToolInvocation` answers with)
31
+ - `MessageFeedback`: `'positive' | 'negative'`
29
32
 
30
- ### optional peer のセットアップ
33
+ ### Setting up the optional peers
31
34
 
32
- 使うサブパスの分だけインストールする。`@k8ordo/ui/ai` 本体はどちらも不要。
35
+ Install only what the subpaths you use require. `@k8ordo/ui/ai` itself needs neither.
33
36
 
34
37
  ```bash
35
- # @k8ordo/ui/ai/response(Response)を使う場合
38
+ # If you use @k8ordo/ui/ai/response (Response)
36
39
  pnpm add streamdown
37
- # @k8ordo/ui/ai-sdk(mapMessageParts)を使う場合
40
+ # If you use @k8ordo/ui/ai-sdk (mapMessageParts)
38
41
  pnpm add ai
39
42
  ```
40
43
 
41
- `Response` を使う場合は streamdown のスタイルシートの読み込みと、Tailwind の `@source` 設定も必要。streamdown のスタイルはビルド済み `styles.css` には含まれないため、`Response` だけは Tailwind CSS 4 のビルド(`@k8ordo/ui/tailwind.css` エントリ)が前提になる:
44
+ `Response` styles what streamdown renders itself, through the
45
+ `data-streamdown` attribute streamdown puts on every element, so it needs no
46
+ Tailwind. Load streamdown's own stylesheet only when you turn on its `animated`
47
+ option, which keeps its keyframes there:
42
48
 
43
49
  ```tsx
44
50
  import 'streamdown/styles.css';
45
51
  ```
46
52
 
47
- ```css
48
- /* アプリの CSS エントリに追加(パスは CSS ファイルから node_modules への相対) */
49
- @source '../node_modules/streamdown/dist/*.js';
50
- ```
51
-
52
- なお本リファレンスの例で使う `useChat` は AI SDK の React バインディング(`pnpm add @ai-sdk/react`)から import する。
53
+ The `useChat` used in the examples below comes from the AI SDK's React bindings (`pnpm add @ai-sdk/react`).
53
54
 
54
- 以下に出てくる `label` / `sendLabel` などの「デフォルト」は文言辞書の既定値(日本語)。`<UIProvider messages={en}>` で辞書ごと切り替えられる([i18n](components.md))。個別の prop を渡した場合はそちらが辞書より優先される。
55
+ The "default" shown for `label`, `sendLabel`, and similar props below is the built-in Japanese dictionary's. The text actually used follows `@k8ordo/i18n`'s current locale (see [i18n](components.md)). Passing the prop directly wins over the dictionary.
55
56
 
56
- ## 全体像
57
+ ## The whole picture
57
58
 
58
- `Conversation`(会話ログ)+ `Message`(吹き出し)+ `PromptInput`(入力欄)が骨組み。`Response` / `Reasoning` / `ToolInvocation` は後から足せる。
59
+ `Conversation` (the log), `Message` (a bubble), and `PromptInput` (the input box) form the skeleton. `Response`, `Reasoning`, `ToolInvocation`, `Attachment`, `Source`, and the message actions can be added later — [AI SDK integration](#ai-sdk-integration-mapmessageparts) shows all of them together.
59
60
 
60
61
  ```tsx
61
62
  'use client';
63
+ import { useChat } from '@ai-sdk/react';
62
64
  import { Avatar, AssistantIcon } from '@k8ordo/ui';
63
65
  import { Conversation, Message, PromptInput } from '@k8ordo/ui/ai';
64
- import { useChat } from '@ai-sdk/react';
65
66
  import type { UIMessage } from 'ai';
66
67
 
67
68
  const textOf = (m: UIMessage) =>
@@ -71,22 +72,31 @@ export function Chat() {
71
72
  const { messages, sendMessage, status, stop } = useChat();
72
73
 
73
74
  return (
74
- <div className="flex h-full flex-col gap-3">
75
+ <div
76
+ style={{
77
+ display: 'flex',
78
+ height: '100%',
79
+ flexDirection: 'column',
80
+ gap: 'calc(var(--spacing) * 3)',
81
+ }}
82
+ >
75
83
  <Conversation.Root>
76
84
  <Conversation.Messages isStreaming={status === 'streaming'}>
77
85
  {messages.map((m) => (
78
86
  <Message.Root
87
+ avatar={
88
+ m.role === 'user' ? undefined : (
89
+ <Avatar
90
+ color="primary"
91
+ icon={<AssistantIcon />}
92
+ name="AI"
93
+ size="sm"
94
+ />
95
+ )
96
+ }
79
97
  from={m.role === 'user' ? 'user' : 'assistant'}
80
98
  key={m.id}
81
99
  >
82
- {m.role !== 'user' && (
83
- <Avatar
84
- color="primary"
85
- icon={<AssistantIcon />}
86
- name="AI"
87
- size="sm"
88
- />
89
- )}
90
100
  <Message.Content>{textOf(m)}</Message.Content>
91
101
  </Message.Root>
92
102
  ))}
@@ -99,7 +109,7 @@ export function Chat() {
99
109
  onSubmit={(text) => sendMessage({ text })}
100
110
  status={status}
101
111
  >
102
- <PromptInput.Textarea placeholder="メッセージを入力" />
112
+ <PromptInput.Textarea placeholder="Type a message" />
103
113
  <PromptInput.Submit />
104
114
  </PromptInput.Root>
105
115
  </div>
@@ -109,7 +119,7 @@ export function Chat() {
109
119
 
110
120
  ## Conversation
111
121
 
112
- 会話ログのスクロール領域。Compound component パターン。最下部に張り付き、新しいメッセージで自動スクロールする。最下部から離れると `ScrollButton` が現れる。
122
+ The scrolling region for the conversation log, as a compound component. It sticks to the bottom and auto-scrolls on a new message. Once you scroll away from the bottom, a `ScrollButton` appears.
113
123
 
114
124
  ```tsx
115
125
  import { Conversation } from '@k8ordo/ui/ai';
@@ -124,40 +134,94 @@ import { Conversation } from '@k8ordo/ui/ai';
124
134
 
125
135
  Props (Conversation.Messages):
126
136
 
127
- - `label`: string(デフォルト: `'チャット'`、aria-label として使用)
128
- - `isStreaming`: boolean(`aria-busy` に反映)
137
+ - `label`: string (default: `'チャット'`, used as the aria-label)
138
+ - `isStreaming`: boolean (reflected in `aria-busy`)
129
139
 
130
140
  Props (Conversation.ScrollButton):
131
141
 
132
- - `label`: string(デフォルト: `'最新のメッセージへ移動'`)
142
+ - `label`: string (default: `'最新のメッセージへ移動'`)
133
143
 
134
144
  ## Message
135
145
 
136
- メッセージ 1 件。`from="user"` は右寄せの吹き出し、`from="assistant"` は地の文として描画される。アバターなどは `Message.Root` の子として自由に並べられる。
146
+ A single message. `from="user"` renders as a right-aligned bubble; `from="assistant"` renders as running text. `avatar` sits beside the message, and the children stack in a column next to it — attachments, the content, sources, and the actions each get their own row.
137
147
 
138
148
  ```tsx
139
149
  import { Message } from '@k8ordo/ui/ai';
140
150
 
141
151
  <Message.Root from="user">
142
- <Message.Content>こんにちは</Message.Content>
152
+ <Message.Content>Hello</Message.Content>
143
153
  </Message.Root>
144
154
 
145
- <Message.Root from="assistant">
146
- <Message.Content isStreaming>生成中の本文…</Message.Content>
155
+ <Message.Root avatar={<Avatar icon={<AssistantIcon />} name="AI" size="sm" />} from="assistant">
156
+ <Message.Content isStreaming>Text still streaming…</Message.Content>
147
157
  </Message.Root>
148
158
  ```
149
159
 
150
160
  Props (Message.Root):
151
161
 
152
- - `from`: `'user'` | `'assistant'`(必須)
162
+ - `from`: `'user'` | `'assistant'` (required)
163
+ - `avatar`: ReactNode (shown beside the message: left for the assistant, right for the user)
164
+ - plus the other `div` attributes (`className` and `style` excluded)
153
165
 
154
166
  Props (Message.Content):
155
167
 
156
- - `isStreaming`: boolean(true でストリーミングカーソルを表示)
168
+ - `isStreaming`: boolean (shows the streaming cursor when true)
169
+ - plus the other `div` attributes (`className` and `style` excluded)
170
+
171
+ ### Message actions
172
+
173
+ `Message.Actions` is the row of icon buttons under a message. `Copy`, `Regenerate`, and `Feedback` carry their own icons and dictionary labels; `Action` is the generic one for anything else. Each shows its label as a tooltip.
174
+
175
+ ```tsx
176
+ <Message.Root avatar={avatar} from="assistant">
177
+ <Message.Content>{text}</Message.Content>
178
+ <Message.Actions>
179
+ <Message.Copy value={text} />
180
+ <Message.Regenerate
181
+ disabled={status === 'submitted' || status === 'streaming'}
182
+ onAction={() => regenerate({ messageId: message.id })}
183
+ />
184
+ <Message.Feedback onChange={(value) => saveFeedback(message.id, value)} />
185
+ <Message.Action label="Share" onAction={() => share(message.id)}>
186
+ <LinkIcon size="sm" />
187
+ </Message.Action>
188
+ </Message.Actions>
189
+ </Message.Root>
190
+ ```
191
+
192
+ - `Copy` is an icon-only, `sm` [`CopyButton`](components.md#copybutton): it writes `value` to the clipboard, shows a check icon — or an error icon when the clipboard refuses — for two seconds, and announces 「コピーしました」 or 「コピーできませんでした」 through a `status` region. Nothing is thrown either way.
193
+ - `Regenerate` and `Action` take `onAction`; a returned promise keeps the button busy (`aria-busy`, `aria-disabled`, presses ignored) until it settles, so `() => regenerate(...)` does not need its own pending state. The button keeps focus meanwhile.
194
+ - `Feedback` is a pair of toggle buttons (`aria-pressed`). Pressing the pressed one again clears it, so `onChange` receives `null`.
195
+
196
+ Props (Message.Actions):
197
+
198
+ - `label`: string (default: `'メッセージの操作'`, used as the group's aria-label)
199
+
200
+ Props (Message.Action):
201
+
202
+ - `label`: string (required; the accessible name and the tooltip)
203
+ - `onAction`: `() => void | Promise<void>`
204
+ - `disabled`: boolean
205
+ - `children`: ReactNode (the icon, `size="sm"`)
206
+
207
+ Props (Message.Copy):
208
+
209
+ - `value`: string (required; the text to copy)
210
+ - `label`: string (default: `'コピー'`)
211
+
212
+ Props (Message.Regenerate):
213
+
214
+ - `onAction`: `() => void | Promise<void>` (required)
215
+ - `label`: string (default: `'再生成'`)
216
+ - `disabled`: boolean
217
+
218
+ Props (Message.Feedback):
219
+
220
+ - `value` / `defaultValue` / `onChange`: `MessageFeedback | null`, controlled or uncontrolled (`onChange` is `(value: MessageFeedback | null) => void`; `null` is no feedback)
157
221
 
158
222
  ## PromptInput
159
223
 
160
- 送信フォーム。Enter で送信、Shift+Enter で改行。IME 変換確定の Enter では送信しない。`status` が `'submitted'` / `'streaming'` の間は `Submit` が停止ボタンに切り替わる。本文は trim され、空文字は送信されない。
224
+ The submit form. Enter sends; Shift+Enter inserts a newline; the Enter that commits an IME conversion does not send. While `status` is `'submitted'` or `'streaming'`, `Submit` turns into a stop button. The body is trimmed, and a message with neither text nor attachments is never sent.
161
225
 
162
226
  ```tsx
163
227
  import { PromptInput } from '@k8ordo/ui/ai';
@@ -167,30 +231,121 @@ import { PromptInput } from '@k8ordo/ui/ai';
167
231
  onSubmit={(message) => send(message)}
168
232
  onStop={stop}
169
233
  >
170
- <PromptInput.Textarea placeholder="メッセージを入力" />
234
+ <PromptInput.Textarea placeholder="Type a message" />
171
235
  <PromptInput.Submit />
172
236
  </PromptInput.Root>;
173
237
  ```
174
238
 
239
+ ### Attachments
240
+
241
+ Pass `accept` to take files. It turns on all three ways in — the `Attach` button's file picker, dropping files onto the input, and pasting them into the textarea — and filters every one of them by the same rule as `<input accept>` (the browser applies it only to the picker). A dropped folder is skipped, as on `FileField.Dropzone`. Without `accept` the input takes text only: `Attach` renders nothing, a pasted file is not taken, and a file dragged over the input shows the not-allowed cursor — the drop is still cancelled, so the browser never opens the file and leaves the chat.
242
+
243
+ `PromptInput.Attachments` lists the files waiting to be sent, image thumbnails included, each with a remove button. `onSubmit` receives them as a `FileList` in its second argument, which the AI SDK's `sendMessage` takes as is. The list empties after each submit, and a message with attachments but no text can be sent — pass `{ files }` alone then, since `sendMessage` turns `text: ''` into an empty text part that some providers reject.
244
+
245
+ ```tsx
246
+ <PromptInput.Root
247
+ accept="image/*,application/pdf"
248
+ maxFiles={4}
249
+ onStop={stop}
250
+ onSubmit={(text, files) =>
251
+ sendMessage(text === '' ? { files } : { text, files })
252
+ }
253
+ status={status}
254
+ >
255
+ <PromptInput.Attachments />
256
+ <PromptInput.Attach />
257
+ <PromptInput.Textarea placeholder="Type a message" />
258
+ <PromptInput.Submit />
259
+ </PromptInput.Root>
260
+ ```
261
+
262
+ Put `Attachments` first: it takes a row of its own above the textarea. Choose `accept` from what your model reads — the AI SDK turns `image/*` and `text/*` into model input by itself, and other types need handling on your server.
263
+
175
264
  Props (PromptInput.Root):
176
265
 
177
- - `status`: ChatStatus(デフォルト: `'ready'`)
178
- - `value` / `defaultValue` / `onChange`: controlled / uncontrolled 両対応(`onChange` は `(value: string) => void`)
179
- - `onSubmit`: `(message: string) => void`(trim 済みの本文)
180
- - `onStop`: `() => void`(送信中に停止ボタンを押したとき)
266
+ - `status`: ChatStatus (default: `'ready'`)
267
+ - `value` / `defaultValue` / `onChange`: supports both controlled and uncontrolled use (`onChange` is `(value: string) => void`)
268
+ - `onSubmit`: `(message: string, files: FileList) => void` (the trimmed body, and the attachments — an empty `FileList` when there are none)
269
+ - `onStop`: `() => void` (when the stop button is pressed mid-send)
270
+ - `accept`: string (the file types to take, in `<input accept>` syntax; omit to take no files)
271
+ - `maxFiles`: number (files beyond it are dropped, first come first kept; `1` also makes the picker single-select)
272
+
273
+ Props (PromptInput.Attachments):
274
+
275
+ - `label`: string (default: `'添付ファイル'`, used as the list's aria-label)
276
+
277
+ Props (PromptInput.Attach):
278
+
279
+ - `label`: string (default: `'ファイルを添付'`)
181
280
 
182
281
  Props (PromptInput.Textarea):
183
282
 
184
- - `placeholder`: string ほか textarea 属性
283
+ - `placeholder`: string, plus the other textarea attributes
185
284
 
186
285
  Props (PromptInput.Submit):
187
286
 
188
- - `sendLabel`: string(デフォルト: `'送信'`)
189
- - `stopLabel`: string(デフォルト: `'停止'`)
287
+ - `sendLabel`: string (default: `'送信'`)
288
+ - `stopLabel`: string (default: `'停止'`)
289
+
290
+ ## Attachment
291
+
292
+ Files attached to a sent message. An image (`image/*`, or the bare `image` the AI SDK allows) shows as a thumbnail with `filename` as its alt text; anything else shows as a chip with its name and media type.
293
+
294
+ ```tsx
295
+ import { Attachment } from '@k8ordo/ui/ai';
296
+
297
+ <Message.Root from="user">
298
+ <Attachment.List>
299
+ {files.map((file) => (
300
+ <Attachment.Item
301
+ filename={file.filename}
302
+ key={file.url}
303
+ mediaType={file.mediaType}
304
+ url={file.url}
305
+ />
306
+ ))}
307
+ </Attachment.List>
308
+ <Message.Content>{text}</Message.Content>
309
+ </Message.Root>;
310
+ ```
311
+
312
+ Props (Attachment.List):
313
+
314
+ - `label`: string (default: `'添付ファイル'`, used as the list's aria-label)
315
+
316
+ Props (Attachment.Item):
317
+
318
+ - `url`: string (required; a hosted URL or a data URL)
319
+ - `mediaType`: string (required)
320
+ - `filename`: string (without it an image's alt text is 「添付画像」 and a file chip shows the media type)
321
+
322
+ An image `url` is loaded as soon as the item renders, with no click in between. Pass URLs your own server produced or vouches for — a data URL, or your storage — rather than an arbitrary URL a model or tool wrote, which could point anywhere (a tracking pixel, an internal address). The AI SDK already turns files a provider generates into data URLs.
323
+
324
+ ## Source
325
+
326
+ The sources a response cites. An item with an `http(s)` `href` is a link that opens in a new tab, labelled by `title` or else the host name; anything else — a document source, or a URL with another scheme — is plain text. The URL comes from the model, so a `javascript:` URL never becomes a link.
327
+
328
+ ```tsx
329
+ import { Source } from '@k8ordo/ui/ai';
330
+
331
+ <Source.List>
332
+ <Source.Item href="https://ordo.k8o.me/ui/ai/chat" title="AI chat" />
333
+ <Source.Item title="Internal design doc v3" />
334
+ </Source.List>;
335
+ ```
336
+
337
+ Props (Source.List):
338
+
339
+ - `label`: string (default: `'出典'`, used as the list's aria-label)
340
+
341
+ Props (Source.Item):
342
+
343
+ - `href`: string (the source's URL)
344
+ - `title`: string (the source's title; falls back to the host name)
190
345
 
191
346
  ## Reasoning
192
347
 
193
- 推論(思考過程)の折りたたみ表示。ストリーミング中はラベルが「思考中…」になる。
348
+ A collapsible view of the model's reasoning. While streaming, the label reads 「思考中…」.
194
349
 
195
350
  ```tsx
196
351
  import { Reasoning } from '@k8ordo/ui/ai';
@@ -201,15 +356,14 @@ import { Reasoning } from '@k8ordo/ui/ai';
201
356
  Props:
202
357
 
203
358
  - `isStreaming`: boolean
204
- - `isOpen` / `defaultOpen` / `onChange`: 開閉の controlled / uncontrolled 両対応(`onChange` は `(isOpen: boolean) => void`)
359
+ - `isOpen` / `defaultOpen` / `onChange`: open state, controlled or uncontrolled (`onChange` is `(isOpen: boolean) => void`)
205
360
 
206
361
  ## Response
207
362
 
208
- ストリーミング対応の Markdown レンダラ。未クローズのコードブロックなど途中の Markdown も破綻なく描画する。optional peer の `streamdown` が必要([セットアップ](#optional-peer-のセットアップ)参照)。
363
+ A streaming-aware Markdown renderer. It renders half-finished Markdown — an unclosed code block, say — without breaking. Requires the optional peer `streamdown` (see [setup](#setting-up-the-optional-peers)).
209
364
 
210
365
  ```tsx
211
366
  import { Response } from '@k8ordo/ui/ai/response';
212
- import 'streamdown/styles.css';
213
367
 
214
368
  <Message.Content>
215
369
  <Response isStreaming={isStreaming}>{markdown}</Response>
@@ -218,47 +372,47 @@ import 'streamdown/styles.css';
218
372
 
219
373
  Props:
220
374
 
221
- - `children`: string(Markdown 文字列、必須)
375
+ - `children`: string (the Markdown, required)
222
376
  - `isStreaming`: boolean
223
- - 上記以外の streamdown の props(`translations` / `controls` / `linkSafety` / `plugins` / `components` / `urlTransform` / `dir` など)はそのまま透過する。`className` と `mode` はライブラリが握る(`mode` は `isStreaming` から決まる)
377
+ - Every other streamdown prop (`translations`, `controls`, `linkSafety`, `plugins`, `components`, `urlTransform`, `dir`, …) passes straight through. The library owns `className`, `mode` (`mode` is derived from `isStreaming`) and `portal`: the confirmation dialog and a table's full screen open inside the `Response`, where its styles reach them
224
378
 
225
- 文言は i18n 辞書から引くので、既定では「コードをコピー」「表をダウンロード」などが日本語で出る。個別に変えたいときは `translations` を渡す(prop > 辞書 > streamdown 既定)。
379
+ The wording comes from the i18n dictionary of the current locale, so strings such as `responseCopyCode` and `responseDownloadTable` follow the rest of the components. Pass `translations` to change individual strings (prop > dictionary > streamdown's own default).
226
380
 
227
- `linkSafety` はライブラリ側で**無効を既定にしている**。streamdown の既定(有効)ではリンクが `<a>` ではなく `<button>` で描画され、⌘クリック・中クリック・リンクアドレスのコピー・支援技術の link ロールが失われるため。確認ダイアログを挟みたい場合は明示的に有効化する:
381
+ The library **defaults `linkSafety` to off**. With streamdown's own default (on), links render as `<button>` rather than `<a>`, which loses ⌘-click, middle-click, copying the link address, and the link role for assistive technology. Turn it on explicitly if you want the confirmation dialog:
228
382
 
229
383
  ```tsx
230
384
  <Response linkSafety={{ enabled: true }}>{markdown}</Response>
231
385
  ```
232
386
 
233
- なお `javascript:` のような危険なスキームは `linkSafety` とは無関係に rehype-harden が無効化するので、既定のままでも生きたリンクにはならない。
387
+ Dangerous schemes such as `javascript:` are neutralized by rehype-harden regardless of `linkSafety`, so they never become live links even with the default.
234
388
 
235
389
  ## Suggestion
236
390
 
237
- 候補プロンプトのチップ表示。クリックで `onSelect` に `value` が渡る。
391
+ Suggested prompts shown as chips. Clicking one passes its `value` to `onSelect`.
238
392
 
239
393
  ```tsx
240
394
  import { Suggestion } from '@k8ordo/ui/ai';
241
395
 
242
396
  <Suggestion.List>
243
- <Suggestion.Item onSelect={send} value="IME 対応について教えて" />
397
+ <Suggestion.Item onSelect={send} value="Tell me about IME support" />
244
398
  <Suggestion.Item onSelect={send} value="streaming">
245
- ストリーミング表示は?
399
+ How does streaming display work?
246
400
  </Suggestion.Item>
247
401
  </Suggestion.List>;
248
402
  ```
249
403
 
250
404
  Props (Suggestion.List):
251
405
 
252
- - `label`: string(デフォルト: `'候補'`、aria-label として使用)
406
+ - `label`: string (default: `'候補'`, used as the aria-label)
253
407
 
254
408
  Props (Suggestion.Item):
255
409
 
256
- - `value`: string(必須。children 省略時は表示テキストも兼ねる)
410
+ - `value`: string (required; also serves as the visible text when children is omitted)
257
411
  - `onSelect`: `(value: string) => void`
258
412
 
259
413
  ## ToolInvocation
260
414
 
261
- ツール呼び出しの折りたたみ表示。`state` に応じてスピナー / 成功 / エラー / 拒否のアイコンが切り替わる(承認待ち・承認応答・入力中は進行中としてスピナー)。
415
+ A collapsible view of a tool call. The icon switches between spinner, success, error, and denied according to `state` (approval responded and input streaming count as in-progress and show the spinner).
262
416
 
263
417
  ```tsx
264
418
  import { ToolInvocation } from '@k8ordo/ui/ai';
@@ -267,23 +421,45 @@ import { ToolInvocation } from '@k8ordo/ui/ai';
267
421
  name="search_web"
268
422
  state="output-available"
269
423
  input={{ query: 'k8ordo UI' }}
270
- output="検索結果…"
424
+ output="Search results…"
271
425
  />;
272
426
  ```
273
427
 
428
+ ### Approval
429
+
430
+ When `state` is `'approval-requested'`, the tool is waiting for the user. Pass the part's `approval` and an `onApprovalResponse`, and a question with Deny / Allow buttons appears below the header — outside the collapsible panel, so it is visible without expanding the call; the input stays one click away in the panel. Pressing one calls `onApprovalResponse({ id: approval.id, approved })`, which is exactly what the AI SDK's `addToolApprovalResponse` takes. Until a returned promise settles, both buttons are `aria-disabled` and ignore presses; they are not natively `disabled`, so the pressed one keeps focus while the answer is sent. Once the state moves on, the question disappears; if it held focus, focus moves to the tool's header instead of falling to `body`.
431
+
432
+ ```tsx
433
+ <ToolInvocation
434
+ name={part.name}
435
+ state={part.state}
436
+ input={part.input}
437
+ approval={part.approval}
438
+ onApprovalResponse={addToolApprovalResponse}
439
+ />
440
+ ```
441
+
442
+ - The question is `approval.requestReason` when the server gave one, 「このツールの実行を許可しますか?」 otherwise.
443
+ - An automatic decision (`approval.isAutomatic`) shows no question and no buttons; there is nothing for the user to answer.
444
+ - Without `onApprovalResponse`, the question shows but the buttons do not.
445
+ - In `'output-denied'`, the panel explains the denial with `approval.reason`, falling back to the default wording.
446
+
447
+ With the AI SDK, send the answer back automatically with `sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithApprovalResponses` on `useChat`; otherwise nothing happens after the user answers.
448
+
274
449
  Props:
275
450
 
276
- - `name`: string(必須、ツール名)
277
- - `state`: ToolState(必須)
278
- - `input`: unknown(文字列以外は JSON 表示)
279
- - `output`: ReactNode(文字列は `pre` 表示、要素はそのまま描画)
280
- - `errorText`: string(`state="output-error"` 時の表示。省略時は既定文言)
281
- - `deniedReason`: string(`state="output-denied"` 時の表示。省略時は既定文言)
282
- - `isOpen` / `defaultOpen` / `onChange`: 開閉の controlled / uncontrolled 両対応
451
+ - `name`: string (required, the tool name)
452
+ - `state`: ToolState (required)
453
+ - `input`: unknown (anything other than a string is shown as JSON)
454
+ - `output`: ReactNode (a string is shown in a `pre`; an element renders as-is)
455
+ - `errorText`: string (shown when `state="output-error"`; falls back to the default wording)
456
+ - `approval`: ToolApproval (the approval being asked for or answered; its `reason` explains an `output-denied` call)
457
+ - `onApprovalResponse`: `(response: ToolApprovalResponse) => void | PromiseLike<void>` (called with the approval `id` and the user's answer)
458
+ - `isOpen` / `defaultOpen` / `onChange`: open state, controlled or uncontrolled
283
459
 
284
- ## AI SDK 連携(mapMessageParts)
460
+ ## AI SDK integration (mapMessageParts)
285
461
 
286
- `@k8ordo/ui/ai-sdk` の `mapMessageParts` は、AI SDK の `UIMessage.parts` を描画しやすい `MappedPart[]` に変換する。React 非依存で、optional peer の `ai`(v7)が必要。
462
+ `mapMessageParts` from `@k8ordo/ui/ai-sdk` converts the AI SDK's `UIMessage.parts` into a `MappedPart[]` that is easy to render. It has no React dependency and requires the optional peer `ai` (v7).
287
463
 
288
464
  ```ts
289
465
  type MappedPart =
@@ -297,49 +473,156 @@ type MappedPart =
297
473
  input?: unknown;
298
474
  output?: unknown;
299
475
  errorText?: string;
300
- deniedReason?: string;
301
- };
476
+ approval?: ToolApproval; // the part's own approval object, id included
477
+ }
478
+ | { kind: 'file'; url: string; mediaType: string; filename?: string }
479
+ | {
480
+ kind: 'source'; // both source-url and source-document
481
+ id: string;
482
+ url?: string; // source-url only
483
+ title?: string;
484
+ mediaType?: string; // source-document only
485
+ filename?: string; // source-document only
486
+ }
487
+ | { kind: 'data'; name: string; id?: string; data: unknown }; // `data-weather` → name 'weather'
302
488
  ```
303
489
 
304
- 利用側が `kind` で分岐して `Response` / `Reasoning` / `ToolInvocation` を描画する:
490
+ Order is preserved. `step-start`, `custom`, and `reasoning-file` parts are skipped.
491
+
492
+ Render each part as its own row under `Message.Root` — the children stack in a column. Files and sources read better as one list each, so pull them out with `filter` and skip them in the loop. A `data` part is yours: pick the ones you know by `name`, and validate what the model put in them before drawing it.
305
493
 
306
494
  ```tsx
495
+ 'use client';
496
+ import { useChat } from '@ai-sdk/react';
497
+ import { Avatar, AssistantIcon } from '@k8ordo/ui';
498
+ import {
499
+ Attachment,
500
+ Message,
501
+ Reasoning,
502
+ Source,
503
+ ToolInvocation,
504
+ } from '@k8ordo/ui/ai';
307
505
  import { mapMessageParts } from '@k8ordo/ui/ai-sdk';
308
- import { Reasoning, ToolInvocation } from '@k8ordo/ui/ai';
309
506
  import { Response } from '@k8ordo/ui/ai/response';
507
+ import { validateGeneratedSpec } from '@k8ordo/ui/json-render';
508
+ import { JsonRenderUI } from '@k8ordo/ui/json-render/registry';
509
+ import { lastAssistantMessageIsCompleteWithApprovalResponses } from 'ai';
510
+ import type { UIMessage } from 'ai';
310
511
 
311
- <Message.Content>
312
- {mapMessageParts(message).map((part, i) => {
313
- if (part.kind === 'reasoning')
314
- return <Reasoning key={i}>{part.text}</Reasoning>;
315
- if (part.kind === 'tool') {
316
- // output は unknown なので、ReactNode に変換してから渡す
317
- return (
318
- <ToolInvocation
319
- key={part.toolCallId}
320
- name={part.name}
321
- state={part.state}
322
- input={part.input}
323
- output={
324
- typeof part.output === 'string'
325
- ? part.output
326
- : JSON.stringify(part.output, null, 2)
327
- }
328
- errorText={part.errorText}
329
- deniedReason={part.deniedReason}
330
- />
331
- );
332
- }
333
- return <Response key={i}>{part.text}</Response>;
334
- })}
335
- </Message.Content>;
512
+ type Chat = ReturnType<typeof useChat>;
513
+
514
+ function ChatMessage({ message, chat }: { message: UIMessage; chat: Chat }) {
515
+ const parts = mapMessageParts(message);
516
+ const files = parts.filter((part) => part.kind === 'file');
517
+ const sources = parts.filter((part) => part.kind === 'source');
518
+ const text = parts
519
+ .map((part) => (part.kind === 'text' ? part.text : ''))
520
+ .join('');
521
+ const isUser = message.role === 'user';
522
+
523
+ return (
524
+ <Message.Root
525
+ avatar={
526
+ isUser ? undefined : (
527
+ <Avatar icon={<AssistantIcon />} name="AI" size="sm" />
528
+ )
529
+ }
530
+ from={isUser ? 'user' : 'assistant'}
531
+ >
532
+ {files.length > 0 && (
533
+ <Attachment.List>
534
+ {files.map((file) => (
535
+ <Attachment.Item
536
+ filename={file.filename}
537
+ key={file.url}
538
+ mediaType={file.mediaType}
539
+ url={file.url}
540
+ />
541
+ ))}
542
+ </Attachment.List>
543
+ )}
544
+ {parts.map((part, i) => {
545
+ const key = `${message.id}-${i}`;
546
+ if (part.kind === 'text') {
547
+ return (
548
+ <Message.Content key={key}>
549
+ <Response>{part.text}</Response>
550
+ </Message.Content>
551
+ );
552
+ }
553
+ if (part.kind === 'reasoning') {
554
+ return <Reasoning key={key}>{part.text}</Reasoning>;
555
+ }
556
+ if (part.kind === 'tool') {
557
+ return (
558
+ <ToolInvocation
559
+ approval={part.approval}
560
+ errorText={part.errorText}
561
+ input={part.input}
562
+ key={part.toolCallId}
563
+ name={part.name}
564
+ onApprovalResponse={chat.addToolApprovalResponse}
565
+ // output is unknown, so convert it to a ReactNode first
566
+ output={
567
+ part.output === undefined
568
+ ? undefined
569
+ : JSON.stringify(part.output, null, 2)
570
+ }
571
+ state={part.state}
572
+ />
573
+ );
574
+ }
575
+ if (part.kind === 'data' && part.name === 'ui') {
576
+ const result = validateGeneratedSpec(part.data);
577
+ return result.ok ? (
578
+ <JsonRenderUI key={key} spec={result.spec} />
579
+ ) : null;
580
+ }
581
+ return null;
582
+ })}
583
+ {sources.length > 0 && (
584
+ <Source.List>
585
+ {sources.map((source) => (
586
+ <Source.Item
587
+ href={source.url}
588
+ key={source.id}
589
+ title={source.title}
590
+ />
591
+ ))}
592
+ </Source.List>
593
+ )}
594
+ {!isUser && text !== '' && (
595
+ <Message.Actions>
596
+ <Message.Copy value={text} />
597
+ <Message.Regenerate
598
+ disabled={
599
+ chat.status === 'submitted' || chat.status === 'streaming'
600
+ }
601
+ onAction={() => chat.regenerate({ messageId: message.id })}
602
+ />
603
+ <Message.Feedback />
604
+ </Message.Actions>
605
+ )}
606
+ </Message.Root>
607
+ );
608
+ }
609
+
610
+ export function Chat() {
611
+ const chat = useChat({
612
+ // sends the answers back as soon as every pending approval has one
613
+ sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithApprovalResponses,
614
+ });
615
+ // … Conversation.Root / chat.messages.map((message) => <ChatMessage … />) / PromptInput
616
+ }
336
617
  ```
337
618
 
338
- `ChatStatus` / `ToolState` 型は `@k8ordo/ui/ai-sdk` からも re-export される。
619
+ `examples/ui-integrations` in the repository runs this against the real `useChat`, with a scripted transport in place of a model.
620
+
621
+ `@k8ordo/ui/ai-sdk` exports the `MappedPart` type, and re-exports the `ChatStatus`, `ToolState`, `ToolApproval`, and `ToolApprovalResponse` types as well.
339
622
 
340
- ## 生成 UI との組み合わせ
623
+ ## Combining with generative UI
341
624
 
342
- LLM がツール結果として返した UI spec を、チャットの吹き出し内で描画できる。詳細は [生成 UI リファレンス](generative-ui.md) を参照。
625
+ A UI spec returned by an LLM as a tool result can be rendered inside a chat bubble. See the [generative UI reference](generative-ui.md) for details.
343
626
 
344
627
  ```tsx
345
628
  'use client';