@effect-tui/react 0.1.3 → 0.1.5

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 (442) hide show
  1. package/dist/jsx-runtime.d.ts +13 -0
  2. package/dist/jsx-runtime.d.ts.map +1 -1
  3. package/dist/jsx-runtime.js.map +1 -1
  4. package/dist/src/codeblock.d.ts.map +1 -1
  5. package/dist/src/codeblock.js.map +1 -1
  6. package/dist/src/components/Divider.d.ts +18 -0
  7. package/dist/src/components/Divider.d.ts.map +1 -0
  8. package/dist/src/components/Divider.js +17 -0
  9. package/dist/src/components/Divider.js.map +1 -0
  10. package/dist/src/components/Markdown.d.ts +66 -0
  11. package/dist/src/components/Markdown.d.ts.map +1 -0
  12. package/dist/src/components/Markdown.js +226 -0
  13. package/dist/src/components/Markdown.js.map +1 -0
  14. package/dist/src/components/MultilineTextInput.d.ts +65 -0
  15. package/dist/src/components/MultilineTextInput.d.ts.map +1 -0
  16. package/dist/src/components/MultilineTextInput.js +607 -0
  17. package/dist/src/components/MultilineTextInput.js.map +1 -0
  18. package/dist/src/components/Overlay.d.ts +46 -0
  19. package/dist/src/components/Overlay.d.ts.map +1 -0
  20. package/dist/src/components/Overlay.js +11 -0
  21. package/dist/src/components/Overlay.js.map +1 -0
  22. package/dist/src/components/Static.d.ts +44 -0
  23. package/dist/src/components/Static.d.ts.map +1 -0
  24. package/dist/src/components/Static.js +53 -0
  25. package/dist/src/components/Static.js.map +1 -0
  26. package/dist/src/components/TextInput.d.ts +55 -0
  27. package/dist/src/components/TextInput.d.ts.map +1 -0
  28. package/dist/src/components/TextInput.js +277 -0
  29. package/dist/src/components/TextInput.js.map +1 -0
  30. package/dist/src/components/index.d.ts +7 -0
  31. package/dist/src/components/index.d.ts.map +1 -0
  32. package/dist/src/components/index.js +7 -0
  33. package/dist/src/components/index.js.map +1 -0
  34. package/dist/src/components/text-editing.d.ts +62 -0
  35. package/dist/src/components/text-editing.d.ts.map +1 -0
  36. package/dist/src/components/text-editing.js +385 -0
  37. package/dist/src/components/text-editing.js.map +1 -0
  38. package/dist/src/console/ConsoleCapture.d.ts +36 -0
  39. package/dist/src/console/ConsoleCapture.d.ts.map +1 -0
  40. package/dist/src/console/ConsoleCapture.js +210 -0
  41. package/dist/src/console/ConsoleCapture.js.map +1 -0
  42. package/dist/src/console/ConsolePopover.d.ts +18 -0
  43. package/dist/src/console/ConsolePopover.d.ts.map +1 -0
  44. package/dist/src/console/ConsolePopover.js +324 -0
  45. package/dist/src/console/ConsolePopover.js.map +1 -0
  46. package/dist/src/console/clipboard.d.ts +10 -0
  47. package/dist/src/console/clipboard.d.ts.map +1 -0
  48. package/dist/src/console/clipboard.js +74 -0
  49. package/dist/src/console/clipboard.js.map +1 -0
  50. package/dist/src/console/index.d.ts +5 -0
  51. package/dist/src/console/index.d.ts.map +1 -0
  52. package/dist/src/console/index.js +33 -0
  53. package/dist/src/console/index.js.map +1 -0
  54. package/dist/src/console/useConsole.d.ts +44 -0
  55. package/dist/src/console/useConsole.d.ts.map +1 -0
  56. package/dist/src/console/useConsole.js +91 -0
  57. package/dist/src/console/useConsole.js.map +1 -0
  58. package/dist/src/debug/DebugOverlay.d.ts +49 -0
  59. package/dist/src/debug/DebugOverlay.d.ts.map +1 -0
  60. package/dist/src/debug/DebugOverlay.js +438 -0
  61. package/dist/src/debug/DebugOverlay.js.map +1 -0
  62. package/dist/src/debug/DiagnosticsPanel.d.ts.map +1 -1
  63. package/dist/src/debug/DiagnosticsPanel.js.map +1 -1
  64. package/dist/src/dev/Toast.d.ts +19 -0
  65. package/dist/src/dev/Toast.d.ts.map +1 -0
  66. package/dist/src/dev/Toast.js +72 -0
  67. package/dist/src/dev/Toast.js.map +1 -0
  68. package/dist/src/dev/index.d.ts +2 -0
  69. package/dist/src/dev/index.d.ts.map +1 -0
  70. package/dist/src/dev/index.js +3 -0
  71. package/dist/src/dev/index.js.map +1 -0
  72. package/dist/src/dev.d.ts +114 -0
  73. package/dist/src/dev.d.ts.map +1 -0
  74. package/dist/src/dev.js +373 -0
  75. package/dist/src/dev.js.map +1 -0
  76. package/dist/src/highlight.d.ts +3 -3
  77. package/dist/src/highlight.d.ts.map +1 -1
  78. package/dist/src/highlight.js.map +1 -1
  79. package/dist/src/hmr-plugin.d.ts +2 -0
  80. package/dist/src/hmr-plugin.d.ts.map +1 -0
  81. package/dist/src/hmr-plugin.js +53 -0
  82. package/dist/src/hmr-plugin.js.map +1 -0
  83. package/dist/src/hooks/index.d.ts +4 -0
  84. package/dist/src/hooks/index.d.ts.map +1 -1
  85. package/dist/src/hooks/index.js +2 -0
  86. package/dist/src/hooks/index.js.map +1 -1
  87. package/dist/src/hooks/use-keyboard.d.ts +11 -0
  88. package/dist/src/hooks/use-keyboard.d.ts.map +1 -1
  89. package/dist/src/hooks/use-keyboard.js +22 -4
  90. package/dist/src/hooks/use-keyboard.js.map +1 -1
  91. package/dist/src/hooks/use-mouse.d.ts +24 -0
  92. package/dist/src/hooks/use-mouse.d.ts.map +1 -0
  93. package/dist/src/hooks/use-mouse.js +41 -0
  94. package/dist/src/hooks/use-mouse.js.map +1 -0
  95. package/dist/src/hooks/use-paste.d.ts +11 -0
  96. package/dist/src/hooks/use-paste.d.ts.map +1 -1
  97. package/dist/src/hooks/use-paste.js +17 -3
  98. package/dist/src/hooks/use-paste.js.map +1 -1
  99. package/dist/src/hooks/use-scroll.d.ts +79 -0
  100. package/dist/src/hooks/use-scroll.d.ts.map +1 -0
  101. package/dist/src/hooks/use-scroll.js +239 -0
  102. package/dist/src/hooks/use-scroll.js.map +1 -0
  103. package/dist/src/hooks/useFrameStats.js.map +1 -1
  104. package/dist/src/hosts/base.d.ts +62 -1
  105. package/dist/src/hosts/base.d.ts.map +1 -1
  106. package/dist/src/hosts/base.js +118 -5
  107. package/dist/src/hosts/base.js.map +1 -1
  108. package/dist/src/hosts/box.d.ts +7 -7
  109. package/dist/src/hosts/box.d.ts.map +1 -1
  110. package/dist/src/hosts/box.js +30 -23
  111. package/dist/src/hosts/box.js.map +1 -1
  112. package/dist/src/hosts/canvas.d.ts +16 -8
  113. package/dist/src/hosts/canvas.d.ts.map +1 -1
  114. package/dist/src/hosts/canvas.js +27 -22
  115. package/dist/src/hosts/canvas.js.map +1 -1
  116. package/dist/src/hosts/codeblock.d.ts +7 -7
  117. package/dist/src/hosts/codeblock.d.ts.map +1 -1
  118. package/dist/src/hosts/codeblock.js +11 -20
  119. package/dist/src/hosts/codeblock.js.map +1 -1
  120. package/dist/src/hosts/flex-container.d.ts +45 -0
  121. package/dist/src/hosts/flex-container.d.ts.map +1 -0
  122. package/dist/src/hosts/flex-container.js +90 -0
  123. package/dist/src/hosts/flex-container.js.map +1 -0
  124. package/dist/src/hosts/hstack.d.ts +6 -11
  125. package/dist/src/hosts/hstack.d.ts.map +1 -1
  126. package/dist/src/hosts/hstack.js +6 -41
  127. package/dist/src/hosts/hstack.js.map +1 -1
  128. package/dist/src/hosts/index.d.ts +4 -0
  129. package/dist/src/hosts/index.d.ts.map +1 -1
  130. package/dist/src/hosts/index.js +10 -0
  131. package/dist/src/hosts/index.js.map +1 -1
  132. package/dist/src/hosts/overlay-item.d.ts +32 -0
  133. package/dist/src/hosts/overlay-item.d.ts.map +1 -0
  134. package/dist/src/hosts/overlay-item.js +54 -0
  135. package/dist/src/hosts/overlay-item.js.map +1 -0
  136. package/dist/src/hosts/overlay.d.ts +30 -0
  137. package/dist/src/hosts/overlay.d.ts.map +1 -0
  138. package/dist/src/hosts/overlay.js +105 -0
  139. package/dist/src/hosts/overlay.js.map +1 -0
  140. package/dist/src/hosts/scroll.d.ts +56 -0
  141. package/dist/src/hosts/scroll.d.ts.map +1 -0
  142. package/dist/src/hosts/scroll.js +204 -0
  143. package/dist/src/hosts/scroll.js.map +1 -0
  144. package/dist/src/hosts/single-child.d.ts +16 -0
  145. package/dist/src/hosts/single-child.d.ts.map +1 -0
  146. package/dist/src/hosts/single-child.js +45 -0
  147. package/dist/src/hosts/single-child.js.map +1 -0
  148. package/dist/src/hosts/spacer.d.ts.map +1 -1
  149. package/dist/src/hosts/spacer.js +7 -3
  150. package/dist/src/hosts/spacer.js.map +1 -1
  151. package/dist/src/hosts/text.d.ts +9 -6
  152. package/dist/src/hosts/text.d.ts.map +1 -1
  153. package/dist/src/hosts/text.js +49 -22
  154. package/dist/src/hosts/text.js.map +1 -1
  155. package/dist/src/hosts/vstack.d.ts +6 -11
  156. package/dist/src/hosts/vstack.d.ts.map +1 -1
  157. package/dist/src/hosts/vstack.js +6 -41
  158. package/dist/src/hosts/vstack.js.map +1 -1
  159. package/dist/src/hosts/zstack.d.ts.map +1 -1
  160. package/dist/src/hosts/zstack.js +16 -5
  161. package/dist/src/hosts/zstack.js.map +1 -1
  162. package/dist/src/index.d.ts +9 -2
  163. package/dist/src/index.d.ts.map +1 -1
  164. package/dist/src/index.js +10 -2
  165. package/dist/src/index.js.map +1 -1
  166. package/dist/src/inline/index.d.ts.map +1 -1
  167. package/dist/src/inline/index.js.map +1 -1
  168. package/dist/src/motion/color-motion-value.d.ts.map +1 -1
  169. package/dist/src/motion/color-motion-value.js.map +1 -1
  170. package/dist/src/motion/color.d.ts +1 -29
  171. package/dist/src/motion/color.d.ts.map +1 -1
  172. package/dist/src/motion/color.js +2 -170
  173. package/dist/src/motion/color.js.map +1 -1
  174. package/dist/src/motion/color.test.js.map +1 -1
  175. package/dist/src/motion/event-emitter.d.ts.map +1 -1
  176. package/dist/src/motion/event-emitter.js.map +1 -1
  177. package/dist/src/motion/frame.js.map +1 -1
  178. package/dist/src/motion/hooks.d.ts.map +1 -1
  179. package/dist/src/motion/hooks.js +8 -3
  180. package/dist/src/motion/hooks.js.map +1 -1
  181. package/dist/src/motion/index.d.ts.map +1 -1
  182. package/dist/src/motion/index.js.map +1 -1
  183. package/dist/src/motion/motion-value.d.ts.map +1 -1
  184. package/dist/src/motion/motion-value.js.map +1 -1
  185. package/dist/src/motion/motion-value.test.js.map +1 -1
  186. package/dist/src/motion/spring-math.d.ts +6 -1
  187. package/dist/src/motion/spring-math.d.ts.map +1 -1
  188. package/dist/src/motion/spring-math.js +6 -1
  189. package/dist/src/motion/spring-math.js.map +1 -1
  190. package/dist/src/motion/types.d.ts.map +1 -1
  191. package/dist/src/motion/types.js.map +1 -1
  192. package/dist/src/profiler.js.map +1 -1
  193. package/dist/src/reconciler/host-config.d.ts +5 -5
  194. package/dist/src/reconciler/host-config.d.ts.map +1 -1
  195. package/dist/src/reconciler/host-config.js +43 -51
  196. package/dist/src/reconciler/host-config.js.map +1 -1
  197. package/dist/src/reconciler/noop-methods.d.ts +29 -0
  198. package/dist/src/reconciler/noop-methods.d.ts.map +1 -0
  199. package/dist/src/reconciler/noop-methods.js +43 -0
  200. package/dist/src/reconciler/noop-methods.js.map +1 -0
  201. package/dist/src/reconciler/types.d.ts +68 -14
  202. package/dist/src/reconciler/types.d.ts.map +1 -1
  203. package/dist/src/remote/Procedures.d.ts +22 -0
  204. package/dist/src/remote/Procedures.d.ts.map +1 -0
  205. package/dist/src/remote/Procedures.js +42 -0
  206. package/dist/src/remote/Procedures.js.map +1 -0
  207. package/dist/src/remote/Router.d.ts +20 -0
  208. package/dist/src/remote/Router.d.ts.map +1 -0
  209. package/dist/src/remote/Router.js +26 -0
  210. package/dist/src/remote/Router.js.map +1 -0
  211. package/dist/src/remote/Server.d.ts +6 -0
  212. package/dist/src/remote/Server.d.ts.map +1 -0
  213. package/dist/src/remote/Server.js +53 -0
  214. package/dist/src/remote/Server.js.map +1 -0
  215. package/dist/src/remote/index.d.ts +18 -0
  216. package/dist/src/remote/index.d.ts.map +1 -0
  217. package/dist/src/remote/index.js +74 -0
  218. package/dist/src/remote/index.js.map +1 -0
  219. package/dist/src/renderer/core/FrameBuilder.d.ts +18 -0
  220. package/dist/src/renderer/core/FrameBuilder.d.ts.map +1 -0
  221. package/dist/src/renderer/core/FrameBuilder.js +38 -0
  222. package/dist/src/renderer/core/FrameBuilder.js.map +1 -0
  223. package/dist/src/renderer/core/RendererState.d.ts +41 -0
  224. package/dist/src/renderer/core/RendererState.d.ts.map +1 -0
  225. package/dist/src/renderer/core/RendererState.js +70 -0
  226. package/dist/src/renderer/core/RendererState.js.map +1 -0
  227. package/dist/src/renderer/core/index.d.ts +3 -0
  228. package/dist/src/renderer/core/index.d.ts.map +1 -0
  229. package/dist/src/renderer/core/index.js +3 -0
  230. package/dist/src/renderer/core/index.js.map +1 -0
  231. package/dist/src/renderer/input/InputProcessor.d.ts +25 -0
  232. package/dist/src/renderer/input/InputProcessor.d.ts.map +1 -0
  233. package/dist/src/renderer/input/InputProcessor.js +81 -0
  234. package/dist/src/renderer/input/InputProcessor.js.map +1 -0
  235. package/dist/src/renderer/input/index.d.ts +2 -0
  236. package/dist/src/renderer/input/index.d.ts.map +1 -0
  237. package/dist/src/renderer/input/index.js +2 -0
  238. package/dist/src/renderer/input/index.js.map +1 -0
  239. package/dist/src/renderer/lifecycle/EventBus.d.ts +41 -0
  240. package/dist/src/renderer/lifecycle/EventBus.d.ts.map +1 -0
  241. package/dist/src/renderer/lifecycle/EventBus.js +78 -0
  242. package/dist/src/renderer/lifecycle/EventBus.js.map +1 -0
  243. package/dist/src/renderer/lifecycle/ResizeManager.d.ts +34 -0
  244. package/dist/src/renderer/lifecycle/ResizeManager.d.ts.map +1 -0
  245. package/dist/src/renderer/lifecycle/ResizeManager.js +47 -0
  246. package/dist/src/renderer/lifecycle/ResizeManager.js.map +1 -0
  247. package/dist/src/renderer/lifecycle/TerminalSetup.d.ts +36 -0
  248. package/dist/src/renderer/lifecycle/TerminalSetup.d.ts.map +1 -0
  249. package/dist/src/renderer/lifecycle/TerminalSetup.js +82 -0
  250. package/dist/src/renderer/lifecycle/TerminalSetup.js.map +1 -0
  251. package/dist/src/renderer/lifecycle/index.d.ts +4 -0
  252. package/dist/src/renderer/lifecycle/index.d.ts.map +1 -0
  253. package/dist/src/renderer/lifecycle/index.js +4 -0
  254. package/dist/src/renderer/lifecycle/index.js.map +1 -0
  255. package/dist/src/renderer/modes/FullscreenRenderer.d.ts +12 -0
  256. package/dist/src/renderer/modes/FullscreenRenderer.d.ts.map +1 -0
  257. package/dist/src/renderer/modes/FullscreenRenderer.js +52 -0
  258. package/dist/src/renderer/modes/FullscreenRenderer.js.map +1 -0
  259. package/dist/src/renderer/modes/InlineRenderer.d.ts +25 -0
  260. package/dist/src/renderer/modes/InlineRenderer.d.ts.map +1 -0
  261. package/dist/src/renderer/modes/InlineRenderer.js +161 -0
  262. package/dist/src/renderer/modes/InlineRenderer.js.map +1 -0
  263. package/dist/src/renderer/modes/RendererMode.d.ts +42 -0
  264. package/dist/src/renderer/modes/RendererMode.d.ts.map +1 -0
  265. package/dist/src/renderer/modes/RendererMode.js +2 -0
  266. package/dist/src/renderer/modes/RendererMode.js.map +1 -0
  267. package/dist/src/renderer/modes/StaticContentRenderer.d.ts +25 -0
  268. package/dist/src/renderer/modes/StaticContentRenderer.d.ts.map +1 -0
  269. package/dist/src/renderer/modes/StaticContentRenderer.js +47 -0
  270. package/dist/src/renderer/modes/StaticContentRenderer.js.map +1 -0
  271. package/dist/src/renderer/modes/index.d.ts +5 -0
  272. package/dist/src/renderer/modes/index.d.ts.map +1 -0
  273. package/dist/src/renderer/modes/index.js +4 -0
  274. package/dist/src/renderer/modes/index.js.map +1 -0
  275. package/dist/src/renderer-context.d.ts +9 -0
  276. package/dist/src/renderer-context.d.ts.map +1 -0
  277. package/dist/src/renderer-context.js +22 -0
  278. package/dist/src/renderer-context.js.map +1 -0
  279. package/dist/src/renderer-types.d.ts +103 -0
  280. package/dist/src/renderer-types.d.ts.map +1 -0
  281. package/dist/src/renderer-types.js +2 -0
  282. package/dist/src/renderer-types.js.map +1 -0
  283. package/dist/src/renderer.d.ts +4 -86
  284. package/dist/src/renderer.d.ts.map +1 -1
  285. package/dist/src/renderer.js +214 -384
  286. package/dist/src/renderer.js.map +1 -1
  287. package/dist/src/test/index.d.ts.map +1 -1
  288. package/dist/src/test/index.js.map +1 -1
  289. package/dist/src/test/mock-streams.d.ts.map +1 -1
  290. package/dist/src/test/mock-streams.js.map +1 -1
  291. package/dist/src/test/render-tui.d.ts.map +1 -1
  292. package/dist/src/test/render-tui.js +2 -5
  293. package/dist/src/test/render-tui.js.map +1 -1
  294. package/dist/src/trace/SpanTree.d.ts.map +1 -1
  295. package/dist/src/trace/SpanTree.js +21 -11
  296. package/dist/src/trace/SpanTree.js.map +1 -1
  297. package/dist/src/trace/format-value.d.ts +15 -0
  298. package/dist/src/trace/format-value.d.ts.map +1 -0
  299. package/dist/src/trace/format-value.js +77 -0
  300. package/dist/src/trace/format-value.js.map +1 -0
  301. package/dist/src/trace/index.d.ts.map +1 -1
  302. package/dist/src/trace/index.js.map +1 -1
  303. package/dist/src/trace/location.js +1 -1
  304. package/dist/src/trace/location.js.map +1 -1
  305. package/dist/src/trace/span-processor.d.ts.map +1 -1
  306. package/dist/src/trace/span-processor.js.map +1 -1
  307. package/dist/src/trace/span-state.d.ts +19 -2
  308. package/dist/src/trace/span-state.d.ts.map +1 -1
  309. package/dist/src/trace/span-state.js +62 -31
  310. package/dist/src/trace/span-state.js.map +1 -1
  311. package/dist/src/trace/tui-logger.js.map +1 -1
  312. package/dist/src/utils/border.d.ts +1 -1
  313. package/dist/src/utils/border.d.ts.map +1 -1
  314. package/dist/src/utils/border.js +6 -0
  315. package/dist/src/utils/border.js.map +1 -1
  316. package/dist/src/utils/flex-layout.d.ts +2 -1
  317. package/dist/src/utils/flex-layout.d.ts.map +1 -1
  318. package/dist/src/utils/flex-layout.js +22 -33
  319. package/dist/src/utils/flex-layout.js.map +1 -1
  320. package/dist/src/utils/index.d.ts +1 -1
  321. package/dist/src/utils/index.d.ts.map +1 -1
  322. package/dist/src/utils/index.js +1 -1
  323. package/dist/src/utils/index.js.map +1 -1
  324. package/dist/src/utils/padding.d.ts.map +1 -1
  325. package/dist/src/utils/padding.js.map +1 -1
  326. package/dist/src/utils/styles.d.ts +20 -1
  327. package/dist/src/utils/styles.d.ts.map +1 -1
  328. package/dist/src/utils/styles.js +36 -1
  329. package/dist/src/utils/styles.js.map +1 -1
  330. package/dist/src/visualize/index.d.ts +8 -19
  331. package/dist/src/visualize/index.d.ts.map +1 -1
  332. package/dist/src/visualize/index.js +11 -25
  333. package/dist/src/visualize/index.js.map +1 -1
  334. package/dist/tsconfig.tsbuildinfo +1 -1
  335. package/jsx-dev-runtime.ts +5 -0
  336. package/jsx-runtime.ts +54 -0
  337. package/package.json +124 -92
  338. package/src/codeblock.tsx +34 -34
  339. package/src/components/Divider.tsx +23 -0
  340. package/src/components/Markdown.tsx +380 -0
  341. package/src/components/MultilineTextInput.tsx +749 -0
  342. package/src/components/Overlay.tsx +56 -0
  343. package/src/components/Static.tsx +68 -0
  344. package/src/components/TextInput.tsx +356 -0
  345. package/src/components/index.ts +6 -0
  346. package/src/components/text-editing.ts +464 -0
  347. package/src/console/ConsoleCapture.ts +272 -0
  348. package/src/console/ConsolePopover.tsx +487 -0
  349. package/src/console/clipboard.ts +81 -0
  350. package/src/console/index.ts +42 -0
  351. package/src/console/useConsole.ts +129 -0
  352. package/src/debug/DebugOverlay.ts +557 -0
  353. package/src/debug/DiagnosticsPanel.tsx +27 -27
  354. package/src/dev/Toast.tsx +117 -0
  355. package/src/dev/index.ts +2 -0
  356. package/src/dev.tsx +489 -0
  357. package/src/highlight.ts +46 -46
  358. package/src/hmr-plugin.ts +61 -0
  359. package/src/hooks/index.ts +4 -0
  360. package/src/hooks/use-keyboard.ts +44 -24
  361. package/src/hooks/use-mouse.ts +51 -0
  362. package/src/hooks/use-paste.ts +21 -6
  363. package/src/hooks/use-scroll.ts +386 -0
  364. package/src/hooks/useFrameStats.ts +17 -17
  365. package/src/hosts/base.ts +180 -59
  366. package/src/hosts/box.ts +117 -94
  367. package/src/hosts/canvas.ts +170 -141
  368. package/src/hosts/codeblock.ts +117 -133
  369. package/src/hosts/flex-container.ts +124 -0
  370. package/src/hosts/hstack.ts +11 -59
  371. package/src/hosts/index.ts +24 -14
  372. package/src/hosts/overlay-item.ts +72 -0
  373. package/src/hosts/overlay.ts +125 -0
  374. package/src/hosts/scroll.ts +255 -0
  375. package/src/hosts/single-child.ts +52 -0
  376. package/src/hosts/spacer.ts +30 -26
  377. package/src/hosts/text.ts +198 -164
  378. package/src/hosts/vstack.ts +11 -59
  379. package/src/hosts/zstack.ts +79 -67
  380. package/src/index.ts +44 -19
  381. package/src/inline/index.tsx +123 -123
  382. package/src/motion/color-motion-value.ts +67 -67
  383. package/src/motion/color.test.ts +107 -107
  384. package/src/motion/color.ts +9 -190
  385. package/src/motion/event-emitter.ts +20 -20
  386. package/src/motion/frame.ts +35 -35
  387. package/src/motion/hooks.ts +144 -139
  388. package/src/motion/index.ts +10 -10
  389. package/src/motion/motion-value.test.ts +207 -207
  390. package/src/motion/motion-value.ts +112 -112
  391. package/src/motion/spring-math.ts +88 -83
  392. package/src/motion/types.ts +25 -25
  393. package/src/profiler.ts +50 -50
  394. package/src/reconciler/host-config.ts +152 -174
  395. package/src/reconciler/noop-methods.ts +55 -0
  396. package/src/reconciler/types.ts +112 -46
  397. package/src/remote/Procedures.ts +52 -0
  398. package/src/remote/Router.ts +58 -0
  399. package/src/remote/Server.ts +76 -0
  400. package/src/remote/index.ts +90 -0
  401. package/src/renderer/core/FrameBuilder.ts +49 -0
  402. package/src/renderer/core/RendererState.ts +80 -0
  403. package/src/renderer/core/index.ts +2 -0
  404. package/src/renderer/input/InputProcessor.ts +94 -0
  405. package/src/renderer/input/index.ts +1 -0
  406. package/src/renderer/lifecycle/EventBus.ts +90 -0
  407. package/src/renderer/lifecycle/ResizeManager.ts +65 -0
  408. package/src/renderer/lifecycle/TerminalSetup.ts +105 -0
  409. package/src/renderer/lifecycle/index.ts +3 -0
  410. package/src/renderer/modes/FullscreenRenderer.ts +53 -0
  411. package/src/renderer/modes/InlineRenderer.ts +186 -0
  412. package/src/renderer/modes/RendererMode.ts +46 -0
  413. package/src/renderer/modes/StaticContentRenderer.ts +56 -0
  414. package/src/renderer/modes/index.ts +4 -0
  415. package/src/renderer-context.ts +27 -0
  416. package/src/renderer-types.ts +109 -0
  417. package/src/renderer.ts +392 -642
  418. package/src/test/index.ts +5 -5
  419. package/src/test/mock-streams.ts +115 -115
  420. package/src/test/render-tui.ts +84 -87
  421. package/src/utils/border.ts +79 -73
  422. package/src/utils/flex-layout.ts +80 -93
  423. package/src/utils/index.ts +1 -1
  424. package/src/utils/padding.ts +27 -27
  425. package/src/utils/styles.ts +50 -7
  426. package/src/visualize/index.tsx +225 -240
  427. package/dist/src/output.d.ts +0 -47
  428. package/dist/src/output.d.ts.map +0 -1
  429. package/dist/src/output.js +0 -125
  430. package/dist/src/output.js.map +0 -1
  431. package/dist/src/terminal.d.ts +0 -37
  432. package/dist/src/terminal.d.ts.map +0 -1
  433. package/dist/src/terminal.js +0 -65
  434. package/dist/src/terminal.js.map +0 -1
  435. package/src/output.ts +0 -156
  436. package/src/terminal.ts +0 -67
  437. package/src/trace/SpanTree.tsx +0 -195
  438. package/src/trace/index.tsx +0 -205
  439. package/src/trace/location.ts +0 -90
  440. package/src/trace/span-processor.ts +0 -65
  441. package/src/trace/span-state.ts +0 -286
  442. package/src/trace/tui-logger.ts +0 -72
