@marimo-team/frontend 0.15.5 → 0.16.0-dev96986

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 (325) hide show
  1. package/dist/assets/ConnectedDataExplorerComponent-CNLoZkWr.js +19 -0
  2. package/dist/assets/{ImageComparisonComponent-CEXMKKA4.js → ImageComparisonComponent-SX7fDaTK.js} +1 -1
  3. package/dist/assets/{VegaLite-Bt14Ds9k.js → VegaLite-MJUW3b7C.js} +6 -6
  4. package/dist/assets/_baseEach-9_logFrf.js +1 -0
  5. package/dist/assets/_baseMap-NzEbKt5c.js +1 -0
  6. package/dist/assets/_baseUniq-C5LFcyNC.js +1 -0
  7. package/dist/assets/_createAggregator-ZRm2b6Zm.js +1 -0
  8. package/dist/assets/agent-panel-BBd11wNX.js +287 -0
  9. package/dist/assets/agent-panel-D92Mfy1i.css +1 -0
  10. package/dist/assets/{any-language-editor-DiwNT6zp.js → any-language-editor-DwAaEQfS.js} +1 -1
  11. package/dist/assets/architectureDiagram-W76B3OCA-BJmVXUoW.js +36 -0
  12. package/dist/assets/{between-horizontal-start-FyewyCGn.js → between-horizontal-start-KiwU-a3C.js} +1 -1
  13. package/dist/assets/{blockDiagram-QIGZ2CNN-BrOkAf_c.js → blockDiagram-QIGZ2CNN-DzxZjE7B.js} +1 -1
  14. package/dist/assets/{c4Diagram-FPNF74CW-BHPzDxE2.js → c4Diagram-FPNF74CW-DjmldG_J.js} +5 -5
  15. package/dist/assets/channel-DHcKBVM4.js +1 -0
  16. package/dist/assets/chat-panel-DgJZr0eS.js +3 -0
  17. package/dist/assets/{chunk-4BX2VUAB-DLxaCNYh.js → chunk-4BX2VUAB-EUTQThiZ.js} +1 -1
  18. package/dist/assets/{chunk-55IACEB6-DdzvO3HR.js → chunk-55IACEB6-DZAiDJxy.js} +1 -1
  19. package/dist/assets/{chunk-FMBD7UC4-R5o-nSiG.js → chunk-FMBD7UC4-Bd0Czs-J.js} +1 -1
  20. package/dist/assets/{chunk-K7UQS3LO-DxaMrGgG.js → chunk-K7UQS3LO-DEKMIknX.js} +1 -1
  21. package/dist/assets/{chunk-QN33PNHL-DqS9-FYm.js → chunk-QN33PNHL-E0jwHU_n.js} +1 -1
  22. package/dist/assets/{chunk-QZHKN3VN-BZ-TzajS.js → chunk-QZHKN3VN-BzaIHJbq.js} +1 -1
  23. package/dist/assets/{chunk-TVAH2DTR-BsgP2dyv.js → chunk-TVAH2DTR-CZFYvqnm.js} +1 -1
  24. package/dist/assets/{chunk-TZMSLE5B-D-h3ahXI.js → chunk-TZMSLE5B-BNqnFjtv.js} +1 -1
  25. package/dist/assets/{circle-play-CQtRZ-rT.js → circle-play-D3J_mYrF.js} +1 -1
  26. package/dist/assets/classDiagram-KNZD7YFC-D-xwLnlX.js +1 -0
  27. package/dist/assets/classDiagram-v2-RKCZMP56-D-xwLnlX.js +1 -0
  28. package/dist/assets/{clear-button-BY6Z_ViL.js → clear-button-ifzRuAR3.js} +1 -1
  29. package/dist/assets/clone-CSxIll62.js +1 -0
  30. package/dist/assets/command-palette-D2fdVSET.js +1 -0
  31. package/dist/assets/common-Ku-cF_2J.js +1 -0
  32. package/dist/assets/{compile-Ct_jzdKr.js → compile-BgZlHW1c.js} +1 -1
  33. package/dist/assets/cose-bilkent-S5V4N54A-CVM83SqK.js +1 -0
  34. package/dist/assets/dagre-5GWH7T2D-ouQPkxT3.js +4 -0
  35. package/dist/assets/{data-grid-overlay-editor-BN_wulc3.js → data-grid-overlay-editor-B47j5GJJ.js} +1 -1
  36. package/dist/assets/datasources-panel-Bt41Zir-.js +1 -0
  37. package/dist/assets/{dependency-graph-panel-BOmSCZf7.js → dependency-graph-panel-CZC_B7pK.js} +4 -4
  38. package/dist/assets/diagram-N5W7TBWH-CQ817ZdR.js +24 -0
  39. package/dist/assets/diagram-QEK2KX5R-DOK_psUO.js +43 -0
  40. package/dist/assets/diagram-S2PKOQOG-CVljmOW8.js +24 -0
  41. package/dist/assets/{documentation-panel-BxjJO_Gw.js → documentation-panel-C7yIvGg1.js} +1 -1
  42. package/dist/assets/edit-page-CyTMQV2u.js +129 -0
  43. package/dist/assets/{ellipsis-vertical-UHbmjI2n.js → ellipsis-vertical-C7FjlUsY.js} +1 -1
  44. package/dist/assets/{empty-state-BIBXzY_0.js → empty-state-DIOGM_CU.js} +1 -1
  45. package/dist/assets/{erDiagram-AWTI2OKA-E84mAle_.js → erDiagram-AWTI2OKA-DYu8cEdc.js} +1 -1
  46. package/dist/assets/{error-panel-MEvQ6K7h.js → error-panel-Ddb8RkFG.js} +1 -1
  47. package/dist/assets/file-explorer-panel-Oy9DbyFP.js +1 -0
  48. package/dist/assets/{flowDiagram-PVAE7QVJ-DfbIRSAW.js → flowDiagram-PVAE7QVJ-CmvW5iTb.js} +1 -1
  49. package/dist/assets/{ganttDiagram-OWAHRB6G-DR4HZ1z_.js → ganttDiagram-OWAHRB6G-BaKQlCaT.js} +4 -4
  50. package/dist/assets/gitGraphDiagram-NY62KEGX-CWO24eP6.js +65 -0
  51. package/dist/assets/{glide-data-editor-nNmo1lPq.js → glide-data-editor-CNDLEJ9a.js} +11 -11
  52. package/dist/assets/graph-BZKTtxsc.js +1 -0
  53. package/dist/assets/home-page-Bvwppn9N.js +9 -0
  54. package/dist/assets/{index-VPWqq2Pg.js → index-0XOUPdwT.js} +1 -1
  55. package/dist/assets/{index-uacyUula.js → index-BH7f3aiU.js} +1 -1
  56. package/dist/assets/{index-Dt9UWeWn.js → index-BJVyzkx5.js} +1 -1
  57. package/dist/assets/{index-BAH034Ue.js → index-B_d_JZGI.js} +1 -1
  58. package/dist/assets/{index-CB2pnVQG.js → index-BgXbBA39.js} +1 -1
  59. package/dist/assets/{index-B8llrTSo.js → index-Brf2DwUM.js} +1 -1
  60. package/dist/assets/{index-BLu5CX6z.js → index-CXrWwFX6.js} +1 -1
  61. package/dist/assets/{index-DyLSuOH1.js → index-CZaurnA9.js} +1 -1
  62. package/dist/assets/{index-BFSnz7iM.js → index-CerjupfZ.js} +1 -1
  63. package/dist/assets/{index-B7yXbrLa.js → index-D-tZfElD.js} +1 -1
  64. package/dist/assets/{index-c6If577Q.js → index-D3PqGupX.js} +1 -1
  65. package/dist/assets/{index-CSgxTUzD.js → index-DCkzth56.js} +1 -1
  66. package/dist/assets/{index-DWOaniGT.js → index-DFrGFNW1.js} +1 -1
  67. package/dist/assets/{index-CPN7TRA1.js → index-DZhOPkOB.js} +1 -1
  68. package/dist/assets/index-DadI618h.css +1 -0
  69. package/dist/assets/{index-DqzMPAC8.js → index-DkntzpX4.js} +2 -2
  70. package/dist/assets/{index-B1_GXGaP.js → index-DmgwT3sx.js} +1 -1
  71. package/dist/assets/index-PmY0x4Zd.js +578 -0
  72. package/dist/assets/{index-Bq516OmX.js → index-WXJFkQHg.js} +1 -1
  73. package/dist/assets/{index-DSU75csX.js → index-qE8lHQ-N.js} +1 -1
  74. package/dist/assets/{index-DMomwMcN.js → index-zrSUQXha.js} +1 -1
  75. package/dist/assets/infoDiagram-STP46IZ2-CAuVVehw.js +2 -0
  76. package/dist/assets/isEmpty-D1t7Gran.js +1 -0
  77. package/dist/assets/{journeyDiagram-BIP6EPQ6-BBiFyygf.js → journeyDiagram-BIP6EPQ6-D4Rp6H_h.js} +1 -1
  78. package/dist/assets/{kanban-definition-6OIFK2YF-DhgA6Nt6.js → kanban-definition-6OIFK2YF-DFt9DftA.js} +4 -4
  79. package/dist/assets/layout-D8WXi2_g.js +1 -0
  80. package/dist/assets/linear-BwY8e5hA.js +1 -0
  81. package/dist/assets/links-4B6ldZ5P.js +7 -0
  82. package/dist/assets/{logs-panel-B9SmTZAW.js → logs-panel-Dxiyt7dO.js} +1 -1
  83. package/dist/assets/{agent-panel-DpQ6muj-.css → markdown-renderer-ClyzDMmG.css} +1 -1
  84. package/dist/assets/markdown-renderer-VDu-NBKB.js +263 -0
  85. package/dist/assets/mermaid-B-O-Puyi.js +1 -0
  86. package/dist/assets/{mermaid.core-4nVOEVX3.js → mermaid.core-BFFCqfOn.js} +41 -41
  87. package/dist/assets/min-DtVSfYKl.js +1 -0
  88. package/dist/assets/{mindmap-definition-Q6HEUPPD-CVLQNn1q.js → mindmap-definition-Q6HEUPPD-kyvIY8Dg.js} +2 -2
  89. package/dist/assets/{number-overlay-editor-CzRzXLcd.js → number-overlay-editor-GjLB2UK4.js} +1 -1
  90. package/dist/assets/outline-panel-CMJjOoN7.js +1 -0
  91. package/dist/assets/packages-panel-nfXB-bKW.js +1 -0
  92. package/dist/assets/{pieDiagram-ADFJNKIX-C5IQ5DBZ.js → pieDiagram-ADFJNKIX-D8JFQcWR.js} +3 -3
  93. package/dist/assets/{quadrantDiagram-LMRXKWRM-CFXFnQxx.js → quadrantDiagram-LMRXKWRM-Nf8GzxXG.js} +1 -1
  94. package/dist/assets/{react-plotly-mzdv02_Y.js → react-plotly-CnW9p7ZA.js} +1 -1
  95. package/dist/assets/{requirementDiagram-4UW4RH46-D9bPC89T.js → requirementDiagram-4UW4RH46-CCUxF8BZ.js} +1 -1
  96. package/dist/assets/run-page-Bl4p3AbZ.js +1 -0
  97. package/dist/assets/sankeyDiagram-GR3RE2ED-Sr8kDwP1.js +10 -0
  98. package/dist/assets/scratchpad-panel-Ja1Mu-W3.js +1 -0
  99. package/dist/assets/secrets-panel-B-3fcSyP.js +1 -0
  100. package/dist/assets/{sequenceDiagram-C3RYC4MD-6N7_hY4k.js → sequenceDiagram-C3RYC4MD-CBJ152Q3.js} +4 -4
  101. package/dist/assets/{slides-component-DMjQomc3.css → slides-component-C-LoGC1U.css} +1 -1
  102. package/dist/assets/{slides-component-EcjC8sDK.js → slides-component-DGtsVP5o.js} +1 -1
  103. package/dist/assets/snippets-panel-ClNnwKBM.js +1 -0
  104. package/dist/assets/sortBy-D47H6Vyl.js +1 -0
  105. package/dist/assets/state-B_RCHTH5.js +1 -0
  106. package/dist/assets/stateDiagram-KXAO66HF-BlBFSAZr.js +1 -0
  107. package/dist/assets/stateDiagram-v2-UMBNRL4Z-DbA-iToo.js +1 -0
  108. package/dist/assets/storage-BNcWOH3-.js +26 -0
  109. package/dist/assets/terminal-CATzv5Hd.js +10 -0
  110. package/dist/assets/time-CsYqILfB.js +1 -0
  111. package/dist/assets/{timeline-definition-XQNQX7LJ-BEaynAiY.js → timeline-definition-XQNQX7LJ-CGrhjuAs.js} +1 -1
  112. package/dist/assets/tracing-DUbJtOyq.js +2 -0
  113. package/dist/assets/{tracing-panel-BmuHLPrY.js → tracing-panel-DmzqPUtc.js} +2 -2
  114. package/dist/assets/{trash-UBqfK4mR.js → trash-rxdjLzkf.js} +1 -1
  115. package/dist/assets/{tree-XiEycetl.js → tree-C2Ul1h1C.js} +1 -1
  116. package/dist/assets/{treemap-75Q7IDZK-CnuVFbBG.js → treemap-75Q7IDZK-N9hyUpyj.js} +20 -20
  117. package/dist/assets/{ts-tags-CloPe9IY.js → ts-tags-DxCDHihD.js} +1 -1
  118. package/dist/assets/variable-panel-BbgupOdG.js +1 -0
  119. package/dist/assets/{vega-component-DsTH4tuX.js → vega-component-CR_MHOBT.js} +1 -1
  120. package/dist/assets/worker-fHbtoWvT.js +1 -0
  121. package/dist/assets/{xychartDiagram-6GGTOJPD-Dcz3O-A3.js → xychartDiagram-6GGTOJPD-jdLZsMb2.js} +1 -1
  122. package/dist/index.html +2 -2
  123. package/package.json +10 -5
  124. package/src/__tests__/mocks.ts +43 -0
  125. package/src/components/app-config/user-config-form.tsx +78 -1
  126. package/src/components/chat/acp/__tests__/__snapshots__/prompt.test.ts.snap +116 -65
  127. package/src/components/chat/acp/__tests__/atoms.test.ts +1 -1
  128. package/src/components/chat/acp/__tests__/context-utils.test.ts +222 -0
  129. package/src/components/chat/acp/__tests__/prompt.test.ts +1 -1
  130. package/src/components/chat/acp/__tests__/state.test.ts +38 -42
  131. package/src/components/chat/acp/agent-docs.tsx +33 -6
  132. package/src/components/chat/acp/agent-panel.css +0 -18
  133. package/src/components/chat/acp/agent-panel.tsx +394 -72
  134. package/src/components/chat/acp/agent-selector.tsx +7 -1
  135. package/src/components/chat/acp/blocks.tsx +40 -10
  136. package/src/components/chat/acp/common.tsx +10 -2
  137. package/src/components/chat/acp/context-utils.ts +127 -0
  138. package/src/components/chat/acp/prompt.ts +96 -53
  139. package/src/components/chat/acp/state.ts +1 -1
  140. package/src/components/chat/acp/types.ts +8 -0
  141. package/src/components/chat/chat-panel.tsx +28 -89
  142. package/src/components/chat/chat-utils.ts +127 -1
  143. package/src/components/chat/markdown-renderer.css +39 -0
  144. package/src/components/chat/markdown-renderer.tsx +12 -47
  145. package/src/components/chat/tool-call-accordion.tsx +148 -26
  146. package/src/components/data-table/SearchBar.tsx +8 -7
  147. package/src/components/data-table/__tests__/column_formatting.test.ts +50 -35
  148. package/src/components/data-table/__tests__/data-table.test.tsx +39 -1
  149. package/src/components/data-table/cell-hover-template/feature.ts +14 -0
  150. package/src/components/data-table/cell-hover-template/types.ts +11 -0
  151. package/src/components/data-table/charts/components/form-fields.tsx +41 -37
  152. package/src/components/data-table/charts/forms/common-chart.tsx +2 -2
  153. package/src/components/data-table/column-explorer-panel/column-explorer.tsx +5 -2
  154. package/src/components/data-table/column-formatting/feature.ts +62 -29
  155. package/src/components/data-table/column-formatting/types.ts +1 -0
  156. package/src/components/data-table/column-header.tsx +3 -1
  157. package/src/components/data-table/column-summary/chart-spec-model.tsx +24 -7
  158. package/src/components/data-table/column-summary/column-summary.tsx +18 -9
  159. package/src/components/data-table/columns.tsx +42 -18
  160. package/src/components/data-table/data-table.tsx +10 -2
  161. package/src/components/data-table/date-popover.tsx +85 -75
  162. package/src/components/data-table/filter-pills.tsx +14 -9
  163. package/src/components/data-table/header-items.tsx +5 -1
  164. package/src/components/data-table/pagination.tsx +20 -13
  165. package/src/components/data-table/renderers.tsx +28 -0
  166. package/src/components/data-table/row-viewer-panel/row-viewer.tsx +10 -8
  167. package/src/components/datasources/column-preview.tsx +6 -2
  168. package/src/components/datasources/datasources.tsx +8 -12
  169. package/src/components/editor/Cell.tsx +6 -0
  170. package/src/components/editor/actions/name-cell-input.tsx +6 -1
  171. package/src/components/editor/actions/useCellActionButton.tsx +3 -1
  172. package/src/components/editor/ai/__tests__/completion-utils.test.ts +178 -1
  173. package/src/components/editor/ai/add-cell-with-ai.tsx +68 -66
  174. package/src/components/editor/ai/ai-completion-editor.tsx +29 -26
  175. package/src/components/editor/ai/completion-handlers.tsx +44 -6
  176. package/src/components/editor/ai/completion-utils.ts +92 -0
  177. package/src/components/editor/ai/transport/chat-transport.tsx +39 -0
  178. package/src/components/editor/cell/CellStatus.tsx +23 -20
  179. package/src/components/editor/cell/CreateCellButton.tsx +3 -4
  180. package/src/components/editor/cell/StagedAICell.tsx +51 -0
  181. package/src/components/editor/cell/cell-actions.tsx +2 -1
  182. package/src/components/editor/cell/code/language-toggle.tsx +3 -4
  183. package/src/components/editor/chrome/wrapper/footer-items/machine-stats.tsx +39 -28
  184. package/src/components/editor/controls/notebook-menu-dropdown.tsx +4 -2
  185. package/src/components/editor/file-tree/requesting-tree.tsx +14 -8
  186. package/src/components/editor/renderers/CellArray.tsx +3 -4
  187. package/src/components/editor/renderers/slides-layout/slides-layout.tsx +3 -3
  188. package/src/components/editor/renderers/slides-layout/types.ts +1 -0
  189. package/src/components/pages/home-page.tsx +4 -1
  190. package/src/components/slides/slides-component.tsx +1 -1
  191. package/src/components/slides/slides.css +6 -0
  192. package/src/components/terminal/__tests__/state.test.ts +207 -0
  193. package/src/components/terminal/hooks.ts +41 -0
  194. package/src/components/terminal/state.ts +75 -0
  195. package/src/components/terminal/terminal.tsx +334 -13
  196. package/src/components/terminal/theme.tsx +57 -0
  197. package/src/components/tracing/tracing-spec.ts +5 -4
  198. package/src/components/ui/range-slider.tsx +4 -2
  199. package/src/components/ui/slider.tsx +3 -1
  200. package/src/components/variables/variables-table.tsx +3 -0
  201. package/src/core/MarimoApp.tsx +9 -6
  202. package/src/core/ai/__tests__/staged-cells.test.ts +356 -0
  203. package/src/core/ai/context/__tests__/registry.test.ts +6 -4
  204. package/src/core/ai/context/providers/cell-output.ts +3 -2
  205. package/src/core/ai/context/providers/error.ts +3 -1
  206. package/src/core/ai/context/providers/file.ts +7 -2
  207. package/src/core/ai/context/providers/tables.ts +3 -2
  208. package/src/core/ai/context/providers/variable.ts +6 -4
  209. package/src/core/ai/staged-cells.ts +208 -0
  210. package/src/core/cells/cells.ts +1 -1
  211. package/src/core/cells/logs.ts +1 -1
  212. package/src/core/codemirror/find-replace/search-highlight.ts +3 -1
  213. package/src/core/codemirror/language/LanguageAdapters.ts +9 -3
  214. package/src/core/codemirror/lsp/federated-lsp.ts +1 -1
  215. package/src/core/codemirror/lsp/notebook-lsp.ts +8 -2
  216. package/src/core/codemirror/readonly/__tests__/extension.test.ts +1 -1
  217. package/src/core/codemirror/rtc/loro/awareness.ts +52 -17
  218. package/src/core/codemirror/rtc/loro/sync.ts +12 -4
  219. package/src/core/config/config-schema.ts +1 -0
  220. package/src/core/config/config.ts +4 -0
  221. package/src/core/hotkeys/hotkeys.ts +8 -4
  222. package/src/core/i18n/__tests__/locale-provider.test.tsx +176 -0
  223. package/src/core/i18n/locale-provider.tsx +35 -0
  224. package/src/core/i18n/with-locale.tsx +12 -0
  225. package/src/core/islands/components/web-components.tsx +13 -10
  226. package/src/core/islands/main.ts +2 -2
  227. package/src/core/kernel/RuntimeState.ts +4 -1
  228. package/src/core/kernel/messages.ts +8 -12
  229. package/src/core/network/DeferredRequestRegistry.ts +16 -4
  230. package/src/core/runtime/runtime.ts +5 -4
  231. package/src/core/saving/__tests__/filename.test.ts +37 -0
  232. package/src/core/static/__tests__/download-html.test.ts +43 -1
  233. package/src/core/wasm/bridge.ts +5 -1
  234. package/src/core/wasm/store.ts +4 -1
  235. package/src/core/wasm/worker/message-buffer.ts +3 -2
  236. package/src/core/websocket/types.ts +22 -16
  237. package/src/core/websocket/useMarimoWebSocket.tsx +2 -2
  238. package/src/css/app/Cell.css +11 -0
  239. package/src/hooks/useFormatting.ts +97 -0
  240. package/src/hooks/useTimer.ts +8 -5
  241. package/src/plugins/core/RenderHTML.tsx +36 -2
  242. package/src/plugins/core/__test__/RenderHTML.test.ts +72 -0
  243. package/src/plugins/core/registerReactComponent.tsx +44 -10
  244. package/src/plugins/impl/DataTablePlugin.tsx +4 -0
  245. package/src/plugins/impl/FileBrowserPlugin.tsx +8 -2
  246. package/src/plugins/impl/RangeSliderPlugin.tsx +5 -3
  247. package/src/plugins/impl/SliderPlugin.tsx +3 -1
  248. package/src/plugins/impl/anywidget/model.ts +16 -5
  249. package/src/plugins/impl/data-editor/types.ts +7 -5
  250. package/src/plugins/impl/data-explorer/components/column-summary.tsx +20 -13
  251. package/src/plugins/impl/panel/utils.ts +6 -4
  252. package/src/plugins/layout/OutlinePlugin.tsx +69 -0
  253. package/src/plugins/layout/StatPlugin.tsx +4 -1
  254. package/src/plugins/plugins.ts +2 -0
  255. package/src/stories/cell.stories.tsx +1 -1
  256. package/src/stories/layout/vertical/one-column.stories.tsx +1 -1
  257. package/src/utils/__tests__/cell-urls.test.ts +29 -0
  258. package/src/utils/__tests__/dates.test.ts +45 -24
  259. package/src/utils/__tests__/filenames.test.ts +18 -0
  260. package/src/utils/__tests__/numbers.test.ts +42 -30
  261. package/src/utils/__tests__/once.test.ts +187 -0
  262. package/src/utils/__tests__/path.test.ts +38 -0
  263. package/src/utils/__tests__/urls.test.ts +56 -1
  264. package/src/utils/dates.ts +15 -10
  265. package/src/utils/edit-distance.ts +8 -6
  266. package/src/utils/errors.ts +9 -0
  267. package/src/utils/id-tree.tsx +21 -10
  268. package/src/utils/localStorage.ts +13 -4
  269. package/src/utils/numbers.ts +11 -11
  270. package/src/utils/once.ts +32 -0
  271. package/src/utils/paths.ts +4 -1
  272. package/src/utils/pluralize.ts +12 -5
  273. package/src/utils/python-poet/poet.ts +30 -15
  274. package/src/utils/time.ts +5 -1
  275. package/dist/assets/ConnectedDataExplorerComponent-Cn5-l2X1.js +0 -19
  276. package/dist/assets/_baseEach-C1FLm7WW.js +0 -1
  277. package/dist/assets/_baseMap-DBVArUYD.js +0 -1
  278. package/dist/assets/_baseUniq-Dk7ZPJ3N.js +0 -1
  279. package/dist/assets/_createAggregator-Bn38fDd3.js +0 -1
  280. package/dist/assets/agent-panel-COUYnuIK.js +0 -475
  281. package/dist/assets/architectureDiagram-W76B3OCA-DBzWQKKu.js +0 -36
  282. package/dist/assets/channel-CjhbjOv4.js +0 -1
  283. package/dist/assets/chat-panel-BPXKoTnZ.js +0 -7
  284. package/dist/assets/chat-panel-Brrs_eeH.css +0 -1
  285. package/dist/assets/classDiagram-KNZD7YFC-DHs5cFzy.js +0 -1
  286. package/dist/assets/classDiagram-v2-RKCZMP56-DHs5cFzy.js +0 -1
  287. package/dist/assets/clone-DM1YNjEn.js +0 -1
  288. package/dist/assets/command-palette-S0bzQp7v.js +0 -1
  289. package/dist/assets/common-B8U9k2Ly.js +0 -1
  290. package/dist/assets/cose-bilkent-S5V4N54A-wz1Sfx7j.js +0 -1
  291. package/dist/assets/dagre-5GWH7T2D-BfpcVBgq.js +0 -4
  292. package/dist/assets/datasources-panel-DfuURLJw.js +0 -1
  293. package/dist/assets/diagram-N5W7TBWH-Bf0oqqQh.js +0 -24
  294. package/dist/assets/diagram-QEK2KX5R-ZTc3qikh.js +0 -43
  295. package/dist/assets/diagram-S2PKOQOG-tLScBy7Z.js +0 -24
  296. package/dist/assets/edit-page-DJ8kJZ9w.js +0 -129
  297. package/dist/assets/file-explorer-panel-CzNUJ63G.js +0 -1
  298. package/dist/assets/gitGraphDiagram-NY62KEGX-C1t6QtVa.js +0 -65
  299. package/dist/assets/graph-CssCVWIq.js +0 -1
  300. package/dist/assets/home-page-9eW6qida.js +0 -9
  301. package/dist/assets/index-CknhX2Vy.css +0 -1
  302. package/dist/assets/index-DcCIe7np.js +0 -28
  303. package/dist/assets/index-OC46250R.js +0 -570
  304. package/dist/assets/infoDiagram-STP46IZ2-CwiAoz9f.js +0 -2
  305. package/dist/assets/layout-DpQrxGW-.js +0 -1
  306. package/dist/assets/linear-NsreOeBF.js +0 -1
  307. package/dist/assets/links-CbvGxbsJ.js +0 -7
  308. package/dist/assets/mermaid-DSt0r6IQ.js +0 -1
  309. package/dist/assets/min-D259kI3t.js +0 -1
  310. package/dist/assets/outline-panel-uvsS-YEQ.js +0 -1
  311. package/dist/assets/packages-panel-xMz9W2hW.js +0 -1
  312. package/dist/assets/run-page-Bb68qdhQ.js +0 -1
  313. package/dist/assets/sankeyDiagram-GR3RE2ED-BSJOau8E.js +0 -10
  314. package/dist/assets/scratchpad-panel-BF4BO-U4.js +0 -1
  315. package/dist/assets/secrets-panel-CdIX44dQ.js +0 -1
  316. package/dist/assets/snippets-panel-Dco9h0rb.js +0 -1
  317. package/dist/assets/sortBy-aLGA-PGK.js +0 -1
  318. package/dist/assets/stateDiagram-KXAO66HF-Bd68WT3b.js +0 -1
  319. package/dist/assets/stateDiagram-v2-UMBNRL4Z-BXz_GSwb.js +0 -1
  320. package/dist/assets/storage-CGlP4lCF.js +0 -26
  321. package/dist/assets/terminal-CxkHubcu.js +0 -9
  322. package/dist/assets/time-D2nr1UgQ.js +0 -1
  323. package/dist/assets/tracing-kTqHxa7q.js +0 -2
  324. package/dist/assets/variable-panel-noTnH-AQ.js +0 -1
  325. package/dist/assets/worker-X5rxzQGQ.js +0 -1
