@womp/kookie-ui 0.8.0 → 0.9.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 (296) hide show
  1. package/AUTHORS +4 -0
  2. package/README.md +1 -1
  3. package/components.css +169 -1
  4. package/dist/cjs/components/chatbar.d.ts +52 -1
  5. package/dist/cjs/components/chatbar.d.ts.map +1 -1
  6. package/dist/cjs/components/chatbar.js +2 -2
  7. package/dist/cjs/components/chatbar.js.map +4 -4
  8. package/dist/cjs/components/index.d.ts +2 -0
  9. package/dist/cjs/components/index.d.ts.map +1 -1
  10. package/dist/cjs/components/index.js +5 -5
  11. package/dist/cjs/components/index.js.map +4 -4
  12. package/dist/cjs/components/message-scroller.d.ts +86 -0
  13. package/dist/cjs/components/message-scroller.d.ts.map +1 -0
  14. package/dist/cjs/components/message-scroller.js +5 -0
  15. package/dist/cjs/components/message-scroller.js.map +7 -0
  16. package/dist/cjs/components/notice.d.ts +67 -0
  17. package/dist/cjs/components/notice.d.ts.map +1 -0
  18. package/dist/cjs/components/notice.js +5 -0
  19. package/dist/cjs/components/notice.js.map +7 -0
  20. package/dist/cjs/components/sidebar.d.ts.map +1 -1
  21. package/dist/cjs/components/sidebar.js +1 -1
  22. package/dist/cjs/components/sidebar.js.map +3 -3
  23. package/dist/cjs/index.js +5 -5
  24. package/dist/cjs/index.js.map +4 -4
  25. package/dist/esm/{chunk-WGWUEU4K.js → chunk-2I7QRVJ5.js} +2 -2
  26. package/dist/esm/{chunk-EHBAK3LQ.js → chunk-43A5GUSI.js} +2 -2
  27. package/dist/esm/{chunk-FEAOFF77.js → chunk-47LMOIW3.js} +2 -2
  28. package/dist/esm/chunk-4JQZUQY7.js +2 -0
  29. package/dist/esm/{chunk-O4CSXNST.js → chunk-4ME6O27S.js} +2 -2
  30. package/dist/esm/{chunk-OEEF6KJG.js → chunk-4XGGX2V2.js} +2 -2
  31. package/dist/esm/{chunk-26I257HE.js → chunk-4XKK32M4.js} +2 -2
  32. package/dist/esm/{chunk-MM5IHQFM.js → chunk-4YFJWXL2.js} +2 -2
  33. package/dist/esm/{chunk-5TAHT6VC.js → chunk-5WRCK4R7.js} +2 -2
  34. package/dist/esm/{chunk-POG3YABW.js → chunk-65GAANJD.js} +2 -2
  35. package/dist/esm/{chunk-UBSLEGQZ.js → chunk-6FLLFCBU.js} +2 -2
  36. package/dist/esm/{chunk-KV4SZP3F.js → chunk-73QGEY2I.js} +2 -2
  37. package/dist/esm/{chunk-WQCB7KSH.js → chunk-7FC7HF76.js} +2 -2
  38. package/dist/esm/{chunk-UNWPH3SO.js → chunk-7RQNB63F.js} +2 -2
  39. package/dist/esm/{chunk-CRBOJ7N7.js → chunk-7UHKEJ7Q.js} +2 -2
  40. package/dist/esm/{chunk-OJSOX3AX.js → chunk-ABSKRHVM.js} +2 -2
  41. package/dist/esm/{chunk-7FKKGUHK.js → chunk-AGSSWWFI.js} +2 -2
  42. package/dist/esm/{chunk-W2LD2YE6.js → chunk-ALWNS44Q.js} +2 -2
  43. package/dist/esm/{chunk-Z7AZNMNX.js → chunk-BW5CO4PZ.js} +2 -2
  44. package/dist/esm/{chunk-KEEPKI2X.js → chunk-CDG5WH4U.js} +2 -2
  45. package/dist/esm/{chunk-IK3MQHA5.js → chunk-CIYF56YS.js} +2 -2
  46. package/dist/esm/{chunk-JDEBKA56.js → chunk-CKMMUHKE.js} +2 -2
  47. package/dist/esm/{chunk-TLGXIWAS.js → chunk-CRTH5LNU.js} +2 -2
  48. package/dist/esm/{chunk-NTNMJX5M.js → chunk-CSKZZOI2.js} +2 -2
  49. package/dist/esm/{chunk-4WU2WKUJ.js → chunk-CTA5ODAO.js} +2 -2
  50. package/dist/esm/{chunk-PDUHBDFC.js → chunk-DSJY5RI3.js} +2 -2
  51. package/dist/esm/{chunk-JDWCQ2XP.js → chunk-E67CIG6A.js} +2 -2
  52. package/dist/esm/{chunk-WIDJYVZF.js → chunk-EPTYNVCU.js} +2 -2
  53. package/dist/esm/{chunk-HMSSFU6I.js → chunk-ERY5TH2M.js} +2 -2
  54. package/dist/esm/{chunk-LJCUPAOI.js → chunk-FG7XM7KJ.js} +2 -2
  55. package/dist/esm/{chunk-ZJ33QP5N.js → chunk-FHOCUZDR.js} +2 -2
  56. package/dist/esm/{chunk-2Q7BJ7YG.js → chunk-GLERJXVS.js} +2 -2
  57. package/dist/esm/{chunk-PYXMGEO7.js → chunk-GO7OHBHW.js} +2 -2
  58. package/dist/esm/{chunk-OQU2SKLN.js → chunk-HF5WY5YE.js} +2 -2
  59. package/dist/esm/{chunk-25X75TI7.js → chunk-HJU4I34X.js} +2 -2
  60. package/dist/esm/{chunk-CBNTPHYK.js → chunk-IHK3H2OM.js} +2 -2
  61. package/dist/esm/{chunk-C5RVO3C3.js → chunk-JDGJSNWT.js} +2 -2
  62. package/dist/esm/chunk-JKS2YXMS.js +1 -0
  63. package/dist/esm/{chunk-PBFSBHBS.js → chunk-JUY7CBSL.js} +2 -2
  64. package/dist/esm/{chunk-F3AXE27Q.js → chunk-K3UAS7RW.js} +2 -2
  65. package/dist/esm/{chunk-FB3PD4Z3.js → chunk-KFR3CK24.js} +2 -2
  66. package/dist/esm/{chunk-AIHQ3MVK.js → chunk-KJUDZCYK.js} +2 -2
  67. package/dist/esm/{chunk-JRFZ535T.js → chunk-KMPE7TJ6.js} +2 -2
  68. package/dist/esm/{chunk-5M7STAH3.js → chunk-KZWNGWIM.js} +2 -2
  69. package/dist/esm/{chunk-H4GR4262.js → chunk-LXWPEDPZ.js} +2 -2
  70. package/dist/esm/chunk-MCQCG6AS.js +2 -0
  71. package/dist/esm/{chunk-JQW4XYBS.js → chunk-MEO7MJMQ.js} +2 -2
  72. package/dist/esm/{chunk-QJVAS7AK.js → chunk-MS5J4MF6.js} +2 -2
  73. package/dist/esm/{chunk-44JZYS7A.js → chunk-MWIIGYAJ.js} +2 -2
  74. package/dist/esm/{chunk-MBCQA7UZ.js → chunk-N4GTDLRD.js} +2 -2
  75. package/dist/esm/{chunk-NV3P2CKH.js → chunk-NIM7DIVH.js} +2 -2
  76. package/dist/esm/{chunk-ZW26J2SA.js → chunk-OGXZHAQL.js} +2 -2
  77. package/dist/esm/{chunk-WJBOOAIO.js → chunk-OLAWVEAI.js} +2 -2
  78. package/dist/esm/{chunk-JQSZF3E2.js → chunk-OMGZG52I.js} +2 -2
  79. package/dist/esm/{chunk-HBIF43PT.js → chunk-PHC3QBV3.js} +2 -2
  80. package/dist/esm/{chunk-OTKQN2KY.js → chunk-PZ7OYATT.js} +2 -2
  81. package/dist/esm/{chunk-P27KV2LS.js → chunk-QWVU2TW4.js} +2 -2
  82. package/dist/esm/chunk-RJP5QUXO.js +2 -0
  83. package/dist/esm/chunk-RJP5QUXO.js.map +7 -0
  84. package/dist/esm/{chunk-6J6YX2VX.js → chunk-RNTCHVFI.js} +2 -2
  85. package/dist/esm/{chunk-IDUVJJYG.js → chunk-S5C5YRBS.js} +2 -2
  86. package/dist/esm/{chunk-RY67WG3O.js → chunk-T4OR62DQ.js} +2 -2
  87. package/dist/esm/{chunk-AO32NT75.js → chunk-UBOOUDS4.js} +2 -2
  88. package/dist/esm/{chunk-DCIQHXAR.js → chunk-VHECAEUP.js} +2 -2
  89. package/dist/esm/{chunk-QEGEUD4D.js → chunk-VNH7BJOA.js} +2 -2
  90. package/dist/esm/{chunk-GGSJXOKR.js → chunk-VR7ZAFYN.js} +2 -2
  91. package/dist/esm/{chunk-ODCVOXEV.js → chunk-VX6ARMWP.js} +2 -2
  92. package/dist/esm/{chunk-G4YKBAZT.js → chunk-VZSQATP6.js} +2 -2
  93. package/dist/esm/chunk-W4WWN3RC.js +2 -0
  94. package/dist/esm/chunk-W4WWN3RC.js.map +7 -0
  95. package/dist/esm/{chunk-YVSM2LGS.js → chunk-WGYUWEQV.js} +2 -2
  96. package/dist/esm/{chunk-7NYODT3Z.js → chunk-WHFJ4JUN.js} +2 -2
  97. package/dist/esm/{chunk-YG66IRW4.js → chunk-X3JM2565.js} +2 -2
  98. package/dist/esm/chunk-XI5YXUCK.js +2 -0
  99. package/dist/esm/{chunk-NQXRWBQM.js → chunk-Y5RCH23Z.js} +2 -2
  100. package/dist/esm/{chunk-WZFVTC7P.js → chunk-YBSRX63K.js} +2 -2
  101. package/dist/esm/chunk-YQRSAP46.js +2 -0
  102. package/dist/esm/chunk-YQRSAP46.js.map +7 -0
  103. package/dist/esm/chunk-YTD3AJAU.js +2 -0
  104. package/dist/esm/chunk-YTD3AJAU.js.map +7 -0
  105. package/dist/esm/{chunk-GDAKJS64.js → chunk-YWENWZOU.js} +2 -2
  106. package/dist/esm/{chunk-7PMMYHZV.js → chunk-ZOY43B55.js} +2 -2
  107. package/dist/esm/{chunk-VTIL55SR.js → chunk-ZZLZGHZQ.js} +2 -2
  108. package/dist/esm/components/_internal/base-button.js +1 -1
  109. package/dist/esm/components/_internal/base-menu.utils.js +1 -1
  110. package/dist/esm/components/_internal/menu-context.js +1 -1
  111. package/dist/esm/components/accordion.js +1 -1
  112. package/dist/esm/components/alert-dialog.js +1 -1
  113. package/dist/esm/components/avatar.js +1 -1
  114. package/dist/esm/components/badge.js +1 -1
  115. package/dist/esm/components/blockquote.js +1 -1
  116. package/dist/esm/components/blockquote.props.js +1 -1
  117. package/dist/esm/components/box.js +1 -1
  118. package/dist/esm/components/button.js +1 -1
  119. package/dist/esm/components/callout.js +1 -1
  120. package/dist/esm/components/card.js +1 -1
  121. package/dist/esm/components/chatbar.d.ts +52 -1
  122. package/dist/esm/components/chatbar.d.ts.map +1 -1
  123. package/dist/esm/components/chatbar.js +1 -1
  124. package/dist/esm/components/checkbox-cards.js +1 -1
  125. package/dist/esm/components/checkbox-group.js +1 -1
  126. package/dist/esm/components/checkbox.js +1 -1
  127. package/dist/esm/components/code.js +1 -1
  128. package/dist/esm/components/code.props.js +1 -1
  129. package/dist/esm/components/combobox.js +1 -1
  130. package/dist/esm/components/container.js +1 -1
  131. package/dist/esm/components/context-menu.js +1 -1
  132. package/dist/esm/components/data-list.js +1 -1
  133. package/dist/esm/components/dialog.js +1 -1
  134. package/dist/esm/components/dropdown-menu.js +1 -1
  135. package/dist/esm/components/em.js +1 -1
  136. package/dist/esm/components/em.props.js +1 -1
  137. package/dist/esm/components/flex.js +1 -1
  138. package/dist/esm/components/grid.js +1 -1
  139. package/dist/esm/components/heading.js +1 -1
  140. package/dist/esm/components/heading.props.js +1 -1
  141. package/dist/esm/components/hover-card.js +1 -1
  142. package/dist/esm/components/icon-button.js +1 -1
  143. package/dist/esm/components/image.js +1 -1
  144. package/dist/esm/components/index.d.ts +2 -0
  145. package/dist/esm/components/index.d.ts.map +1 -1
  146. package/dist/esm/components/index.js +1 -1
  147. package/dist/esm/components/inset.js +1 -1
  148. package/dist/esm/components/kbd.js +1 -1
  149. package/dist/esm/components/link.js +1 -1
  150. package/dist/esm/components/link.props.js +1 -1
  151. package/dist/esm/components/message-scroller.d.ts +86 -0
  152. package/dist/esm/components/message-scroller.d.ts.map +1 -0
  153. package/dist/esm/components/message-scroller.js +2 -0
  154. package/dist/esm/components/message-scroller.js.map +7 -0
  155. package/dist/esm/components/navbar.js +1 -1
  156. package/dist/esm/components/notice.d.ts +67 -0
  157. package/dist/esm/components/notice.d.ts.map +1 -0
  158. package/dist/esm/components/notice.js +2 -0
  159. package/dist/esm/components/notice.js.map +7 -0
  160. package/dist/esm/components/popover.js +1 -1
  161. package/dist/esm/components/progress.js +1 -1
  162. package/dist/esm/components/quote.js +1 -1
  163. package/dist/esm/components/quote.props.js +1 -1
  164. package/dist/esm/components/radio-cards.js +1 -1
  165. package/dist/esm/components/radio-group.js +1 -1
  166. package/dist/esm/components/radio.js +1 -1
  167. package/dist/esm/components/schemas/index.js +1 -1
  168. package/dist/esm/components/scroll-area.js +1 -1
  169. package/dist/esm/components/section.js +1 -1
  170. package/dist/esm/components/segmented-control.js +1 -1
  171. package/dist/esm/components/select.js +1 -1
  172. package/dist/esm/components/separator.js +1 -1
  173. package/dist/esm/components/sheet.js +1 -1
  174. package/dist/esm/components/sidebar.d.ts.map +1 -1
  175. package/dist/esm/components/sidebar.js +1 -1
  176. package/dist/esm/components/skeleton.js +1 -1
  177. package/dist/esm/components/slider.js +1 -1
  178. package/dist/esm/components/spinner.js +1 -1
  179. package/dist/esm/components/strong.js +1 -1
  180. package/dist/esm/components/strong.props.js +1 -1
  181. package/dist/esm/components/switch.js +1 -1
  182. package/dist/esm/components/tab-nav.js +1 -1
  183. package/dist/esm/components/table.js +1 -1
  184. package/dist/esm/components/tabs.js +1 -1
  185. package/dist/esm/components/text-area.js +1 -1
  186. package/dist/esm/components/text-field.js +1 -1
  187. package/dist/esm/components/text.js +1 -1
  188. package/dist/esm/components/text.props.js +1 -1
  189. package/dist/esm/components/theme-panel.js +1 -1
  190. package/dist/esm/components/toggle-button.js +1 -1
  191. package/dist/esm/components/toggle-icon-button.js +1 -1
  192. package/dist/esm/components/toolbar.js +1 -1
  193. package/dist/esm/components/tooltip.js +1 -1
  194. package/dist/esm/components/user-card.js +1 -1
  195. package/dist/esm/components/virtual-menu.js +1 -1
  196. package/dist/esm/helpers/extract-props.js +1 -1
  197. package/dist/esm/helpers/get-margin-styles.js +1 -1
  198. package/dist/esm/helpers/get-responsive-styles.js +1 -1
  199. package/dist/esm/helpers/index.js +1 -1
  200. package/dist/esm/index.js +1 -1
  201. package/dist/esm/props/index.js +1 -1
  202. package/package.json +2 -1
  203. package/src/components/_internal/base-sidebar-menu.css +2 -1
  204. package/src/components/chatbar.css +24 -0
  205. package/src/components/chatbar.tsx +102 -15
  206. package/src/components/index.css +2 -0
  207. package/src/components/index.tsx +7 -0
  208. package/src/components/message-scroller.css +54 -0
  209. package/src/components/message-scroller.tsx +165 -0
  210. package/src/components/notice.css +91 -0
  211. package/src/components/notice.tsx +151 -0
  212. package/src/components/sidebar.tsx +17 -28
  213. package/styles.css +169 -1
  214. package/dist/esm/chunk-3AOFY2B4.js +0 -2
  215. package/dist/esm/chunk-3AOFY2B4.js.map +0 -7
  216. package/dist/esm/chunk-3PTSRBVY.js +0 -2
  217. package/dist/esm/chunk-3PTSRBVY.js.map +0 -7
  218. package/dist/esm/chunk-GM7KMQDI.js +0 -2
  219. package/dist/esm/chunk-QDW5ZG5E.js +0 -1
  220. package/dist/esm/chunk-QEL55MLF.js +0 -2
  221. package/dist/esm/chunk-XDDKT4NF.js +0 -2
  222. /package/dist/esm/{chunk-WGWUEU4K.js.map → chunk-2I7QRVJ5.js.map} +0 -0
  223. /package/dist/esm/{chunk-EHBAK3LQ.js.map → chunk-43A5GUSI.js.map} +0 -0
  224. /package/dist/esm/{chunk-FEAOFF77.js.map → chunk-47LMOIW3.js.map} +0 -0
  225. /package/dist/esm/{chunk-GM7KMQDI.js.map → chunk-4JQZUQY7.js.map} +0 -0
  226. /package/dist/esm/{chunk-O4CSXNST.js.map → chunk-4ME6O27S.js.map} +0 -0
  227. /package/dist/esm/{chunk-OEEF6KJG.js.map → chunk-4XGGX2V2.js.map} +0 -0
  228. /package/dist/esm/{chunk-26I257HE.js.map → chunk-4XKK32M4.js.map} +0 -0
  229. /package/dist/esm/{chunk-MM5IHQFM.js.map → chunk-4YFJWXL2.js.map} +0 -0
  230. /package/dist/esm/{chunk-5TAHT6VC.js.map → chunk-5WRCK4R7.js.map} +0 -0
  231. /package/dist/esm/{chunk-POG3YABW.js.map → chunk-65GAANJD.js.map} +0 -0
  232. /package/dist/esm/{chunk-UBSLEGQZ.js.map → chunk-6FLLFCBU.js.map} +0 -0
  233. /package/dist/esm/{chunk-KV4SZP3F.js.map → chunk-73QGEY2I.js.map} +0 -0
  234. /package/dist/esm/{chunk-WQCB7KSH.js.map → chunk-7FC7HF76.js.map} +0 -0
  235. /package/dist/esm/{chunk-UNWPH3SO.js.map → chunk-7RQNB63F.js.map} +0 -0
  236. /package/dist/esm/{chunk-CRBOJ7N7.js.map → chunk-7UHKEJ7Q.js.map} +0 -0
  237. /package/dist/esm/{chunk-OJSOX3AX.js.map → chunk-ABSKRHVM.js.map} +0 -0
  238. /package/dist/esm/{chunk-7FKKGUHK.js.map → chunk-AGSSWWFI.js.map} +0 -0
  239. /package/dist/esm/{chunk-W2LD2YE6.js.map → chunk-ALWNS44Q.js.map} +0 -0
  240. /package/dist/esm/{chunk-Z7AZNMNX.js.map → chunk-BW5CO4PZ.js.map} +0 -0
  241. /package/dist/esm/{chunk-KEEPKI2X.js.map → chunk-CDG5WH4U.js.map} +0 -0
  242. /package/dist/esm/{chunk-IK3MQHA5.js.map → chunk-CIYF56YS.js.map} +0 -0
  243. /package/dist/esm/{chunk-JDEBKA56.js.map → chunk-CKMMUHKE.js.map} +0 -0
  244. /package/dist/esm/{chunk-TLGXIWAS.js.map → chunk-CRTH5LNU.js.map} +0 -0
  245. /package/dist/esm/{chunk-NTNMJX5M.js.map → chunk-CSKZZOI2.js.map} +0 -0
  246. /package/dist/esm/{chunk-4WU2WKUJ.js.map → chunk-CTA5ODAO.js.map} +0 -0
  247. /package/dist/esm/{chunk-PDUHBDFC.js.map → chunk-DSJY5RI3.js.map} +0 -0
  248. /package/dist/esm/{chunk-JDWCQ2XP.js.map → chunk-E67CIG6A.js.map} +0 -0
  249. /package/dist/esm/{chunk-WIDJYVZF.js.map → chunk-EPTYNVCU.js.map} +0 -0
  250. /package/dist/esm/{chunk-HMSSFU6I.js.map → chunk-ERY5TH2M.js.map} +0 -0
  251. /package/dist/esm/{chunk-LJCUPAOI.js.map → chunk-FG7XM7KJ.js.map} +0 -0
  252. /package/dist/esm/{chunk-ZJ33QP5N.js.map → chunk-FHOCUZDR.js.map} +0 -0
  253. /package/dist/esm/{chunk-2Q7BJ7YG.js.map → chunk-GLERJXVS.js.map} +0 -0
  254. /package/dist/esm/{chunk-PYXMGEO7.js.map → chunk-GO7OHBHW.js.map} +0 -0
  255. /package/dist/esm/{chunk-OQU2SKLN.js.map → chunk-HF5WY5YE.js.map} +0 -0
  256. /package/dist/esm/{chunk-25X75TI7.js.map → chunk-HJU4I34X.js.map} +0 -0
  257. /package/dist/esm/{chunk-CBNTPHYK.js.map → chunk-IHK3H2OM.js.map} +0 -0
  258. /package/dist/esm/{chunk-C5RVO3C3.js.map → chunk-JDGJSNWT.js.map} +0 -0
  259. /package/dist/esm/{chunk-QDW5ZG5E.js.map → chunk-JKS2YXMS.js.map} +0 -0
  260. /package/dist/esm/{chunk-PBFSBHBS.js.map → chunk-JUY7CBSL.js.map} +0 -0
  261. /package/dist/esm/{chunk-F3AXE27Q.js.map → chunk-K3UAS7RW.js.map} +0 -0
  262. /package/dist/esm/{chunk-FB3PD4Z3.js.map → chunk-KFR3CK24.js.map} +0 -0
  263. /package/dist/esm/{chunk-AIHQ3MVK.js.map → chunk-KJUDZCYK.js.map} +0 -0
  264. /package/dist/esm/{chunk-JRFZ535T.js.map → chunk-KMPE7TJ6.js.map} +0 -0
  265. /package/dist/esm/{chunk-5M7STAH3.js.map → chunk-KZWNGWIM.js.map} +0 -0
  266. /package/dist/esm/{chunk-H4GR4262.js.map → chunk-LXWPEDPZ.js.map} +0 -0
  267. /package/dist/esm/{chunk-QEL55MLF.js.map → chunk-MCQCG6AS.js.map} +0 -0
  268. /package/dist/esm/{chunk-JQW4XYBS.js.map → chunk-MEO7MJMQ.js.map} +0 -0
  269. /package/dist/esm/{chunk-QJVAS7AK.js.map → chunk-MS5J4MF6.js.map} +0 -0
  270. /package/dist/esm/{chunk-44JZYS7A.js.map → chunk-MWIIGYAJ.js.map} +0 -0
  271. /package/dist/esm/{chunk-MBCQA7UZ.js.map → chunk-N4GTDLRD.js.map} +0 -0
  272. /package/dist/esm/{chunk-NV3P2CKH.js.map → chunk-NIM7DIVH.js.map} +0 -0
  273. /package/dist/esm/{chunk-ZW26J2SA.js.map → chunk-OGXZHAQL.js.map} +0 -0
  274. /package/dist/esm/{chunk-WJBOOAIO.js.map → chunk-OLAWVEAI.js.map} +0 -0
  275. /package/dist/esm/{chunk-JQSZF3E2.js.map → chunk-OMGZG52I.js.map} +0 -0
  276. /package/dist/esm/{chunk-HBIF43PT.js.map → chunk-PHC3QBV3.js.map} +0 -0
  277. /package/dist/esm/{chunk-OTKQN2KY.js.map → chunk-PZ7OYATT.js.map} +0 -0
  278. /package/dist/esm/{chunk-P27KV2LS.js.map → chunk-QWVU2TW4.js.map} +0 -0
  279. /package/dist/esm/{chunk-6J6YX2VX.js.map → chunk-RNTCHVFI.js.map} +0 -0
  280. /package/dist/esm/{chunk-IDUVJJYG.js.map → chunk-S5C5YRBS.js.map} +0 -0
  281. /package/dist/esm/{chunk-RY67WG3O.js.map → chunk-T4OR62DQ.js.map} +0 -0
  282. /package/dist/esm/{chunk-AO32NT75.js.map → chunk-UBOOUDS4.js.map} +0 -0
  283. /package/dist/esm/{chunk-DCIQHXAR.js.map → chunk-VHECAEUP.js.map} +0 -0
  284. /package/dist/esm/{chunk-QEGEUD4D.js.map → chunk-VNH7BJOA.js.map} +0 -0
  285. /package/dist/esm/{chunk-GGSJXOKR.js.map → chunk-VR7ZAFYN.js.map} +0 -0
  286. /package/dist/esm/{chunk-ODCVOXEV.js.map → chunk-VX6ARMWP.js.map} +0 -0
  287. /package/dist/esm/{chunk-G4YKBAZT.js.map → chunk-VZSQATP6.js.map} +0 -0
  288. /package/dist/esm/{chunk-YVSM2LGS.js.map → chunk-WGYUWEQV.js.map} +0 -0
  289. /package/dist/esm/{chunk-7NYODT3Z.js.map → chunk-WHFJ4JUN.js.map} +0 -0
  290. /package/dist/esm/{chunk-YG66IRW4.js.map → chunk-X3JM2565.js.map} +0 -0
  291. /package/dist/esm/{chunk-XDDKT4NF.js.map → chunk-XI5YXUCK.js.map} +0 -0
  292. /package/dist/esm/{chunk-NQXRWBQM.js.map → chunk-Y5RCH23Z.js.map} +0 -0
  293. /package/dist/esm/{chunk-WZFVTC7P.js.map → chunk-YBSRX63K.js.map} +0 -0
  294. /package/dist/esm/{chunk-GDAKJS64.js.map → chunk-YWENWZOU.js.map} +0 -0
  295. /package/dist/esm/{chunk-7PMMYHZV.js.map → chunk-ZOY43B55.js.map} +0 -0
  296. /package/dist/esm/{chunk-VTIL55SR.js.map → chunk-ZZLZGHZQ.js.map} +0 -0