@@ -2,221 +2,221 @@ import { describe, it, expect } from "vitest"
2
2
  import { motionValue } from "./motion-value.js"
3
3
 
4
4
  describe("MotionValue", () => {
5
- describe("basic operations", () => {
6
- it("initializes with correct value", () => {
7
- const mv = motionValue(100)
8
- expect(mv.get()).toBe(100)
9
- })
10
-
11
- it("jump() sets value immediately", () => {
12
- const mv = motionValue(0)
13
- mv.jump(50)
14
- expect(mv.get()).toBe(50)
15
- expect(mv.getVelocity()).toBe(0)
16
- })
17
-
18
- it("jump() stops any active animation", () => {
19
- const mv = motionValue(0)
20
- mv.set(100) // Start animation
21
- expect(mv.isAnimating()).toBe(true)
22
- mv.jump(50)
23
- expect(mv.isAnimating()).toBe(false)
24
- expect(mv.get()).toBe(50)
25
- })
26
- })
27
-
28
- describe("spring animation", () => {
29
- it("set() starts animation toward target", () => {
30
- const mv = motionValue(0)
31
- mv.set(100)
32
- expect(mv.isAnimating()).toBe(true)
33
- })
34
-
35
- it("notifies on change", () => {
36
- const mv = motionValue(0)
37
- const values: number[] = []
38
- mv.on("change", (v) => values.push(v))
39
- mv.jump(50)
40
- expect(values).toContain(50)
41
- })
42
-
43
- it("notifies animationStart and animationComplete", async () => {
44
- const mv = motionValue(0)
45
- let started = false
46
- let completed = false
47
- mv.on("animationStart", () => {
48
- started = true
49
- })
50
- mv.on("animationComplete", () => {
51
- completed = true
52
- })
53
-
54
- mv.set(100, { stiffness: 1000, damping: 50 }) // Fast spring
55
- expect(started).toBe(true)
56
-
57
- // Wait for animation to complete
58
- await new Promise((r) => setTimeout(r, 500))
59
- expect(completed).toBe(true)
60
- })
61
-
62
- it("stop() halts animation", () => {
63
- const mv = motionValue(0)
64
- mv.set(100)
65
- expect(mv.isAnimating()).toBe(true)
66
- mv.stop()
67
- expect(mv.isAnimating()).toBe(false)
68
- })
69
- })
70
-
71
- describe("spring physics correctness", () => {
72
- it("reaches target value when settled", async () => {
73
- const mv = motionValue(0)
74
- mv.set(100, { stiffness: 500, damping: 30 })
75
-
76
- await new Promise((r) => setTimeout(r, 1000))
77
- expect(mv.get()).toBeCloseTo(100, 1)
78
- })
79
-
80
- it("velocity is zero when settled", async () => {
81
- const mv = motionValue(0)
82
- mv.set(100, { stiffness: 500, damping: 30 })
83
-
84
- await new Promise((r) => setTimeout(r, 1000))
85
- expect(Math.abs(mv.getVelocity())).toBeLessThan(0.1)
86
- })
87
- })
88
-
89
- describe("retargeting", () => {
90
- it("preserves velocity when retargeting mid-animation", async () => {
91
- const mv = motionValue(0)
92
- mv.set(100, { stiffness: 100, damping: 10 })
93
-
94
- // Wait a bit for velocity to build up
95
- await new Promise((r) => setTimeout(r, 50))
96
-
97
- const velocityBefore = mv.getVelocity()
98
- const positionBefore = mv.get()
99
-
100
- // Retarget to opposite direction
101
- mv.set(0, { stiffness: 100, damping: 10 })
102
-
103
- // Velocity should be preserved (same value, continuing momentum)
104
- expect(mv.getVelocity()).toBeCloseTo(velocityBefore, 1)
105
- expect(mv.get()).toBeCloseTo(positionBefore, 1)
106
- })
107
-
108
- it("curves smoothly when reversing direction", async () => {
109
- const mv = motionValue(0)
110
- mv.set(100, { stiffness: 100, damping: 15 })
111
-
112
- // Wait for positive velocity
113
- await new Promise((r) => setTimeout(r, 30))
114
- const velBefore = mv.getVelocity()
115
- expect(velBefore).toBeGreaterThan(0)
116
-
117
- // Retarget back to 0
118
- mv.set(0, { stiffness: 100, damping: 15 })
119
-
120
- // Should still have positive velocity immediately after retarget
121
- expect(mv.getVelocity()).toBeGreaterThan(0)
122
-
123
- // Wait a bit - velocity should decrease and eventually reverse
124
- await new Promise((r) => setTimeout(r, 100))
125
- // Position should have moved past where it was (momentum carried it)
126
- // or started moving back toward 0
127
- })
128
- })
129
-
130
- describe("visualDuration/bounce API", () => {
131
- it("visualDuration controls animation speed", async () => {
132
- const fast = motionValue(0)
133
- const slow = motionValue(0)
134
-
135
- fast.set(100, { visualDuration: 0.1, bounce: 0 })
136
- slow.set(100, { visualDuration: 0.5, bounce: 0 })
137
-
138
- await new Promise((r) => setTimeout(r, 150))
139
-
140
- // Fast should be closer to target
141
- expect(Math.abs(100 - fast.get())).toBeLessThan(Math.abs(100 - slow.get()))
142
- })
143
-
144
- it("bounce: 0 means no overshoot (critically damped)", async () => {
145
- const mv = motionValue(0)
146
- mv.set(100, { visualDuration: 0.3, bounce: 0 })
147
-
148
- const values: number[] = []
149
- mv.on("change", (v) => values.push(v))
150
-
151
- await new Promise((r) => setTimeout(r, 500))
152
-
153
- // Should never exceed target
154
- const max = Math.max(...values)
155
- expect(max).toBeLessThanOrEqual(100.5) // Small tolerance for numerical precision
156
- })
157
-
158
- it("bounce > 0 allows overshoot", async () => {
159
- const mv = motionValue(0)
160
- mv.set(100, { visualDuration: 0.3, bounce: 0.3 })
161
-
162
- const values: number[] = []
163
- mv.on("change", (v) => values.push(v))
164
-
165
- await new Promise((r) => setTimeout(r, 500))
166
-
167
- // Should overshoot target
168
- const max = Math.max(...values)
169
- expect(max).toBeGreaterThan(100)
170
- })
171
- })
5
+ describe("basic operations", () => {
6
+ it("initializes with correct value", () => {
7
+ const mv = motionValue(100)
8
+ expect(mv.get()).toBe(100)
9
+ })
10
+
11
+ it("jump() sets value immediately", () => {
12
+ const mv = motionValue(0)
13
+ mv.jump(50)
14
+ expect(mv.get()).toBe(50)
15
+ expect(mv.getVelocity()).toBe(0)
16
+ })
17
+
18
+ it("jump() stops any active animation", () => {
19
+ const mv = motionValue(0)
20
+ mv.set(100) // Start animation
21
+ expect(mv.isAnimating()).toBe(true)
22
+ mv.jump(50)
23
+ expect(mv.isAnimating()).toBe(false)
24
+ expect(mv.get()).toBe(50)
25
+ })
26
+ })
27
+
28
+ describe("spring animation", () => {
29
+ it("set() starts animation toward target", () => {
30
+ const mv = motionValue(0)
31
+ mv.set(100)
32
+ expect(mv.isAnimating()).toBe(true)
33
+ })
34
+
35
+ it("notifies on change", () => {
36
+ const mv = motionValue(0)
37
+ const values: number[] = []
38
+ mv.on("change", (v) => values.push(v))
39
+ mv.jump(50)
40
+ expect(values).toContain(50)
41
+ })
42
+
43
+ it("notifies animationStart and animationComplete", async () => {
44
+ const mv = motionValue(0)
45
+ let started = false
46
+ let completed = false
47
+ mv.on("animationStart", () => {
48
+ started = true
49
+ })
50
+ mv.on("animationComplete", () => {
51
+ completed = true
52
+ })
53
+
54
+ mv.set(100, { stiffness: 1000, damping: 50 }) // Fast spring
55
+ expect(started).toBe(true)
56
+
57
+ // Wait for animation to complete
58
+ await new Promise((r) => setTimeout(r, 500))
59
+ expect(completed).toBe(true)
60
+ })
61
+
62
+ it("stop() halts animation", () => {
63
+ const mv = motionValue(0)
64
+ mv.set(100)
65
+ expect(mv.isAnimating()).toBe(true)
66
+ mv.stop()
67
+ expect(mv.isAnimating()).toBe(false)
68
+ })
69
+ })
70
+
71
+ describe("spring physics correctness", () => {
72
+ it("reaches target value when settled", async () => {
73
+ const mv = motionValue(0)
74
+ mv.set(100, { stiffness: 500, damping: 30 })
75
+
76
+ await new Promise((r) => setTimeout(r, 1000))
77
+ expect(mv.get()).toBeCloseTo(100, 1)
78
+ })
79
+
80
+ it("velocity is zero when settled", async () => {
81
+ const mv = motionValue(0)
82
+ mv.set(100, { stiffness: 500, damping: 30 })
83
+
84
+ await new Promise((r) => setTimeout(r, 1000))
85
+ expect(Math.abs(mv.getVelocity())).toBeLessThan(0.1)
86
+ })
87
+ })
88
+
89
+ describe("retargeting", () => {
90
+ it("preserves velocity when retargeting mid-animation", async () => {
91
+ const mv = motionValue(0)
92
+ mv.set(100, { stiffness: 100, damping: 10 })
93
+
94
+ // Wait a bit for velocity to build up
95
+ await new Promise((r) => setTimeout(r, 50))
96
+
97
+ const velocityBefore = mv.getVelocity()
98
+ const positionBefore = mv.get()
99
+
100
+ // Retarget to opposite direction
101
+ mv.set(0, { stiffness: 100, damping: 10 })
102
+
103
+ // Velocity should be preserved (same value, continuing momentum)
104
+ expect(mv.getVelocity()).toBeCloseTo(velocityBefore, 1)
105
+ expect(mv.get()).toBeCloseTo(positionBefore, 1)
106
+ })
107
+
108
+ it("curves smoothly when reversing direction", async () => {
109
+ const mv = motionValue(0)
110
+ mv.set(100, { stiffness: 100, damping: 15 })
111
+
112
+ // Wait for positive velocity
113
+ await new Promise((r) => setTimeout(r, 30))
114
+ const velBefore = mv.getVelocity()
115
+ expect(velBefore).toBeGreaterThan(0)
116
+
117
+ // Retarget back to 0
118
+ mv.set(0, { stiffness: 100, damping: 15 })
119
+
120
+ // Should still have positive velocity immediately after retarget
121
+ expect(mv.getVelocity()).toBeGreaterThan(0)
122
+
123
+ // Wait a bit - velocity should decrease and eventually reverse
124
+ await new Promise((r) => setTimeout(r, 100))
125
+ // Position should have moved past where it was (momentum carried it)
126
+ // or started moving back toward 0
127
+ })
128
+ })
129
+
130
+ describe("visualDuration/bounce API", () => {
131
+ it("visualDuration controls animation speed", async () => {
132
+ const fast = motionValue(0)
133
+ const slow = motionValue(0)
134
+
135
+ fast.set(100, { visualDuration: 0.1, bounce: 0 })
136
+ slow.set(100, { visualDuration: 0.5, bounce: 0 })
137
+
138
+ await new Promise((r) => setTimeout(r, 150))
139
+
140
+ // Fast should be closer to target
141
+ expect(Math.abs(100 - fast.get())).toBeLessThan(Math.abs(100 - slow.get()))
142
+ })
143
+
144
+ it("bounce: 0 means no overshoot (critically damped)", async () => {
145
+ const mv = motionValue(0)
146
+ mv.set(100, { visualDuration: 0.3, bounce: 0 })
147
+
148
+ const values: number[] = []
149
+ mv.on("change", (v) => values.push(v))
150
+
151
+ await new Promise((r) => setTimeout(r, 500))
152
+
153
+ // Should never exceed target
154
+ const max = Math.max(...values)
155
+ expect(max).toBeLessThanOrEqual(100.5) // Small tolerance for numerical precision
156
+ })
157
+
158
+ it("bounce > 0 allows overshoot", async () => {
159
+ const mv = motionValue(0)
160
+ mv.set(100, { visualDuration: 0.3, bounce: 0.3 })
161
+
162
+ const values: number[] = []
163
+ mv.on("change", (v) => values.push(v))
164
+
165
+ await new Promise((r) => setTimeout(r, 500))
166
+
167
+ // Should overshoot target
168
+ const max = Math.max(...values)
169
+ expect(max).toBeGreaterThan(100)
170
+ })
171
+ })
172
172
 
173
- describe("cleanup", () => {
174
- it("destroy() stops animation and clears subscribers", () => {
175
- const mv = motionValue(0)
176
- mv.on("change", () => {
177
- // subscriber added
178
- })
173
+ describe("cleanup", () => {
174
+ it("destroy() stops animation and clears subscribers", () => {
175
+ const mv = motionValue(0)
176
+ mv.on("change", () => {
177
+ // subscriber added
178
+ })
179
179
 
180
- mv.set(100)
181
- mv.destroy()
180
+ mv.set(100)
181
+ mv.destroy()
182
182
 
183
- expect(mv.isAnimating()).toBe(false)
183
+ expect(mv.isAnimating()).toBe(false)
184
184
 
185
- // After destroy, just verify it doesn't throw
186
- mv.jump(50)
187
- })
185
+ // After destroy, just verify it doesn't throw
186
+ mv.jump(50)
187
+ })
188
188
 
189
- it("unsubscribe function works", () => {
190
- const mv = motionValue(0)
191
- const values: number[] = []
192
- const unsub = mv.on("change", (v) => values.push(v))
189
+ it("unsubscribe function works", () => {
190
+ const mv = motionValue(0)
191
+ const values: number[] = []
192
+ const unsub = mv.on("change", (v) => values.push(v))
193
193
 
194
- mv.jump(10)
195
- expect(values).toContain(10)
194
+ mv.jump(10)
195
+ expect(values).toContain(10)
196
196
 
197
- unsub()
198
- mv.jump(20)
199
- expect(values).not.toContain(20)
200
- })
201
- })
197
+ unsub()
198
+ mv.jump(20)
199
+ expect(values).not.toContain(20)
200
+ })
201
+ })
202
202
  })