@@ -1,5 +1,6 @@
1
1
  /* Copyright 2024 Marimo. All rights reserved. */
2
2
  import React from "react";
3
+ import { useDateFormatter, useLocale } from "react-aria";
3
4
  import { Tooltip } from "@/components/ui/tooltip";
4
5
 
5
6
  interface DatePopoverProps {
@@ -19,33 +20,17 @@ export const DatePopover: React.FC<DatePopoverProps> = ({
19
20
  }
20
21
 
21
22
  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">{relativeTime}</div>
26
+ <div className="text-muted-foreground mb-2">
27
+ <RelativeTime date={dateObj} />
28
+ </div>
27
29
  <div className="space-y-1">
28
30
  {type === "datetime" ? (
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
- )
31
+ <TimezoneDisplay date={dateObj} />
42
32
  ) : (
43
- <span>
44
- {dateObj.toLocaleDateString("en-US", {
45
- timeZone: "UTC",
46
- dateStyle: "long",
47
- })}
48
- </span>
33
+ <DateDisplay date={dateObj} />
49
34
  )}
50
35
  </div>
51
36
  </div>
@@ -58,57 +43,79 @@ export const DatePopover: React.FC<DatePopoverProps> = ({
58
43
  );
59
44
  };
60
45
 
61
- function getTimezones(date: Date) {
62
- const localTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
63
-
46
+ const TimezoneDisplay = ({ date }: { date: Date }) => {
47
+ const { locale } = useLocale();
48
+ const localTimezone = Intl.DateTimeFormat(locale).resolvedOptions().timeZone;
64
49
  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
- }
89
50
 
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
- }
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
+ });
103
110
 
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", {
111
+ return <span>{dateFormatter.format(date)}</span>;
112
+ };
113
+
114
+ const RelativeTime = ({ date }: { date: Date }) => {
115
+ const { locale } = useLocale();
116
+
117
+ // Initialize relative time formatter with current locale and "auto" numeric style
118
+ const relativeTimeFormatter = new Intl.RelativeTimeFormat(locale, {
112
119
  numeric: "auto",
113
120
  });
114
121
 
@@ -117,7 +124,6 @@ function getRelativeTime(date: Date): string {
117
124
  const differenceInSeconds = (currentTime.getTime() - date.getTime()) / 1000;
118
125
 
119
126
  // Define time units with their thresholds and conversion factors
120
- // Format: [threshold before next unit, seconds in this unit, unit name]
121
127
  const timeUnits: Array<[number, number, string]> = [
122
128
  [60, 1, "second"], // Less than 60 seconds
123
129
  [60, 60, "minute"], // Less than 60 minutes
@@ -134,13 +140,17 @@ function getRelativeTime(date: Date): string {
134
140
  // Convert to fixed decimal and negate since RelativeTimeFormat expects
135
141
  // negative values for past times and positive for future times
136
142
  const roundedValue = -Number(valueInUnits.toFixed(1));
137
- return relativeTimeFormatter.format(
138
- roundedValue,
139
- unitName as Intl.RelativeTimeFormatUnit,
143
+ return (
144
+ <span>
145
+ {relativeTimeFormatter.format(
146
+ roundedValue,
147
+ unitName as Intl.RelativeTimeFormatUnit,
148
+ )}
149
+ </span>
140
150
  );
141
151
  }
142
152
  }
143
153
 
144
154
  // Should never reach here due to Infinity threshold, but provide fallback
145
- return relativeTimeFormatter.format(0, "second");
146
- }
155
+ return <span>{relativeTimeFormatter.format(0, "second")}</span>;
156
+ };
@@ -7,6 +7,7 @@ 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";
10
11
  import { logNever } from "@/utils/assertNever";
11
12
  import { Badge } from "../ui/badge";
12
13
  import type { ColumnFilterValue } from "./filters";
@@ -18,12 +19,21 @@ interface Props<TData> {
18
19
  }
19
20
 
20
21
  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
+
21
28
  if (!filters || filters.length === 0) {
22
29
  return null;
23
30
  }
24
31
 
25
32
  function renderFilterPill(filter: ColumnFilter) {
26
- const formattedValue = formatValue(filter.value as ColumnFilterValue);
33
+ const formattedValue = formatValue(
34
+ filter.value as ColumnFilterValue,
35
+ timeFormatter,
36
+ );
27
37
  if (!formattedValue) {
28
38
  return null;
29
39
  }
@@ -52,7 +62,7 @@ export const FilterPills = <TData,>({ filters, table }: Props<TData>) => {
52
62
  );
53
63
  };
54
64
 
55
- function formatValue(value: ColumnFilterValue) {
65
+ function formatValue(value: ColumnFilterValue, timeFormatter: DateFormatter) {
56
66
  if (!("type" in value)) {
57
67
  return;
58
68
  }
@@ -71,14 +81,9 @@ function formatValue(value: ColumnFilterValue) {
71
81
  return formatMinMax(value.min?.toISOString(), value.max?.toISOString());
72
82
  }
73
83
  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
- });
79
84
  return formatMinMax(
80
- value.min ? formatTime.format(value.min) : undefined,
81
- value.max ? formatTime.format(value.max) : undefined,
85
+ value.min ? timeFormatter.format(value.min) : undefined,
86
+ value.max ? timeFormatter.format(value.max) : undefined,
82
87
  );
83
88
  }
