@djangocfg/ui-tools 2.1.404 → 2.1.408

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 (336) hide show
  1. package/README.md +9 -11
  2. package/dist/file-icon/index.cjs +449 -61
  3. package/dist/file-icon/index.cjs.map +1 -1
  4. package/dist/file-icon/index.d.cts +56 -18
  5. package/dist/file-icon/index.d.ts +56 -18
  6. package/dist/file-icon/index.mjs +448 -62
  7. package/dist/file-icon/index.mjs.map +1 -1
  8. package/dist/tree/index.cjs +49 -22
  9. package/dist/tree/index.cjs.map +1 -1
  10. package/dist/tree/index.d.cts +9 -3
  11. package/dist/tree/index.d.ts +9 -3
  12. package/dist/tree/index.mjs +49 -22
  13. package/dist/tree/index.mjs.map +1 -1
  14. package/dist/{types-B_zhyAqR.d.cts → types-eEu8SeiQ.d.cts} +4 -0
  15. package/dist/{types-B_zhyAqR.d.ts → types-eEu8SeiQ.d.ts} +4 -0
  16. package/package.json +13 -16
  17. package/src/components/FloatingToolbar/index.tsx +37 -3
  18. package/src/lib/page-snapshot/__tests__/capture-integration.test.ts +85 -0
  19. package/src/lib/page-snapshot/__tests__/engine.test.ts +36 -0
  20. package/src/lib/page-snapshot/__tests__/redaction-integration.test.ts +99 -0
  21. package/src/lib/page-snapshot/__tests__/tokens.test.ts +17 -0
  22. package/src/lib/page-snapshot/capture/__tests__/budget.test.ts +49 -0
  23. package/src/lib/page-snapshot/capture/__tests__/chrome-filter.test.ts +47 -0
  24. package/src/lib/page-snapshot/capture/__tests__/fold.test.ts +66 -0
  25. package/src/lib/page-snapshot/capture/__tests__/scope.test.ts +74 -0
  26. package/src/lib/page-snapshot/capture/__tests__/walk.test.ts +129 -0
  27. package/src/lib/page-snapshot/capture/accessible-name.ts +73 -0
  28. package/src/lib/page-snapshot/capture/budget.ts +95 -0
  29. package/src/lib/page-snapshot/capture/chrome-filter.ts +81 -0
  30. package/src/lib/page-snapshot/capture/classify.ts +111 -0
  31. package/src/lib/page-snapshot/capture/dom-utils.ts +111 -0
  32. package/src/lib/page-snapshot/capture/fold.ts +96 -0
  33. package/src/lib/page-snapshot/capture/scope.ts +169 -0
  34. package/src/lib/page-snapshot/capture/walk.ts +250 -0
  35. package/src/lib/page-snapshot/cst/__tests__/serialize.test.ts +50 -0
  36. package/src/lib/page-snapshot/cst/directives.ts +47 -0
  37. package/src/lib/page-snapshot/cst/payload.ts +50 -0
  38. package/src/lib/page-snapshot/cst/serialize.ts +84 -0
  39. package/src/lib/page-snapshot/cst/types.ts +115 -0
  40. package/src/lib/page-snapshot/engine.ts +176 -0
  41. package/src/lib/page-snapshot/index.ts +93 -0
  42. package/src/lib/page-snapshot/react/PageSnapshotChip.tsx +72 -0
  43. package/src/lib/page-snapshot/react/PageSnapshotPreview.tsx +78 -0
  44. package/src/lib/page-snapshot/react/__tests__/PageSnapshotChip.test.tsx +54 -0
  45. package/src/lib/page-snapshot/react/__tests__/provider.test.tsx +103 -0
  46. package/src/lib/page-snapshot/react/__tests__/use-page-snapshot-toggle.test.tsx +62 -0
  47. package/src/lib/page-snapshot/react/provider.tsx +162 -0
  48. package/src/lib/page-snapshot/react/use-page-snapshot-toggle.ts +47 -0
  49. package/src/lib/page-snapshot/react/use-page-snapshot.ts +67 -0
  50. package/src/lib/page-snapshot/redaction/__tests__/audit.test.ts +25 -0
  51. package/src/lib/page-snapshot/redaction/__tests__/heuristics.test.ts +73 -0
  52. package/src/lib/page-snapshot/redaction/__tests__/luhn.test.ts +26 -0
  53. package/src/lib/page-snapshot/redaction/__tests__/patterns.test.ts +60 -0
  54. package/src/lib/page-snapshot/redaction/audit.ts +58 -0
  55. package/src/lib/page-snapshot/redaction/heuristics.ts +75 -0
  56. package/src/lib/page-snapshot/redaction/index.ts +75 -0
  57. package/src/lib/page-snapshot/redaction/luhn.ts +25 -0
  58. package/src/lib/page-snapshot/redaction/patterns.ts +111 -0
  59. package/src/lib/page-snapshot/refs/__tests__/registry.test.ts +24 -0
  60. package/src/lib/page-snapshot/refs/registry.ts +46 -0
  61. package/src/lib/page-snapshot/staleness/__tests__/hash.test.ts +34 -0
  62. package/src/lib/page-snapshot/staleness/hash.ts +20 -0
  63. package/src/lib/page-snapshot/tokens.ts +15 -0
  64. package/src/tools/AudioPlayer/context/PlayerProvider.tsx +13 -14
  65. package/src/tools/AudioPlayer/hooks/useAudioElementEvents.ts +55 -6
  66. package/src/tools/AudioPlayer/lazy.tsx +13 -27
  67. package/src/tools/AudioPlayer/parts/Meta/TimeDisplay.tsx +2 -5
  68. package/src/tools/Chat/README.md +267 -39
  69. package/src/tools/Chat/composer/Composer.tsx +471 -0
  70. package/src/tools/Chat/composer/ComposerActionBar.tsx +65 -0
  71. package/src/tools/Chat/composer/ComposerBanner.tsx +128 -0
  72. package/src/tools/Chat/composer/ComposerButton.tsx +64 -0
  73. package/src/tools/Chat/composer/ComposerFooter.tsx +90 -0
  74. package/src/tools/Chat/composer/ComposerMenuButton.tsx +62 -0
  75. package/src/tools/Chat/composer/ComposerModelPicker.tsx +104 -0
  76. package/src/tools/Chat/composer/ComposerRichTextarea.tsx +88 -0
  77. package/src/tools/Chat/composer/ComposerToolPill.tsx +95 -0
  78. package/src/tools/Chat/composer/index.ts +45 -0
  79. package/src/tools/Chat/composer/size-context.tsx +26 -0
  80. package/src/tools/Chat/composer/types.ts +143 -0
  81. package/src/tools/Chat/composer/useComposerActions.tsx +164 -0
  82. package/src/tools/Chat/context/ChatProvider.tsx +54 -3
  83. package/src/tools/Chat/core/__tests__/metadata.test.ts +69 -0
  84. package/src/tools/Chat/core/index.ts +23 -1
  85. package/src/tools/Chat/core/markdown.ts +1 -1
  86. package/src/tools/Chat/core/metadata.ts +47 -0
  87. package/src/tools/Chat/core/payload-dispatch.ts +1 -1
  88. package/src/tools/Chat/core/transport/http.ts +71 -32
  89. package/src/tools/Chat/core/transport/sse.ts +18 -10
  90. package/src/tools/Chat/highlight/HighlightOverlay.tsx +101 -0
  91. package/src/tools/Chat/highlight/README.md +103 -0
  92. package/src/tools/Chat/highlight/SpotlightCanvas.tsx +153 -0
  93. package/src/tools/Chat/highlight/__tests__/HighlightOverlay.test.tsx +112 -0
  94. package/src/tools/Chat/highlight/__tests__/resolveRef.test.ts +55 -0
  95. package/src/tools/Chat/highlight/index.ts +21 -0
  96. package/src/tools/Chat/highlight/resolveRef.ts +42 -0
  97. package/src/tools/Chat/highlight/types.ts +49 -0
  98. package/src/tools/Chat/highlight/useHighlightTargets.ts +128 -0
  99. package/src/tools/Chat/hooks/index.ts +0 -5
  100. package/src/tools/Chat/hooks/useAutoFocusOnStreamEnd.ts +28 -47
  101. package/src/tools/Chat/hooks/useChat.ts +47 -14
  102. package/src/tools/Chat/hooks/useChatComposer.ts +2 -2
  103. package/src/tools/Chat/hooks/useChatLayout.ts +1 -1
  104. package/src/tools/Chat/hooks/useStreamEndFocus.ts +54 -0
  105. package/src/tools/Chat/index.ts +25 -219
  106. package/src/tools/Chat/launcher/ChatDock.tsx +1 -1
  107. package/src/tools/Chat/launcher/ChatLauncher.tsx +1 -1
  108. package/src/tools/Chat/launcher/{ChatHeader.tsx → header/ChatHeader.tsx} +24 -11
  109. package/src/tools/Chat/launcher/{ChatHeaderActionButton.tsx → header/ChatHeaderActionButton.tsx} +34 -3
  110. package/src/tools/Chat/launcher/{ChatHeaderLanguageButton.tsx → header/ChatHeaderLanguageButton.tsx} +2 -2
  111. package/src/tools/Chat/launcher/{ChatHeaderModeToggle.tsx → header/ChatHeaderModeToggle.tsx} +1 -1
  112. package/src/tools/Chat/launcher/{ChatHeaderResetButton.tsx → header/ChatHeaderResetButton.tsx} +2 -1
  113. package/src/tools/Chat/launcher/{HeaderSlots.tsx → header/HeaderSlots.tsx} +3 -3
  114. package/src/tools/Chat/launcher/header/index.ts +26 -0
  115. package/src/tools/Chat/launcher/index.ts +3 -10
  116. package/src/tools/Chat/lazy.tsx +38 -284
  117. package/src/tools/Chat/{components → messages}/MessageBubble.tsx +58 -5
  118. package/src/tools/Chat/{components → messages}/MessageList.tsx +8 -25
  119. package/src/tools/Chat/messages/blocks/MessageBlocks.tsx +131 -0
  120. package/src/tools/Chat/messages/blocks/builtin.tsx +91 -0
  121. package/src/tools/Chat/messages/blocks/index.ts +12 -0
  122. package/src/tools/Chat/messages/blocks/registry.tsx +42 -0
  123. package/src/tools/Chat/messages/blocks/renderers/AudioBlock.tsx +20 -0
  124. package/src/tools/Chat/messages/blocks/renderers/CodeBlock.tsx +19 -0
  125. package/src/tools/Chat/messages/blocks/renderers/GalleryBlock.tsx +26 -0
  126. package/src/tools/Chat/messages/blocks/renderers/ImageBlock.tsx +27 -0
  127. package/src/tools/Chat/messages/blocks/renderers/JsonBlock.tsx +12 -0
  128. package/src/tools/Chat/messages/blocks/renderers/LottieBlock.tsx +11 -0
  129. package/src/tools/Chat/messages/blocks/renderers/MapBlock.tsx +36 -0
  130. package/src/tools/Chat/messages/blocks/renderers/MermaidBlock.tsx +11 -0
  131. package/src/tools/Chat/messages/blocks/renderers/VideoBlock.tsx +24 -0
  132. package/src/tools/Chat/messages/blocks/renderers/types.ts +8 -0
  133. package/src/tools/Chat/{components → messages}/index.ts +11 -5
  134. package/src/tools/Chat/public.ts +212 -0
  135. package/src/tools/Chat/shell/ChatRoot.tsx +326 -0
  136. package/src/tools/Chat/{components → shell}/EmptyState.tsx +4 -2
  137. package/src/tools/Chat/shell/index.ts +15 -0
  138. package/src/tools/Chat/types/block.ts +120 -0
  139. package/src/tools/Chat/types/config.ts +0 -5
  140. package/src/tools/Chat/types/index.ts +17 -0
  141. package/src/tools/Chat/types/message.ts +3 -0
  142. package/src/tools/Chat/utils/index.ts +4 -0
  143. package/src/tools/CodeEditor/README.md +4 -6
  144. package/src/tools/CodeEditor/components/DiffEditor.tsx +48 -13
  145. package/src/tools/CodeEditor/components/Editor.tsx +96 -44
  146. package/src/tools/CodeEditor/context/EditorProvider.tsx +34 -17
  147. package/src/tools/CodeEditor/hooks/useEditorTheme.ts +92 -99
  148. package/src/tools/CodeEditor/hooks/useMonaco.ts +37 -22
  149. package/src/tools/CodeEditor/lazy.tsx +6 -0
  150. package/src/tools/CodeEditor/lib/index.ts +1 -1
  151. package/src/tools/CodeEditor/lib/themes.ts +3 -39
  152. package/src/tools/CronScheduler/CronScheduler.client.tsx +230 -61
  153. package/src/tools/CronScheduler/components/CustomInput.tsx +21 -4
  154. package/src/tools/CronScheduler/components/DayChips.tsx +13 -11
  155. package/src/tools/CronScheduler/components/MonthDayGrid.tsx +4 -4
  156. package/src/tools/CronScheduler/components/SchedulePreview.tsx +7 -3
  157. package/src/tools/CronScheduler/components/TimeSelector.tsx +1 -1
  158. package/src/tools/CronScheduler/index.tsx +1 -1
  159. package/src/tools/CronScheduler/types/index.ts +8 -3
  160. package/src/tools/CronScheduler/utils/cron-humanize.ts +61 -16
  161. package/src/tools/CronScheduler/utils/cron-parser.ts +13 -4
  162. package/src/tools/FileIcon/FileIcon.tsx +24 -39
  163. package/src/tools/FileIcon/get-file-icon.ts +73 -0
  164. package/src/tools/FileIcon/icons/icon-data.ts +399 -0
  165. package/src/tools/FileIcon/index.ts +4 -0
  166. package/src/tools/FileIcon/loader.ts +17 -35
  167. package/src/tools/FileIcon/specialFolders.ts +18 -0
  168. package/src/tools/Gallery/components/lightbox/GalleryLightbox.tsx +112 -35
  169. package/src/tools/Gallery/components/media/GalleryVideo.tsx +21 -2
  170. package/src/tools/Gallery/components/preview/GalleryCarousel.tsx +11 -1
  171. package/src/tools/Gallery/hooks/usePreloadImages.ts +54 -7
  172. package/src/tools/ImageViewer/components/ImageInfo.tsx +12 -1
  173. package/src/tools/ImageViewer/components/ImageToolbar.tsx +51 -43
  174. package/src/tools/ImageViewer/components/ImageViewer.tsx +106 -26
  175. package/src/tools/ImageViewer/hooks/useImageLoading.ts +13 -0
  176. package/src/tools/ImageViewer/utils/constants.ts +3 -0
  177. package/src/tools/ImageViewer/utils/index.ts +1 -0
  178. package/src/tools/JsonForm/JsonSchemaForm.tsx +4 -1
  179. package/src/tools/JsonForm/templates/ArrayFieldTemplate.tsx +5 -3
  180. package/src/tools/JsonForm/templates/BaseInputTemplate.tsx +7 -4
  181. package/src/tools/JsonForm/templates/ErrorListTemplate.tsx +3 -1
  182. package/src/tools/JsonForm/templates/ObjectFieldTemplate.tsx +23 -3
  183. package/src/tools/JsonForm/widgets/ColorWidget.tsx +20 -12
  184. package/src/tools/JsonForm/widgets/NumberWidget.tsx +14 -9
  185. package/src/tools/JsonForm/widgets/RadioWidget.tsx +78 -0
  186. package/src/tools/JsonForm/widgets/SelectWidget.tsx +1 -0
  187. package/src/tools/JsonForm/widgets/SliderWidget.tsx +7 -4
  188. package/src/tools/JsonForm/widgets/TextWidget.tsx +41 -17
  189. package/src/tools/JsonForm/widgets/index.ts +1 -0
  190. package/src/tools/JsonTree/components/JsonContent.tsx +115 -40
  191. package/src/tools/LottiePlayer/LottiePlayer.client.tsx +177 -72
  192. package/src/tools/LottiePlayer/index.tsx +14 -4
  193. package/src/tools/LottiePlayer/lazy.tsx +11 -3
  194. package/src/tools/LottiePlayer/types.ts +31 -1
  195. package/src/tools/LottiePlayer/useLottie.ts +32 -9
  196. package/src/tools/LottiePlayer/usePrefersReducedMotion.ts +46 -0
  197. package/src/tools/Map/components/LayerSwitcher.tsx +54 -21
  198. package/src/tools/Map/components/MapCluster.tsx +28 -21
  199. package/src/tools/Map/components/MapContainer.tsx +11 -4
  200. package/src/tools/Map/components/MapLegend.tsx +46 -15
  201. package/src/tools/Map/components/MapMarker.tsx +31 -2
  202. package/src/tools/Map/hooks/useMapEvents.ts +64 -105
  203. package/src/tools/MarkdownEditor/MarkdownEditor.tsx +61 -6
  204. package/src/tools/MarkdownEditor/MentionList.tsx +37 -4
  205. package/src/tools/MarkdownEditor/createMentionSuggestion.ts +11 -0
  206. package/src/tools/MarkdownEditor/lazy.tsx +32 -7
  207. package/src/tools/MarkdownEditor/styles.css +13 -0
  208. package/src/tools/MarkdownMessage/CodeBlock.tsx +40 -17
  209. package/src/tools/MarkdownMessage/MarkdownMessage.tsx +26 -6
  210. package/src/tools/MarkdownMessage/components.tsx +22 -9
  211. package/src/tools/MarkdownMessage/types.ts +24 -1
  212. package/src/tools/Mermaid/Mermaid.client.tsx +27 -5
  213. package/src/tools/Mermaid/components/MermaidErrorPanel.tsx +31 -0
  214. package/src/tools/Mermaid/components/MermaidFullscreenModal.tsx +14 -17
  215. package/src/tools/Mermaid/hooks/useMermaidRenderer.ts +264 -168
  216. package/src/tools/Mermaid/hooks/useMermaidValidation.ts +76 -10
  217. package/src/tools/Mermaid/index.tsx +6 -0
  218. package/src/tools/Mermaid/utils/mermaid-helpers.ts +141 -18
  219. package/src/tools/OpenapiViewer/components/DocsLayout/EndpointDoc/SchemaFields/FieldRow.tsx +11 -1
  220. package/src/tools/OpenapiViewer/components/DocsLayout/EndpointDoc/SchemaFields/buildTree.ts +49 -20
  221. package/src/tools/OpenapiViewer/components/DocsLayout/EndpointDoc/index.tsx +7 -0
  222. package/src/tools/OpenapiViewer/components/DocsLayout/grouping.ts +7 -4
  223. package/src/tools/OpenapiViewer/constants.ts +3 -0
  224. package/src/tools/OpenapiViewer/hooks/useOpenApiSchema.ts +73 -11
  225. package/src/tools/OpenapiViewer/utils/schemaExport.ts +26 -6
  226. package/src/tools/PrettyCode/PrettyCode.client.tsx +23 -16
  227. package/src/tools/PrettyCode/lazy.tsx +1 -1
  228. package/src/tools/SpeechRecognition/README.md +1 -1
  229. package/src/tools/SpeechRecognition/__tests__/language.test.ts +9 -3
  230. package/src/tools/SpeechRecognition/components/RecordingPulse.tsx +59 -0
  231. package/src/tools/SpeechRecognition/components/index.ts +2 -0
  232. package/src/tools/SpeechRecognition/core/engine/external.ts +24 -7
  233. package/src/tools/SpeechRecognition/core/language.ts +23 -6
  234. package/src/tools/SpeechRecognition/hooks/usePushToTalk.ts +36 -5
  235. package/src/tools/SpeechRecognition/hooks/useSpeechRecognition.ts +18 -11
  236. package/src/tools/SpeechRecognition/widgets/VoiceComposerSlot.tsx +94 -26
  237. package/src/tools/SpeechRecognition/widgets/index.ts +1 -1
  238. package/src/tools/Tree/README.md +4 -8
  239. package/src/tools/Tree/TreeRoot.tsx +22 -10
  240. package/src/tools/Tree/components/TreeContent.tsx +24 -4
  241. package/src/tools/Tree/components/TreeLabel.tsx +8 -2
  242. package/src/tools/Tree/components/TreeRow.tsx +16 -6
  243. package/src/tools/Tree/data/flatten.ts +10 -4
  244. package/src/tools/Tree/types.ts +4 -0
  245. package/src/tools/Uploader/components/UploadAddButton.tsx +29 -6
  246. package/src/tools/Uploader/components/UploadDropzone.tsx +63 -7
  247. package/src/tools/Uploader/components/UploadPageDropOverlay.tsx +19 -5
  248. package/src/tools/Uploader/components/UploadPreviewItem.tsx +47 -17
  249. package/src/tools/Uploader/components/UploadPreviewList.tsx +24 -12
  250. package/src/tools/Uploader/utils/formatters.ts +8 -3
  251. package/src/tools/VideoPlayer/README.md +87 -230
  252. package/src/tools/VideoPlayer/VideoPlayer.tsx +82 -0
  253. package/src/tools/VideoPlayer/canvas/canvas-dispatcher.tsx +34 -0
  254. package/src/tools/VideoPlayer/canvas/hls-canvas.tsx +39 -0
  255. package/src/tools/VideoPlayer/canvas/iframe-canvas.tsx +33 -0
  256. package/src/tools/VideoPlayer/canvas/index.ts +12 -0
  257. package/src/tools/VideoPlayer/canvas/jsx-augmentation.ts +47 -0
  258. package/src/tools/VideoPlayer/canvas/native-canvas.tsx +38 -0
  259. package/src/tools/VideoPlayer/canvas/vimeo-canvas.tsx +40 -0
  260. package/src/tools/VideoPlayer/canvas/youtube-canvas.tsx +78 -0
  261. package/src/tools/VideoPlayer/index.ts +51 -65
  262. package/src/tools/VideoPlayer/lazy.tsx +11 -54
  263. package/src/tools/VideoPlayer/parts/controls-bar.tsx +35 -0
  264. package/src/tools/VideoPlayer/parts/fullscreen.tsx +19 -0
  265. package/src/tools/VideoPlayer/parts/index.ts +15 -0
  266. package/src/tools/VideoPlayer/parts/pip.tsx +19 -0
  267. package/src/tools/VideoPlayer/parts/play-button.tsx +19 -0
  268. package/src/tools/VideoPlayer/parts/playback-rate.tsx +31 -0
  269. package/src/tools/VideoPlayer/parts/poster.tsx +3 -0
  270. package/src/tools/VideoPlayer/parts/seek-bar.tsx +26 -0
  271. package/src/tools/VideoPlayer/parts/volume.tsx +32 -0
  272. package/src/tools/VideoPlayer/styles/video-player.css +141 -0
  273. package/src/tools/VideoPlayer/types.ts +82 -0
  274. package/src/tools/VideoPlayer/utils/parse-embed-url.ts +70 -0
  275. package/src/tools/VideoPlayer/utils/vimeo-id.ts +24 -0
  276. package/src/tools/VideoPlayer/utils/youtube-id.ts +64 -0
  277. package/src/tools/index.ts +37 -29
  278. package/src/tools/Chat/components/AudioToggle.tsx +0 -78
  279. package/src/tools/Chat/components/ChatRoot.tsx +0 -305
  280. package/src/tools/Chat/components/Composer.tsx +0 -216
  281. package/src/tools/Chat/hooks/useChatScroll.ts +0 -145
  282. package/src/tools/Chat/types.ts +0 -9
  283. package/src/tools/JsonTree/components/JsonToolbar.tsx +0 -95
  284. package/src/tools/JsonTree/hooks/useElementCorner.ts +0 -84
  285. package/src/tools/JsonTree/hooks/useNavbarHeight.ts +0 -83
  286. package/src/tools/OpenapiViewer/components/DocsLayout/schemaFields.ts +0 -121
  287. package/src/tools/Tour/README.md +0 -373
  288. package/src/tools/Tour/components/Tour.tsx +0 -12
  289. package/src/tools/Tour/components/TourContent.tsx +0 -171
  290. package/src/tools/Tour/components/TourNavigation.tsx +0 -77
  291. package/src/tools/Tour/components/TourProgress.tsx +0 -88
  292. package/src/tools/Tour/components/TourSpotlight.tsx +0 -199
  293. package/src/tools/Tour/components/index.ts +0 -5
  294. package/src/tools/Tour/context/TourContext.ts +0 -19
  295. package/src/tools/Tour/context/TourProvider.tsx +0 -292
  296. package/src/tools/Tour/context/index.ts +0 -2
  297. package/src/tools/Tour/hooks/index.ts +0 -3
  298. package/src/tools/Tour/hooks/useKeyboardNavigation.ts +0 -59
  299. package/src/tools/Tour/hooks/useStepTarget.ts +0 -121
  300. package/src/tools/Tour/hooks/useTour.ts +0 -42
  301. package/src/tools/Tour/index.ts +0 -38
  302. package/src/tools/Tour/types/index.ts +0 -224
  303. package/src/tools/Tour/utils/dom.ts +0 -98
  304. package/src/tools/Tour/utils/index.ts +0 -3
  305. package/src/tools/Tour/utils/logger.ts +0 -3
  306. package/src/tools/Tour/utils/scrollIntoView.ts +0 -24
  307. package/src/tools/VideoPlayer/components/VideoControls.tsx +0 -138
  308. package/src/tools/VideoPlayer/components/VideoErrorFallback.tsx +0 -172
  309. package/src/tools/VideoPlayer/components/VideoPlayer.tsx +0 -201
  310. package/src/tools/VideoPlayer/components/index.ts +0 -14
  311. package/src/tools/VideoPlayer/context/VideoPlayerContext.tsx +0 -52
  312. package/src/tools/VideoPlayer/context/index.ts +0 -8
  313. package/src/tools/VideoPlayer/hooks/index.ts +0 -12
  314. package/src/tools/VideoPlayer/hooks/useVideoPlayerSettings.ts +0 -71
  315. package/src/tools/VideoPlayer/hooks/useVideoPositionCache.ts +0 -117
  316. package/src/tools/VideoPlayer/providers/NativeProvider.tsx +0 -284
  317. package/src/tools/VideoPlayer/providers/StreamProvider.tsx +0 -505
  318. package/src/tools/VideoPlayer/providers/VidstackProvider.tsx +0 -397
  319. package/src/tools/VideoPlayer/providers/index.ts +0 -8
  320. package/src/tools/VideoPlayer/types/index.ts +0 -38
  321. package/src/tools/VideoPlayer/types/player.ts +0 -116
  322. package/src/tools/VideoPlayer/types/provider.ts +0 -93
  323. package/src/tools/VideoPlayer/types/sources.ts +0 -97
  324. package/src/tools/VideoPlayer/utils/debug.ts +0 -14
  325. package/src/tools/VideoPlayer/utils/fileSource.ts +0 -78
  326. package/src/tools/VideoPlayer/utils/index.ts +0 -12
  327. package/src/tools/VideoPlayer/utils/resolvers.ts +0 -75
  328. /package/src/tools/Chat/{config.ts → constants.ts} +0 -0
  329. /package/src/tools/Chat/launcher/{ChatHeaderAudioToggle.tsx → header/ChatHeaderAudioToggle.tsx} +0 -0
  330. /package/src/tools/Chat/{components → messages}/Attachments.tsx +0 -0
  331. /package/src/tools/Chat/{components → messages}/JumpToLatest.tsx +0 -0
  332. /package/src/tools/Chat/{components → messages}/MessageActions.tsx +0 -0
  333. /package/src/tools/Chat/{components → messages}/Sources.tsx +0 -0
  334. /package/src/tools/Chat/{components → messages}/StreamingIndicator.tsx +0 -0
  335. /package/src/tools/Chat/{components → messages}/ToolCalls.tsx +0 -0
  336. /package/src/tools/Chat/{components → shell}/ErrorBanner.tsx +0 -0
