@marimo-team/frontend 0.16.0-dev96986 → 0.16.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 (253) hide show
  1. package/dist/assets/ConnectedDataExplorerComponent-BErMbWvG.js +19 -0
  2. package/dist/assets/{ImageComparisonComponent-SX7fDaTK.js → ImageComparisonComponent-fTHv1Ih0.js} +1 -1
  3. package/dist/assets/{VegaLite-MJUW3b7C.js → VegaLite-Bdi-TyfY.js} +1 -1
  4. package/dist/assets/_baseEach-CNBxBxvS.js +1 -0
  5. package/dist/assets/_baseMap-D1WHjKrd.js +1 -0
  6. package/dist/assets/_baseUniq-CCgDNtZb.js +1 -0
  7. package/dist/assets/{_createAggregator-ZRm2b6Zm.js → _createAggregator-DcD0kTA5.js} +1 -1
  8. package/dist/assets/{agent-panel-BBd11wNX.js → agent-panel-Crv430aI.js} +57 -76
  9. package/dist/assets/{any-language-editor-DwAaEQfS.js → any-language-editor-CQh552Wu.js} +1 -1
  10. package/dist/assets/{architectureDiagram-W76B3OCA-BJmVXUoW.js → architectureDiagram-W76B3OCA-BAJeBxzt.js} +1 -1
  11. package/dist/assets/{between-horizontal-start-KiwU-a3C.js → between-horizontal-start-Boxgxbt_.js} +1 -1
  12. package/dist/assets/{blockDiagram-QIGZ2CNN-DzxZjE7B.js → blockDiagram-QIGZ2CNN-CL-1svEK.js} +1 -1
  13. package/dist/assets/{c4Diagram-FPNF74CW-DjmldG_J.js → c4Diagram-FPNF74CW-BbEqbCTl.js} +1 -1
  14. package/dist/assets/channel-_2eNSz0n.js +1 -0
  15. package/dist/assets/chat-panel-CXh5Wl6C.js +3 -0
  16. package/dist/assets/{chunk-4BX2VUAB-EUTQThiZ.js → chunk-4BX2VUAB-C--8TXeE.js} +1 -1
  17. package/dist/assets/{chunk-55IACEB6-DZAiDJxy.js → chunk-55IACEB6-Bj00HDqq.js} +1 -1
  18. package/dist/assets/{chunk-FMBD7UC4-Bd0Czs-J.js → chunk-FMBD7UC4-C-lhB6hN.js} +1 -1
  19. package/dist/assets/{chunk-K7UQS3LO-DEKMIknX.js → chunk-K7UQS3LO-B-pGTXPt.js} +1 -1
  20. package/dist/assets/{chunk-QN33PNHL-E0jwHU_n.js → chunk-QN33PNHL-DqUzGhvm.js} +1 -1
  21. package/dist/assets/{chunk-QZHKN3VN-BzaIHJbq.js → chunk-QZHKN3VN-TntJHfSk.js} +1 -1
  22. package/dist/assets/{chunk-TVAH2DTR-CZFYvqnm.js → chunk-TVAH2DTR-HUJb1psV.js} +1 -1
  23. package/dist/assets/{chunk-TZMSLE5B-BNqnFjtv.js → chunk-TZMSLE5B-BK3C__t3.js} +1 -1
  24. package/dist/assets/{circle-play-D3J_mYrF.js → circle-play-DBLOv1Yu.js} +1 -1
  25. package/dist/assets/classDiagram-KNZD7YFC-BGmh9POF.js +1 -0
  26. package/dist/assets/classDiagram-v2-RKCZMP56-BGmh9POF.js +1 -0
  27. package/dist/assets/{clear-button-ifzRuAR3.js → clear-button-BeoFbEKH.js} +1 -1
  28. package/dist/assets/clone-BFDSPAj3.js +1 -0
  29. package/dist/assets/{command-palette-D2fdVSET.js → command-palette-CXZiSv0I.js} +1 -1
  30. package/dist/assets/{common-Ku-cF_2J.js → common-C7oJcmCT.js} +1 -1
  31. package/dist/assets/{compile-BgZlHW1c.js → compile-7L0MwhyI.js} +1 -1
  32. package/dist/assets/{cose-bilkent-S5V4N54A-CVM83SqK.js → cose-bilkent-S5V4N54A-BMkGLcVC.js} +1 -1
  33. package/dist/assets/{dagre-5GWH7T2D-ouQPkxT3.js → dagre-5GWH7T2D-BJtRienS.js} +1 -1
  34. package/dist/assets/{data-grid-overlay-editor-B47j5GJJ.js → data-grid-overlay-editor-DBkmGtNs.js} +1 -1
  35. package/dist/assets/datasources-panel-B7FbYLiy.js +1 -0
  36. package/dist/assets/{dependency-graph-panel-CZC_B7pK.js → dependency-graph-panel-DEdOxp2X.js} +1 -1
  37. package/dist/assets/{diagram-N5W7TBWH-CQ817ZdR.js → diagram-N5W7TBWH-CmECY3nb.js} +1 -1
  38. package/dist/assets/{diagram-QEK2KX5R-DOK_psUO.js → diagram-QEK2KX5R-DMOVSNKD.js} +1 -1
  39. package/dist/assets/{diagram-S2PKOQOG-CVljmOW8.js → diagram-S2PKOQOG-BiJ96PNQ.js} +1 -1
  40. package/dist/assets/{documentation-panel-C7yIvGg1.js → documentation-panel-xULhaEv3.js} +1 -1
  41. package/dist/assets/edit-page-BrYda9VE.js +129 -0
  42. package/dist/assets/{ellipsis-vertical-C7FjlUsY.js → ellipsis-vertical-BBqXIlc2.js} +1 -1
  43. package/dist/assets/{empty-state-DIOGM_CU.js → empty-state-B3dA3G5P.js} +1 -1
  44. package/dist/assets/{erDiagram-AWTI2OKA-DYu8cEdc.js → erDiagram-AWTI2OKA-MP1DiFRo.js} +1 -1
  45. package/dist/assets/{error-panel-Ddb8RkFG.js → error-panel-Cc1sv-Ag.js} +1 -1
  46. package/dist/assets/file-explorer-panel-Bw59Kva1.js +1 -0
  47. package/dist/assets/{flowDiagram-PVAE7QVJ-CmvW5iTb.js → flowDiagram-PVAE7QVJ-BX7caPp7.js} +1 -1
  48. package/dist/assets/{ganttDiagram-OWAHRB6G-BaKQlCaT.js → ganttDiagram-OWAHRB6G-B462g4Yf.js} +4 -4
  49. package/dist/assets/{gitGraphDiagram-NY62KEGX-CWO24eP6.js → gitGraphDiagram-NY62KEGX-CGgvZ9-9.js} +1 -1
  50. package/dist/assets/{glide-data-editor-CNDLEJ9a.js → glide-data-editor-C0gUFZON.js} +11 -11
  51. package/dist/assets/{graph-BZKTtxsc.js → graph-CHRVBzY5.js} +1 -1
  52. package/dist/assets/home-page-Fb2osjys.js +9 -0
  53. package/dist/assets/{index-zrSUQXha.js → index-BVgAenPd.js} +1 -1
  54. package/dist/assets/{index-Brf2DwUM.js → index-BY93Ejhl.js} +1 -1
  55. package/dist/assets/{index-CerjupfZ.js → index-C-8WADat.js} +1 -1
  56. package/dist/assets/{index-DZhOPkOB.js → index-C-GhZ7ti.js} +1 -1
  57. package/dist/assets/{index-CZaurnA9.js → index-C1v_Z9et.js} +1 -1
  58. package/dist/assets/{index-0XOUPdwT.js → index-C4Tn5NvJ.js} +1 -1
  59. package/dist/assets/{index-B_d_JZGI.js → index-C77h_TXN.js} +1 -1
  60. package/dist/assets/{index-BJVyzkx5.js → index-CQDrxQ0j.js} +1 -1
  61. package/dist/assets/{index-DFrGFNW1.js → index-CWMgowgL.js} +1 -1
  62. package/dist/assets/{index-DmgwT3sx.js → index-Clbi_Yaq.js} +1 -1
  63. package/dist/assets/{index-D-tZfElD.js → index-CpTPJo4k.js} +1 -1
  64. package/dist/assets/index-Cx0bsY1w.css +1 -0
  65. package/dist/assets/{index-DkntzpX4.js → index-D1vmG6DS.js} +1 -1
  66. package/dist/assets/{index-D3PqGupX.js → index-D9UKkrr2.js} +1 -1
  67. package/dist/assets/{index-BgXbBA39.js → index-DEQvTChO.js} +1 -1
  68. package/dist/assets/index-DKEudB02.js +578 -0
  69. package/dist/assets/{index-DCkzth56.js → index-DRMm6SNo.js} +1 -1
  70. package/dist/assets/{index-WXJFkQHg.js → index-DoRmcrKM.js} +1 -1
  71. package/dist/assets/{index-qE8lHQ-N.js → index-lYa_leQE.js} +1 -1
  72. package/dist/assets/{index-CXrWwFX6.js → index-vmICa5KN.js} +1 -1
  73. package/dist/assets/{index-BH7f3aiU.js → index-z9bohSQJ.js} +1 -1
  74. package/dist/assets/infoDiagram-STP46IZ2-CVyrdLc8.js +2 -0
  75. package/dist/assets/{isEmpty-D1t7Gran.js → isEmpty-DU_ogP_D.js} +1 -1
  76. package/dist/assets/{journeyDiagram-BIP6EPQ6-D4Rp6H_h.js → journeyDiagram-BIP6EPQ6-C6EgLP_Q.js} +1 -1
  77. package/dist/assets/{kanban-definition-6OIFK2YF-DFt9DftA.js → kanban-definition-6OIFK2YF-BXzYO1yj.js} +1 -1
  78. package/dist/assets/{layout-D8WXi2_g.js → layout-jihVw5-i.js} +1 -1
  79. package/dist/assets/{linear-BwY8e5hA.js → linear-C4blANlC.js} +1 -1
  80. package/dist/assets/links-D59GIweI.js +7 -0
  81. package/dist/assets/{logs-panel-Dxiyt7dO.js → logs-panel-D401qzZh.js} +1 -1
  82. package/dist/assets/{markdown-renderer-VDu-NBKB.js → markdown-renderer-Cd9eYyaL.js} +20 -20
  83. package/dist/assets/{mermaid-B-O-Puyi.js → mermaid-BEVuRz_O.js} +1 -1
  84. package/dist/assets/{mermaid.core-BFFCqfOn.js → mermaid.core-CaSnaLH0.js} +4 -4
  85. package/dist/assets/min-DUMu_zeK.js +1 -0
  86. package/dist/assets/{mindmap-definition-Q6HEUPPD-kyvIY8Dg.js → mindmap-definition-Q6HEUPPD-BXUM5MT2.js} +1 -1
  87. package/dist/assets/{number-overlay-editor-GjLB2UK4.js → number-overlay-editor-4uWXGlPG.js} +1 -1
  88. package/dist/assets/outline-panel-DIzkvm2I.js +1 -0
  89. package/dist/assets/{packages-panel-nfXB-bKW.js → packages-panel-CJL0MVlj.js} +1 -1
  90. package/dist/assets/{pieDiagram-ADFJNKIX-D8JFQcWR.js → pieDiagram-ADFJNKIX-Dxt5PVNo.js} +1 -1
  91. package/dist/assets/{quadrantDiagram-LMRXKWRM-Nf8GzxXG.js → quadrantDiagram-LMRXKWRM-D4pUaA31.js} +1 -1
  92. package/dist/assets/{react-plotly-CnW9p7ZA.js → react-plotly-cJZ0VWBq.js} +1 -1
  93. package/dist/assets/{requirementDiagram-4UW4RH46-CCUxF8BZ.js → requirementDiagram-4UW4RH46-DVRTjgas.js} +1 -1
  94. package/dist/assets/{run-page-Bl4p3AbZ.js → run-page-BUEnMC9w.js} +1 -1
  95. package/dist/assets/{sankeyDiagram-GR3RE2ED-Sr8kDwP1.js → sankeyDiagram-GR3RE2ED-CVFnD9C-.js} +1 -1
  96. package/dist/assets/{scratchpad-panel-Ja1Mu-W3.js → scratchpad-panel-BIgRENkI.js} +1 -1
  97. package/dist/assets/{secrets-panel-B-3fcSyP.js → secrets-panel-xY5-V_BD.js} +1 -1
  98. package/dist/assets/{sequenceDiagram-C3RYC4MD-CBJ152Q3.js → sequenceDiagram-C3RYC4MD-_lY4ZN_S.js} +1 -1
  99. package/dist/assets/{slides-component-C-LoGC1U.css → slides-component-DMjQomc3.css} +1 -1
  100. package/dist/assets/{slides-component-DGtsVP5o.js → slides-component-Xjymwj7X.js} +1 -1
  101. package/dist/assets/snippets-panel-CTPYW41n.js +1 -0
  102. package/dist/assets/sortBy-BNZKwiq_.js +1 -0
  103. package/dist/assets/{state-B_RCHTH5.js → state-C4NiC9tO.js} +1 -1
  104. package/dist/assets/{stateDiagram-KXAO66HF-BlBFSAZr.js → stateDiagram-KXAO66HF-Da0JQWCn.js} +1 -1
  105. package/dist/assets/stateDiagram-v2-UMBNRL4Z-D5lYZOOt.js +1 -0
  106. package/dist/assets/storage-CMdLzB_c.js +26 -0
  107. package/dist/assets/{terminal-CATzv5Hd.js → terminal-BPwTkXae.js} +1 -1
  108. package/dist/assets/{time-CsYqILfB.js → time-Dv5_Ouz_.js} +1 -1
  109. package/dist/assets/{timeline-definition-XQNQX7LJ-CGrhjuAs.js → timeline-definition-XQNQX7LJ-Dxh5Zu2e.js} +1 -1
  110. package/dist/assets/tracing-BCIurUfa.js +2 -0
  111. package/dist/assets/{tracing-panel-DmzqPUtc.js → tracing-panel-DAzrzNmm.js} +2 -2
  112. package/dist/assets/{trash-rxdjLzkf.js → trash-Dc6DSjz_.js} +1 -1
  113. package/dist/assets/{tree-C2Ul1h1C.js → tree-jheoerAX.js} +1 -1
  114. package/dist/assets/{treemap-75Q7IDZK-N9hyUpyj.js → treemap-75Q7IDZK-IgpxeGaf.js} +27 -27
  115. package/dist/assets/variable-panel-DYAiLBmF.js +1 -0
  116. package/dist/assets/{vega-component-CR_MHOBT.js → vega-component-BpfpiPKI.js} +1 -1
  117. package/dist/assets/worker-X5rxzQGQ.js +1 -0
  118. package/dist/assets/{xychartDiagram-6GGTOJPD-jdLZsMb2.js → xychartDiagram-6GGTOJPD-CmNigJ31.js} +1 -1
  119. package/dist/index.html +2 -2
  120. package/package.json +2 -3
  121. package/src/components/app-config/user-config-form.tsx +1 -46
  122. package/src/components/chat/acp/__tests__/__snapshots__/prompt.test.ts.snap +43 -62
  123. package/src/components/chat/acp/__tests__/atoms.test.ts +1 -1
  124. package/src/components/chat/acp/__tests__/state.test.ts +36 -36
  125. package/src/components/chat/acp/agent-panel.tsx +27 -24
  126. package/src/components/chat/acp/blocks.tsx +6 -6
  127. package/src/components/chat/acp/prompt.ts +43 -62
  128. package/src/components/chat/chat-panel.tsx +1 -5
  129. package/src/components/chat/markdown-renderer.tsx +10 -6
  130. package/src/components/chat/tool-call-accordion.tsx +20 -52
  131. package/src/components/data-table/SearchBar.tsx +7 -8
  132. package/src/components/data-table/__tests__/column_formatting.test.ts +35 -50
  133. package/src/components/data-table/__tests__/data-table.test.tsx +1 -39
  134. package/src/components/data-table/charts/components/form-fields.tsx +37 -41
  135. package/src/components/data-table/charts/forms/common-chart.tsx +2 -2
  136. package/src/components/data-table/column-explorer-panel/column-explorer.tsx +2 -5
  137. package/src/components/data-table/column-formatting/feature.ts +29 -62
  138. package/src/components/data-table/column-formatting/types.ts +0 -1
  139. package/src/components/data-table/column-header.tsx +1 -3
  140. package/src/components/data-table/column-summary/chart-spec-model.tsx +7 -24
  141. package/src/components/data-table/column-summary/column-summary.tsx +9 -18
  142. package/src/components/data-table/columns.tsx +18 -42
  143. package/src/components/data-table/data-table.tsx +2 -10
  144. package/src/components/data-table/date-popover.tsx +75 -85
  145. package/src/components/data-table/filter-pills.tsx +9 -14
  146. package/src/components/data-table/header-items.tsx +1 -5
  147. package/src/components/data-table/pagination.tsx +13 -20
  148. package/src/components/data-table/renderers.tsx +0 -28
  149. package/src/components/data-table/row-viewer-panel/row-viewer.tsx +8 -10
  150. package/src/components/datasources/column-preview.tsx +2 -6
  151. package/src/components/datasources/datasources.tsx +12 -8
  152. package/src/components/editor/ai/transport/chat-transport.tsx +1 -4
  153. package/src/components/editor/cell/CellStatus.tsx +20 -23
  154. package/src/components/editor/cell/CreateCellButton.tsx +4 -3
  155. package/src/components/editor/cell/code/language-toggle.tsx +4 -3
  156. package/src/components/editor/chrome/wrapper/footer-items/machine-stats.tsx +28 -39
  157. package/src/components/editor/controls/notebook-menu-dropdown.tsx +2 -4
  158. package/src/components/editor/file-tree/requesting-tree.tsx +8 -14
  159. package/src/components/editor/renderers/CellArray.tsx +4 -3
  160. package/src/components/editor/renderers/slides-layout/slides-layout.tsx +3 -3
  161. package/src/components/editor/renderers/slides-layout/types.ts +0 -1
  162. package/src/components/pages/home-page.tsx +1 -4
  163. package/src/components/slides/slides-component.tsx +1 -1
  164. package/src/components/slides/slides.css +0 -6
  165. package/src/components/terminal/theme.tsx +0 -1
  166. package/src/components/tracing/tracing-spec.ts +4 -5
  167. package/src/components/ui/range-slider.tsx +2 -4
  168. package/src/components/ui/slider.tsx +1 -3
  169. package/src/components/variables/variables-table.tsx +0 -3
  170. package/src/core/MarimoApp.tsx +6 -9
  171. package/src/core/ai/context/__tests__/registry.test.ts +4 -6
  172. package/src/core/ai/context/providers/cell-output.ts +2 -3
  173. package/src/core/ai/context/providers/error.ts +1 -3
  174. package/src/core/ai/context/providers/file.ts +2 -7
  175. package/src/core/ai/context/providers/tables.ts +2 -3
  176. package/src/core/ai/context/providers/variable.ts +4 -6
  177. package/src/core/cells/logs.ts +1 -1
  178. package/src/core/codemirror/find-replace/search-highlight.ts +1 -3
  179. package/src/core/codemirror/language/LanguageAdapters.ts +3 -9
  180. package/src/core/codemirror/lsp/notebook-lsp.ts +2 -8
  181. package/src/core/codemirror/readonly/__tests__/extension.test.ts +1 -1
  182. package/src/core/codemirror/rtc/loro/awareness.ts +17 -52
  183. package/src/core/codemirror/rtc/loro/sync.ts +4 -12
  184. package/src/core/config/config-schema.ts +0 -1
  185. package/src/core/config/config.ts +0 -4
  186. package/src/core/hotkeys/hotkeys.ts +4 -8
  187. package/src/core/islands/components/web-components.tsx +10 -13
  188. package/src/core/kernel/RuntimeState.ts +1 -4
  189. package/src/core/kernel/messages.ts +2 -2
  190. package/src/core/network/DeferredRequestRegistry.ts +4 -16
  191. package/src/core/runtime/runtime.ts +4 -5
  192. package/src/core/wasm/bridge.ts +1 -5
  193. package/src/core/wasm/store.ts +1 -4
  194. package/src/core/wasm/worker/message-buffer.ts +2 -3
  195. package/src/core/websocket/types.ts +16 -22
  196. package/src/hooks/useTimer.ts +5 -8
  197. package/src/plugins/core/registerReactComponent.tsx +10 -16
  198. package/src/plugins/impl/DataTablePlugin.tsx +0 -4
  199. package/src/plugins/impl/RangeSliderPlugin.tsx +3 -5
  200. package/src/plugins/impl/SliderPlugin.tsx +1 -3
  201. package/src/plugins/impl/anywidget/model.ts +5 -16
  202. package/src/plugins/impl/data-editor/types.ts +5 -7
  203. package/src/plugins/impl/data-explorer/components/column-summary.tsx +13 -20
  204. package/src/plugins/impl/panel/utils.ts +4 -6
  205. package/src/plugins/layout/StatPlugin.tsx +1 -4
  206. package/src/plugins/plugins.ts +0 -2
  207. package/src/utils/__tests__/dates.test.ts +24 -45
  208. package/src/utils/__tests__/numbers.test.ts +30 -42
  209. package/src/utils/dates.ts +10 -15
  210. package/src/utils/edit-distance.ts +6 -8
  211. package/src/utils/errors.ts +1 -1
  212. package/src/utils/id-tree.tsx +10 -21
  213. package/src/utils/localStorage.ts +4 -13
  214. package/src/utils/numbers.ts +11 -11
  215. package/src/utils/once.ts +0 -32
  216. package/src/utils/paths.ts +1 -4
  217. package/src/utils/pluralize.ts +5 -12
  218. package/src/utils/python-poet/poet.ts +15 -30
  219. package/src/utils/time.ts +1 -5
  220. package/dist/assets/ConnectedDataExplorerComponent-CNLoZkWr.js +0 -19
  221. package/dist/assets/_baseEach-9_logFrf.js +0 -1
  222. package/dist/assets/_baseMap-NzEbKt5c.js +0 -1
  223. package/dist/assets/_baseUniq-C5LFcyNC.js +0 -1
  224. package/dist/assets/channel-DHcKBVM4.js +0 -1
  225. package/dist/assets/chat-panel-DgJZr0eS.js +0 -3
  226. package/dist/assets/classDiagram-KNZD7YFC-D-xwLnlX.js +0 -1
  227. package/dist/assets/classDiagram-v2-RKCZMP56-D-xwLnlX.js +0 -1
  228. package/dist/assets/clone-CSxIll62.js +0 -1
  229. package/dist/assets/datasources-panel-Bt41Zir-.js +0 -1
  230. package/dist/assets/edit-page-CyTMQV2u.js +0 -129
  231. package/dist/assets/file-explorer-panel-Oy9DbyFP.js +0 -1
  232. package/dist/assets/home-page-Bvwppn9N.js +0 -9
  233. package/dist/assets/index-DadI618h.css +0 -1
  234. package/dist/assets/index-PmY0x4Zd.js +0 -578
  235. package/dist/assets/infoDiagram-STP46IZ2-CAuVVehw.js +0 -2
  236. package/dist/assets/links-4B6ldZ5P.js +0 -7
  237. package/dist/assets/min-DtVSfYKl.js +0 -1
  238. package/dist/assets/outline-panel-CMJjOoN7.js +0 -1
  239. package/dist/assets/snippets-panel-ClNnwKBM.js +0 -1
  240. package/dist/assets/sortBy-D47H6Vyl.js +0 -1
  241. package/dist/assets/stateDiagram-v2-UMBNRL4Z-DbA-iToo.js +0 -1
  242. package/dist/assets/storage-BNcWOH3-.js +0 -26
  243. package/dist/assets/tracing-DUbJtOyq.js +0 -2
  244. package/dist/assets/variable-panel-BbgupOdG.js +0 -1
  245. package/dist/assets/worker-fHbtoWvT.js +0 -1
  246. package/src/components/data-table/cell-hover-template/feature.ts +0 -14
  247. package/src/components/data-table/cell-hover-template/types.ts +0 -11
  248. package/src/core/i18n/__tests__/locale-provider.test.tsx +0 -176
  249. package/src/core/i18n/locale-provider.tsx +0 -35
  250. package/src/core/i18n/with-locale.tsx +0 -12
  251. package/src/hooks/useFormatting.ts +0 -97
  252. package/src/plugins/layout/OutlinePlugin.tsx +0 -69
  253. package/src/utils/__tests__/once.test.ts +0 -187