@@ -1,2 +1,2 @@
1
- import{a as Go}from"../chunk-MQWH2IFO.js";import{a as Bo,b as Co}from"../chunk-TZTUPQYK.js";import{a as Do}from"../chunk-CLMOWP5T.js";import{a as Eo,b as Fo}from"../chunk-MN3XALXD.js";import{a as uo}from"../chunk-XDDKT4NF.js";import{a as vo}from"../chunk-AF6XKU3W.js";import{a as wo}from"../chunk-AUV6B4AH.js";import{a as yo,b as zo,c as Ao}from"../chunk-BALS3AVM.js";import{a as so}from"../chunk-OJU5GCDZ.js";import{a as qo}from"../chunk-CRSHBENJ.js";import{a as jo}from"../chunk-NIX6Z3JG.js";import{a as io}from"../chunk-FC2DBBJ3.js";import{a as ko,b as lo,c as no}from"../chunk-EBQZ3Z22.js";import{a as co}from"../chunk-QEL55MLF.js";import{a as go}from"../chunk-OWMA6GTG.js";import{a as ho}from"../chunk-VLTXI4A7.js";import"../chunk-STPMPY3X.js";import{a as ao}from"../chunk-7FKKGUHK.js";import{a as bo}from"../chunk-5XV4QEP5.js";import{a as to}from"../chunk-L6UXAITB.js";import{a as po}from"../chunk-GFOSP3PZ.js";import{a as xo}from"../chunk-JAMLW534.js";import{a as mo}from"../chunk-VJSZG35J.js";import"../chunk-YKPMLM7M.js";import"../chunk-WOR3JCLX.js";import{a as fo}from"../chunk-GM7KMQDI.js";import{a as _}from"../chunk-72AHPGPN.js";import{a as $}from"../chunk-PPNWGWN3.js";import"../chunk-OA7C34MJ.js";import{a as oo,b as ro,c as eo}from"../chunk-NIIEIZKQ.js";import{a as Y}from"../chunk-5SNHUVDA.js";import"../chunk-UICSVJ3B.js";import{a as Z}from"../chunk-5M7STAH3.js";import"../chunk-6DWDNKLS.js";import{a as T}from"../chunk-OGVKSYLL.js";import{a as U}from"../chunk-OO652UQW.js";import{a as V}from"../chunk-5KICSAT7.js";import{a as X}from"../chunk-667BKCUG.js";import{a as W}from"../chunk-HAGKI7NA.js";import{a as O}from"../chunk-QFPHEY77.js";import{a as Q}from"../chunk-BPVVFHYD.js";import{a as P}from"../chunk-QQ62LO3X.js";import{a as R}from"../chunk-YVSM2LGS.js";import{a as S}from"../chunk-FGORMEAO.js";import{a as M}from"../chunk-OTKQN2KY.js";import{a as N}from"../chunk-26I257HE.js";import{a as I}from"../chunk-G2CKYO2I.js";import"../chunk-AXUDFYLY.js";import{a as H}from"../chunk-KNQBAOMV.js";import{a as L}from"../chunk-FD2TR343.js";import{a as K}from"../chunk-ZE2KAVXW.js";import{a as J}from"../chunk-WYADYDPN.js";import{a as F,b as G}from"../chunk-ZWZGUBL4.js";import{a as E}from"../chunk-XKBLNVOD.js";import{a as D}from"../chunk-GCUGJXI2.js";import{a as C}from"../chunk-XYVLQDGR.js";import{a as l}from"../chunk-3KB2XWBE.js";import{a as k}from"../chunk-SMGDH54W.js";import{a as j}from"../chunk-SNR5VFWG.js";import{a as h}from"../chunk-K53W3ELO.js";import{a as c}from"../chunk-TTFUM47A.js";import{a as d}from"../chunk-VX44UTQ5.js";import{a as g}from"../chunk-ERGJN7FJ.js";import{a as x}from"../chunk-JFWMAYEH.js";import{a as p,b as t}from"../chunk-KRJTW535.js";import{a as n}from"../chunk-F6V7GBNQ.js";import{a as q,b as s,c as u,d as v,e as w,f as y}from"../chunk-3KSGRY6I.js";import{a as z}from"../chunk-ARIV4AT5.js";import{a as i}from"../chunk-GSTOGDAJ.js";import{a,b}from"../chunk-WRWNN2NW.js";import{a as o}from"../chunk-NZJGC6ZW.js";import{a as A}from"../chunk-WMGIFPI2.js";import{a as B}from"../chunk-CFNESRYI.js";import{a as r,b as e,c as f,d as m}from"../chunk-ZNK6AH2G.js";import"../chunk-OS3FCYZY.js";export{m as accentColorPropDef,r as accentColors,E as alertDialogContentPropDefs,o as asChildPropDef,O as avatarPropDefs,P as badgePropDefs,R as blockquotePropDefs,S as boxPropDefs,b as breakpointSet,a as breakpoints,x as buttonPropDefs,T as calloutRootPropDefs,U as cardPropDefs,X as checkboxCardsRootPropDefs,Y as checkboxGroupRootPropDefs,n as checkboxPropDefs,Z as codePropDefs,f as colorPropDef,$ as containerPropDefs,w as contextMenuCheckboxItemPropDefs,u as contextMenuContentPropDefs,v as contextMenuItemPropDefs,y as contextMenuRadioItemPropDefs,u as contextMenuSubContentPropDefs,ro as dataListItemPropDefs,eo as dataListLabelPropDefs,oo as dataListRootPropDefs,D as dialogContentPropDefs,w as dropdownMenuCheckboxItemPropDefs,s as dropdownMenuContentPropDefs,v as dropdownMenuItemPropDefs,y as dropdownMenuRadioItemPropDefs,u as dropdownMenuSubContentPropDefs,fo as emPropDefs,F as emphases,G as emphasisPropDef,k as flexPropDefs,j as gapPropDefs,e as grayColors,W as gridPropDefs,M as headingPropDefs,d as heightPropDefs,mo as hoverCardContentPropDefs,x as iconButtonPropDefs,po as imagePropDefs,xo as insetPropDefs,z as kbdPropDefs,h as layoutPropDefs,H as leadingTrimPropDef,ao as linkPropDefs,i as marginPropDefs,c as paddingPropDefs,_ as popoverContentPropDefs,bo as progressPropDefs,co as quotePropDefs,p as radii,go as radioCardsRootPropDefs,ho as radioGroupRootPropDefs,A as radioPropDefs,t as radiusPropDef,V as scrollAreaPropDefs,jo as sectionPropDefs,io as segmentedControlRootPropDefs,no as selectContentPropDefs,ko as selectRootPropDefs,lo as selectTriggerPropDefs,qo as separatorPropDefs,Go as shadowPropDefs,to as skeletonPropDefs,so as sliderPropDefs,l as spinnerPropDefs,uo as strongPropDefs,q as submenuBehaviors,vo as switchPropDefs,wo as tabNavLinkPropDefs,B as tabNavRootPropDefs,Ao as tableCellPropDefs,yo as tableRootPropDefs,zo as tableRowPropDefs,Co as tabsContentPropDefs,B as tabsListPropDefs,Bo as tabsRootPropDefs,I as textAlignPropDef,Do as textAreaPropDefs,Eo as textFieldRootPropDefs,Fo as textFieldSlotPropDefs,N as textPropDefs,J as textWrapPropDef,C as themePropDefs,Q as tooltipPropDefs,K as truncatePropDef,L as weightPropDef,g as widthPropDefs};
1
+ import{a as Go}from"../chunk-MQWH2IFO.js";import{a as yo,b as zo,c as Ao}from"../chunk-BALS3AVM.js";import{a as Bo,b as Co}from"../chunk-TZTUPQYK.js";import{a as Do}from"../chunk-CLMOWP5T.js";import{a as Eo,b as Fo}from"../chunk-MN3XALXD.js";import{a as uo}from"../chunk-XI5YXUCK.js";import{a as vo}from"../chunk-AF6XKU3W.js";import{a as wo}from"../chunk-AUV6B4AH.js";import{a as so}from"../chunk-OJU5GCDZ.js";import{a as ko,b as lo,c as no}from"../chunk-EBQZ3Z22.js";import{a as qo}from"../chunk-CRSHBENJ.js";import{a as jo}from"../chunk-NIX6Z3JG.js";import{a as io}from"../chunk-FC2DBBJ3.js";import"../chunk-STPMPY3X.js";import{a as bo}from"../chunk-5XV4QEP5.js";import{a as co}from"../chunk-MCQCG6AS.js";import{a as go}from"../chunk-OWMA6GTG.js";import{a as ho}from"../chunk-VLTXI4A7.js";import{a as ao}from"../chunk-AGSSWWFI.js";import{a as to}from"../chunk-L6UXAITB.js";import{a as po}from"../chunk-GFOSP3PZ.js";import{a as xo}from"../chunk-JAMLW534.js";import{a as mo}from"../chunk-VJSZG35J.js";import"../chunk-YKPMLM7M.js";import"../chunk-WOR3JCLX.js";import{a as fo}from"../chunk-4JQZUQY7.js";import{a as _}from"../chunk-72AHPGPN.js";import{a as $}from"../chunk-PPNWGWN3.js";import"../chunk-OA7C34MJ.js";import{a as oo,b as ro,c as eo}from"../chunk-NIIEIZKQ.js";import{a as Y}from"../chunk-5SNHUVDA.js";import"../chunk-UICSVJ3B.js";import{a as Z}from"../chunk-KZWNGWIM.js";import"../chunk-6DWDNKLS.js";import{a as T}from"../chunk-OGVKSYLL.js";import{a as U}from"../chunk-OO652UQW.js";import{a as V}from"../chunk-5KICSAT7.js";import{a as X}from"../chunk-667BKCUG.js";import{a as W}from"../chunk-HAGKI7NA.js";import{a as O}from"../chunk-QFPHEY77.js";import{a as Q}from"../chunk-BPVVFHYD.js";import{a as P}from"../chunk-QQ62LO3X.js";import{a as R}from"../chunk-WGYUWEQV.js";import{a as S}from"../chunk-FGORMEAO.js";import{a as M}from"../chunk-PZ7OYATT.js";import{a as N}from"../chunk-4XKK32M4.js";import{a as I}from"../chunk-G2CKYO2I.js";import"../chunk-AXUDFYLY.js";import{a as H}from"../chunk-KNQBAOMV.js";import{a as L}from"../chunk-FD2TR343.js";import{a as J}from"../chunk-WYADYDPN.js";import{a as K}from"../chunk-ZE2KAVXW.js";import{a as F,b as G}from"../chunk-ZWZGUBL4.js";import{a as E}from"../chunk-XKBLNVOD.js";import{a as D}from"../chunk-GCUGJXI2.js";import{a as C}from"../chunk-XYVLQDGR.js";import{a as l}from"../chunk-3KB2XWBE.js";import{a as k}from"../chunk-SMGDH54W.js";import{a as j}from"../chunk-SNR5VFWG.js";import{a as h}from"../chunk-K53W3ELO.js";import{a as c}from"../chunk-TTFUM47A.js";import{a as d}from"../chunk-VX44UTQ5.js";import{a as g}from"../chunk-ERGJN7FJ.js";import{a as x}from"../chunk-JFWMAYEH.js";import{a as p,b as t}from"../chunk-KRJTW535.js";import{a as n}from"../chunk-F6V7GBNQ.js";import{a as q,b as s,c as u,d as v,e as w,f as y}from"../chunk-3KSGRY6I.js";import{a as z}from"../chunk-ARIV4AT5.js";import{a as i}from"../chunk-GSTOGDAJ.js";import{a,b}from"../chunk-WRWNN2NW.js";import{a as o}from"../chunk-NZJGC6ZW.js";import{a as A}from"../chunk-WMGIFPI2.js";import{a as B}from"../chunk-CFNESRYI.js";import{a as r,b as e,c as f,d as m}from"../chunk-ZNK6AH2G.js";import"../chunk-OS3FCYZY.js";export{m as accentColorPropDef,r as accentColors,E as alertDialogContentPropDefs,o as asChildPropDef,O as avatarPropDefs,P as badgePropDefs,R as blockquotePropDefs,S as boxPropDefs,b as breakpointSet,a as breakpoints,x as buttonPropDefs,T as calloutRootPropDefs,U as cardPropDefs,X as checkboxCardsRootPropDefs,Y as checkboxGroupRootPropDefs,n as checkboxPropDefs,Z as codePropDefs,f as colorPropDef,$ as containerPropDefs,w as contextMenuCheckboxItemPropDefs,u as contextMenuContentPropDefs,v as contextMenuItemPropDefs,y as contextMenuRadioItemPropDefs,u as contextMenuSubContentPropDefs,ro as dataListItemPropDefs,eo as dataListLabelPropDefs,oo as dataListRootPropDefs,D as dialogContentPropDefs,w as dropdownMenuCheckboxItemPropDefs,s as dropdownMenuContentPropDefs,v as dropdownMenuItemPropDefs,y as dropdownMenuRadioItemPropDefs,u as dropdownMenuSubContentPropDefs,fo as emPropDefs,F as emphases,G as emphasisPropDef,k as flexPropDefs,j as gapPropDefs,e as grayColors,W as gridPropDefs,M as headingPropDefs,d as heightPropDefs,mo as hoverCardContentPropDefs,x as iconButtonPropDefs,po as imagePropDefs,xo as insetPropDefs,z as kbdPropDefs,h as layoutPropDefs,H as leadingTrimPropDef,ao as linkPropDefs,i as marginPropDefs,c as paddingPropDefs,_ as popoverContentPropDefs,bo as progressPropDefs,co as quotePropDefs,p as radii,go as radioCardsRootPropDefs,ho as radioGroupRootPropDefs,A as radioPropDefs,t as radiusPropDef,V as scrollAreaPropDefs,jo as sectionPropDefs,io as segmentedControlRootPropDefs,no as selectContentPropDefs,ko as selectRootPropDefs,lo as selectTriggerPropDefs,qo as separatorPropDefs,Go as shadowPropDefs,to as skeletonPropDefs,so as sliderPropDefs,l as spinnerPropDefs,uo as strongPropDefs,q as submenuBehaviors,vo as switchPropDefs,wo as tabNavLinkPropDefs,B as tabNavRootPropDefs,Ao as tableCellPropDefs,yo as tableRootPropDefs,zo as tableRowPropDefs,Co as tabsContentPropDefs,B as tabsListPropDefs,Bo as tabsRootPropDefs,I as textAlignPropDef,Do as textAreaPropDefs,Eo as textFieldRootPropDefs,Fo as textFieldSlotPropDefs,N as textPropDefs,J as textWrapPropDef,C as themePropDefs,Q as tooltipPropDefs,K as truncatePropDef,L as weightPropDef,g as widthPropDefs};
2
2
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@womp/kookie-ui",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Kookie UI v1: a React component library with design tokens, flexible theming, a full layout shell, and comprehensive documentation.",
5
5
  "keywords": [
6
6
  "react",
@@ -150,6 +150,7 @@
150
150
  "dependencies": {
151
151
  "@radix-ui/colors": "^3.0.0",
152
152
  "@radix-ui/react-accordion": "^1.2.20",
153
+ "@shadcn/react": "0.3.1",
153
154
  "@tanstack/react-virtual": "^3.14.13",
154
155
  "@zag-js/react": "^1.44.0",
155
156
  "@zag-js/splitter": "^1.44.0",
@@ -189,7 +189,8 @@
189
189
  padding-inline-start: var(--base-menu-item-padding-left);
190
190
  padding-inline-end: var(--base-menu-item-padding-right);
191
191
  box-sizing: border-box;
192
- color: var(--gray-a10);
192
+ /* a11 keeps the label above 4.5:1 on every sidebar background. */
193
+ color: var(--gray-a11);
193
194
  user-select: none;
194
195
  cursor: default;
195
196
 
@@ -9,6 +9,9 @@
9
9
  /* Defaults */
10
10
  .rt-ChatbarRoot {
11
11
  --chatbar-attachment-thumb: var(--space-8);
12
+ /* A column: notices, then the box (which fills any height the consumer gives the root), then context. */
13
+ display: flex;
14
+ flex-direction: column;
12
15
 
13
16
  /*
14
17
  * Component-level material override
@@ -595,3 +598,24 @@
595
598
  }
596
599
  }
597
600
  }
601
+
602
+ /***************************************************************************************************
603
+ * *
604
+ * NOTICES AND CONTEXT *
605
+ * *
606
+ ***************************************************************************************************/
607
+
608
+ /* Notices stand above the box, in a column; the last one is nearest the text. */
609
+ .rt-ChatbarNotices {
610
+ display: flex;
611
+ flex-direction: column;
612
+ gap: var(--space-2);
613
+ margin-bottom: var(--space-2);
614
+ }
615
+
616
+ /* Context is quiet text below the box, inset to line up with the text inside it. */
617
+ .rt-ChatbarContext {
618
+ padding: var(--space-2) var(--space-3) 0;
619
+ min-width: 0;
620
+ overflow-wrap: anywhere;
621
+ }
@@ -9,6 +9,8 @@ import { CloseIcon, FileTextIcon } from './icons.js';
9
9
  import { Flex } from './flex.js';
10
10
  import { ScrollArea } from './scroll-area.js';
11
11
  import { Slot } from './slot.js';
12
+ import { NoticeSizeContext } from './notice.js';
13
+ import { Spinner } from './spinner.js';
12
14
  import { Text } from './text.js';
13
15
  import { VisuallyHidden } from './visually-hidden.js';
14
16
  import type { ComponentPropsWithout, RemovedProps } from '../helpers/component-props.js';
@@ -257,6 +259,19 @@ interface ChatbarRootBaseProps {
257
259
  * Provides methods to focus the textarea and open the file picker.
258
260
  */
259
261
  apiRef?: React.Ref<ChatbarApi>;
262
+
263
+ /**
264
+ * Messages that need an answer before the next message, such as `Notice` and `Confirmation`.
265
+ * They stack in a column above the chatbar, in the order given, so put the one the next
266
+ * message answers last, nearest the text. They sit outside the box: a button in a notice never
267
+ * submits the message, and pressing one never collapses the chatbar.
268
+ */
269
+ notices?: React.ReactNode;
270
+ /**
271
+ * Short facts that stay true about the conversation, such as the model or the context left.
272
+ * They sit below the chatbar, inset from its sides.
273
+ */
274
+ context?: React.ReactNode;
260
275
  }
261
276
 
262
277
  type RootElement = React.ElementRef<'div'>;
@@ -328,6 +343,8 @@ const Root = React.forwardRef<RootElement, RootProps>((props, forwardedRef) => {
328
343
  dropzone = true,
329
344
  apiRef,
330
345
  onBlurCapture,
346
+ notices,
347
+ context,
331
348
  ...divProps
332
349
  } = props;
333
350
  const effectiveMaterial = material || panelBackground;
@@ -704,7 +721,12 @@ const Root = React.forwardRef<RootElement, RootProps>((props, forwardedRef) => {
704
721
  style={{ display: 'none' }}
705
722
  onChange={handleFileInputChange}
706
723
  />
707
- <div {...(dropzone ? getRootProps() : {})} style={{ width: '100%', height: '100%' }} onPointerDown={handleContainerPointerDown}>
724
+ {notices ? (
725
+ <div className="rt-ChatbarNotices">
726
+ <NoticeSizeContext.Provider value={size}>{notices}</NoticeSizeContext.Provider>
727
+ </div>
728
+ ) : null}
729
+ <div {...(dropzone ? getRootProps() : {})} style={{ width: '100%', flex: '1 1 auto', minHeight: 0 }} onPointerDown={handleContainerPointerDown}>
708
730
  <m.div
709
731
  className={classNames('rt-ChatbarBox', `rt-variant-${variant ?? 'surface'}`)}
710
732
  style={{ position: 'relative' }}
@@ -729,6 +751,11 @@ const Root = React.forwardRef<RootElement, RootProps>((props, forwardedRef) => {
729
751
  )}
730
752
  </m.div>
731
753
  </div>
754
+ {context ? (
755
+ <Text as="div" size={size === '3' ? '2' : '1'} emphasis="medium" className="rt-ChatbarContext">
756
+ {context}
757
+ </Text>
758
+ ) : null}
732
759
  <VisuallyHidden role="status" aria-live="polite">
733
760
  {dragActive ? 'Drop files here to attach.' : <span key={announcement.id}>{announcement.text}</span>}
734
761
  </VisuallyHidden>
@@ -1187,6 +1214,8 @@ const RowEnd = React.forwardRef<HTMLDivElement, RowSlotProps>((props, forwardedR
1187
1214
  });
1188
1215
  RowEnd.displayName = 'Chatbar.RowEnd';
1189
1216
 
1217
+ type SendStatus = 'ready' | 'submitted' | 'streaming' | 'error';
1218
+
1190
1219
  type SendProps = Omit<IconButtonProps, 'aria-label' | 'aria-labelledby'> & {
1191
1220
  /** Optional override for accessible name. Defaults to "Send". */
1192
1221
  'aria-label'?: string;
@@ -1194,6 +1223,25 @@ type SendProps = Omit<IconButtonProps, 'aria-label' | 'aria-labelledby'> & {
1194
1223
  asChild?: boolean;
1195
1224
  /** Clear message and attachments after sending. Defaults to Root `clearOnSubmit`. */
1196
1225
  clearOnSend?: boolean;
1226
+ /**
1227
+ * What the button means. `ready` sends. While a reply is `submitted` or `streaming` and the
1228
+ * box is empty, the button STOPS the reply (`onStop`); with a draft in the box it still sends,
1229
+ * and the app decides whether sending interrupts the reply. After an `error`, an empty box
1230
+ * makes it RETRY (`onRetry`). Default `ready`.
1231
+ */
1232
+ status?: SendStatus;
1233
+ /** Called when the button is pressed to stop a reply. */
1234
+ onStop?: () => void;
1235
+ /** Called when the button is pressed to retry after an error. */
1236
+ onRetry?: () => void;
1237
+ /** Accessible name while it stops. Default "Stop". */
1238
+ stopLabel?: string;
1239
+ /** Accessible name while it retries. Default "Retry". */
1240
+ retryLabel?: string;
1241
+ /** Glyph while it stops. Defaults to a square, or a spinner while `submitted`. */
1242
+ stopIcon?: React.ReactNode;
1243
+ /** Glyph while it retries. */
1244
+ retryIcon?: React.ReactNode;
1197
1245
  };
1198
1246
 
1199
1247
  const Send = React.forwardRef<HTMLButtonElement, SendProps>((props, forwardedRef) => {
@@ -1208,6 +1256,13 @@ const Send = React.forwardRef<HTMLButtonElement, SendProps>((props, forwardedRef
1208
1256
  variant: variantProp,
1209
1257
  tabIndex,
1210
1258
  onClick,
1259
+ status = 'ready',
1260
+ onStop,
1261
+ onRetry,
1262
+ stopLabel = 'Stop',
1263
+ retryLabel = 'Retry',
1264
+ stopIcon,
1265
+ retryIcon,
1211
1266
  'aria-label': ariaLabel,
1212
1267
  'aria-labelledby': ariaLabelledby,
1213
1268
  ...buttonProps
@@ -1215,30 +1270,64 @@ const Send = React.forwardRef<HTMLButtonElement, SendProps>((props, forwardedRef
1215
1270
  const ctx = useChatbarContext();
1216
1271
  const value = React.useContext(ChatbarValueContext);
1217
1272
 
1218
- if (ctx.sendMode === 'never') return null;
1219
-
1220
1273
  const hasContent = hasText(value) || ctx.attachments.length > 0;
1221
- const visible = ctx.sendMode === 'always' || hasContent;
1222
- const inactive = disabled || ctx.disabled || ctx.readOnly || !hasContent;
1274
+ const running = status === 'submitted' || status === 'streaming';
1275
+ const mode: 'send' | 'stop' | 'retry' = hasContent ? 'send' : running ? 'stop' : status === 'error' ? 'retry' : 'send';
1276
+
1277
+ if (ctx.sendMode === 'never' && mode === 'send') return null;
1278
+
1279
+ const visible = mode !== 'send' || ctx.sendMode === 'always' || hasContent;
1280
+ const inactive = mode === 'send' ? disabled || ctx.disabled || ctx.readOnly || !hasContent : disabled || ctx.disabled;
1223
1281
 
1224
- const labelProps: { 'aria-label': string } | { 'aria-labelledby': string } = ariaLabelledby
1225
- ? { 'aria-labelledby': ariaLabelledby }
1226
- : { 'aria-label': ariaLabel ?? 'Send' };
1282
+ const sendName = ariaLabel ?? 'Send';
1283
+ const labelProps: { 'aria-label': string } | { 'aria-labelledby': string } =
1284
+ mode === 'stop' ? { 'aria-label': stopLabel } : mode === 'retry' ? { 'aria-label': retryLabel } : ariaLabelledby ? { 'aria-labelledby': ariaLabelledby } : { 'aria-label': sendName };
1227
1285
 
1228
1286
  const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
1229
1287
  onClick?.(event);
1230
1288
  if (event.defaultPrevented || inactive) return;
1289
+ if (mode === 'stop') {
1290
+ onStop?.();
1291
+ return;
1292
+ }
1293
+ if (mode === 'retry') {
1294
+ onRetry?.();
1295
+ return;
1296
+ }
1231
1297
  const clear = clearOnSend ?? ctx.clearOnSubmit;
1232
1298
  // Clearing hides and disables this button; keep keyboard focus in the composer
1233
1299
  if (ctx.submit(clear) && clear) ctx.textareaRef.current?.focus({ preventScroll: true });
1234
1300
  };
1235
1301
 
1302
+ const glyph =
1303
+ mode === 'stop' ? (
1304
+ stopIcon ?? (status === 'submitted' ? <Spinner size={ctx.size} /> : (
1305
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" aria-hidden>
1306
+ <rect x="7" y="7" width="10" height="10" rx="2" />
1307
+ </svg>
1308
+ ))
1309
+ ) : mode === 'retry' ? (
1310
+ retryIcon ?? (
1311
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
1312
+ <path d="M3 12a9 9 0 1 0 3-6.7L3 8" />
1313
+ <path d="M3 3v5h5" />
1314
+ </svg>
1315
+ )
1316
+ ) : (
1317
+ children ?? (
1318
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
1319
+ <path d="M5 12h14" />
1320
+ <path d="m12 5 7 7-7 7" />
1321
+ </svg>
1322
+ )
1323
+ );
1324
+
1236
1325
  return (
1237
1326
  <IconButton
1238
1327
  {...buttonProps}
1239
1328
  ref={forwardedRef}
1240
1329
  size={sizeProp ?? ctx.size}
1241
- variant={variantProp ?? (ctx.open ? 'solid' : 'ghost')}
1330
+ variant={variantProp ?? (ctx.open || mode !== 'send' ? 'solid' : 'ghost')}
1242
1331
  disabled={inactive}
1243
1332
  className={classNames('rt-ChatbarSend', className)}
1244
1333
  style={{ opacity: visible ? 1 : 0, pointerEvents: visible ? undefined : 'none', ...style }}
@@ -1247,14 +1336,11 @@ const Send = React.forwardRef<HTMLButtonElement, SendProps>((props, forwardedRef
1247
1336
  tabIndex={visible ? tabIndex : -1}
1248
1337
  asChild={asChild}
1249
1338
  onClick={handleClick}
1339
+ data-status={status}
1340
+ data-mode={mode}
1250
1341
  {...labelProps}
1251
1342
  >
1252
- {children ?? (
1253
- <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
1254
- <path d="M5 12h14" />
1255
- <path d="m12 5 7 7-7 7" />
1256
- </svg>
1257
- )}
1343
+ {glyph}
1258
1344
  </IconButton>
1259
1345
  );
1260
1346
  });
@@ -1278,4 +1364,5 @@ export type {
1278
1364
  AttachmentStatus as ChatbarAttachmentStatus,
1279
1365
  ExpandOn as ChatbarExpandOn,
1280
1366
  SendMode as ChatbarSendMode,
1367
+ SendStatus as ChatbarSendStatus,
1281
1368
  };
@@ -62,6 +62,8 @@
62
62
  @import './user-card.css';
63
63
  @import './virtual-menu.css';
64
64
  @import './chatbar.css';
65
+ @import './message-scroller.css';
66
+ @import './notice.css';
65
67
 
66
68
  .radix-themes:where([data-is-root-theme='true']) {
67
69
  /* Create a new stacking context on the root `Theme` so layered components work out of the box */
@@ -80,3 +80,10 @@ export * as Sidebar from './sidebar.js';
80
80
  export * as Shell from './shell.js';
81
81
  export * as Sheet from './sheet.js';
82
82
  export * as Chatbar from './chatbar.js';
83
+ export * as MessageScroller from './message-scroller.js';
84
+ export {
85
+ Notice,
86
+ Confirmation,
87
+ type NoticeProps,
88
+ type ConfirmationProps,
89
+ } from './notice.js';
@@ -0,0 +1,54 @@
1
+ /*
2
+ * MessageScroller — the transcript's layout. The behaviour is shadcn/ui's primitive.
3
+ */
4
+
5
+ .rt-MessageScrollerRoot {
6
+ position: relative;
7
+ display: flex;
8
+ flex-direction: column;
9
+ min-height: 0;
10
+ }
11
+
12
+ .rt-MessageScrollerViewport {
13
+ flex: 1 1 auto;
14
+ min-height: 0;
15
+ overflow-y: auto;
16
+ overflow-x: hidden;
17
+ overscroll-behavior: contain;
18
+ scrollbar-width: thin;
19
+ scrollbar-color: var(--gray-a6) transparent;
20
+ outline: none;
21
+
22
+ &:where(:focus-visible) {
23
+ outline: 2px solid var(--focus-8);
24
+ outline-offset: -2px;
25
+ }
26
+ }
27
+
28
+ .rt-MessageScrollerContent {
29
+ display: flex;
30
+ flex-direction: column;
31
+ min-height: 100%;
32
+ }
33
+
34
+ .rt-MessageScrollerItem {
35
+ min-width: 0;
36
+ }
37
+
38
+ /* The jump button floats over the bottom edge of the viewport, centred by its margins, never by a
39
+ transform: a button's own press and hover motion may use `translate`, and a centring transform
40
+ would be replaced by it. */
41
+ .rt-MessageScrollerButton {
42
+ position: absolute;
43
+ bottom: var(--space-3);
44
+ left: 0;
45
+ right: 0;
46
+ margin-inline: auto;
47
+ z-index: 1;
48
+ }
49
+
50
+ /* Asleep while the reader is at the end: the primitive makes it inert; this makes it unseen. */
51
+ .rt-MessageScrollerButton:where([data-active='false']) {
52
+ opacity: 0;
53
+ pointer-events: none;
54
+ }
@@ -0,0 +1,165 @@
1
+ 'use client';
2
+
3
+ /**
4
+ * MessageScroller — a transcript that follows a conversation.
5
+ *
6
+ * The behaviour is shadcn/ui's Message Scroller primitive (`@shadcn/react/message-scroller`,
7
+ * MIT, https://ui.shadcn.com). Streaming, anchoring a new turn, keeping your place when history
8
+ * loads above, and jumping back to the latest are a body of edge cases nobody should rewrite, so
9
+ * Kookie takes the primitive and adds only the surface: the parts, the class names, the button.
10
+ *
11
+ * Anatomy
12
+ * ```tsx
13
+ * <MessageScroller.Root>
14
+ * <MessageScroller.Viewport aria-label="Conversation">
15
+ * <MessageScroller.Content>
16
+ * <MessageScroller.Item messageId="u1" scrollAnchor>…</MessageScroller.Item>
17
+ * <MessageScroller.Item messageId="a1">…</MessageScroller.Item>
18
+ * </MessageScroller.Content>
19
+ * </MessageScroller.Viewport>
20
+ * <MessageScroller.Button aria-label="Jump to the latest" />
21
+ * </MessageScroller.Root>
22
+ * ```
23
+ *
24
+ * The viewport is its own scroller. Kookie's `ScrollArea` is Radix's, and Radix cannot hand its
25
+ * viewport element to another library, so the transcript scrolls natively with a thin scrollbar.
26
+ *
27
+ * Requires React 19, which the primitive needs.
28
+ */
29
+
30
+ import * as React from 'react';
31
+ import classNames from 'classnames';
32
+ import {
33
+ MessageScroller as Primitive,
34
+ useMessageScroller,
35
+ useMessageScrollerScrollable,
36
+ useMessageScrollerVisibility,
37
+ type MessageScrollerDefaultScrollPosition,
38
+ type MessageScrollerScrollOptions,
39
+ type MessageScrollerScrollable,
40
+ type MessageScrollerVisibilityState,
41
+ } from '@shadcn/react/message-scroller';
42
+
43
+ import { IconButton, type IconButtonProps } from './icon-button.js';
44
+
45
+ interface RootProps extends React.ComponentPropsWithoutRef<'div'> {
46
+ /**
47
+ * Keeps the newest content in view while the reader is at the end. Default `true`.
48
+ * Once the reader scrolls up, the transcript stays where they are until they return.
49
+ */
50
+ autoScroll?: boolean;
51
+ /** Where the transcript opens: `end` (default), `start`, or the last anchored message. */
52
+ defaultScrollPosition?: MessageScrollerDefaultScrollPosition;
53
+ /** Distance in pixels from the end that still counts as "at the end". */
54
+ scrollEdgeThreshold?: number;
55
+ /** Space in pixels kept above a message when one is scrolled to or anchored. */
56
+ scrollMargin?: number;
57
+ }
58
+
59
+ /** Holds the scroll state. Everything else goes inside it. */
60
+ const Root = React.forwardRef<HTMLDivElement, RootProps>(
61
+ ({ autoScroll = true, defaultScrollPosition = 'end', scrollEdgeThreshold, scrollMargin, className, children, ...props }, forwardedRef) => (
62
+ <Primitive.Provider
63
+ autoScroll={autoScroll}
64
+ defaultScrollPosition={defaultScrollPosition}
65
+ {...(scrollEdgeThreshold != null ? { scrollEdgeThreshold } : {})}
66
+ {...(scrollMargin != null ? { scrollMargin } : {})}
67
+ >
68
+ <Primitive.Root {...props} ref={forwardedRef} className={classNames('rt-MessageScrollerRoot', className)}>
69
+ {children}
70
+ </Primitive.Root>
71
+ </Primitive.Provider>
72
+ ),
73
+ );
74
+ Root.displayName = 'MessageScroller.Root';
75
+
76
+ interface ViewportProps extends React.ComponentPropsWithoutRef<'div'> {
77
+ /** Name of the transcript region, e.g. "Conversation". */
78
+ 'aria-label'?: string;
79
+ /** Keep the reader's place when older messages are added above. Default `true`. */
80
+ preserveScrollOnPrepend?: boolean;
81
+ }
82
+
83
+ /** The scrolling element. */
84
+ const Viewport = React.forwardRef<HTMLDivElement, ViewportProps>(({ className, 'aria-label': label, ...props }, forwardedRef) => (
85
+ // The primitive names an unnamed viewport "Messages", in English. An empty name is skipped by
86
+ // accessible-name computation, so a transcript is only named when the app names it.
87
+ <Primitive.Viewport aria-label={label ?? ''} {...props} ref={forwardedRef} className={classNames('rt-MessageScrollerViewport', className)} />
88
+ ));
89
+ Viewport.displayName = 'MessageScroller.Viewport';
90
+
91
+ type ContentProps = React.ComponentPropsWithoutRef<'div'>;
92
+
93
+ /** The list of messages, inside the viewport. */
94
+ const Content = React.forwardRef<HTMLDivElement, ContentProps>(({ className, ...props }, forwardedRef) => (
95
+ <Primitive.Content {...props} ref={forwardedRef} className={classNames('rt-MessageScrollerContent', className)} />
96
+ ));
97
+ Content.displayName = 'MessageScroller.Content';
98
+
99
+ interface ItemProps extends React.ComponentPropsWithoutRef<'div'> {
100
+ /** A stable id, so the row can be scrolled to with `useMessageScroller().scrollToMessage`. */
101
+ messageId?: string;
102
+ /** Anchor this row near the top when it arrives. Set it on the person's own messages. */
103
+ scrollAnchor?: boolean;
104
+ }
105
+
106
+ /** One row of the transcript. */
107
+ const Item = React.forwardRef<HTMLDivElement, ItemProps>(({ className, ...props }, forwardedRef) => (
108
+ <Primitive.Item {...props} ref={forwardedRef} className={classNames('rt-MessageScrollerItem', className)} />
109
+ ));
110
+ Item.displayName = 'MessageScroller.Item';
111
+
112
+ type ButtonProps = Omit<IconButtonProps, 'aria-label' | 'aria-labelledby'> & {
113
+ /** Accessible name, in your words. Default "Jump to the latest". */
114
+ 'aria-label'?: string;
115
+ /** `end` jumps to the latest message (default); `start` to the first. */
116
+ direction?: 'start' | 'end';
117
+ /** Scroll behaviour of the jump. Default `smooth`. */
118
+ behavior?: ScrollBehavior;
119
+ };
120
+
121
+ /**
122
+ * Jumps back to the latest message. It renders only while the reader is away from the end.
123
+ * Place it inside `Root`, after the viewport. It sits over the viewport's bottom edge.
124
+ */
125
+ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
126
+ ({ direction = 'end', behavior, className, children, size = '2', variant = 'surface', color = 'gray', radius = 'full', 'aria-label': label, ...props }, forwardedRef) => (
127
+ <Primitive.Button
128
+ direction={direction}
129
+ {...(behavior ? { behavior } : {})}
130
+ render={
131
+ <IconButton
132
+ {...props}
133
+ ref={forwardedRef}
134
+ size={size}
135
+ variant={variant}
136
+ color={color}
137
+ radius={radius}
138
+ aria-label={label ?? (direction === 'end' ? 'Jump to the latest' : 'Jump to the first')}
139
+ className={classNames('rt-MessageScrollerButton', className)}
140
+ data-direction={direction}
141
+ >
142
+ {children ?? (
143
+ <svg width="15" height="15" viewBox="0 0 15 15" fill="none" aria-hidden style={direction === 'start' ? { transform: 'rotate(180deg)' } : undefined}>
144
+ <path d="M7.5 2.5v10M3.5 8.5l4 4 4-4" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
145
+ </svg>
146
+ )}
147
+ </IconButton>
148
+ }
149
+ />
150
+ ),
151
+ );
152
+ Button.displayName = 'MessageScroller.Button';
153
+
154
+ export { Root, Viewport, Content, Item, Button, useMessageScroller, useMessageScrollerScrollable, useMessageScrollerVisibility };
155
+ export type {
156
+ RootProps as MessageScrollerRootProps,
157
+ ViewportProps as MessageScrollerViewportProps,
158
+ ContentProps as MessageScrollerContentProps,
159
+ ItemProps as MessageScrollerItemProps,
160
+ ButtonProps as MessageScrollerButtonProps,
161
+ MessageScrollerDefaultScrollPosition,
162
+ MessageScrollerScrollOptions,
163
+ MessageScrollerScrollable,
164
+ MessageScrollerVisibilityState,
165
+ };
@@ -0,0 +1,91 @@
1
+ /*
2
+ * Notice and Confirmation — one strip, two kinds.
3
+ * It takes space and never floats: no position, no z-index.
4
+ */
5
+
6
+ .rt-NoticeRoot {
7
+ box-sizing: border-box;
8
+ display: flex;
9
+ align-items: center;
10
+ min-width: 0;
11
+ color: var(--accent-ink);
12
+ border-radius: var(--notice-radius);
13
+
14
+ --material-blend: 100%;
15
+ --material-alpha: 0;
16
+ background-color: color-mix(in srgb, var(--accent-a3) calc(var(--material-alpha) * 100%), var(--accent-3) var(--material-blend));
17
+
18
+ &:where([data-material='translucent']) {
19
+ --material-blend: 60%;
20
+ --material-alpha: 1;
21
+ backdrop-filter: var(--backdrop-filter-components-enabled);
22
+ }
23
+
24
+ @media (forced-colors: active) {
25
+ border: 1px solid CanvasText;
26
+ }
27
+ }
28
+
29
+ /* Gray is the resting category: its fill is one step quieter and its words are the ordinary ink. */
30
+ .rt-NoticeRoot:where([data-accent-color='gray']) {
31
+ background-color: color-mix(in srgb, var(--gray-a3) calc(var(--material-alpha) * 100%), var(--gray-3) var(--material-blend));
32
+ color: var(--gray-12);
33
+ }
34
+
35
+ .rt-NoticeIcon {
36
+ display: flex;
37
+ flex: none;
38
+ align-items: center;
39
+
40
+ /* stylelint-disable-next-line selector-max-type */
41
+ & :where(svg) {
42
+ width: var(--notice-icon-size);
43
+ height: var(--notice-icon-size);
44
+ }
45
+ }
46
+
47
+ .rt-NoticeText {
48
+ flex: 1 1 auto;
49
+ min-width: 0;
50
+ overflow-wrap: anywhere;
51
+ }
52
+
53
+ .rt-NoticeActions {
54
+ display: flex;
55
+ flex: none;
56
+ align-items: center;
57
+ gap: var(--space-1);
58
+ }
59
+
60
+ /* A question wraps its answers under the words when the strip is narrow. */
61
+ .rt-NoticeRoot:where([data-kind='confirmation']) {
62
+ flex-wrap: wrap;
63
+
64
+ & :where(.rt-NoticeActions) {
65
+ margin-left: auto;
66
+ }
67
+ }
68
+
69
+ .rt-NoticeRoot {
70
+ &:where(.rt-r-size-1) {
71
+ gap: var(--space-2);
72
+ padding: var(--space-1) var(--space-1) var(--space-1) var(--space-3);
73
+ min-height: calc(var(--space-6) + var(--space-2));
74
+ --notice-radius: var(--radius-surface-1);
75
+ --notice-icon-size: var(--content-icon-size-1);
76
+ }
77
+ &:where(.rt-r-size-2) {
78
+ gap: var(--space-2);
79
+ padding: var(--space-1) var(--space-1) var(--space-1) var(--space-3);
80
+ min-height: calc(var(--space-7) + var(--space-2));
81
+ --notice-radius: var(--radius-surface-2);
82
+ --notice-icon-size: var(--content-icon-size-2);
83
+ }
84
+ &:where(.rt-r-size-3) {
85
+ gap: var(--space-3);
86
+ padding: var(--space-2) var(--space-2) var(--space-2) var(--space-4);
87
+ min-height: calc(var(--space-8) + var(--space-2));
88
+ --notice-radius: var(--radius-surface-3);
89
+ --notice-icon-size: var(--content-icon-size-3);
90
+ }
91
+ }