@@ -0,0 +1,212 @@
1
+ 'use client';
2
+
3
+ /**
4
+ * Chat — shared "light surface".
5
+ *
6
+ * The single source of truth for everything safe to load synchronously:
7
+ * types, runtime constants, pure `core` + transports, hooks (no UI),
8
+ * notifier, payload-dispatch, logger, utils, styles, context.
9
+ *
10
+ * Both root entry points re-export this module verbatim:
11
+ * - `index.ts` (`@djangocfg/ui-tools`) — `public` + heavy sync components
12
+ * - `lazy.tsx` (`@djangocfg/ui-tools/chat`) — `public` + Lazy* wrappers
13
+ *
14
+ * Heavy UI components must NOT be added here — they belong in `index.ts`
15
+ * (sync) and `lazy.tsx` (lazy) only.
16
+ *
17
+ * `./chat` is the only sanctioned Chat subpath — do not add new subpaths
18
+ * (avoids the dual-bundle / two-React-context trap).
19
+ */
20
+
21
+ // Types
22
+ export type {
23
+ ChatRole,
24
+ ChatMessage,
25
+ ChatPersona,
26
+ ChatToolCall,
27
+ ChatAttachment,
28
+ ChatSource,
29
+ ChatDisplayMode,
30
+ ChatUserContext,
31
+ ChatAssistantContext,
32
+ ChatPrefs,
33
+ ChatConfig,
34
+ ChatLabels,
35
+ ChatTransport,
36
+ ChatStreamEvent,
37
+ CreateSessionOptions,
38
+ SessionInfo,
39
+ HistoryPage,
40
+ StreamOptions,
41
+ SendOptions,
42
+ MessageBlock,
43
+ MessageBlockKind,
44
+ BlockAppearance,
45
+ TextBlock,
46
+ MarkdownBlock,
47
+ AudioBlock,
48
+ VideoBlock,
49
+ ImageBlock,
50
+ GalleryBlock,
51
+ MapBlock,
52
+ JsonBlock,
53
+ MermaidBlock,
54
+ CodeBlock,
55
+ LottieBlock,
56
+ CustomBlock,
57
+ } from './types';
58
+ export { DEFAULT_LABELS } from './types';
59
+
60
+ // Constants — plain runtime constants, no UI imports
61
+ export {
62
+ STORAGE_KEYS,
63
+ CSS_VARS,
64
+ DEFAULT_Z_INDEX,
65
+ LIMITS,
66
+ DEFAULT_SIDEBAR,
67
+ HOTKEYS,
68
+ CHAT_EVENT_NAME,
69
+ type ChatEventDetail,
70
+ } from './constants';
71
+
72
+ // Core (pure) — reducer / id / token buffer / persona / initials
73
+ export {
74
+ reducer,
75
+ initialState,
76
+ createId,
77
+ createTokenBuffer,
78
+ resolvePersona,
79
+ deriveInitials,
80
+ type ChatState,
81
+ type ChatAction,
82
+ type TokenBuffer,
83
+ } from './core';
84
+
85
+ // Transport — pure functions, no UI
86
+ export {
87
+ createHttpTransport,
88
+ createMockTransport,
89
+ parseSSE,
90
+ TransportError,
91
+ createPydanticAIChatTransport,
92
+ createToolIdQueue,
93
+ mapPydanticAIEvent,
94
+ createPydanticAISSEMap,
95
+ type HttpTransportConfig,
96
+ type MockTransportOptions,
97
+ type ParseSSEOptions,
98
+ type PydanticAIChatTransportOpts,
99
+ type PydanticAIEvent,
100
+ type ToolIdQueue,
101
+ } from './core/transport';
102
+
103
+ // Hooks — React state glue, no JSX / UI components
104
+ export {
105
+ useChat,
106
+ useChatComposer,
107
+ useChatHistory,
108
+ useChatLayout,
109
+ useChatAudio,
110
+ useAutoFocusOnStreamEnd,
111
+ useRegisterComposer,
112
+ useChatReset,
113
+ useVisitorFingerprint,
114
+ useChatDockPrefs,
115
+ DEFAULT_DOCK_PREFS,
116
+ useFocusOnEmptyClick,
117
+ useChatUnread,
118
+ useChatUnreadNotifier,
119
+ useChatLightbox,
120
+ type UseChatUnreadOptions,
121
+ type UseChatUnreadReturn,
122
+ type UseChatUnreadNotifierOptions,
123
+ type UseChatConfig,
124
+ type UseChatReturn,
125
+ type UseChatComposerOptions,
126
+ type UseChatComposerReturn,
127
+ type UseChatHistoryOptions,
128
+ type UseChatLayoutConfig,
129
+ type UseChatLayoutReturn,
130
+ type UseAutoFocusOnStreamEndOptions,
131
+ type Focusable,
132
+ type UseChatResetOptions,
133
+ type UseChatResetReturn,
134
+ type UseVisitorFingerprintOptions,
135
+ type ChatDockPrefs,
136
+ type UseChatDockPrefsOptions,
137
+ type UseChatDockPrefsReturn,
138
+ type UseFocusOnEmptyClickOptions,
139
+ type UseChatLightboxReturn,
140
+ type ChatLightboxState,
141
+ type ChatLightboxScope,
142
+ } from './hooks';
143
+
144
+ // Audio
145
+ export {
146
+ useChatAudioPrefs,
147
+ DEFAULT_CHAT_SOUNDS,
148
+ type ChatAudioEvent,
149
+ type ChatAudioSounds,
150
+ type ChatAudioConfig,
151
+ type UseChatAudioReturn,
152
+ } from './core/audio';
153
+
154
+ // Notifier — title rotation + favicon badge + page-visibility + cross-tab
155
+ export {
156
+ createBrowserNotifier,
157
+ createNoopNotifier,
158
+ createTitleRotator,
159
+ createFaviconBadge,
160
+ createCrossTabNotifier,
161
+ isPageHidden,
162
+ onVisibilityChange,
163
+ type ChatNotifier,
164
+ type BrowserNotifierOptions,
165
+ type TitleRotatorOptions,
166
+ type TitleMode,
167
+ type FaviconBadgeOptions,
168
+ type CrossTabNotifierOptions,
169
+ } from './notifier';
170
+
171
+ // Tool-call payload dispatcher — pure
172
+ export {
173
+ dispatchToolPayload,
174
+ isPlainObject,
175
+ isLatLng,
176
+ isGeoJSONFeatureCollection,
177
+ isStringValue,
178
+ type ToolPayloadMatcher,
179
+ type ToolPayloadFallback,
180
+ } from './core/payload-dispatch';
181
+
182
+ // Dev logger (consola-based, namespace "chat:*")
183
+ export { getChatLogger, type ChatLogger, type ChatLogScope } from './core/logger';
184
+
185
+ // Utils — pure helpers
186
+ export { sanitizeDraft, isSubmittableDraft, collectImageAttachments } from './utils';
187
+
188
+ // Styles — role-aware className tokens + hooks
189
+ export {
190
+ BUBBLE_SURFACE,
191
+ ANCHOR,
192
+ TOGGLE,
193
+ DESTRUCTIVE_SURFACE,
194
+ TOOL_CALL,
195
+ useChatBubbleStyles,
196
+ useChatRoleStyles,
197
+ useChatDestructiveStyles,
198
+ type ChatBubbleSurface,
199
+ type ChatBubbleStyles,
200
+ type ChatRoleStyles,
201
+ type ChatDestructiveStyles,
202
+ } from './styles';
203
+
204
+ // Context — provider + hooks for callers wiring custom chat shells
205
+ export {
206
+ ChatProvider,
207
+ useChatContext,
208
+ useChatContextOptional,
209
+ type ChatContextValue,
210
+ type ChatProviderProps,
211
+ type ComposerHandle,
212
+ } from './context';
@@ -0,0 +1,326 @@
1
+ 'use client';
2
+
3
+ import { type ReactNode, useMemo, useRef, useState } from 'react';
4
+
5
+ import { cn } from '@djangocfg/ui-core/lib';
6
+
7
+ import type { ChatAttachment, ChatConfig, ChatMessage, ChatTransport } from '../types';
8
+ import type { ChatAudioConfig } from '../core/audio/types';
9
+ import {
10
+ ChatProvider,
11
+ useChatContext,
12
+ useChatContextOptional,
13
+ type ChatContextValue,
14
+ } from '../context';
15
+ import { useChatComposer, type UseChatComposerReturn } from '../hooks/useChatComposer';
16
+ import { useFocusOnEmptyClick } from '../hooks/useFocusOnEmptyClick';
17
+ import { Composer } from '../composer/Composer';
18
+ import type {
19
+ ComposerAppearance,
20
+ ComposerFooterProps,
21
+ ComposerLayout,
22
+ ComposerSize,
23
+ ComposerSlots,
24
+ } from '../composer/types';
25
+ import { EmptyState } from './EmptyState';
26
+ import { ErrorBanner } from './ErrorBanner';
27
+ import { JumpToLatest } from '../messages/JumpToLatest';
28
+ import { MessageBubble } from '../messages/MessageBubble';
29
+ import { MessageList, type MessageListHandle } from '../messages/MessageList';
30
+ import type { AttachmentRendererMap } from '../messages/Attachments';
31
+ import type { BlockRegistry } from '../messages/blocks';
32
+ import type { ToolCallsProps } from '../messages/ToolCalls';
33
+
34
+ /** Empty-state render API — seeds + focuses the composer from prompt chips. */
35
+ export interface ChatEmptyApi {
36
+ setValue: (v: string) => void;
37
+ focus: () => void;
38
+ }
39
+
40
+ /** Full-replacement render API for the composer slot — the live composer
41
+ * hook plus the resolved {@link ChatComposerConfig} that produced it.
42
+ * One source of truth; no hand-mirrored field list. */
43
+ export interface ChatComposerRenderApi {
44
+ composer: UseChatComposerReturn;
45
+ config: ChatComposerConfig;
46
+ }
47
+
48
+ /** Composer-region configuration for `<ChatRoot composer={…}>`. Groups
49
+ * every knob that forwards into the built-in `<Composer>`. */
50
+ export interface ChatComposerConfig {
51
+ /** Visual size variant. Default `md`. */
52
+ size?: ComposerSize;
53
+ /** Input-surface layout. Default `stacked` (`sm` → `inline`). */
54
+ layout?: ComposerLayout;
55
+ /** Extra className on the `<Composer>` wrapper. */
56
+ className?: string;
57
+ /** Hide the composer entirely (e.g. while waiting for human approval). */
58
+ hidden?: boolean;
59
+ /** Show the paperclip "attach" button. */
60
+ showAttachmentButton?: boolean;
61
+ /** Called when the user clicks the attach button. */
62
+ onPickFiles?: () => void;
63
+ /** Tier A declarative slots — action clusters + raw-node escape hatches. */
64
+ slots?: ComposerSlots;
65
+ /** Footer toolbar below the input surface. `false` hides it. */
66
+ footer?: ComposerFooterProps | false;
67
+ /** Full replacement — receives the live composer hook + this config. */
68
+ render?: (api: ChatComposerRenderApi) => ReactNode;
69
+ }
70
+
71
+ /** Named ReactNode slots for `<ChatRoot slots={…}>`. The `header` / `empty`
72
+ * slots accept either a node or a render fn — no separate `renderX` prop. */
73
+ export interface ChatSlots {
74
+ /** Sticky banner above the message list (e.g. quota warning). */
75
+ banner?: ReactNode;
76
+ /** Header row below the banner — node, or a fn given the chat context. */
77
+ header?: ReactNode | ((ctx: ChatContextValue) => ReactNode);
78
+ /** Replaces the default `<EmptyState>` — node, or a fn given a seed API. */
79
+ empty?: ReactNode | ((api: ChatEmptyApi) => ReactNode);
80
+ /** Replaces the default `<JumpToLatest>` floating pill. */
81
+ jumpToLatest?: ReactNode;
82
+ }
83
+
84
+ /** Message-rendering configuration for `<ChatRoot messages={…}>`. */
85
+ export interface ChatMessagesConfig {
86
+ /** Replace `<MessageBubble>` per message. */
87
+ render?: (m: ChatMessage, i: number) => ReactNode;
88
+ /**
89
+ * Render arbitrary content beneath every default `<MessageBubble>`
90
+ * (not invoked when `render` is set — the host owns layout then).
91
+ */
92
+ renderAfter?: (m: ChatMessage) => ReactNode;
93
+ /** Forwarded into `<MessageBubble toolCallsProps>` to swap payload renderers. */
94
+ toolCallsProps?: Omit<ToolCallsProps, 'calls'>;
95
+ /** Per-type attachment renderers — `{ image, audio, video, file, default }`. */
96
+ attachmentRenderers?: AttachmentRendererMap;
97
+ /** Called when an attachment tile is clicked (e.g. open lightbox). */
98
+ onAttachmentOpen?: (attachment: ChatAttachment) => void;
99
+ /**
100
+ * Registry of `kind` → renderer for `message.blocks`. Merge host
101
+ * overrides over the defaults with `createBlockRegistry({ … })`.
102
+ * Omit to use `BUILTIN_BLOCK_REGISTRY`.
103
+ */
104
+ blockRegistry?: BlockRegistry;
105
+ }
106
+
107
+ export interface ChatRootProps {
108
+ // ---- core wiring -------------------------------------------------------
109
+ /**
110
+ * Transport. Required UNLESS `<ChatRoot>` is rendered inside an
111
+ * existing `<ChatProvider>` (e.g. mounted by `<ChatLauncher>`), in
112
+ * which case the ambient provider is reused and `transport` is
113
+ * ignored.
114
+ */
115
+ transport?: ChatTransport;
116
+ config?: ChatConfig;
117
+ /** Session wiring — pre-existing id to attach, auto-create toggle. */
118
+ session?: { initialId?: string; autoCreate?: boolean };
119
+ streaming?: boolean;
120
+ /** Audio-trigger configuration. Off by default (no `sounds` map). */
121
+ audio?: ChatAudioConfig;
122
+ /**
123
+ * Verbose dev-mode logging via `consola` (namespace `chat:*`).
124
+ * Defaults to `isDev` from `@djangocfg/ui-core/lib`.
125
+ */
126
+ debug?: boolean;
127
+
128
+ // ---- presentation ------------------------------------------------------
129
+ /** Spaciousness of the whole chat — scales bubbles + composer.
130
+ * `compact` (default) for embedded chat, `full` for full-page. */
131
+ appearance?: ComposerAppearance;
132
+ /** Extra className on the `<ChatRoot>` wrapper. */
133
+ className?: string;
134
+ /** Extra className forwarded to the `<MessageList>` scroll container. */
135
+ listClassName?: string;
136
+
137
+ // ---- composition (grouped) --------------------------------------------
138
+ /** Named ReactNode slots — banner, header, empty, jumpToLatest. */
139
+ slots?: ChatSlots;
140
+ /** Composer-region configuration. */
141
+ composer?: ChatComposerConfig;
142
+ /** Message-rendering configuration. */
143
+ messages?: ChatMessagesConfig;
144
+
145
+ // ---- behavior ----------------------------------------------------------
146
+ /**
147
+ * Click in the message area → focus the composer (Slack / ChatGPT).
148
+ * @default true
149
+ */
150
+ focusOnEmptyClick?: boolean;
151
+ }
152
+
153
+ export function ChatRoot(props: ChatRootProps) {
154
+ const { transport, config, session, streaming, audio, debug, className, listClassName, ...rest } = props;
155
+ // When mounted under a launcher-owned `<ChatProvider>`, reuse that
156
+ // provider instead of wrapping in a second one. This lets host code
157
+ // freely nest `<ChatRoot>` inside `<ChatLauncher>` without losing
158
+ // `headerSlots` access to the same session / clearMessages / audio.
159
+ const ambient = useChatContextOptional();
160
+ if (ambient) {
161
+ return <ChatRootShell className={className} listClassName={listClassName} parts={rest} />;
162
+ }
163
+ if (!transport) {
164
+ throw new Error(
165
+ '<ChatRoot> requires `transport` when mounted outside a <ChatProvider>.',
166
+ );
167
+ }
168
+ return (
169
+ <ChatProvider
170
+ transport={transport}
171
+ config={config}
172
+ initialSessionId={session?.initialId}
173
+ autoCreateSession={session?.autoCreate}
174
+ streaming={streaming}
175
+ audio={audio}
176
+ debug={debug}
177
+ blockRegistry={rest.messages?.blockRegistry}
178
+ >
179
+ <ChatRootShell className={className} listClassName={listClassName} parts={rest} />
180
+ </ChatProvider>
181
+ );
182
+ }
183
+
184
+ type ChatRootParts = Pick<
185
+ ChatRootProps,
186
+ 'appearance' | 'slots' | 'composer' | 'messages' | 'focusOnEmptyClick'
187
+ >;
188
+
189
+ interface ChatRootShellProps {
190
+ className?: string;
191
+ listClassName?: string;
192
+ parts: ChatRootParts;
193
+ }
194
+
195
+ function ChatRootShell({ className, listClassName, parts }: ChatRootShellProps) {
196
+ const { slots = {}, composer: composerConfig = {}, messages = {} } = parts;
197
+ const chat = useChatContext();
198
+ const composer = useChatComposer({
199
+ onSubmit: (content, attachments) => chat.sendMessage(content, attachments),
200
+ disabled: chat.isStreaming,
201
+ });
202
+ const onMessagesMouseUp = useFocusOnEmptyClick({
203
+ enabled: parts.focusOnEmptyClick !== false,
204
+ });
205
+ // Stream-end composer re-focus is handled by `<ChatProvider>` — it
206
+ // covers every usage pattern, not just `ChatRoot`.
207
+ // MessageList (virtuoso) owns the scroll viewport. We talk to it via
208
+ // the imperative handle (scrollToBottom) and the `onAtBottomChange`
209
+ // callback (drives the pill).
210
+ const listRef = useRef<MessageListHandle | null>(null);
211
+ const [isAtBottom, setIsAtBottom] = useState(true);
212
+ // The id of the most-recent user-sent message — passed as
213
+ // `scrollAnchorId` so every send re-anchors the viewport.
214
+ const lastUserMessageId = useMemo(() => {
215
+ const msgs = chat.messages;
216
+ for (let i = msgs.length - 1; i >= 0; i -= 1) {
217
+ if (msgs[i].role === 'user') return msgs[i].id;
218
+ }
219
+ return null;
220
+ }, [chat.messages]);
221
+ const handleStartReached = chat.hasMore && !chat.isLoadingMore
222
+ ? () => void chat.loadMore()
223
+ : undefined;
224
+
225
+ const greeting = chat.config.greeting ?? 'How can I help?';
226
+ const description = chat.config.description;
227
+ const suggestions = chat.config.suggestions;
228
+
229
+ const headerNode = typeof slots.header === 'function'
230
+ ? slots.header(chat)
231
+ : slots.header;
232
+
233
+ const emptyNode = typeof slots.empty === 'function'
234
+ ? slots.empty({ setValue: composer.setValue, focus: composer.focus })
235
+ : (slots.empty ?? (
236
+ <EmptyState
237
+ greeting={greeting}
238
+ description={description}
239
+ suggestions={suggestions}
240
+ onPickSuggestion={(prompt) => {
241
+ composer.setValue(prompt);
242
+ composer.focus();
243
+ }}
244
+ />
245
+ ));
246
+
247
+ // `appearance` scales the whole chat (bubbles + composer). Default
248
+ // `compact` keeps every embedded chat pixel-identical.
249
+ const appearance: ComposerAppearance = parts.appearance ?? 'compact';
250
+
251
+ const renderItem = messages.render
252
+ ?? ((m: ChatMessage) => (
253
+ <MessageBubble
254
+ key={m.id}
255
+ message={m}
256
+ appearance={appearance}
257
+ toolCallsProps={messages.toolCallsProps}
258
+ attachmentRenderers={messages.attachmentRenderers}
259
+ blockRegistry={messages.blockRegistry}
260
+ onAttachmentOpen={messages.onAttachmentOpen}
261
+ renderAfterMessage={messages.renderAfter}
262
+ onCopy={() => copy(m.content)}
263
+ onRegenerate={() => void chat.regenerate(m.id)}
264
+ onDelete={() => chat.deleteMessage(m.id)}
265
+ />
266
+ ));
267
+
268
+ return (
269
+ <div className={cn('relative flex h-full min-h-0 flex-col overflow-hidden', className)}>
270
+ {slots.banner ?? null}
271
+ {headerNode ?? null}
272
+ <div className="relative flex min-h-0 flex-1 flex-col" onMouseUp={onMessagesMouseUp}>
273
+ <ErrorBanner
274
+ error={chat.error}
275
+ onDismiss={chat.error ? () => chat.clearMessages() : undefined}
276
+ onRetry={chat.error ? () => void chat.regenerate() : undefined}
277
+ />
278
+ <MessageList
279
+ ref={listRef}
280
+ renderItem={renderItem}
281
+ appearance={appearance}
282
+ renderEmpty={() => <>{emptyNode}</>}
283
+ className={listClassName}
284
+ onStartReached={handleStartReached}
285
+ onAtBottomChange={setIsAtBottom}
286
+ scrollAnchorId={lastUserMessageId}
287
+ />
288
+ <div className="pointer-events-none absolute inset-x-0 bottom-2 flex justify-center">
289
+ {slots.jumpToLatest ?? (
290
+ <JumpToLatest
291
+ visible={!isAtBottom}
292
+ onClick={() => listRef.current?.scrollToBottom(true)}
293
+ />
294
+ )}
295
+ </div>
296
+ </div>
297
+ {!composerConfig.hidden && (
298
+ composerConfig.render
299
+ ? composerConfig.render({ composer, config: composerConfig })
300
+ : (
301
+ <Composer
302
+ composer={composer}
303
+ placeholder={chat.config.placeholder}
304
+ showAttachmentButton={composerConfig.showAttachmentButton}
305
+ onPickFiles={composerConfig.onPickFiles}
306
+ size={composerConfig.size}
307
+ appearance={appearance}
308
+ layout={composerConfig.layout}
309
+ className={composerConfig.className}
310
+ composerSlots={composerConfig.slots}
311
+ footer={composerConfig.footer ?? {}}
312
+ />
313
+ )
314
+ )}
315
+ </div>
316
+ );
317
+ }
318
+
319
+ function copy(text: string) {
320
+ if (typeof navigator !== 'undefined' && navigator.clipboard) {
321
+ void navigator.clipboard.writeText(text);
322
+ }
323
+ }
324
+
325
+ // re-export for convenience: composer hook return is a common slot dependency
326
+ export type { UseChatComposerReturn };
@@ -24,7 +24,9 @@ export function EmptyState({
24
24
  <div className="grid size-10 place-items-center rounded-full bg-muted">
25
25
  <Sparkles aria-hidden className="size-5 text-muted-foreground" />
26
26
  </div>
27
- {greeting ? <h2 className="text-base font-semibold">{greeting}</h2> : null}
27
+ {greeting ? (
28
+ <h2 className="text-base font-semibold text-foreground">{greeting}</h2>
29
+ ) : null}
28
30
  {description ? (
29
31
  <p className="max-w-md text-sm text-muted-foreground">{description}</p>
30
32
  ) : null}
@@ -35,7 +37,7 @@ export function EmptyState({
35
37
  key={s.prompt}
36
38
  type="button"
37
39
  onClick={() => onPickSuggestion?.(s.prompt)}
38
- className="rounded-lg border border-border bg-background/60 px-3 py-2 text-left text-xs hover:bg-accent"
40
+ className="rounded-lg border border-border bg-background/60 px-3 py-2 text-left text-xs text-foreground hover:bg-accent hover:text-accent-foreground"
39
41
  >
40
42
  {s.label}
41
43
  </button>
@@ -0,0 +1,15 @@
1
+ 'use client';
2
+
3
+ /** Shell — composition-root pieces (ChatRoot preset, empty / error states). */
4
+
5
+ export {
6
+ ChatRoot,
7
+ type ChatRootProps,
8
+ type ChatComposerConfig,
9
+ type ChatComposerRenderApi,
10
+ type ChatSlots,
11
+ type ChatMessagesConfig,
12
+ type ChatEmptyApi,
13
+ } from './ChatRoot';
14
+ export { EmptyState, type EmptyStateProps } from './EmptyState';
15
+ export { ErrorBanner, type ErrorBannerProps } from './ErrorBanner';
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Message blocks — typed, serializable rich-content slots.
3
+ *
4
+ * A `ChatMessage` may carry `blocks: MessageBlock[]`. Each block is a
5
+ * discriminated union member keyed by `kind`. Payloads are plain JSON
6
+ * (no Date, no Float32Array, no React nodes) so blocks survive history
7
+ * persistence and SSE transport. See `@docs/message-blocks.md`.
8
+ */
9
+
10
+ /** Spaciousness hint forwarded from the bubble to renderers. */
11
+ export type BlockAppearance = 'compact' | 'full';
12
+
13
+ interface BlockBase {
14
+ /** Stable id — used as React key and for memo diffing. */
15
+ id: string;
16
+ /** Optional caption rendered above the block. */
17
+ caption?: string;
18
+ }
19
+
20
+ export interface TextBlock extends BlockBase {
21
+ kind: 'text';
22
+ text: string;
23
+ }
24
+
25
+ export interface MarkdownBlock extends BlockBase {
26
+ kind: 'markdown';
27
+ markdown: string;
28
+ }
29
+
30
+ export interface AudioBlock extends BlockBase {
31
+ kind: 'audio';
32
+ src: string;
33
+ title?: string;
34
+ artist?: string;
35
+ cover?: string;
36
+ /** `compact` → AudioPlayer variant. */
37
+ variant?: 'default' | 'compact';
38
+ }
39
+
40
+ export interface VideoBlock extends BlockBase {
41
+ kind: 'video';
42
+ /** Raw URL string — VideoPlayer auto-classifies YouTube/Vimeo/HLS/MP4. */
43
+ src: string;
44
+ poster?: string;
45
+ title?: string;
46
+ aspectRatio?: number | 'auto' | 'fill';
47
+ }
48
+
49
+ export interface ImageBlock extends BlockBase {
50
+ kind: 'image';
51
+ src: string;
52
+ alt?: string;
53
+ /** When true → zoom/pan ImageViewer; else a plain `<img>`. */
54
+ interactive?: boolean;
55
+ }
56
+
57
+ export interface GalleryBlock extends BlockBase {
58
+ kind: 'gallery';
59
+ items: Array<{ id: string; src: string; thumbnail?: string; alt?: string }>;
60
+ }
61
+
62
+ export interface MapBlock extends BlockBase {
63
+ kind: 'map';
64
+ center: { lat: number; lng: number };
65
+ zoom?: number;
66
+ markers?: Array<{ id: string; lat: number; lng: number; label?: string }>;
67
+ }
68
+
69
+ export interface JsonBlock extends BlockBase {
70
+ kind: 'json';
71
+ data: unknown;
72
+ /** JsonTree display mode. */
73
+ mode?: 'full' | 'compact' | 'inline';
74
+ }
75
+
76
+ export interface MermaidBlock extends BlockBase {
77
+ kind: 'mermaid';
78
+ chart: string;
79
+ }
80
+
81
+ export interface CodeBlock extends BlockBase {
82
+ kind: 'code';
83
+ code: string;
84
+ language: string;
85
+ }
86
+
87
+ export interface LottieBlock extends BlockBase {
88
+ kind: 'lottie';
89
+ /** Animation JSON URL or inline animationData object. */
90
+ src: string;
91
+ }
92
+
93
+ /**
94
+ * Escape hatch for host-defined block types. The built-in registry
95
+ * renders it as the unknown-kind fallback unless the host registers a
96
+ * `custom` renderer that switches on `name`.
97
+ */
98
+ export interface CustomBlock extends BlockBase {
99
+ kind: 'custom';
100
+ /** Host-defined sub-type, dispatched by the host's own renderer. */
101
+ name: string;
102
+ payload: unknown;
103
+ }
104
+
105
+ export type MessageBlock =
106
+ | TextBlock
107
+ | MarkdownBlock
108
+ | AudioBlock
109
+ | VideoBlock
110
+ | ImageBlock
111
+ | GalleryBlock
112
+ | MapBlock
113
+ | JsonBlock
114
+ | MermaidBlock
115
+ | CodeBlock
116
+ | LottieBlock
117
+ | CustomBlock;
118
+
119
+ /** The discriminant literal — `'audio' | 'video' | …`. */
120
+ export type MessageBlockKind = MessageBlock['kind'];