@@ -19,13 +19,11 @@ import {
19
19
  useReactTable,
20
20
  } from "@tanstack/react-table";
21
21
  import React, { memo } from "react";
22
- import { useLocale } from "react-aria";
23
22
 
24
23
  import { Table } from "@/components/ui/table";
25
24
  import type { GetRowIds } from "@/plugins/impl/DataTablePlugin";
26
25
  import { cn } from "@/utils/cn";
27
26
  import type { PanelType } from "../editor/chrome/panels/context-aware-panel/context-aware-panel";
28
- import { CellHoverTemplateFeature } from "./cell-hover-template/feature";
29
27
  import { CellSelectionFeature } from "./cell-selection/feature";
30
28
  import type { CellSelectionState } from "./cell-selection/types";
31
29
  import { CellStylingFeature } from "./cell-styling/feature";
@@ -65,7 +63,6 @@ interface DataTableProps<TData> extends Partial<DownloadActionProps> {
65
63
  rowSelection?: RowSelectionState;
66
64
  cellSelection?: CellSelectionState;
67
65
  cellStyling?: CellStyleState | null;
68
- hoverTemplate?: string | null;
69
66
  onRowSelectionChange?: OnChangeFn<RowSelectionState>;
70
67
  onCellSelectionChange?: OnChangeFn<CellSelectionState>;
71
68
  getRowIds?: GetRowIds;
@@ -106,7 +103,6 @@ const DataTableInternal = <TData,>({
106
103
  rowSelection,
107
104
  cellSelection,
108
105
  cellStyling,
109
- hoverTemplate,
110
106
  paginationState,
111
107
  setPaginationState,
112
108
  downloadAs,
@@ -135,7 +131,6 @@ const DataTableInternal = <TData,>({
135
131
  }: DataTableProps<TData>) => {
136
132
  const [isSearchEnabled, setIsSearchEnabled] = React.useState<boolean>(false);
137
133
  const [showLoadingBar, setShowLoadingBar] = React.useState<boolean>(false);
138
- const { locale } = useLocale();
139
134
 
140
135
  const { columnPinning, setColumnPinning } = useColumnPinning(
141
136
  freezeColumnsLeft,
@@ -181,7 +176,6 @@ const DataTableInternal = <TData,>({
181
176
  ColumnFormattingFeature,
182
177
  CellSelectionFeature,
183
178
  CellStylingFeature,
184
- CellHoverTemplateFeature,
185
179
  CopyColumnFeature,
186
180
  FocusRowFeature,
187
181
  ],
@@ -205,7 +199,6 @@ const DataTableInternal = <TData,>({
205
199
  },
206
200
  }
207
201
  : {}),
208
- locale: locale,
209
202
  manualPagination: manualPagination,
210
203
  getPaginationRowModel: getPaginationRowModel(),
211
204
  // sorting
@@ -240,11 +233,10 @@ const DataTableInternal = <TData,>({
240
233
  ? {}
241
234
  : // No pagination, show all rows
242
235
  { pagination: { pageIndex: 0, pageSize: data.length } }),
243
- rowSelection: rowSelection ?? {},
244
- cellSelection: cellSelection ?? [],
236
+ rowSelection,
237
+ cellSelection,
245
238
  cellStyling,
246
239
  columnPinning: columnPinning,
247
- cellHoverTemplate: hoverTemplate,
248
240
  },
249
241
  });
250
242
 
@@ -1,6 +1,5 @@
1
1
  /* Copyright 2024 Marimo. All rights reserved. */
2
2
  import React from "react";
3
- import { useDateFormatter, useLocale } from "react-aria";
4
3
  import { Tooltip } from "@/components/ui/tooltip";
5
4
 
6
5
  interface DatePopoverProps {
@@ -20,17 +19,33 @@ export const DatePopover: React.FC<DatePopoverProps> = ({
20
19
  }
21
20
 
22
21
  const dateObj = new Date(date);
22
+ const relativeTime = getRelativeTime(dateObj);
23
23
 
24
24
  const content = (
25
25
  <div className="min-w-[240px] p-1 text-sm">
26
- <div className="text-muted-foreground mb-2">
27
- <RelativeTime date={dateObj} />
28
- </div>
26
+ <div className="text-muted-foreground mb-2">{relativeTime}</div>
29
27
  <div className="space-y-1">
30
28
  {type === "datetime" ? (
31
- <TimezoneDisplay date={dateObj} />
29
+ Object.entries(getTimezones(dateObj)).map(
30
+ ([timezone, formattedDate]) => (
31
+ <div
32
+ key={timezone}
33
+ className="grid grid-cols-[fit-content(40px)_1fr] gap-4 items-center justify-items-end"
34
+ >
35
+ <span className="bg-muted rounded-md py-1 px-2 w-fit ml-auto">
36
+ {timezone}
37
+ </span>
38
+ <span>{formattedDate}</span>
39
+ </div>
40
+ ),
41
+ )
32
42
  ) : (
33
- <DateDisplay date={dateObj} />
43
+ <span>
44
+ {dateObj.toLocaleDateString("en-US", {
45
+ timeZone: "UTC",
46
+ dateStyle: "long",
47
+ })}
48
+ </span>
34
49
  )}
35
50
  </div>
36
51
  </div>
@@ -43,79 +58,57 @@ export const DatePopover: React.FC<DatePopoverProps> = ({
43
58
  );
44
59
  };
45
60
 
46
- const TimezoneDisplay = ({ date }: { date: Date }) => {
47
- const { locale } = useLocale();
48
- const localTimezone = Intl.DateTimeFormat(locale).resolvedOptions().timeZone;
49
- const hasSubSeconds = date.getUTCMilliseconds() !== 0;
50
-
51
- const utcFormatter = useDateFormatter(
52
- hasSubSeconds
53
- ? {
54
- timeZone: "UTC",
55
- year: "numeric",
56
- month: "2-digit",
57
- day: "2-digit",
58
- hour: "2-digit",
59
- minute: "2-digit",
60
- second: "2-digit",
61
- fractionalSecondDigits: 3,
62
- }
63
- : {
64
- timeZone: "UTC",
65
- dateStyle: "long",
66
- timeStyle: "medium",
67
- },
68
- );
69
-
70
- const localFormatter = useDateFormatter(
71
- hasSubSeconds
72
- ? {
73
- timeZone: localTimezone,
74
- year: "numeric",
75
- month: "2-digit",
76
- day: "2-digit",
77
- hour: "2-digit",
78
- minute: "2-digit",
79
- second: "2-digit",
80
- fractionalSecondDigits: 3,
81
- }
82
- : {
83
- timeZone: localTimezone,
84
- dateStyle: "long",
85
- timeStyle: "medium",
86
- },
87
- );
88
-
89
- return (
90
- <>
91
- <div className="grid grid-cols-[fit-content(40px)_1fr] gap-4 items-center justify-items-end">
92
- <span className="bg-muted rounded-md py-1 px-2 w-fit ml-auto">UTC</span>
93
- <span>{utcFormatter.format(date)}</span>
94
- </div>
95
- <div className="grid grid-cols-[fit-content(40px)_1fr] gap-4 items-center justify-items-end">
96
- <span className="bg-muted rounded-md py-1 px-2 w-fit ml-auto">
97
- {localTimezone}
98
- </span>
99
- <span>{localFormatter.format(date)}</span>
100
- </div>
101
- </>
102
- );
103
- };
104
-
105
- const DateDisplay = ({ date }: { date: Date }) => {
106
- const dateFormatter = useDateFormatter({
107
- timeZone: "UTC",
108
- dateStyle: "long",
109
- });
61
+ function getTimezones(date: Date) {
62
+ const localTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
110
63
 
111
- return <span>{dateFormatter.format(date)}</span>;
112
- };
64
+ const hasSubSeconds = date.getUTCMilliseconds() !== 0;
65
+ if (hasSubSeconds) {
66
+ return {
67
+ UTC: new Intl.DateTimeFormat("en-US", {
68
+ timeZone: "UTC",
69
+ year: "numeric",
70
+ month: "2-digit",
71
+ day: "2-digit",
72
+ hour: "2-digit",
73
+ minute: "2-digit",
74
+ second: "2-digit",
75
+ fractionalSecondDigits: 3,
76
+ }).format(date),
77
+ [localTimezone]: new Intl.DateTimeFormat("en-US", {
78
+ timeZone: localTimezone,
79
+ year: "numeric",
80
+ month: "2-digit",
81
+ day: "2-digit",
82
+ hour: "2-digit",
83
+ minute: "2-digit",
84
+ second: "2-digit",
85
+ fractionalSecondDigits: 3,
86
+ }).format(date),
87
+ };
88
+ }
113
89
 
114
- const RelativeTime = ({ date }: { date: Date }) => {
115
- const { locale } = useLocale();
90
+ return {
91
+ UTC: new Intl.DateTimeFormat("en-US", {
92
+ timeZone: "UTC",
93
+ dateStyle: "long",
94
+ timeStyle: "medium",
95
+ }).format(date),
96
+ [localTimezone]: new Intl.DateTimeFormat("en-US", {
97
+ timeZone: localTimezone,
98
+ dateStyle: "long",
99
+ timeStyle: "medium",
100
+ }).format(date),
101
+ };
102
+ }
116
103
 
117
- // Initialize relative time formatter with current locale and "auto" numeric style
118
- const relativeTimeFormatter = new Intl.RelativeTimeFormat(locale, {
104
+ /**
105
+ * Converts a date into a human-readable relative time string (e.g. "2 hours ago", "in 5 minutes")
106
+ * Uses Intl.RelativeTimeFormat for localized formatting
107
+ */
108
+ function getRelativeTime(date: Date): string {
109
+ // Initialize relative time formatter with English locale and "auto" numeric style
110
+ // "auto" allows for strings like "yesterday" instead of "1 day ago"
111
+ const relativeTimeFormatter = new Intl.RelativeTimeFormat("en", {
119
112
  numeric: "auto",
120
113
  });
121
114
 
@@ -124,6 +117,7 @@ const RelativeTime = ({ date }: { date: Date }) => {
124
117
  const differenceInSeconds = (currentTime.getTime() - date.getTime()) / 1000;
125
118
 
126
119
  // Define time units with their thresholds and conversion factors
120
+ // Format: [threshold before next unit, seconds in this unit, unit name]
127
121
  const timeUnits: Array<[number, number, string]> = [
128
122
  [60, 1, "second"], // Less than 60 seconds
129
123
  [60, 60, "minute"], // Less than 60 minutes
@@ -140,17 +134,13 @@ const RelativeTime = ({ date }: { date: Date }) => {
140
134
  // Convert to fixed decimal and negate since RelativeTimeFormat expects
141
135
  // negative values for past times and positive for future times
142
136
  const roundedValue = -Number(valueInUnits.toFixed(1));
143
- return (
144
- <span>
145
- {relativeTimeFormatter.format(
146
- roundedValue,
147
- unitName as Intl.RelativeTimeFormatUnit,
148
- )}
149
- </span>
137
+ return relativeTimeFormatter.format(
138
+ roundedValue,
139
+ unitName as Intl.RelativeTimeFormatUnit,
150
140
  );
151
141
  }
152
142
  }
153
143
 
154
144
  // Should never reach here due to Infinity threshold, but provide fallback
155
- return <span>{relativeTimeFormatter.format(0, "second")}</span>;
156
- };
145
+ return relativeTimeFormatter.format(0, "second");
146
+ }
@@ -7,7 +7,6 @@ import type {
7
7
  Table,
8
8
  } from "@tanstack/react-table";
9
9
  import { XIcon } from "lucide-react";
10
- import { type DateFormatter, useDateFormatter } from "react-aria";
11
10
  import { logNever } from "@/utils/assertNever";
12
11
  import { Badge } from "../ui/badge";
13
12
  import type { ColumnFilterValue } from "./filters";
@@ -19,21 +18,12 @@ interface Props<TData> {
19
18
  }
20
19
 
21
20
  export const FilterPills = <TData,>({ filters, table }: Props<TData>) => {
22
- const timeFormatter = useDateFormatter({
23
- hour: "2-digit",
24
- minute: "2-digit",
25
- second: "2-digit",
26
- });
27
-
28
21
  if (!filters || filters.length === 0) {
29
22
  return null;
30
23
  }
31
24
 
32
25
  function renderFilterPill(filter: ColumnFilter) {
33
- const formattedValue = formatValue(
34
- filter.value as ColumnFilterValue,
35
- timeFormatter,
36
- );
26
+ const formattedValue = formatValue(filter.value as ColumnFilterValue);
37
27
  if (!formattedValue) {
38
28
  return null;
39
29
  }
@@ -62,7 +52,7 @@ export const FilterPills = <TData,>({ filters, table }: Props<TData>) => {
62
52
  );
63
53
  };
64
54
 
65
- function formatValue(value: ColumnFilterValue, timeFormatter: DateFormatter) {
55
+ function formatValue(value: ColumnFilterValue) {
66
56
  if (!("type" in value)) {
67
57
  return;
68
58
  }
@@ -81,9 +71,14 @@ function formatValue(value: ColumnFilterValue, timeFormatter: DateFormatter) {
81
71
  return formatMinMax(value.min?.toISOString(), value.max?.toISOString());
82
72
  }
83
73
  if (value.type === "time") {
74
+ const formatTime = new Intl.DateTimeFormat("en-US", {
75
+ hour: "2-digit",
76
+ minute: "2-digit",
77
+ second: "2-digit",
78
+ });
84
79
  return formatMinMax(
85
- value.min ? timeFormatter.format(value.min) : undefined,
86
- value.max ? timeFormatter.format(value.max) : undefined,
80
+ value.min ? formatTime.format(value.min) : undefined,
81
+ value.max ? formatTime.format(value.max) : undefined,
87
82
  );
88
83
  }
89
84
  if (value.type === "datetime") {
@@ -34,7 +34,6 @@ import { NAMELESS_COLUMN_PREFIX } from "./columns";
34
34
 
35
35
  export function renderFormatOptions<TData, TValue>(
36
36
  column: Column<TData, TValue>,
37
- locale: string,
38
37
  ) {
39
38
  const dataType: DataType | undefined = column.columnDef.meta?.dataType;
40
39
  const columnFormatOptions = dataType ? formatOptions[dataType] : [];
@@ -52,9 +51,6 @@ export function renderFormatOptions<TData, TValue>(
52
51
  </DropdownMenuSubTrigger>
53
52
  <DropdownMenuPortal>
54
53
  <DropdownMenuSubContent>
55
- <div className="text-xs text-muted-foreground px-2 py-1">
56
- Locale: {locale}
57
- </div>
58
54
  {Boolean(currentFormat) && (
59
55
  <>
60
56
  <DropdownMenuItem
@@ -76,7 +72,7 @@ export function renderFormatOptions<TData, TValue>(
76
72
  {option}
77
73
  </span>
78
74
  <span className="ml-auto pl-5 text-xs text-muted-foreground">
79
- {formattingExample(option, locale)}
75
+ {formattingExample(option)}
80
76
  </span>
81
77
  </DropdownMenuItem>
82
78
  ))}
@@ -9,10 +9,8 @@ import {
9
9
  ChevronsLeft,
10
10
  ChevronsRight,
11
11
  } from "lucide-react";
12
- import { useLocale } from "react-aria";
13
12
  import { Button } from "@/components/ui/button";
14
13
  import { Events } from "@/utils/events";
15
- import { prettyNumber } from "@/utils/numbers";
16
14
  import { PluralWord } from "@/utils/pluralize";
17
15
  import {
18
16
  Select,
@@ -42,8 +40,6 @@ export const DataTablePagination = <TData,>({
42
40
  tableLoading,
43
41
  showPageSizeSelector,
44
42
  }: DataTablePaginationProps<TData>) => {
45
- const { locale } = useLocale();
46
-
47
43
  const renderTotal = () => {
48
44
  const { rowSelection, cellSelection } = table.getState();
49
45
  let selected = Object.keys(rowSelection).length;
@@ -62,7 +58,7 @@ export const DataTablePagination = <TData,>({
62
58
  if (isAllPageSelected && !isAllSelected) {
63
59
  return (
64
60
  <>
65
- <span>{prettyNumber(selected, locale)} selected</span>
61
+ <span>{prettyNumber(selected)} selected</span>
66
62
  <Button
67
63
  size="xs"
68
64
  data-testid="select-all-button"
@@ -77,7 +73,7 @@ export const DataTablePagination = <TData,>({
77
73
  }
78
74
  }}
79
75
  >
80
- Select all {prettyNumber(numRows, locale)}
76
+ Select all {prettyNumber(numRows)}
81
77
  </Button>
82
78
  </>
83
79
  );
@@ -86,7 +82,7 @@ export const DataTablePagination = <TData,>({
86
82
  if (selected) {
87
83
  return (
88
84
  <>
89
- <span>{prettyNumber(selected, locale)} selected</span>
85
+ <span>{prettyNumber(selected)} selected</span>
90
86
  <Button
91
87
  size="xs"
92
88
  data-testid="clear-selection-button"
@@ -111,11 +107,7 @@ export const DataTablePagination = <TData,>({
111
107
  );
112
108
  }
113
109
 
114
- const rowColumnCount = prettifyRowColumnCount(
115
- numRows,
116
- totalColumns,
117
- locale,
118
- );
110
+ const rowColumnCount = prettifyRowColumnCount(numRows, totalColumns);
119
111
  return <span>{rowColumnCount}</span>;
120
112
  };
121
113
  const currentPage = Math.min(
@@ -207,9 +199,7 @@ export const DataTablePagination = <TData,>({
207
199
  handlePageChange(() => table.setPageIndex(page))
208
200
  }
209
201
  />
210
- <span className="shrink-0">
211
- of {prettyNumber(totalPages, locale)}
212
- </span>
202
+ <span className="shrink-0">of {prettyNumber(totalPages)}</span>
213
203
  </div>
214
204
  <Button
215
205
  size="xs"
@@ -242,6 +232,10 @@ export const DataTablePagination = <TData,>({
242
232
  );
243
233
  };
244
234
 
235
+ function prettyNumber(value: number): string {
236
+ return new Intl.NumberFormat().format(value);
237
+ }
238
+
245
239
  export const PageSelector = ({
246
240
  currentPage,
247
241
  totalPages,
@@ -319,18 +313,17 @@ export const PageSelector = ({
319
313
  );
320
314
  };
321
315
 
322
- export function prettifyRowCount(rowCount: number, locale: string): string {
323
- return `${prettyNumber(rowCount, locale)} ${new PluralWord("row").pluralize(rowCount)}`;
316
+ export function prettifyRowCount(rowCount: number): string {
317
+ return `${prettyNumber(rowCount)} ${new PluralWord("row").pluralize(rowCount)}`;
324
318
  }
325
319
 
326
320
  export const prettifyRowColumnCount = (
327
321
  numRows: number | "too_many",
328
322
  totalColumns: number,
329
- locale: string,
330
323
  ): string => {
331
324
  const rowsLabel =
332
- numRows === "too_many" ? "Unknown" : prettifyRowCount(numRows, locale);
333
- const columnsLabel = `${prettyNumber(totalColumns, locale)} ${new PluralWord("column").pluralize(totalColumns)}`;
325
+ numRows === "too_many" ? "Unknown" : prettifyRowCount(numRows);
326
+ const columnsLabel = `${prettyNumber(totalColumns)} ${new PluralWord("column").pluralize(totalColumns)}`;
334
327
 
335
328
  return [rowsLabel, columnsLabel].join(", ");
336
329
  };
@@ -93,25 +93,6 @@ export const DataTableBody = <TData,>({
93
93
  handleCellsKeyDown,
94
94
  } = useCellRangeSelection({ table });
95
95
 
96
- function applyHoverTemplate(
97
- template: string,
98
- cells: Array<Cell<TData, unknown>>,
99
- ): string {
100
- const variableRegex = /{{(\w+)}}/g;
101
- // Map column id -> stringified value
102
- const idToValue = new Map<string, string>();
103
- for (const c of cells) {
104
- const v = c.getValue();
105
- // Prefer empty string for nulls to keep tooltip clean
106
- const s = renderUnknownValue({ value: v, nullAsEmptyString: true });
107
- idToValue.set(c.column.id, s);
108
- }
109
- return template.replace(variableRegex, (_substr, varName: string) => {
110
- const val = idToValue.get(varName);
111
- return val !== undefined ? val : `{{${varName}}}`;
112
- });
113
- }
114
-
115
96
  const renderCells = (cells: Array<Cell<TData, unknown>>) => {
116
97
  return cells.map((cell) => {
117
98
  const { className, style: pinningstyle } = getPinningStyles(cell.column);
@@ -120,7 +101,6 @@ export const DataTableBody = <TData,>({
120
101
  cell.getUserStyling?.() || {},
121
102
  pinningstyle,
122
103
  );
123
-
124
104
  return (
125
105
  <TableCell
126
106
  tabIndex={0}
@@ -165,18 +145,10 @@ export const DataTableBody = <TData,>({
165
145
  const isRowViewedInPanel =
166
146
  rowViewerPanelOpen && viewedRowIdx === rowIndex;
167
147
 
168
- // Compute hover title once per row using this row's cells (visible or hidden)
169
- const hoverTemplate = table.getState().cellHoverTemplate || null;
170
- const rowCells = row.getAllCells();
171
- const rowTitle = hoverTemplate
172
- ? applyHoverTemplate(hoverTemplate, rowCells)
173
- : undefined;
174
-
175
148
  return (
176
149
  <TableRow
177
150
  key={row.id}
178
151
  data-state={row.getIsSelected() && "selected"}
179
- title={rowTitle}
180
152
  // These classes ensure that empty rows (nulls) still render
181
153
  className={cn(
182
154
  "border-t h-6",
@@ -15,7 +15,6 @@ import {
15
15
  SearchIcon,
16
16
  } from "lucide-react";
17
17
  import { useRef, useState } from "react";
18
- import { useLocale } from "react-aria";
19
18
  import { ColumnName } from "@/components/datasources/components";
20
19
  import { CopyClipboardIcon } from "@/components/icons/copy-icon";
21
20
  import { KeyboardHotkeys } from "@/components/shortcuts/renderShortcut";
@@ -67,7 +66,6 @@ export const RowViewerPanel: React.FC<RowViewerPanelProps> = ({
67
66
  const [searchQuery, setSearchQuery] = useState("");
68
67
  const panelRef = useRef<HTMLDivElement>(null);
69
68
  const searchInputRef = useRef<HTMLInputElement>(null);
70
- const { locale } = useLocale();
71
69
 
72
70
  const tooManyRows = totalRows === TOO_MANY_ROWS;
73
71
 
@@ -206,13 +204,13 @@ export const RowViewerPanel: React.FC<RowViewerPanelProps> = ({
206
204
  applyColumnFormatting: (value) => value,
207
205
  } as Column<unknown>;
208
206
 
209
- const cellContent = renderCellValue({
210
- column: mockColumn,
211
- renderValue: () => columnValue,
212
- getValue: () => columnValue,
213
- selectCell: undefined,
214
- cellStyles: "text-left break-word",
215
- });
207
+ const cellContent = renderCellValue(
208
+ mockColumn,
209
+ () => columnValue,
210
+ () => columnValue,
211
+ undefined,
212
+ "text-left break-word",
213
+ );
216
214
 
217
215
  const copyValue =
218
216
  typeof columnValue === "object"
@@ -288,7 +286,7 @@ export const RowViewerPanel: React.FC<RowViewerPanelProps> = ({
288
286
  <span className="text-xs">
289
287
  {tooManyRows
290
288
  ? `Row ${rowIdx + 1}`
291
- : `Row ${rowIdx + 1} of ${prettifyRowCount(totalRows, locale)}`}
289
+ : `Row ${rowIdx + 1} of ${prettifyRowCount(totalRows)}`}
292
290
  </span>
293
291
  <Button
294
292
  variant="outline"
@@ -3,7 +3,6 @@
3
3
  import { useAtomValue } from "jotai";
4
4
  import { PlusSquareIcon } from "lucide-react";
5
5
  import React, { Suspense } from "react";
6
- import { useLocale } from "react-aria";
7
6
  import { maybeAddAltairImport } from "@/core/cells/add-missing-import";
8
7
  import { useCellActions } from "@/core/cells/cells";
9
8
  import { useLastFocusedCellId } from "@/core/cells/focus";
@@ -43,7 +42,6 @@ export const DatasetColumnPreview: React.FC<{
43
42
  }> = ({ table, column, preview, onAddColumnChart, sqlTableContext }) => {
44
43
  const { theme } = useTheme();
45
44
  const { previewDatasetColumn } = useRequestClient();
46
- const { locale } = useLocale();
47
45
 
48
46
  const previewColumn = () => {
49
47
  previewDatasetColumn({
@@ -109,8 +107,7 @@ export const DatasetColumnPreview: React.FC<{
109
107
  refetchPreview: previewColumn,
110
108
  });
111
109
 
112
- const stats =
113
- preview.stats && renderStats(preview.stats, column.type, locale);
110
+ const stats = preview.stats && renderStats(preview.stats, column.type);
114
111
 
115
112
  const chart = preview.chart_spec && renderChart(preview.chart_spec, theme);
116
113
 
@@ -178,7 +175,6 @@ export function renderPreviewError({
178
175
  export function renderStats(
179
176
  stats: Partial<Record<ColumnHeaderStatsKey, unknown>>,
180
177
  dataType: DataType,
181
- locale: string,
182
178
  ) {
183
179
  return (
184
180
  <div className="gap-x-16 gap-y-1 grid grid-cols-2-fit border rounded p-2 empty:hidden">
@@ -193,7 +189,7 @@ export function renderStats(
193
189
  {convertStatsName(key as ColumnHeaderStatsKey, dataType)}
194
190
  </span>
195
191
  <span className="text-xs font-bold text-muted-foreground tracking-wide">
196
- {prettyNumber(value, locale)}
192
+ {prettyNumber(value)}
197
193
  </span>
198
194
  <CopyClipboardIcon
199
195
  className="h-3 w-3 invisible group-hover:visible"
@@ -304,12 +304,10 @@ const DatabaseItem: React.FC<{
304
304
  }> = ({ hasSearch, engineName, database, children }) => {
305
305
  const [isExpanded, setIsExpanded] = React.useState(false);
306
306
  const [isSelected, setIsSelected] = React.useState(false);
307
- const [prevHasSearch, setPrevHasSearch] = React.useState(hasSearch);
308
307
 
309
- if (prevHasSearch !== hasSearch) {
310
- setPrevHasSearch(hasSearch);
308
+ React.useEffect(() => {
311
309
  setIsExpanded(hasSearch);
312
- }
310
+ }, [hasSearch]);
313
311
 
314
312
  return (
315
313
  <>
@@ -401,10 +399,14 @@ const SchemaItem: React.FC<{
401
399
  children: React.ReactNode;
402
400
  hasSearch: boolean;
403
401
  }> = ({ databaseName, schema, children, hasSearch }) => {
404
- const [isExpanded, setIsExpanded] = React.useState(hasSearch);
402
+ const [isExpanded, setIsExpanded] = React.useState(false);
405
403
  const [isSelected, setIsSelected] = React.useState(false);
406
404
  const uniqueValue = `${databaseName}:${schema.name}`;
407
405
 
406
+ React.useEffect(() => {
407
+ setIsExpanded(hasSearch);
408
+ }, [hasSearch]);
409
+
408
410
  if (isSchemaless(schema.name)) {
409
411
  return children;
410
412
  }
@@ -691,9 +693,11 @@ const DatasetColumnItem: React.FC<{
691
693
  const closeAllColumns = useAtomValue(closeAllColumnsAtom);
692
694
  const setExpandedColumns = useSetAtom(expandedColumnsAtom);
693
695
 
694
- if (closeAllColumns && isExpanded) {
695
- setIsExpanded(false);
696
- }
696
+ React.useEffect(() => {
697
+ if (closeAllColumns) {
698
+ setIsExpanded(false);
699
+ }
700
+ }, [closeAllColumns]);
697
701
 
698
702
  if (isExpanded) {
699
703
  setExpandedColumns(
@@ -13,14 +13,11 @@ import {
13
13
  export class StreamingChunkTransport<
14
14
  UI_MESSAGE extends UIMessage,
15
15
  > extends DefaultChatTransport<UI_MESSAGE> {
16
- private onChunkReceived: (chunk: UIMessageChunk) => void;
17
-
18
16
  constructor(
19
17
  options: HttpChatTransportInitOptions<UI_MESSAGE> = {},
20
- onChunkReceived: (chunk: UIMessageChunk) => void,
18
+ private onChunkReceived: (chunk: UIMessageChunk) => void,
21
19
  ) {
22
20
  super(options);
23
- this.onChunkReceived = onChunkReceived;
24
21
  }
25
22
 
26
23
  protected override processResponseStream(