203
203
 
204
204
  describe("createSpringResolver", () => {
205
- // Test the analytical spring formulas directly
206
- // These are internal but critical for correctness
207
-
208
- it("initial position equals from", () => {
209
- const mv = motionValue(50)
210
- mv.set(100, { stiffness: 100, damping: 10 })
211
- // At t=0, should still be at initial position
212
- expect(mv.get()).toBe(50)
213
- })
214
-
215
- it("initial velocity is preserved", () => {
216
- const mv = motionValue(0)
217
- mv.set(100, { stiffness: 100, damping: 10 })
218
-
219
- // Initial velocity should be 0 (starting from rest)
220
- expect(mv.getVelocity()).toBe(0)
221
- })
205
+ // Test the analytical spring formulas directly
206
+ // These are internal but critical for correctness
207
+
208
+ it("initial position equals from", () => {
209
+ const mv = motionValue(50)
210
+ mv.set(100, { stiffness: 100, damping: 10 })
211
+ // At t=0, should still be at initial position
212
+ expect(mv.get()).toBe(50)
213
+ })
214
+
215
+ it("initial velocity is preserved", () => {
216
+ const mv = motionValue(0)
217
+ mv.set(100, { stiffness: 100, damping: 10 })
218
+
219
+ // Initial velocity should be 0 (starting from rest)
220
+ expect(mv.getVelocity()).toBe(0)
221
+ })
222
222
  })
