@nadicodeai/ui 0.20.0 → 0.22.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 (350) hide show
  1. package/AGENTS.md +4 -3
  2. package/README.md +14 -21
  3. package/dist/agents.d.ts +10 -0
  4. package/dist/agents.d.ts.map +1 -0
  5. package/dist/agents.js +9 -0
  6. package/dist/components/badge.d.ts +1 -1
  7. package/dist/components/brand-icons/apple.d.ts +18 -0
  8. package/dist/components/brand-icons/apple.d.ts.map +1 -0
  9. package/dist/components/brand-icons/apple.js +22 -0
  10. package/dist/components/brand-icons/brand-icon.d.ts +22 -0
  11. package/dist/components/brand-icons/brand-icon.d.ts.map +1 -0
  12. package/dist/components/brand-icons/brand-icon.js +26 -0
  13. package/dist/components/brand-icons/linux.d.ts +18 -0
  14. package/dist/components/brand-icons/linux.d.ts.map +1 -0
  15. package/dist/components/brand-icons/linux.js +25 -0
  16. package/dist/components/brand-icons/windows.d.ts +18 -0
  17. package/dist/components/brand-icons/windows.d.ts.map +1 -0
  18. package/dist/components/brand-icons/windows.js +22 -0
  19. package/dist/components/brand-icons.d.ts +5 -0
  20. package/dist/components/brand-icons.d.ts.map +1 -0
  21. package/dist/components/brand-icons.js +10 -0
  22. package/dist/components/button.d.ts +1 -1
  23. package/dist/components/button.js +1 -1
  24. package/dist/components/card-marketing.js +2 -2
  25. package/dist/components/card.d.ts +4 -3
  26. package/dist/components/card.d.ts.map +1 -1
  27. package/dist/components/card.js +12 -2
  28. package/dist/components/chart-breakdown-table.js +1 -1
  29. package/dist/components/chart-bullet-bar.d.ts +18 -2
  30. package/dist/components/chart-bullet-bar.d.ts.map +1 -1
  31. package/dist/components/chart-bullet-bar.js +62 -9
  32. package/dist/components/chart-date-range-control.d.ts +11 -1
  33. package/dist/components/chart-date-range-control.d.ts.map +1 -1
  34. package/dist/components/chart-date-range-control.js +13 -3
  35. package/dist/components/chart-entity-colors.d.ts +7 -1
  36. package/dist/components/chart-entity-colors.d.ts.map +1 -1
  37. package/dist/components/chart-entity-colors.js +7 -1
  38. package/dist/components/chart-kpi-stat.d.ts.map +1 -1
  39. package/dist/components/chart-kpi-stat.js +1 -1
  40. package/dist/components/chart-time-series.d.ts.map +1 -1
  41. package/dist/components/chart-time-series.js +62 -4
  42. package/dist/components/chart.js +2 -2
  43. package/dist/components/code-editor-mockup.js +1 -1
  44. package/dist/components/nav-bar.js +1 -1
  45. package/dist/components/radio-group.d.ts +1 -1
  46. package/dist/components/radio-group.d.ts.map +1 -1
  47. package/dist/components/radio-group.js +2 -2
  48. package/dist/components/theme-mode-switcher.d.ts +10 -3
  49. package/dist/components/theme-mode-switcher.d.ts.map +1 -1
  50. package/dist/components/theme-mode-switcher.js +14 -7
  51. package/dist/components/use-case-bento.d.ts +2 -4
  52. package/dist/components/use-case-bento.d.ts.map +1 -1
  53. package/dist/components/use-case-bento.js +2 -3
  54. package/dist/eslint/index.js +91 -0
  55. package/dist/eslint/rules/jsx-class-utility.js +231 -0
  56. package/dist/eslint/rules/no-deprecated-zod-api.js +156 -0
  57. package/dist/eslint/rules/no-design-system-src-import.js +11 -0
  58. package/dist/eslint/rules/no-invalid-token-utility.js +46 -0
  59. package/dist/eslint/rules/no-native-visible-control.js +86 -0
  60. package/dist/eslint/rules/no-raw-color-utility.js +109 -0
  61. package/dist/eslint/rules/no-raw-focus-ring-width.js +30 -0
  62. package/dist/eslint/rules/no-raw-logo-import.js +41 -0
  63. package/dist/eslint/rules/no-shadcn-appearance-override.js +191 -0
  64. package/dist/eslint/rules/no-token-category-bypass.js +53 -0
  65. package/dist/eslint/rules/no-ui-src-import.js +10 -0
  66. package/dist/eslint/rules/no-unpinned-vercel-functions-import.js +100 -0
  67. package/dist/eslint/rules/src-import-boundary.js +207 -0
  68. package/dist/hooks/index.d.ts +0 -1
  69. package/dist/hooks/index.d.ts.map +1 -1
  70. package/dist/hooks/index.js +0 -1
  71. package/dist/index.d.ts +1 -16
  72. package/dist/index.d.ts.map +1 -1
  73. package/dist/index.js +1 -16
  74. package/dist/internal/assistant-ui/attachment.d.ts +5 -0
  75. package/dist/internal/assistant-ui/attachment.d.ts.map +1 -0
  76. package/dist/internal/assistant-ui/attachment.js +93 -0
  77. package/dist/internal/assistant-ui/follow-up-suggestions.d.ts +3 -0
  78. package/dist/internal/assistant-ui/follow-up-suggestions.d.ts.map +1 -0
  79. package/dist/internal/assistant-ui/follow-up-suggestions.js +8 -0
  80. package/dist/internal/assistant-ui/markdown-text.d.ts +2 -0
  81. package/dist/internal/assistant-ui/markdown-text.d.ts.map +1 -0
  82. package/dist/internal/assistant-ui/markdown-text.js +54 -0
  83. package/dist/internal/assistant-ui/reasoning.d.ts +31 -0
  84. package/dist/internal/assistant-ui/reasoning.d.ts.map +1 -0
  85. package/dist/internal/assistant-ui/reasoning.js +118 -0
  86. package/dist/internal/assistant-ui/thread.d.ts +26 -0
  87. package/dist/internal/assistant-ui/thread.d.ts.map +1 -0
  88. package/dist/internal/assistant-ui/thread.js +118 -0
  89. package/dist/internal/assistant-ui/tool-fallback.d.ts +10 -0
  90. package/dist/internal/assistant-ui/tool-fallback.d.ts.map +1 -0
  91. package/dist/internal/assistant-ui/tool-fallback.js +163 -0
  92. package/dist/internal/assistant-ui/tool-group.d.ts +18 -0
  93. package/dist/internal/assistant-ui/tool-group.d.ts.map +1 -0
  94. package/dist/internal/assistant-ui/tool-group.js +44 -0
  95. package/dist/internal/assistant-ui/tooltip-icon-button.d.ts +8 -0
  96. package/dist/internal/assistant-ui/tooltip-icon-button.d.ts.map +1 -0
  97. package/dist/internal/assistant-ui/tooltip-icon-button.js +10 -0
  98. package/dist/styles/globals.css +3 -209
  99. package/docs/agents/nadicodeai-ui.md +4 -6
  100. package/docs/component-classification.md +1 -1
  101. package/docs/consuming-cross-repo.md +32 -3
  102. package/docs/contract.md +16 -6
  103. package/docs/migration/base-ui-migration.md +0 -11
  104. package/docs/product-compositions.md +1 -1
  105. package/llms.txt +5 -6
  106. package/package.json +17 -29
  107. package/skills/nadicodeai-ui/SKILL.md +5 -7
  108. package/dist/ai-elements.d.ts +0 -49
  109. package/dist/ai-elements.d.ts.map +0 -1
  110. package/dist/ai-elements.js +0 -48
  111. package/dist/components/agent-avatar.d.ts +0 -7
  112. package/dist/components/agent-avatar.d.ts.map +0 -1
  113. package/dist/components/agent-avatar.js +0 -6
  114. package/dist/components/agent-chat.d.ts +0 -20
  115. package/dist/components/agent-chat.d.ts.map +0 -1
  116. package/dist/components/agent-chat.js +0 -10
  117. package/dist/components/agent-composer.d.ts +0 -56
  118. package/dist/components/agent-composer.d.ts.map +0 -1
  119. package/dist/components/agent-composer.js +0 -56
  120. package/dist/components/agent-message.d.ts +0 -117
  121. package/dist/components/agent-message.d.ts.map +0 -1
  122. package/dist/components/agent-message.js +0 -99
  123. package/dist/components/agent-thread.d.ts +0 -26
  124. package/dist/components/agent-thread.d.ts.map +0 -1
  125. package/dist/components/agent-thread.js +0 -63
  126. package/dist/components/agent-tool-approval.d.ts +0 -27
  127. package/dist/components/agent-tool-approval.d.ts.map +0 -1
  128. package/dist/components/agent-tool-approval.js +0 -43
  129. package/dist/components/ai-elements/agent.d.ts +0 -27
  130. package/dist/components/ai-elements/agent.d.ts.map +0 -1
  131. package/dist/components/ai-elements/agent.js +0 -25
  132. package/dist/components/ai-elements/artifact.d.ts +0 -24
  133. package/dist/components/ai-elements/artifact.d.ts.map +0 -1
  134. package/dist/components/ai-elements/artifact.js +0 -20
  135. package/dist/components/ai-elements/attachments.d.ts +0 -55
  136. package/dist/components/ai-elements/attachments.d.ts.map +0 -1
  137. package/dist/components/ai-elements/attachments.js +0 -125
  138. package/dist/components/ai-elements/audio-player.d.ts +0 -30
  139. package/dist/components/ai-elements/audio-player.d.ts.map +0 -1
  140. package/dist/components/ai-elements/audio-player.js +0 -41
  141. package/dist/components/ai-elements/canvas.d.ts +0 -8
  142. package/dist/components/ai-elements/canvas.d.ts.map +0 -1
  143. package/dist/components/ai-elements/canvas.js +0 -5
  144. package/dist/components/ai-elements/chain-of-thought.d.ts +0 -30
  145. package/dist/components/ai-elements/chain-of-thought.d.ts.map +0 -1
  146. package/dist/components/ai-elements/chain-of-thought.js +0 -49
  147. package/dist/components/ai-elements/checkpoint.d.ts +0 -12
  148. package/dist/components/ai-elements/checkpoint.d.ts.map +0 -1
  149. package/dist/components/ai-elements/checkpoint.js +0 -10
  150. package/dist/components/ai-elements/code-block.d.ts +0 -53
  151. package/dist/components/ai-elements/code-block.d.ts.map +0 -1
  152. package/dist/components/ai-elements/code-block.js +0 -239
  153. package/dist/components/ai-elements/commit.d.ts +0 -65
  154. package/dist/components/ai-elements/commit.d.ts.map +0 -1
  155. package/dist/components/ai-elements/commit.js +0 -83
  156. package/dist/components/ai-elements/confirmation.d.ts +0 -50
  157. package/dist/components/ai-elements/confirmation.d.ts.map +0 -1
  158. package/dist/components/ai-elements/confirmation.js +0 -57
  159. package/dist/components/ai-elements/connection.d.ts +0 -6
  160. package/dist/components/ai-elements/connection.d.ts.map +0 -1
  161. package/dist/components/ai-elements/connection.js +0 -10
  162. package/dist/components/ai-elements/context.d.ts +0 -33
  163. package/dist/components/ai-elements/context.d.ts.map +0 -1
  164. package/dist/components/ai-elements/context.js +0 -147
  165. package/dist/components/ai-elements/controls.d.ts +0 -5
  166. package/dist/components/ai-elements/controls.d.ts.map +0 -1
  167. package/dist/components/ai-elements/controls.js +0 -5
  168. package/dist/components/ai-elements/conversation.d.ts +0 -24
  169. package/dist/components/ai-elements/conversation.d.ts.map +0 -1
  170. package/dist/components/ai-elements/conversation.js +0 -41
  171. package/dist/components/ai-elements/edge.d.ts +0 -6
  172. package/dist/components/ai-elements/edge.d.ts.map +0 -1
  173. package/dist/components/ai-elements/edge.js +0 -88
  174. package/dist/components/ai-elements/environment-variables.d.ts +0 -39
  175. package/dist/components/ai-elements/environment-variables.d.ts.map +0 -1
  176. package/dist/components/ai-elements/environment-variables.js +0 -60
  177. package/dist/components/ai-elements/file-tree.d.ts +0 -27
  178. package/dist/components/ai-elements/file-tree.d.ts.map +0 -1
  179. package/dist/components/ai-elements/file-tree.js +0 -73
  180. package/dist/components/ai-elements/image.d.ts +0 -7
  181. package/dist/components/ai-elements/image.d.ts.map +0 -1
  182. package/dist/components/ai-elements/image.js +0 -3
  183. package/dist/components/ai-elements/inline-citation.d.ts +0 -39
  184. package/dist/components/ai-elements/inline-citation.d.ts.map +0 -1
  185. package/dist/components/ai-elements/inline-citation.js +0 -86
  186. package/dist/components/ai-elements/jsx-preview.d.ts +0 -30
  187. package/dist/components/ai-elements/jsx-preview.d.ts.map +0 -1
  188. package/dist/components/ai-elements/jsx-preview.js +0 -159
  189. package/dist/components/ai-elements/message.d.ts +0 -38
  190. package/dist/components/ai-elements/message.d.ts.map +0 -1
  191. package/dist/components/ai-elements/message.js +0 -91
  192. package/dist/components/ai-elements/mic-selector.d.ts +0 -46
  193. package/dist/components/ai-elements/mic-selector.d.ts.map +0 -1
  194. package/dist/components/ai-elements/mic-selector.js +0 -180
  195. package/dist/components/ai-elements/model-selector.d.ts +0 -36
  196. package/dist/components/ai-elements/model-selector.d.ts.map +0 -1
  197. package/dist/components/ai-elements/model-selector.js +0 -18
  198. package/dist/components/ai-elements/node.d.ts +0 -22
  199. package/dist/components/ai-elements/node.d.ts.map +0 -1
  200. package/dist/components/ai-elements/node.js +0 -12
  201. package/dist/components/ai-elements/open-in-chat.d.ts +0 -27
  202. package/dist/components/ai-elements/open-in-chat.d.ts.map +0 -1
  203. package/dist/components/ai-elements/open-in-chat.js +0 -81
  204. package/dist/components/ai-elements/package-info.d.ts +0 -30
  205. package/dist/components/ai-elements/package-info.d.ts.map +0 -1
  206. package/dist/components/ai-elements/package-info.js +0 -50
  207. package/dist/components/ai-elements/panel.d.ts +0 -6
  208. package/dist/components/ai-elements/panel.d.ts.map +0 -1
  209. package/dist/components/ai-elements/panel.js +0 -5
  210. package/dist/components/ai-elements/persona.d.ts +0 -49
  211. package/dist/components/ai-elements/persona.d.ts.map +0 -1
  212. package/dist/components/ai-elements/persona.js +0 -175
  213. package/dist/components/ai-elements/plan.d.ts +0 -27
  214. package/dist/components/ai-elements/plan.d.ts.map +0 -1
  215. package/dist/components/ai-elements/plan.js +0 -34
  216. package/dist/components/ai-elements/prompt-input.d.ts +0 -149
  217. package/dist/components/ai-elements/prompt-input.d.ts.map +0 -1
  218. package/dist/components/ai-elements/prompt-input.js +0 -704
  219. package/dist/components/ai-elements/queue.d.ts +0 -62
  220. package/dist/components/ai-elements/queue.d.ts.map +0 -1
  221. package/dist/components/ai-elements/queue.js +0 -24
  222. package/dist/components/ai-elements/reasoning.d.ts +0 -27
  223. package/dist/components/ai-elements/reasoning.d.ts.map +0 -1
  224. package/dist/components/ai-elements/reasoning.js +0 -92
  225. package/dist/components/ai-elements/sandbox.d.ts +0 -25
  226. package/dist/components/ai-elements/sandbox.d.ts.map +0 -1
  227. package/dist/components/ai-elements/sandbox.js +0 -15
  228. package/dist/components/ai-elements/schema-display.d.ts +0 -56
  229. package/dist/components/ai-elements/schema-display.d.ts.map +0 -1
  230. package/dist/components/ai-elements/schema-display.js +0 -90
  231. package/dist/components/ai-elements/shimmer.d.ts +0 -10
  232. package/dist/components/ai-elements/shimmer.d.ts.map +0 -1
  233. package/dist/components/ai-elements/shimmer.js +0 -11
  234. package/dist/components/ai-elements/snippet.d.ts +0 -19
  235. package/dist/components/ai-elements/snippet.d.ts.map +0 -1
  236. package/dist/components/ai-elements/snippet.js +0 -32
  237. package/dist/components/ai-elements/sources.d.ts +0 -13
  238. package/dist/components/ai-elements/sources.d.ts.map +0 -1
  239. package/dist/components/ai-elements/sources.js +0 -9
  240. package/dist/components/ai-elements/speech-input.d.ts +0 -55
  241. package/dist/components/ai-elements/speech-input.d.ts.map +0 -1
  242. package/dist/components/ai-elements/speech-input.js +0 -187
  243. package/dist/components/ai-elements/stack-trace.d.ts +0 -38
  244. package/dist/components/ai-elements/stack-trace.d.ts.map +0 -1
  245. package/dist/components/ai-elements/stack-trace.js +0 -181
  246. package/dist/components/ai-elements/suggestion.d.ts +0 -11
  247. package/dist/components/ai-elements/suggestion.d.ts.map +0 -1
  248. package/dist/components/ai-elements/suggestion.js +0 -13
  249. package/dist/components/ai-elements/task.d.ts +0 -15
  250. package/dist/components/ai-elements/task.d.ts.map +0 -1
  251. package/dist/components/ai-elements/task.js +0 -10
  252. package/dist/components/ai-elements/terminal.d.ts +0 -28
  253. package/dist/components/ai-elements/terminal.d.ts.map +0 -1
  254. package/dist/components/ai-elements/terminal.js +0 -55
  255. package/dist/components/ai-elements/test-results.d.ts +0 -59
  256. package/dist/components/ai-elements/test-results.d.ts.map +0 -1
  257. package/dist/components/ai-elements/test-results.js +0 -98
  258. package/dist/components/ai-elements/tool.d.ts +0 -32
  259. package/dist/components/ai-elements/tool.d.ts.map +0 -1
  260. package/dist/components/ai-elements/tool.js +0 -49
  261. package/dist/components/ai-elements/toolbar.d.ts +0 -6
  262. package/dist/components/ai-elements/toolbar.d.ts.map +0 -1
  263. package/dist/components/ai-elements/toolbar.js +0 -5
  264. package/dist/components/ai-elements/transcription.d.ts +0 -17
  265. package/dist/components/ai-elements/transcription.d.ts.map +0 -1
  266. package/dist/components/ai-elements/transcription.js +0 -36
  267. package/dist/components/ai-elements/voice-selector.d.ts +0 -65
  268. package/dist/components/ai-elements/voice-selector.d.ts.map +0 -1
  269. package/dist/components/ai-elements/voice-selector.js +0 -224
  270. package/dist/components/ai-elements/web-preview.d.ts +0 -35
  271. package/dist/components/ai-elements/web-preview.d.ts.map +0 -1
  272. package/dist/components/ai-elements/web-preview.js +0 -66
  273. package/dist/components/artifact-panel.d.ts +0 -130
  274. package/dist/components/artifact-panel.d.ts.map +0 -1
  275. package/dist/components/artifact-panel.js +0 -180
  276. package/dist/components/attachment.d.ts +0 -24
  277. package/dist/components/attachment.d.ts.map +0 -1
  278. package/dist/components/attachment.js +0 -68
  279. package/dist/components/bubble.d.ts +0 -17
  280. package/dist/components/bubble.d.ts.map +0 -1
  281. package/dist/components/bubble.js +0 -59
  282. package/dist/components/demo-surface.d.ts +0 -34
  283. package/dist/components/demo-surface.d.ts.map +0 -1
  284. package/dist/components/demo-surface.js +0 -21
  285. package/dist/components/files-preview.d.ts +0 -36
  286. package/dist/components/files-preview.d.ts.map +0 -1
  287. package/dist/components/files-preview.js +0 -85
  288. package/dist/components/marker.d.ts +0 -11
  289. package/dist/components/marker.d.ts.map +0 -1
  290. package/dist/components/marker.js +0 -34
  291. package/dist/components/message-scroller.d.ts +0 -17
  292. package/dist/components/message-scroller.d.ts.map +0 -1
  293. package/dist/components/message-scroller.js +0 -29
  294. package/dist/components/message.d.ts +0 -11
  295. package/dist/components/message.d.ts.map +0 -1
  296. package/dist/components/message.js +0 -21
  297. package/dist/components/state-notice.d.ts +0 -13
  298. package/dist/components/state-notice.d.ts.map +0 -1
  299. package/dist/components/state-notice.js +0 -8
  300. package/dist/components/watch-it-work-band.d.ts +0 -12
  301. package/dist/components/watch-it-work-band.d.ts.map +0 -1
  302. package/dist/components/watch-it-work-band.js +0 -8
  303. package/dist/hooks/use-controllable-state.d.ts +0 -9
  304. package/dist/hooks/use-controllable-state.d.ts.map +0 -1
  305. package/dist/hooks/use-controllable-state.js +0 -23
  306. package/dist/lib/agent-attachment.d.ts +0 -11
  307. package/dist/lib/agent-attachment.d.ts.map +0 -1
  308. package/dist/lib/agent-attachment.js +0 -19
  309. package/dist/lib/agent-contracts.d.ts +0 -132
  310. package/dist/lib/agent-contracts.d.ts.map +0 -1
  311. package/dist/lib/agent-contracts.js +0 -6
  312. package/dist/lib/agent-state.d.ts +0 -22
  313. package/dist/lib/agent-state.d.ts.map +0 -1
  314. package/dist/lib/agent-state.js +0 -96
  315. package/dist/lib/agent-work-state.d.ts +0 -36
  316. package/dist/lib/agent-work-state.d.ts.map +0 -1
  317. package/dist/lib/agent-work-state.js +0 -36
  318. package/dist/lib/message-scroller-primitive/components.d.ts +0 -17
  319. package/dist/lib/message-scroller-primitive/components.d.ts.map +0 -1
  320. package/dist/lib/message-scroller-primitive/components.js +0 -204
  321. package/dist/lib/message-scroller-primitive/geometry.d.ts +0 -51
  322. package/dist/lib/message-scroller-primitive/geometry.d.ts.map +0 -1
  323. package/dist/lib/message-scroller-primitive/geometry.js +0 -199
  324. package/dist/lib/message-scroller-primitive/index.d.ts +0 -12
  325. package/dist/lib/message-scroller-primitive/index.d.ts.map +0 -1
  326. package/dist/lib/message-scroller-primitive/index.js +0 -12
  327. package/dist/lib/message-scroller-primitive/stores.d.ts +0 -6
  328. package/dist/lib/message-scroller-primitive/stores.d.ts.map +0 -1
  329. package/dist/lib/message-scroller-primitive/stores.js +0 -53
  330. package/dist/lib/message-scroller-primitive/types.d.ts +0 -88
  331. package/dist/lib/message-scroller-primitive/types.d.ts.map +0 -1
  332. package/dist/lib/message-scroller-primitive/types.js +0 -40
  333. package/dist/lib/message-scroller-primitive/use-message-scroller-commands.d.ts +0 -19
  334. package/dist/lib/message-scroller-primitive/use-message-scroller-commands.d.ts.map +0 -1
  335. package/dist/lib/message-scroller-primitive/use-message-scroller-commands.js +0 -188
  336. package/dist/lib/message-scroller-primitive/use-message-scroller-controller.d.ts +0 -7
  337. package/dist/lib/message-scroller-primitive/use-message-scroller-controller.d.ts.map +0 -1
  338. package/dist/lib/message-scroller-primitive/use-message-scroller-controller.js +0 -506
  339. package/dist/lib/message-scroller-primitive/use-message-scroller-refs.d.ts +0 -49
  340. package/dist/lib/message-scroller-primitive/use-message-scroller-refs.d.ts.map +0 -1
  341. package/dist/lib/message-scroller-primitive/use-message-scroller-refs.js +0 -90
  342. package/dist/lib/message-scroller-primitive/use-render.d.ts +0 -22
  343. package/dist/lib/message-scroller-primitive/use-render.d.ts.map +0 -1
  344. package/dist/lib/message-scroller-primitive/use-render.js +0 -113
  345. package/dist/lib/message-scroller-primitive/utils.d.ts +0 -4
  346. package/dist/lib/message-scroller-primitive/utils.d.ts.map +0 -1
  347. package/dist/lib/message-scroller-primitive/utils.js +0 -9
  348. package/docs/agent-work-surfaces.md +0 -132
  349. package/docs/migration/ai-elements-vendoring.md +0 -29
  350. package/docs/terminal-tui-semantics.md +0 -172