84
89
  if (value.type === "datetime") {
@@ -34,6 +34,7 @@ import { NAMELESS_COLUMN_PREFIX } from "./columns";
34
34
 
35
35
  export function renderFormatOptions<TData, TValue>(
36
36
  column: Column<TData, TValue>,
37
+ locale: string,
37
38
  ) {
38
39
  const dataType: DataType | undefined = column.columnDef.meta?.dataType;
39
40
  const columnFormatOptions = dataType ? formatOptions[dataType] : [];
@@ -51,6 +52,9 @@ export function renderFormatOptions<TData, TValue>(
51
52
  </DropdownMenuSubTrigger>
52
53
  <DropdownMenuPortal>
53
54
  <DropdownMenuSubContent>
55
+ <div className="text-xs text-muted-foreground px-2 py-1">
56
+ Locale: {locale}
57
+ </div>
54
58
  {Boolean(currentFormat) && (
55
59
  <>
56
60
  <DropdownMenuItem
@@ -72,7 +76,7 @@ export function renderFormatOptions<TData, TValue>(
72
76
  {option}
73
77
  </span>
74
78
  <span className="ml-auto pl-5 text-xs text-muted-foreground">
75
- {formattingExample(option)}
79
+ {formattingExample(option, locale)}
76
80
  </span>
77
81
  </DropdownMenuItem>
78
82
  ))}
@@ -9,8 +9,10 @@ import {
9
9
  ChevronsLeft,
10
10
  ChevronsRight,
11
11
  } from "lucide-react";
12
+ import { useLocale } from "react-aria";
12
13
  import { Button } from "@/components/ui/button";
13
14
  import { Events } from "@/utils/events";
15
+ import { prettyNumber } from "@/utils/numbers";
14
16
  import { PluralWord } from "@/utils/pluralize";
15
17
  import {
16
18
  Select,
@@ -40,6 +42,8 @@ export const DataTablePagination = <TData,>({
40
42
  tableLoading,
41
43
  showPageSizeSelector,
42
44
  }: DataTablePaginationProps<TData>) => {
45
+ const { locale } = useLocale();
46
+
43
47
  const renderTotal = () => {
44
48
  const { rowSelection, cellSelection } = table.getState();
45
49
  let selected = Object.keys(rowSelection).length;
@@ -58,7 +62,7 @@ export const DataTablePagination = <TData,>({
58
62
  if (isAllPageSelected && !isAllSelected) {
59
63
  return (
60
64
  <>
61
- <span>{prettyNumber(selected)} selected</span>
65
+ <span>{prettyNumber(selected, locale)} selected</span>
62
66
  <Button
63
67
  size="xs"
64
68
  data-testid="select-all-button"
@@ -73,7 +77,7 @@ export const DataTablePagination = <TData,>({
73
77
  }
74
78
  }}
75
79
  >
76
- Select all {prettyNumber(numRows)}
80
+ Select all {prettyNumber(numRows, locale)}
77
81
  </Button>
78
82
  </>
79
83
  );
@@ -82,7 +86,7 @@ export const DataTablePagination = <TData,>({
82
86
  if (selected) {
83
87
  return (
84
88
  <>
85
- <span>{prettyNumber(selected)} selected</span>
89
+ <span>{prettyNumber(selected, locale)} selected</span>
86
90
  <Button
87
91
  size="xs"
88
92
  data-testid="clear-selection-button"
@@ -107,7 +111,11 @@ export const DataTablePagination = <TData,>({
107
111
  );
108
112
  }
109
113
 
110
- const rowColumnCount = prettifyRowColumnCount(numRows, totalColumns);
114
+ const rowColumnCount = prettifyRowColumnCount(
115
+ numRows,
116
+ totalColumns,
117
+ locale,
118
+ );
111
119
  return <span>{rowColumnCount}</span>;
112
120
  };
113
121
  const currentPage = Math.min(
@@ -199,7 +207,9 @@ export const DataTablePagination = <TData,>({
199
207
  handlePageChange(() => table.setPageIndex(page))
200
208
  }
201
209
  />
202
- <span className="shrink-0">of {prettyNumber(totalPages)}</span>
210
+ <span className="shrink-0">
211
+ of {prettyNumber(totalPages, locale)}
212
+ </span>
203
213
  </div>
204
214
  <Button
205
215
  size="xs"
@@ -232,10 +242,6 @@ export const DataTablePagination = <TData,>({
232
242
  );
233
243
  };
234
244
 
235
- function prettyNumber(value: number): string {
236
- return new Intl.NumberFormat().format(value);
237
- }
238
-
239
245
  export const PageSelector = ({
240
246
  currentPage,
241
247
  totalPages,
@@ -313,17 +319,18 @@ export const PageSelector = ({
313
319
  );
314
320
  };
315
321
 
316
- export function prettifyRowCount(rowCount: number): string {
317
- return `${prettyNumber(rowCount)} ${new PluralWord("row").pluralize(rowCount)}`;
322
+ export function prettifyRowCount(rowCount: number, locale: string): string {
323
+ return `${prettyNumber(rowCount, locale)} ${new PluralWord("row").pluralize(rowCount)}`;
318
324
  }
319
325
 
320
326
  export const prettifyRowColumnCount = (
321
327
  numRows: number | "too_many",
322
328
  totalColumns: number,
329
+ locale: string,
323
330
  ): string => {
324
331
  const rowsLabel =
325
- numRows === "too_many" ? "Unknown" : prettifyRowCount(numRows);
326
- const columnsLabel = `${prettyNumber(totalColumns)} ${new PluralWord("column").pluralize(totalColumns)}`;
332
+ numRows === "too_many" ? "Unknown" : prettifyRowCount(numRows, locale);
333
+ const columnsLabel = `${prettyNumber(totalColumns, locale)} ${new PluralWord("column").pluralize(totalColumns)}`;
327
334
 
328
335
  return [rowsLabel, columnsLabel].join(", ");
329
336
  };
@@ -93,6 +93,25 @@ 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
+
96
115
  const renderCells = (cells: Array<Cell<TData, unknown>>) => {
97
116
  return cells.map((cell) => {
98
117
  const { className, style: pinningstyle } = getPinningStyles(cell.column);
@@ -101,6 +120,7 @@ export const DataTableBody = <TData,>({
101
120
  cell.getUserStyling?.() || {},
102
121
  pinningstyle,
103
122
  );
123
+
104
124
  return (
105
125
  <TableCell
106
126
  tabIndex={0}
@@ -145,10 +165,18 @@ export const DataTableBody = <TData,>({
145
165
  const isRowViewedInPanel =
146
166
  rowViewerPanelOpen && viewedRowIdx === rowIndex;
147
167
 
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
+
148
175
  return (
149
176
  <TableRow
150
177
  key={row.id}
151
178
  data-state={row.getIsSelected() && "selected"}
179
+ title={rowTitle}
152
180
  // These classes ensure that empty rows (nulls) still render
153
181
  className={cn(
154
182
  "border-t h-6",
@@ -15,6 +15,7 @@ import {
15
15
  SearchIcon,
16
16
  } from "lucide-react";
17
17
  import { useRef, useState } from "react";
18
+ import { useLocale } from "react-aria";
18
19
  import { ColumnName } from "@/components/datasources/components";
19
20
  import { CopyClipboardIcon } from "@/components/icons/copy-icon";
20
21
  import { KeyboardHotkeys } from "@/components/shortcuts/renderShortcut";
@@ -66,6 +67,7 @@ export const RowViewerPanel: React.FC<RowViewerPanelProps> = ({
66
67
  const [searchQuery, setSearchQuery] = useState("");
67
68
  const panelRef = useRef<HTMLDivElement>(null);
68
69
  const searchInputRef = useRef<HTMLInputElement>(null);
70
+ const { locale } = useLocale();
69
71
 
70
72
  const tooManyRows = totalRows === TOO_MANY_ROWS;
71
73
 
@@ -204,13 +206,13 @@ export const RowViewerPanel: React.FC<RowViewerPanelProps> = ({
204
206
  applyColumnFormatting: (value) => value,
205
207
  } as Column<unknown>;
206
208
 
207
- const cellContent = renderCellValue(
208
- mockColumn,
209
- () => columnValue,
210
- () => columnValue,
211
- undefined,
212
- "text-left break-word",
213
- );
209
+ const cellContent = renderCellValue({
210
+ column: mockColumn,
211
+ renderValue: () => columnValue,
212
+ getValue: () => columnValue,
213
+ selectCell: undefined,
214
+ cellStyles: "text-left break-word",
215
+ });
214
216
 
215
217
  const copyValue =
216
218
  typeof columnValue === "object"
@@ -286,7 +288,7 @@ export const RowViewerPanel: React.FC<RowViewerPanelProps> = ({
286
288
  <span className="text-xs">
287
289
  {tooManyRows
288
290
  ? `Row ${rowIdx + 1}`
289
- : `Row ${rowIdx + 1} of ${prettifyRowCount(totalRows)}`}
291
+ : `Row ${rowIdx + 1} of ${prettifyRowCount(totalRows, locale)}`}
290
292
  </span>
291
293
  <Button
292
294
  variant="outline"
@@ -3,6 +3,7 @@
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";
6
7
  import { maybeAddAltairImport } from "@/core/cells/add-missing-import";
7
8
  import { useCellActions } from "@/core/cells/cells";
8
9
  import { useLastFocusedCellId } from "@/core/cells/focus";
@@ -42,6 +43,7 @@ export const DatasetColumnPreview: React.FC<{
42
43
  }> = ({ table, column, preview, onAddColumnChart, sqlTableContext }) => {
43
44
  const { theme } = useTheme();
44
45
  const { previewDatasetColumn } = useRequestClient();
46
+ const { locale } = useLocale();
45
47
 
46
48
  const previewColumn = () => {
47
49
  previewDatasetColumn({
@@ -107,7 +109,8 @@ export const DatasetColumnPreview: React.FC<{
107
109
  refetchPreview: previewColumn,
108
110
  });
109
111
 
110
- const stats = preview.stats && renderStats(preview.stats, column.type);
112
+ const stats =
113
+ preview.stats && renderStats(preview.stats, column.type, locale);
111
114
 
112
115
  const chart = preview.chart_spec && renderChart(preview.chart_spec, theme);
113
116
 
@@ -175,6 +178,7 @@ export function renderPreviewError({
175
178
  export function renderStats(
176
179
  stats: Partial<Record<ColumnHeaderStatsKey, unknown>>,
177
180
  dataType: DataType,
181
+ locale: string,
178
182
  ) {
179
183
  return (
180
184
  <div className="gap-x-16 gap-y-1 grid grid-cols-2-fit border rounded p-2 empty:hidden">
@@ -189,7 +193,7 @@ export function renderStats(
189
193
  {convertStatsName(key as ColumnHeaderStatsKey, dataType)}
190
194
  </span>
191
195
  <span className="text-xs font-bold text-muted-foreground tracking-wide">
192
- {prettyNumber(value)}
196
+ {prettyNumber(value, locale)}
193
197
  </span>
194
198
  <CopyClipboardIcon
195
199
  className="h-3 w-3 invisible group-hover:visible"
@@ -304,10 +304,12 @@ 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);
307
308
 
308
- React.useEffect(() => {
309
+ if (prevHasSearch !== hasSearch) {
310
+ setPrevHasSearch(hasSearch);
309
311
  setIsExpanded(hasSearch);
310
- }, [hasSearch]);
312
+ }
311
313
 
312
314
  return (
313
315
  <>
@@ -399,14 +401,10 @@ const SchemaItem: React.FC<{
399
401
  children: React.ReactNode;
400
402
  hasSearch: boolean;
401
403
  }> = ({ databaseName, schema, children, hasSearch }) => {
402
- const [isExpanded, setIsExpanded] = React.useState(false);
404
+ const [isExpanded, setIsExpanded] = React.useState(hasSearch);
403
405
  const [isSelected, setIsSelected] = React.useState(false);
404
406
  const uniqueValue = `${databaseName}:${schema.name}`;
405
407
 
406
- React.useEffect(() => {
407
- setIsExpanded(hasSearch);
408
- }, [hasSearch]);
409
-
410
408
  if (isSchemaless(schema.name)) {
411
409
  return children;
412
410
  }
@@ -693,11 +691,9 @@ const DatasetColumnItem: React.FC<{
693
691
  const closeAllColumns = useAtomValue(closeAllColumnsAtom);
694
692
  const setExpandedColumns = useSetAtom(expandedColumnsAtom);
695
693
 
696
- React.useEffect(() => {
697
- if (closeAllColumns) {
698
- setIsExpanded(false);
699
- }
700
- }, [closeAllColumns]);
694
+ if (closeAllColumns && isExpanded) {
695
+ setIsExpanded(false);
696
+ }
701
697
 
702
698
  if (isExpanded) {
703
699
  setExpandedColumns(
@@ -72,6 +72,10 @@ import { CollapsedCellBanner, CollapseToggle } from "./cell/collapse";
72
72
  import { DeleteButton } from "./cell/DeleteButton";
73
73
  import { PendingDeleteConfirmation } from "./cell/PendingDeleteConfirmation";
74
74
  import { RunButton } from "./cell/RunButton";
75
+ import {
76
+ StagedAICellBackground,
77
+ StagedAICellFooter,
78
+ } from "./cell/StagedAICell";
75
79
  import { useDeleteCellCallback } from "./cell/useDeleteCell";
76
80
  import { useRunCell } from "./cell/useRunCells";
77
81
  import { HideCodeButton } from "./code/readonly-python-code";
@@ -571,6 +575,7 @@ const EditableCellComponent = ({
571
575
  >
572
576
  {cellOutput === "above" && outputArea}
573
577
  <div className={cn("tray")} data-hidden={isMarkdownCodeHidden}>
578
+ <StagedAICellBackground cellId={cellId} />
574
579
  <div className="absolute right-2 -top-4 z-10">
575
580
  <CellToolbar
576
581
  edited={cellData.edited}
@@ -729,6 +734,7 @@ const EditableCellComponent = ({
729
734
  />
730
735
  <PendingDeleteConfirmation cellId={cellId} />
731
736
  </div>
737
+ <StagedAICellFooter cellId={cellId} />
732
738
  {isCollapsed && (
733
739
  <CollapsedCellBanner
734
740
  onClick={() => actions.expandCell({ cellId })}
@@ -19,12 +19,14 @@ interface Props
19
19
  value: string;
20
20
  onChange: (newName: string) => void;
21
21
  placeholder?: string;
22
+ onEnterKey?: () => void;
22
23
  }
23
24
 
24
25
  export const NameCellInput: React.FC<Props> = ({
25
26
  value,
26
27
  onChange,
27
28
  placeholder,
29
+ onEnterKey,
28
30
  ...props
29
31
  }) => {
30
32
  const ref = useRef<HTMLInputElement>(null);
@@ -53,7 +55,10 @@ export const NameCellInput: React.FC<Props> = ({
53
55
  ref={ref}
54
56
  placeholder={placeholder}
55
57
  className="shadow-none! hover:shadow-none focus:shadow-none focus-visible:shadow-none"
56
- onKeyDown={Events.onEnter(Events.stopPropagation())}
58
+ onKeyDown={Events.onEnter((e) => {
59
+ Events.stopPropagation()(e);
60
+ onEnterKey?.();
61
+ })}
57
62
  {...props}
58
63
  />
59
64
  );
@@ -73,9 +73,10 @@ export interface CellActionButtonProps
73
73
 
74
74
  interface Props {
75
75
  cell: CellActionButtonProps | null;
76
+ closePopover?: () => void;
76
77
  }
77
78
 
78
- export function useCellActionButtons({ cell }: Props) {
79
+ export function useCellActionButtons({ cell, closePopover }: Props) {
79
80
  const {
80
81
  createNewCell: createCell,
81
82
  updateCellConfig,
@@ -177,6 +178,7 @@ export function useCellActionButtons({ cell }: Props) {
177
178
  placeholder={"cell name"}
178
179
  value={name}
179
180
  onChange={(newName) => updateCellName({ cellId, name: newName })}
181
+ onEnterKey={() => closePopover?.()}
180
182
  />
181
183
  ),
182
184
  },