@@ -10,117 +10,117 @@ import { type SpringOptions, DEFAULT_SPRING_OPTIONS } from "./types.js"
10
10
 
11
11
  /** Create a MotionValue. Factory function like Motion's motionValue(). */
12
12
  export function motionValue<T>(initial: T): MotionValue<T> {
13
- return new MotionValue(initial)
13
+ return new MotionValue(initial)
14
14
  }
15
15
 
16
16
  /**
17
17
  * MotionValue tracks a value and its velocity, supporting spring animations.
18
18
  */
19
19
  export class MotionValue<T = number> extends EventEmitter<T> {
20
- private current: T
21
- private target: T
22
- private velocity = 0
23
- private animation: { stop: () => void } | null = null
24
-
25
- constructor(initial: T) {
26
- super()
27
- this.current = initial
28
- this.target = initial
29
- }
30
-
31
- /** Get the current value */
32
- get(): T {
33
- return this.current
34
- }
35
-
36
- /** Set value immediately (no animation) */
37
- jump(value: T) {
38
- this.stop()
39
- this.current = value
40
- this.target = value
41
- this.velocity = 0
42
- this.notify("change", value)
43
- }
44
-
45
- /** Set target and animate with spring */
46
- set(value: T, options?: SpringOptions) {
47
- if (typeof value !== "number" || typeof this.current !== "number") {
48
- // Non-numeric: jump immediately
49
- this.jump(value)
50
- return
51
- }
52
- this.target = value
53
- this.animateSpring(options)
54
- }
55
-
56
- /** Get current velocity */
57
- getVelocity(): number {
58
- return this.velocity
59
- }
60
-
61
- /** Check if currently animating */
62
- isAnimating(): boolean {
63
- return this.animation !== null
64
- }
65
-
66
- /** Stop any active animation */
67
- stop() {
68
- if (this.animation) {
69
- this.animation.stop()
70
- this.animation = null
71
- }
72
- }
73
-
74
- /** Destroy and clean up */
75
- destroy() {
76
- this.stop()
77
- this.clearSubscribers()
78
- }
79
-
80
- private animateSpring(options?: SpringOptions) {
81
- this.stop()
82
-
83
- const opts = { ...DEFAULT_SPRING_OPTIONS, ...options }
84
- const from = this.current as number
85
- const to = this.target as number
86
-
87
- if (from === to) return
88
-
89
- // Derive stiffness/damping from visualDuration/bounce if provided
90
- let { stiffness, damping, mass } = opts
91
- if (opts.visualDuration && opts.visualDuration > 0) {
92
- const derived = springFromVisualDuration(opts.visualDuration, opts.bounce)
93
- stiffness = derived.stiffness
94
- damping = derived.damping
95
- }
96
-
97
- // Create spring resolver (analytical solution)
98
- const resolver = createSpringResolver(from, to, this.velocity, stiffness, damping, mass)
99
-
100
- this.notify("animationStart", undefined)
101
- const startTime = Date.now()
102
-
103
- const unsubscribe = subscribeFrame(() => {
104
- const elapsed = (Date.now() - startTime) / 1000 // seconds
105
-
106
- const state = resolver(elapsed)
107
- this.current = state.value as T
108
- this.velocity = state.velocity
109
-
110
- this.notify("change", this.current)
111
-
112
- if (state.done) {
113
- this.current = to as T
114
- this.velocity = 0
115
- this.animation = null
116
- this.notify("change", this.current)
117
- this.notify("animationComplete", undefined)
118
- unsubscribe()
119
- }
120
- })
121
-
122
- this.animation = { stop: unsubscribe }
123
- }
20
+ private current: T
21
+ private target: T
22
+ private velocity = 0
23
+ private animation: { stop: () => void } | null = null
24
+
25
+ constructor(initial: T) {
26
+ super()
27
+ this.current = initial
28
+ this.target = initial
29
+ }
30
+
31
+ /** Get the current value */
32
+ get(): T {
33
+ return this.current
34
+ }
35
+
36
+ /** Set value immediately (no animation) */
37
+ jump(value: T) {
38
+ this.stop()
39
+ this.current = value
40
+ this.target = value
41
+ this.velocity = 0
42
+ this.notify("change", value)
43
+ }
44
+
45
+ /** Set target and animate with spring */
46
+ set(value: T, options?: SpringOptions) {
47
+ if (typeof value !== "number" || typeof this.current !== "number") {
48
+ // Non-numeric: jump immediately
49
+ this.jump(value)
50
+ return
51
+ }
52
+ this.target = value
53
+ this.animateSpring(options)
54
+ }
55
+
56
+ /** Get current velocity */
57
+ getVelocity(): number {
58
+ return this.velocity
59
+ }
60
+
61
+ /** Check if currently animating */
62
+ isAnimating(): boolean {
63
+ return this.animation !== null
64
+ }
65
+
66
+ /** Stop any active animation */
67
+ stop() {
68
+ if (this.animation) {
69
+ this.animation.stop()
70
+ this.animation = null
71
+ }
72
+ }
73
+
74
+ /** Destroy and clean up */
75
+ destroy() {
76
+ this.stop()
77
+ this.clearSubscribers()
78
+ }
79
+
80
+ private animateSpring(options?: SpringOptions) {
81
+ this.stop()
82
+
83
+ const opts = { ...DEFAULT_SPRING_OPTIONS, ...options }
84
+ const from = this.current as number
85
+ const to = this.target as number
86
+
87
+ if (from === to) return
88
+
89
+ // Derive stiffness/damping from visualDuration/bounce if provided
90
+ let { stiffness, damping, mass } = opts
91
+ if (opts.visualDuration && opts.visualDuration > 0) {
92
+ const derived = springFromVisualDuration(opts.visualDuration, opts.bounce)
93
+ stiffness = derived.stiffness
94
+ damping = derived.damping
95
+ }
96
+
97
+ // Create spring resolver (analytical solution)
98
+ const resolver = createSpringResolver(from, to, this.velocity, stiffness, damping, mass)
99
+
100
+ this.notify("animationStart", undefined)
101
+ const startTime = Date.now()
102
+
103
+ const unsubscribe = subscribeFrame(() => {
104
+ const elapsed = (Date.now() - startTime) / 1000 // seconds
105
+
106
+ const state = resolver(elapsed)
107
+ this.current = state.value as T
108
+ this.velocity = state.velocity
109
+
110
+ this.notify("change", this.current)
111
+
112
+ if (state.done) {
113
+ this.current = to as T
114
+ this.velocity = 0
115
+ this.animation = null
116
+ this.notify("change", this.current)
117
+ this.notify("animationComplete", undefined)
118
+ unsubscribe()
119
+ }
120
+ })
121
+
122
+ this.animation = { stop: unsubscribe }
123
+ }
124
124
  }
125
125
 
126
126
  // Re-export everything for backwards compatibility
@@ -129,12 +129,12 @@ export type { EventName, Subscriber } from "./event-emitter.js"
129
129
  export { createSpringResolver, springFromVisualDuration, isSpringSettled } from "./spring-math.js"
130
130
  export { ColorMotionValue } from "./color-motion-value.js"
131
131
  export {
132
- useMotionValue,
133
- useSpring,
134
- useSprings,
135
- useSpringRenderer,
136
- useMotionValueEvent,
137
- useColorMotionValue,
138
- useColorSpring,
132
+ useMotionValue,
133
+ useSpring,
134
+ useSprings,
135
+ useSpringRenderer,
136
+ useMotionValueEvent,
137
+ useColorMotionValue,
138
+ useColorSpring,
139
139
  } from "./hooks.js"
140
140
  export type { RGBA, ColorInput } from "./color.js"