@@ -1,506 +0,0 @@
1
- // Vendored from @shadcn/react 0.2.1 (upstream github.com/shadcn-ui).
2
- // Adapted only for repo import paths and formatting; not added as an npm dependency.
3
- import * as React from "react";
4
- import { getContentBottom, getElementTop, getElementViewportTop, getFirstVisibleMessageItem, getFlexGap, getLastScrollAnchor, getMessageScrollerItems, getMessageScrollerScrollable, getMessageScrollerVisibilityState, getNewScrollAnchor, getUnanchoredScrollAnchor, hasMultipleNewScrollAnchors, } from "./geometry.js";
5
- import { DEFAULT_SCROLL_EDGE_THRESHOLD, DEFAULT_SCROLL_MARGIN, DEFAULT_SCROLL_PREVIOUS_ITEM_PEEK, EMPTY_MESSAGE_SCROLLER_VISIBILITY_STATE, SCROLL_POSITION_EPSILON, } from "./types.js";
6
- import { useMessageScrollerCommands } from "./use-message-scroller-commands.js";
7
- import { useMessageScrollerRefs } from "./use-message-scroller-refs.js";
8
- // Builds a ref callback that stores the node and runs onMount once it attaches.
9
- function useElementRef(elementRef, onMount) {
10
- return React.useCallback((element) => {
11
- elementRef.current = element;
12
- if (element) {
13
- onMount();
14
- }
15
- }, [elementRef, onMount]);
16
- }
17
- // Orchestrator hook. Decides when to scroll and delegates the moves to
18
- // useMessageScrollerCommands; state and visibility commits are coalesced on a
19
- // requestAnimationFrame and torn down on cleanup for StrictMode safety.
20
- function useMessageScrollerController({ autoScroll = false, defaultScrollPosition = "end", scrollEdgeThreshold = DEFAULT_SCROLL_EDGE_THRESHOLD, scrollPreviousItemPeek = DEFAULT_SCROLL_PREVIOUS_ITEM_PEEK, scrollMargin = DEFAULT_SCROLL_MARGIN, }) {
21
- const refs = useMessageScrollerRefs({
22
- autoScroll,
23
- scrollEdgeThreshold,
24
- scrollMargin,
25
- scrollPreviousItemPeek,
26
- });
27
- const { streamingTurnRef, autoScrollRef, autoscrollingRef, autoscrollingTimeoutRef, contentRef, defaultScrollPositionAppliedRef, firstItemRef, itemCountRef, lastScrollTopRef, messageElementsRef, modeRef, pendingScrollFrameRef, pendingScrollToMessageRef, prependRestoreRef, preserveScrollOnPrependRef, rootRef, scrollEdgeThresholdRef, scrollMarginRef, scrollPreviousItemPeekRef, spacerGapRef, spacerHeightRef, spacerRef, stateFrameRef, stateStore, viewportRef, visibilityFrameRef, visibilityObserverRef, visibilityStore, visibleMessageIdsRef, handledScrollAnchorsRef, } = refs;
28
- const previousDefaultScrollPositionRef = React.useRef(defaultScrollPosition);
29
- if (previousDefaultScrollPositionRef.current !== defaultScrollPosition) {
30
- previousDefaultScrollPositionRef.current = defaultScrollPosition;
31
- defaultScrollPositionAppliedRef.current = false;
32
- }
33
- const writeStateAttributes = React.useCallback((state) => {
34
- const root = rootRef.current;
35
- const viewport = viewportRef.current;
36
- const scrollable = [state.start && "start", state.end && "end"].filter(Boolean).join(" ");
37
- const autoScrolling = autoscrollingRef.current;
38
- for (const element of [root, viewport]) {
39
- if (!element) {
40
- continue;
41
- }
42
- if (scrollable) {
43
- element.setAttribute("data-scrollable", scrollable);
44
- }
45
- else {
46
- element.removeAttribute("data-scrollable");
47
- }
48
- element.toggleAttribute("data-autoscrolling", autoScrolling);
49
- }
50
- }, []);
51
- // Owns the one follow-bottom transition: arm at the bottom, release on any
52
- // scroll away (including a scrollbar drag), suppressed during a programmatic
53
- // scroll so the auto-scroll animation cannot release itself. Arming also
54
- // skips the anchored-to-message hold: the tail spacer makes a freshly
55
- // anchored turn read as "at the end", and re-arming there would let the
56
- // first streamed chunk yank the reader off the anchor. The hold hands back
57
- // to following in handleResize, once the reply consumes the tail spacer.
58
- const reconcileFollowMode = React.useCallback((scrollable) => {
59
- const scrollTop = viewportRef.current?.scrollTop ?? 0;
60
- // Content growing past the live edge also reads as "not at the end", but
61
- // only a scrollbar drag moves scrollTop up. Growth must not release
62
- // follow-output: the resize handler is coalesced onto a frame, so a state
63
- // commit can observe the grown content before follow catches up.
64
- const scrolledUp = scrollTop < lastScrollTopRef.current - SCROLL_POSITION_EPSILON;
65
- lastScrollTopRef.current = scrollTop;
66
- if (autoScrollRef.current &&
67
- !scrollable.end &&
68
- modeRef.current !== "settling-jump" &&
69
- modeRef.current !== "anchored-to-message") {
70
- modeRef.current = "following-bottom";
71
- }
72
- else if (modeRef.current === "following-bottom" &&
73
- scrollable.end &&
74
- scrolledUp &&
75
- !autoscrollingRef.current) {
76
- modeRef.current = "free-scrolling";
77
- }
78
- }, []);
79
- const commitScrollState = React.useCallback(() => {
80
- const nextState = getMessageScrollerScrollable({
81
- content: contentRef.current,
82
- scrollEdgeThreshold: scrollEdgeThresholdRef.current,
83
- spacer: spacerRef.current,
84
- viewport: viewportRef.current,
85
- });
86
- reconcileFollowMode(nextState);
87
- // While follow-output is engaged the scroller is already closing any gap a
88
- // streamed chunk just opened, so publishing it as scrollable toward the
89
- // end would strobe the scroll button once per chunk. Reconcile runs on the
90
- // raw geometry first, so a commit that releases follow still publishes the
91
- // gap it released over.
92
- const publishedState = modeRef.current === "following-bottom" ? { ...nextState, end: false } : nextState;
93
- writeStateAttributes(publishedState);
94
- stateStore.setSnapshot(publishedState);
95
- }, [reconcileFollowMode, stateStore, writeStateAttributes]);
96
- const scheduleStateCommit = React.useCallback(() => {
97
- if (stateFrameRef.current !== null) {
98
- return;
99
- }
100
- stateFrameRef.current = window.requestAnimationFrame(() => {
101
- stateFrameRef.current = null;
102
- commitScrollState();
103
- });
104
- }, [commitScrollState]);
105
- const scheduleVisibilitySync = React.useCallback(() => {
106
- if (!visibilityStore.hasListeners()) {
107
- return;
108
- }
109
- if (visibilityFrameRef.current !== null) {
110
- return;
111
- }
112
- visibilityFrameRef.current = window.requestAnimationFrame(() => {
113
- visibilityFrameRef.current = null;
114
- // A frame can outlive the last unsubscribe. Recomputing here would
115
- // overwrite the EMPTY snapshot that teardown just wrote, leaving a stale
116
- // value for the next subscriber to read.
117
- if (!visibilityStore.hasListeners()) {
118
- return;
119
- }
120
- visibilityStore.setSnapshot(getMessageScrollerVisibilityState({
121
- content: contentRef.current,
122
- scrollMargin: scrollMarginRef.current,
123
- scrollPreviousItemPeek: scrollPreviousItemPeekRef.current,
124
- spacer: spacerRef.current,
125
- viewport: viewportRef.current,
126
- visibleMessageIds: visibleMessageIdsRef.current,
127
- }));
128
- });
129
- }, [visibilityStore]);
130
- const { flushPendingScrollToMessage, reanchorToAnchoredMessage, scrollToElement, scrollToEnd, scrollToMessage, scrollToStart, } = useMessageScrollerCommands({
131
- refs,
132
- commitScrollState,
133
- scheduleStateCommit,
134
- scheduleVisibilitySync,
135
- });
136
- const restorePrependedAnchor = React.useCallback(() => {
137
- const anchor = prependRestoreRef.current;
138
- const viewport = viewportRef.current;
139
- if (!anchor || !viewport || !anchor.element.isConnected) {
140
- return false;
141
- }
142
- // Compare the anchor relative to the viewport, not to the content. Native
143
- // scroll anchoring leaves the viewport-relative position unchanged, so this
144
- // is a no-op where the browser already handled the prepend and only corrects
145
- // the scroll where it did not (e.g. Safari) — without trusting a capability
146
- // flag, which some engines report incorrectly.
147
- const nextViewportTop = getElementViewportTop(anchor.element, viewport);
148
- const delta = nextViewportTop - anchor.viewportTop;
149
- if (Math.abs(delta) <= SCROLL_POSITION_EPSILON) {
150
- return false;
151
- }
152
- viewport.scrollTop += delta;
153
- anchor.viewportTop = getElementViewportTop(anchor.element, viewport);
154
- scheduleStateCommit();
155
- scheduleVisibilitySync();
156
- return true;
157
- }, [scheduleStateCommit, scheduleVisibilitySync]);
158
- const capturePrependAnchor = React.useCallback(() => {
159
- const content = contentRef.current;
160
- const viewport = viewportRef.current;
161
- if (!content || !viewport) {
162
- prependRestoreRef.current = null;
163
- return;
164
- }
165
- const anchor = getFirstVisibleMessageItem({
166
- content,
167
- spacer: spacerRef.current,
168
- viewport,
169
- });
170
- prependRestoreRef.current = anchor
171
- ? {
172
- element: anchor,
173
- viewportTop: getElementViewportTop(anchor, viewport),
174
- }
175
- : null;
176
- }, []);
177
- const schedulePendingScrollToMessageFlush = React.useCallback(() => {
178
- if (pendingScrollFrameRef.current !== null) {
179
- return;
180
- }
181
- pendingScrollFrameRef.current = window.requestAnimationFrame(() => {
182
- pendingScrollFrameRef.current = null;
183
- if (flushPendingScrollToMessage()) {
184
- capturePrependAnchor();
185
- }
186
- });
187
- }, [capturePrependAnchor, flushPendingScrollToMessage]);
188
- const applyDefaultScrollPosition = React.useCallback(() => {
189
- if (!defaultScrollPosition ||
190
- defaultScrollPositionAppliedRef.current ||
191
- itemCountRef.current === 0) {
192
- return false;
193
- }
194
- let handled = false;
195
- if (defaultScrollPosition === "last-anchor") {
196
- const content = contentRef.current;
197
- const viewport = viewportRef.current;
198
- const anchor = content && viewport
199
- ? getLastScrollAnchor(getMessageScrollerItems(content, spacerRef.current))
200
- : null;
201
- if (!content || !viewport || !anchor) {
202
- handled = scrollToEnd({ behavior: "auto" });
203
- }
204
- else {
205
- const anchorTop = getElementTop(anchor, viewport);
206
- const contentBottom = getContentBottom({
207
- content,
208
- spacer: spacerRef.current,
209
- viewport,
210
- });
211
- // A short last turn already fits below the anchor, so opening at the end
212
- // shows the whole turn without leaving a blank gap beneath it.
213
- const lastTurnFits = contentBottom - anchorTop <= viewport.clientHeight;
214
- handled = lastTurnFits
215
- ? scrollToEnd({ behavior: "auto" })
216
- : scrollToElement(anchor, { align: "start" }, { keepPreviousPeek: true });
217
- }
218
- }
219
- else {
220
- handled =
221
- defaultScrollPosition === "end"
222
- ? scrollToEnd({ behavior: "auto" })
223
- : scrollToStart({ behavior: "auto" });
224
- }
225
- if (!handled) {
226
- return false;
227
- }
228
- defaultScrollPositionAppliedRef.current = true;
229
- return true;
230
- }, [defaultScrollPosition, scrollToElement, scrollToEnd, scrollToStart]);
231
- const handleContentChange = React.useCallback(() => {
232
- const content = contentRef.current;
233
- if (!content) {
234
- return;
235
- }
236
- const items = getMessageScrollerItems(content, spacerRef.current);
237
- const previousItemCount = itemCountRef.current;
238
- const previousFirstItem = firstItemRef.current;
239
- itemCountRef.current = items.length;
240
- firstItemRef.current = items[0] ?? null;
241
- // Reconcile the scroll position with the new content. Every path re-captures
242
- // the prepend anchor afterward, so each branch just returns.
243
- //
244
- // Branch order is load-bearing: first-content, prepended, appended, updated.
245
- const reconcileScrollPosition = () => {
246
- if (flushPendingScrollToMessage()) {
247
- return;
248
- }
249
- if (previousItemCount === 0) {
250
- if (applyDefaultScrollPosition()) {
251
- return;
252
- }
253
- if (items.length > 0 && autoScrollRef.current && scrollToEnd({ behavior: "auto" })) {
254
- return;
255
- }
256
- commitScrollState();
257
- scheduleVisibilitySync();
258
- return;
259
- }
260
- const previousFirstItemIndex = previousFirstItem ? items.indexOf(previousFirstItem) : -1;
261
- const didPrepend = preserveScrollOnPrependRef.current && previousFirstItemIndex > 0;
262
- if (didPrepend) {
263
- // Prepended rows are not new appends. Restore the prior scroll position.
264
- // The restore is a no-op where native scroll anchoring already did it.
265
- restorePrependedAnchor();
266
- return;
267
- }
268
- if (items.length > previousItemCount) {
269
- const anchor = getNewScrollAnchor(items, previousItemCount);
270
- if (anchor) {
271
- // While the reader is following the live end, a batch of several
272
- // anchored turns arriving at once should keep following the end — not
273
- // yank back to anchor the first turn of the batch. A single new anchor
274
- // still moves to the top as usual.
275
- if (autoScrollRef.current &&
276
- modeRef.current === "following-bottom" &&
277
- hasMultipleNewScrollAnchors(items, previousItemCount)) {
278
- scrollToEnd({ behavior: "auto" });
279
- return;
280
- }
281
- scrollToElement(anchor, { align: "start" }, { keepPreviousPeek: true });
282
- handledScrollAnchorsRef.current.add(anchor);
283
- return;
284
- }
285
- }
286
- if (items.length === previousItemCount) {
287
- const anchor = getUnanchoredScrollAnchor(items, handledScrollAnchorsRef.current);
288
- if (anchor) {
289
- scrollToElement(anchor, { align: "start" }, { keepPreviousPeek: true });
290
- handledScrollAnchorsRef.current.add(anchor);
291
- return;
292
- }
293
- }
294
- // Appends with no new anchor (and content-only updates) fall through here:
295
- // keep following the end if we still are, otherwise just recommit state.
296
- if (modeRef.current === "following-bottom" && autoScrollRef.current) {
297
- scrollToEnd({ behavior: "auto" });
298
- }
299
- else {
300
- commitScrollState();
301
- scheduleVisibilitySync();
302
- }
303
- };
304
- reconcileScrollPosition();
305
- capturePrependAnchor();
306
- }, [
307
- applyDefaultScrollPosition,
308
- capturePrependAnchor,
309
- commitScrollState,
310
- flushPendingScrollToMessage,
311
- restorePrependedAnchor,
312
- scheduleVisibilitySync,
313
- scrollToElement,
314
- scrollToEnd,
315
- ]);
316
- const handleResize = React.useCallback(() => {
317
- if (modeRef.current === "following-bottom" && autoScrollRef.current) {
318
- scrollToEnd({ behavior: "auto" });
319
- return;
320
- }
321
- // Hold the anchored turn in place as content below it resizes (a reply
322
- // streaming in, or a transient marker collapsing) — otherwise the shrinking
323
- // content lets the browser clamp scrollTop and the turn drops.
324
- const previousSpacerHeight = spacerHeightRef.current;
325
- if (reanchorToAnchoredMessage()) {
326
- // The reply streaming below the anchor consumes the tail spacer as it
327
- // grows. Once the last of it is gone the reply has filled the viewport
328
- // and the reader is genuinely at the live edge, so autoScroll hands off
329
- // from the anchor hold to following the bottom. Requiring the >0 → 0
330
- // transition keeps a turn taller than the viewport (placed with no
331
- // spacer) held instead of yanked to the end.
332
- if (autoScrollRef.current && previousSpacerHeight > 0 && spacerHeightRef.current === 0) {
333
- scrollToEnd({ behavior: "auto" });
334
- }
335
- return;
336
- }
337
- scheduleStateCommit();
338
- scheduleVisibilitySync();
339
- }, [reanchorToAnchoredMessage, scheduleStateCommit, scheduleVisibilitySync, scrollToEnd]);
340
- const observeVisibility = React.useCallback(() => {
341
- const viewport = viewportRef.current;
342
- if (!viewport || !visibilityStore.hasListeners()) {
343
- return;
344
- }
345
- if (typeof IntersectionObserver === "undefined") {
346
- scheduleVisibilitySync();
347
- return;
348
- }
349
- if (!visibilityObserverRef.current) {
350
- visibilityObserverRef.current = new IntersectionObserver((entries) => {
351
- for (const entry of entries) {
352
- const messageId = entry.target.dataset.messageId;
353
- if (!messageId) {
354
- continue;
355
- }
356
- if (entry.isIntersecting) {
357
- visibleMessageIdsRef.current.add(messageId);
358
- }
359
- else {
360
- visibleMessageIdsRef.current.delete(messageId);
361
- }
362
- }
363
- scheduleVisibilitySync();
364
- }, {
365
- root: viewport,
366
- // Shrink the root's top edge to the anchoring line so a previous turn
367
- // peeking in the scrollMargin + peek band is not reported as visible,
368
- // keeping visibleMessageIds consistent with currentAnchorId. Captured
369
- // at observe time; a prop change rebuilds the observer on resubscribe.
370
- rootMargin: `${-(scrollMarginRef.current + scrollPreviousItemPeekRef.current)}px 0px 0px 0px`,
371
- threshold: [0, 0.01, 0.5, 1],
372
- });
373
- }
374
- messageElementsRef.current.forEach((element) => {
375
- visibilityObserverRef.current?.observe(element);
376
- });
377
- scheduleVisibilitySync();
378
- }, [scheduleVisibilitySync, visibilityStore]);
379
- const unobserveVisibility = React.useCallback(() => {
380
- if (visibilityFrameRef.current !== null) {
381
- window.cancelAnimationFrame(visibilityFrameRef.current);
382
- visibilityFrameRef.current = null;
383
- }
384
- visibilityObserverRef.current?.disconnect();
385
- visibilityObserverRef.current = null;
386
- visibleMessageIdsRef.current.clear();
387
- visibilityStore.setSnapshot(EMPTY_MESSAGE_SCROLLER_VISIBILITY_STATE);
388
- }, [visibilityStore]);
389
- const registerMessage = React.useCallback((messageId, element, removedElement) => {
390
- if (element) {
391
- messageElementsRef.current.set(messageId, element);
392
- visibilityObserverRef.current?.observe(element);
393
- scheduleVisibilitySync();
394
- if (pendingScrollToMessageRef.current?.messageId === messageId) {
395
- schedulePendingScrollToMessageFlush();
396
- }
397
- return;
398
- }
399
- if (removedElement && messageElementsRef.current.get(messageId) === removedElement) {
400
- messageElementsRef.current.delete(messageId);
401
- visibleMessageIdsRef.current.delete(messageId);
402
- visibilityObserverRef.current?.unobserve(removedElement);
403
- scheduleVisibilitySync();
404
- }
405
- }, [schedulePendingScrollToMessageFlush, scheduleVisibilitySync]);
406
- const userScrollIntent = React.useCallback(() => {
407
- if (modeRef.current === "following-bottom" ||
408
- modeRef.current === "anchored-to-message" ||
409
- modeRef.current === "settling-jump") {
410
- // A deliberate gesture releases auto-follow, turn-anchoring, and an in-flight
411
- // programmatic jump so re-pinning (and re-arming) never fights the reader.
412
- streamingTurnRef.current = null;
413
- modeRef.current = "free-scrolling";
414
- }
415
- }, []);
416
- const mirrorStateAttributes = React.useCallback(() => writeStateAttributes(stateStore.getSnapshot()), [stateStore, writeStateAttributes]);
417
- const setRootElement = useElementRef(rootRef, mirrorStateAttributes);
418
- const setViewportElement = useElementRef(viewportRef, mirrorStateAttributes);
419
- const setContentElement = React.useCallback((element) => {
420
- contentRef.current = element;
421
- }, []);
422
- const setSpacerElement = React.useCallback((element) => {
423
- spacerRef.current = element;
424
- spacerGapRef.current = getFlexGap(element?.parentElement ?? null);
425
- }, []);
426
- const syncAfterScroll = React.useCallback(() => {
427
- commitScrollState();
428
- scheduleVisibilitySync();
429
- capturePrependAnchor();
430
- }, [capturePrependAnchor, commitScrollState, scheduleVisibilitySync]);
431
- const context = React.useMemo(() => ({
432
- handleContentChange,
433
- handleResize,
434
- observeVisibility,
435
- preserveScrollOnPrependRef,
436
- scrollToEnd,
437
- scrollToMessage,
438
- scrollToStart,
439
- setContentElement,
440
- setRootElement,
441
- setSpacerElement,
442
- setViewportElement,
443
- stateStore,
444
- syncAfterScroll,
445
- unobserveVisibility,
446
- userScrollIntent,
447
- viewportRef,
448
- visibilityStore,
449
- }), [
450
- handleContentChange,
451
- handleResize,
452
- observeVisibility,
453
- scrollToEnd,
454
- scrollToMessage,
455
- scrollToStart,
456
- setContentElement,
457
- setRootElement,
458
- setSpacerElement,
459
- setViewportElement,
460
- stateStore,
461
- syncAfterScroll,
462
- unobserveVisibility,
463
- userScrollIntent,
464
- visibilityStore,
465
- ]);
466
- React.useLayoutEffect(() => {
467
- applyDefaultScrollPosition();
468
- }, [applyDefaultScrollPosition]);
469
- React.useEffect(() => {
470
- return () => {
471
- // Reset every ref after cancelling. StrictMode replays effects on the same
472
- // refs (unmount then remount), so a frame id left non-null here makes the
473
- // scheduler on remount think a frame is still pending and never reschedule.
474
- if (stateFrameRef.current !== null) {
475
- window.cancelAnimationFrame(stateFrameRef.current);
476
- stateFrameRef.current = null;
477
- }
478
- if (visibilityFrameRef.current !== null) {
479
- window.cancelAnimationFrame(visibilityFrameRef.current);
480
- visibilityFrameRef.current = null;
481
- }
482
- if (autoscrollingTimeoutRef.current !== null) {
483
- window.clearTimeout(autoscrollingTimeoutRef.current);
484
- autoscrollingTimeoutRef.current = null;
485
- }
486
- if (pendingScrollFrameRef.current !== null) {
487
- window.cancelAnimationFrame(pendingScrollFrameRef.current);
488
- pendingScrollFrameRef.current = null;
489
- }
490
- visibilityObserverRef.current?.disconnect();
491
- visibilityObserverRef.current = null;
492
- };
493
- }, []);
494
- React.useLayoutEffect(() => {
495
- if (autoScroll && modeRef.current === "following-bottom" && itemCountRef.current > 0) {
496
- scrollToEnd({ behavior: "auto" });
497
- return;
498
- }
499
- commitScrollState();
500
- }, [autoScroll, commitScrollState, scrollToEnd]);
501
- return {
502
- context,
503
- registerMessage,
504
- };
505
- }
506
- export { useMessageScrollerController };
@@ -1,49 +0,0 @@
1
- import * as React from "react";
2
- import type { MessageScrollerMode, MessageScrollerScrollable, MessageScrollerScrollOptions, MessageScrollerStore, MessageScrollerVisibilityStore } from "./types";
3
- type MessageScrollerRefs = {
4
- autoScrollRef: React.RefObject<boolean>;
5
- autoscrollingRef: React.RefObject<boolean>;
6
- autoscrollingTimeoutRef: React.RefObject<number | null>;
7
- streamingTurnRef: React.RefObject<HTMLElement | null>;
8
- contentRef: React.RefObject<HTMLDivElement | null>;
9
- defaultScrollPositionAppliedRef: React.RefObject<boolean>;
10
- firstItemRef: React.RefObject<HTMLElement | null>;
11
- itemCountRef: React.RefObject<number>;
12
- lastScrollTopRef: React.RefObject<number>;
13
- messageElementsRef: React.RefObject<Map<string, HTMLElement>>;
14
- modeRef: React.RefObject<MessageScrollerMode>;
15
- pendingScrollFrameRef: React.RefObject<number | null>;
16
- pendingScrollToMessageRef: React.RefObject<{
17
- messageId: string;
18
- options?: MessageScrollerScrollOptions;
19
- } | null>;
20
- prependRestoreRef: React.RefObject<{
21
- element: HTMLElement;
22
- viewportTop: number;
23
- } | null>;
24
- preserveScrollOnPrependRef: React.RefObject<boolean>;
25
- rootRef: React.RefObject<HTMLDivElement | null>;
26
- scrollEdgeThresholdRef: React.RefObject<number>;
27
- scrollMarginRef: React.RefObject<number>;
28
- scrollPreviousItemPeekRef: React.RefObject<number>;
29
- spacerGapRef: React.RefObject<number>;
30
- spacerHeightRef: React.RefObject<number>;
31
- spacerRef: React.RefObject<HTMLDivElement | null>;
32
- stateFrameRef: React.RefObject<number | null>;
33
- stateStore: MessageScrollerStore<MessageScrollerScrollable>;
34
- viewportRef: React.RefObject<HTMLDivElement | null>;
35
- visibilityFrameRef: React.RefObject<number | null>;
36
- visibilityObserverRef: React.RefObject<IntersectionObserver | null>;
37
- visibilityStore: MessageScrollerVisibilityStore;
38
- visibleMessageIdsRef: React.RefObject<Set<string>>;
39
- handledScrollAnchorsRef: React.RefObject<WeakSet<HTMLElement>>;
40
- };
41
- declare function useMessageScrollerRefs({ autoScroll, scrollEdgeThreshold, scrollMargin, scrollPreviousItemPeek, }: {
42
- autoScroll: boolean;
43
- scrollEdgeThreshold: number;
44
- scrollMargin: number;
45
- scrollPreviousItemPeek: number;
46
- }): MessageScrollerRefs;
47
- export { useMessageScrollerRefs };
48
- export type { MessageScrollerRefs };
49
- //# sourceMappingURL=use-message-scroller-refs.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-message-scroller-refs.d.ts","sourceRoot":"","sources":["../../../src/lib/message-scroller-primitive/use-message-scroller-refs.ts"],"names":[],"mappings":"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"}
@@ -1,90 +0,0 @@
1
- // Vendored from @shadcn/react 0.2.1 (upstream github.com/shadcn-ui).
2
- // Adapted only for repo import paths and formatting; not added as an npm dependency.
3
- import * as React from "react";
4
- import { areScrollStatesEqual, createMessageScrollerStore, createMessageScrollerVisibilityStore, } from "./stores.js";
5
- import { EMPTY_MESSAGE_SCROLLER_SCROLLABLE } from "./types.js";
6
- // Builds the per-instance ref bag: the two external stores constructed once, and
7
- // the latest prop values mirrored onto refs each render so callbacks stay stable.
8
- function useMessageScrollerRefs({ autoScroll, scrollEdgeThreshold, scrollMargin, scrollPreviousItemPeek, }) {
9
- const autoScrollRef = React.useRef(autoScroll);
10
- const autoscrollingRef = React.useRef(false);
11
- const contentRef = React.useRef(null);
12
- const defaultScrollPositionAppliedRef = React.useRef(false);
13
- const scrollEdgeThresholdRef = React.useRef(scrollEdgeThreshold);
14
- const itemCountRef = React.useRef(0);
15
- const firstItemRef = React.useRef(null);
16
- // The scrollTop seen by the previous state commit, so follow-release can tell
17
- // a reader scrolling up from content growing past the live edge.
18
- const lastScrollTopRef = React.useRef(0);
19
- const modeRef = React.useRef(autoScroll ? "following-bottom" : "free-scrolling");
20
- const messageElementsRef = React.useRef(new Map());
21
- const pendingScrollToMessageRef = React.useRef(null);
22
- // The row to hold steady on the next prepend: the first visible row, or a jump
23
- // target seeded by scrollToElement. restorePrependedAnchor reads only this.
24
- const prependRestoreRef = React.useRef(null);
25
- // The turn held at the reading line so a reply streaming in below it can re-pin
26
- // it instead of letting scrollTop clamp it loose.
27
- const streamingTurnRef = React.useRef(null);
28
- const scrollPreviousItemPeekRef = React.useRef(scrollPreviousItemPeek);
29
- const preserveScrollOnPrependRef = React.useRef(true);
30
- const rootRef = React.useRef(null);
31
- const scrollMarginRef = React.useRef(scrollMargin);
32
- const pendingScrollFrameRef = React.useRef(null);
33
- const spacerGapRef = React.useRef(0);
34
- const spacerHeightRef = React.useRef(0);
35
- const spacerRef = React.useRef(null);
36
- const stateFrameRef = React.useRef(null);
37
- const stateStoreRef = React.useRef(null);
38
- const autoscrollingTimeoutRef = React.useRef(null);
39
- const viewportRef = React.useRef(null);
40
- const visibilityFrameRef = React.useRef(null);
41
- const visibilityObserverRef = React.useRef(null);
42
- const visibilityStoreRef = React.useRef(null);
43
- const visibleMessageIdsRef = React.useRef(new Set());
44
- const handledScrollAnchorsRef = React.useRef(new WeakSet());
45
- if (stateStoreRef.current === null) {
46
- stateStoreRef.current = createMessageScrollerStore(EMPTY_MESSAGE_SCROLLER_SCROLLABLE, areScrollStatesEqual);
47
- }
48
- if (visibilityStoreRef.current === null) {
49
- visibilityStoreRef.current = createMessageScrollerVisibilityStore();
50
- }
51
- // Track the latest prop values on every render so callbacks read fresh values
52
- // without being recreated (the useLatest pattern).
53
- autoScrollRef.current = autoScroll;
54
- scrollEdgeThresholdRef.current = scrollEdgeThreshold;
55
- scrollMarginRef.current = scrollMargin;
56
- scrollPreviousItemPeekRef.current = scrollPreviousItemPeek;
57
- return {
58
- autoScrollRef,
59
- autoscrollingRef,
60
- autoscrollingTimeoutRef,
61
- streamingTurnRef,
62
- contentRef,
63
- defaultScrollPositionAppliedRef,
64
- firstItemRef,
65
- itemCountRef,
66
- lastScrollTopRef,
67
- messageElementsRef,
68
- modeRef,
69
- pendingScrollFrameRef,
70
- pendingScrollToMessageRef,
71
- prependRestoreRef,
72
- preserveScrollOnPrependRef,
73
- rootRef,
74
- scrollEdgeThresholdRef,
75
- scrollMarginRef,
76
- scrollPreviousItemPeekRef,
77
- spacerGapRef,
78
- spacerHeightRef,
79
- spacerRef,
80
- stateFrameRef,
81
- stateStore: stateStoreRef.current,
82
- viewportRef,
83
- visibilityFrameRef,
84
- visibilityObserverRef,
85
- visibilityStore: visibilityStoreRef.current,
86
- visibleMessageIdsRef,
87
- handledScrollAnchorsRef,
88
- };
89
- }
90
- export { useMessageScrollerRefs };
@@ -1,22 +0,0 @@
1
- import * as React from "react";
2
- type RenderState = Record<string, unknown>;
3
- type RenderFunction<TState extends RenderState> = (props: Record<string, unknown>, state: TState) => React.ReactElement | null;
4
- type RenderProp<TState extends RenderState> = React.ReactElement | RenderFunction<TState>;
5
- type StateAttributesMapping<TState extends RenderState> = Partial<{
6
- [K in keyof TState]: (value: TState[K]) => Record<string, string | undefined> | null | undefined;
7
- }>;
8
- type UseRenderComponentProps<TElement extends React.ElementType, TState extends RenderState = RenderState> = React.ComponentPropsWithRef<TElement> & {
9
- render?: RenderProp<TState>;
10
- };
11
- type UseRenderOptions<TElement extends React.ElementType, TState extends RenderState> = {
12
- defaultTagName: TElement;
13
- props?: React.ComponentPropsWithRef<TElement>;
14
- render?: RenderProp<TState>;
15
- state?: TState;
16
- stateAttributesMapping?: StateAttributesMapping<TState>;
17
- };
18
- declare function useRender<TElement extends React.ElementType, TState extends RenderState = RenderState>({ defaultTagName, props, render, state, stateAttributesMapping, }: UseRenderOptions<TElement, TState>): React.ReactElement<any, string | React.JSXElementConstructor<any>> | null;
19
- declare function mergeProps<TElement extends React.ElementType>(...sources: Array<React.ComponentPropsWithRef<TElement> | Record<string, unknown> | undefined>): React.ComponentPropsWithRef<TElement>;
20
- declare function composeRefs<T>(...refs: Array<React.Ref<T> | undefined>): React.RefCallback<T> | undefined;
21
- export { composeRefs, mergeProps, useRender, type UseRenderComponentProps };
22
- //# sourceMappingURL=use-render.d.ts.map