@marimo-team/frontend 0.25.2-dev3 → 0.25.2-dev31

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 (216) hide show
  1. package/dist/assets/{ConnectedDataExplorerComponent-DJ5jwKfp.js → ConnectedDataExplorerComponent-Bli_Q2Pf.js} +1 -1
  2. package/dist/assets/{ErrorBoundary-BeE1cdgM.js → ErrorBoundary-Dx6lhNls.js} +2 -2
  3. package/dist/assets/{LazyAnyLanguageCodeMirror-B_IYTCX5.js → LazyAnyLanguageCodeMirror-CfdjWQov.js} +2 -2
  4. package/dist/assets/{RunButton-C2kFUhyO.js → RunButton-5jKnc29t.js} +2 -2
  5. package/dist/assets/__vite-browser-external-BgsHWynV.js +1 -0
  6. package/dist/assets/__vite-browser-external-DMJaCYJh.js +1 -0
  7. package/dist/assets/{abnfDiagram-VCTEODGH-CSPJSGaM.js → abnfDiagram-VCTEODGH-CS9VJ4IQ.js} +1 -1
  8. package/dist/assets/{add-cell-with-ai-BFgdVPaN.js → add-cell-with-ai-h_sx2HjG.js} +1 -1
  9. package/dist/assets/{agent-panel-Dh7yWh9P.js → agent-panel-C3MlqlHQ.js} +1 -1
  10. package/dist/assets/{ai-model-dropdown-DJ2elMLM.js → ai-model-dropdown-D_95EaOb.js} +1 -1
  11. package/dist/assets/{alert-dialog-CeE3i3Qa.js → alert-dialog-BsB0FYEL.js} +1 -1
  12. package/dist/assets/{any-language-editor-Cj_HzlZY.js → any-language-editor-DqrxopyM.js} +1 -1
  13. package/dist/assets/{app-config-button-DBCTefOX.js → app-config-button-AOmd3MSM.js} +1 -1
  14. package/dist/assets/architecture-7GRP2DOG-d-euXJif.js +1 -0
  15. package/dist/assets/{architectureDiagram-5GKGNRK7-7iukRoC9.js → architectureDiagram-5GKGNRK7-Cnq1OhHb.js} +1 -1
  16. package/dist/assets/{blockDiagram-I7D4REHJ-cuhpQB60.js → blockDiagram-I7D4REHJ-Belx_uSy.js} +1 -1
  17. package/dist/assets/{button-BoklZTGL.js → button-qFeU84ax.js} +1 -1
  18. package/dist/assets/{c4Diagram-7LVT6UL2-CMQEYn6T.js → c4Diagram-7LVT6UL2-B4RJxCU5.js} +1 -1
  19. package/dist/assets/{cache-panel-C0oB1kE2.js → cache-panel-ByvhZkRB.js} +1 -1
  20. package/dist/assets/{capabilities-Bj3s1hGN.js → capabilities-BqUNf14U.js} +1 -1
  21. package/dist/assets/{cells-CzugpTQu.js → cells-BXPymufT.js} +2 -2
  22. package/dist/assets/channel-CNw_DjeM.js +1 -0
  23. package/dist/assets/chat-display-Bl_cm4Bv.js +1 -0
  24. package/dist/assets/{chat-panel-BGw0bqDk.js → chat-panel-G5k-O9XI.js} +1 -1
  25. package/dist/assets/{chat-ui-CZZFGlZi.js → chat-ui-B9ojDwqD.js} +1 -1
  26. package/dist/assets/{chunk-4HAMMTFA-C6Tl7kEY.js → chunk-4HAMMTFA-BskE_kxl.js} +1 -1
  27. package/dist/assets/{chunk-75Z2AOVW-BzzYECN7.js → chunk-75Z2AOVW-BGGJQUsr.js} +1 -1
  28. package/dist/assets/{chunk-DU6HZSFF-BlpgvKzl.js → chunk-DU6HZSFF-BbUeHz2R.js} +1 -1
  29. package/dist/assets/{chunk-F27PBJKO-BVIgLGPF.js → chunk-F27PBJKO-BIJD5Wdq.js} +1 -1
  30. package/dist/assets/{chunk-GMAD6QVW-hv6IsAru.js → chunk-GMAD6QVW-De3yHY5A.js} +1 -1
  31. package/dist/assets/{chunk-GVQU2GXP-Duv4ZYb-.js → chunk-GVQU2GXP-CKFdw6Un.js} +1 -1
  32. package/dist/assets/{chunk-IMKFNOWR-BIILwBhp.js → chunk-IMKFNOWR-DaJnBQov.js} +1 -1
  33. package/dist/assets/{chunk-L3NEJ4N5-B2hafvRU.js → chunk-L3NEJ4N5-9WBGd7N9.js} +1 -1
  34. package/dist/assets/{chunk-OSK3NFVY-SNGRdtNA.js → chunk-OSK3NFVY-CawDZVpS.js} +1 -1
  35. package/dist/assets/{chunk-P2QGCYS3-_SeE0QXb.js → chunk-P2QGCYS3-C7JwFzl3.js} +1 -1
  36. package/dist/assets/{chunk-POPQ4Y6H-BB5NNJFE.js → chunk-POPQ4Y6H-B9wQmUAO.js} +1 -1
  37. package/dist/assets/{chunk-PWAF6VOD-BZoBqp8x.js → chunk-PWAF6VOD-D5iYVIst.js} +1 -1
  38. package/dist/assets/{chunk-SHT3W25Y-BtLGdeDB.js → chunk-SHT3W25Y-ChLuP8JP.js} +1 -1
  39. package/dist/assets/{chunk-SVP7TREG-B0UfxhUP.js → chunk-SVP7TREG-BZxpXOz-.js} +1 -1
  40. package/dist/assets/{chunk-TICWLB2K-BP7vel_P.js → chunk-TICWLB2K-WyejxyKe.js} +1 -1
  41. package/dist/assets/{chunk-YOKDWASO-CaoEAGJk.js → chunk-YOKDWASO-84E-_nIR.js} +4 -4
  42. package/dist/assets/{circle-CeQt3rdW.js → circle-CzTMKZwz.js} +1 -1
  43. package/dist/assets/classDiagram-ZZMXUADV-D3p0TN4D.js +1 -0
  44. package/dist/assets/classDiagram-v2-VYDZK3BY-D3p0TN4D.js +1 -0
  45. package/dist/assets/{code-visibility-BFNYI7hr.js → code-visibility-dpVhqYNL.js} +1 -1
  46. package/dist/assets/{command-palette-DN4JoOLD.js → command-palette-D6z9kPg7.js} +1 -1
  47. package/dist/assets/{common-DUCPhoyP.js → common-ByaXhTaS.js} +1 -1
  48. package/dist/assets/{components-DAmFBASm.js → components-Bg0jEPXR.js} +1 -1
  49. package/dist/assets/{components-CK7CeYlo.js → components-D5oqtiLg.js} +1 -1
  50. package/dist/assets/{config-B4VJJibu.js → config-2Nts63h2.js} +1 -1
  51. package/dist/assets/{config-BxZgoFvi.js → config-BdH5RvM0.js} +1 -1
  52. package/dist/assets/{config-DpGPGznL.js → config-D7CP5wR5.js} +1 -1
  53. package/dist/assets/{copy-BhJktFeI.js → copy-B--GzTEX.js} +1 -1
  54. package/dist/assets/{copy-icon-DFhUGBjO.js → copy-icon-DQuttmjH.js} +1 -1
  55. package/dist/assets/{createReducer-BPvK7C_R.js → createReducer-CI8rlZE9.js} +1 -1
  56. package/dist/assets/{cynefin-OW5HDTMX-DIiiykJg.js → cynefin-OW5HDTMX-GFKj4n0O.js} +1 -1
  57. package/dist/assets/{cynefinDiagram-5FMLGOSQ-BARZRQBb.js → cynefinDiagram-5FMLGOSQ-ADfRyIGN.js} +1 -1
  58. package/dist/assets/{dagre-DVyyr7Cb.js → dagre-BNpoWXcL.js} +1 -1
  59. package/dist/assets/{dagre-GXQ25YYZ-79s0lOP0.js → dagre-GXQ25YYZ-Diet3S0x.js} +1 -1
  60. package/dist/assets/{data-grid-overlay-editor-DPfnIudL.js → data-grid-overlay-editor-BEM-ieFB.js} +1 -1
  61. package/dist/assets/{dependency-graph-panel-BN4CLayU.js → dependency-graph-panel-CrensQ9d.js} +1 -1
  62. package/dist/assets/{diagram-S7CK7UJ4-BCviGhvd.js → diagram-S7CK7UJ4-CCX9feKM.js} +1 -1
  63. package/dist/assets/{diagram-UQ7AKVKN-Ds-BT46T.js → diagram-UQ7AKVKN-DMu2JraT.js} +1 -1
  64. package/dist/assets/{diagram-VSXAHHWV-CK4GkM-q.js → diagram-VSXAHHWV-Dtg7sh2B.js} +1 -1
  65. package/dist/assets/{diagram-VX7I27RA-BtL2eh0t.js → diagram-VX7I27RA-D3OGvedU.js} +1 -1
  66. package/dist/assets/{diagram-Z3DM3KII-C6SmbLBS.js → diagram-Z3DM3KII-MArsMIcf.js} +1 -1
  67. package/dist/assets/{dist-CyYN7zJg.js → dist-DFI04FfI.js} +1 -1
  68. package/dist/assets/{documentation-panel-CzRbXV5u.js → documentation-panel-DDYXbqvp.js} +1 -1
  69. package/dist/assets/{dropdown-menu-VuyoeQOD.js → dropdown-menu-Crx6knLg.js} +1 -1
  70. package/dist/assets/{ebnfDiagram-PWID7BFC-D_JU4cMQ.js → ebnfDiagram-PWID7BFC-vQJPmojo.js} +1 -1
  71. package/dist/assets/{edit-page-jGNYBqQo.js → edit-page-C7naRe4T.js} +45 -45
  72. package/dist/assets/{erDiagram-RLTQ6QDP-Z9MJ6X-r.js → erDiagram-RLTQ6QDP-DbMS_wVH.js} +1 -1
  73. package/dist/assets/{error-entries-CDSsy76p.js → error-entries-FCI5CEqR.js} +1 -1
  74. package/dist/assets/{error-panel-ABvjFG3p.js → error-panel-CgT73q4b.js} +1 -1
  75. package/dist/assets/eventmodeling-NTZA5JFV-C7Lb8MCA.js +1 -0
  76. package/dist/assets/{feedback-button-CZhLiwkO.js → feedback-button-B0hzbli5.js} +1 -1
  77. package/dist/assets/{file-explorer-panel-DTiEpmVE.js → file-explorer-panel-Dl3gX4fl.js} +1 -1
  78. package/dist/assets/{file-name-input-C1C8xrjA.js → file-name-input-CV0fYc67.js} +1 -1
  79. package/dist/assets/{filename-fxG7K_MU.js → filename-DZ9xkzQn.js} +1 -1
  80. package/dist/assets/flowDiagram-HODETNUW-C9M5c8rH.js +1 -0
  81. package/dist/assets/{fullscreen-BmzAqMKq.js → fullscreen-3wS6IaIC.js} +1 -1
  82. package/dist/assets/{gallery-page-Moi4ZdJ0.js → gallery-page-B6WMdce0.js} +1 -1
  83. package/dist/assets/{ganttDiagram-EL5Y4UJY-Cgy11k0G.js → ganttDiagram-EL5Y4UJY-DtBccFoD.js} +1 -1
  84. package/dist/assets/{gitGraph-4MIJSDKK-BlIdVC2G.js → gitGraph-4MIJSDKK-BZrVnUIX.js} +1 -1
  85. package/dist/assets/{gitGraphDiagram-WWUBYQGX-CVH8fay_.js → gitGraphDiagram-WWUBYQGX-BWNR7nHV.js} +1 -1
  86. package/dist/assets/{glide-data-editor-CbsCWu-K.js → glide-data-editor-qrXT33Qd.js} +4 -4
  87. package/dist/assets/{graphlib-3maKwbRO.js → graphlib-C-6pc4Zd.js} +1 -1
  88. package/dist/assets/has-DmAIW7kM.js +1 -0
  89. package/dist/assets/{highlighted-body-KPVGNVTW-D9V82ncH.js → highlighted-body-KPVGNVTW-DxcqwMAu.js} +1 -1
  90. package/dist/assets/{home-page-UAgVOkCZ.js → home-page-DsILx4TF.js} +1 -1
  91. package/dist/assets/{index--sT8xf-8.css → index-C4-iduJO.css} +1 -1
  92. package/dist/assets/{index-DafnX1Xx.js → index-DYVlDtsu.js} +11 -11
  93. package/dist/assets/{info-A6RAGUB7-BdPbe-lF.js → info-A6RAGUB7-u3lEx9f-.js} +1 -1
  94. package/dist/assets/{infoDiagram-27XIBGKW-Dk8U81nJ.js → infoDiagram-27XIBGKW-b4WMhbpt.js} +1 -1
  95. package/dist/assets/{input-BDakodZ2.js → input-D4bMj5Nb.js} +1 -1
  96. package/dist/assets/{ishikawaDiagram-5VMMS53U-CzHQlMUQ.js → ishikawaDiagram-5VMMS53U-DQxtMs4g.js} +1 -1
  97. package/dist/assets/{journeyDiagram-3NMN7TZE-DRc8ACzh.js → journeyDiagram-3NMN7TZE-yCIlrFH1.js} +1 -1
  98. package/dist/assets/{kanban-definition-UXKFOSKX-CVyVYiI6.js → kanban-definition-UXKFOSKX-rhD_vnwl.js} +1 -1
  99. package/dist/assets/{logs-panel-Bz5ysVX4.js → logs-panel-ByevEcIA.js} +1 -1
  100. package/dist/assets/{menu-items-BBdeXCvU.js → menu-items-D-vbZmqL.js} +1 -1
  101. package/dist/assets/{mermaid-D_jPUVqz.js → mermaid-B2ngFN0c.js} +4 -4
  102. package/dist/assets/mermaid-HWGCJPDP-Bk1fR60Q.js +1 -0
  103. package/dist/assets/{mermaid-parser.core-3RKOfUXB.js → mermaid-parser.core-BdlE0Iab.js} +3 -3
  104. package/dist/assets/{mindmap-definition-YA3MSWOX-D5t6Aq5Z.js → mindmap-definition-YA3MSWOX-D5hDBYDC.js} +1 -1
  105. package/dist/assets/{number-overlay-editor-FAD8sjFU.js → number-overlay-editor-BcElw1N2.js} +1 -1
  106. package/dist/assets/{numbers-DsgsDslU.js → numbers-DyJNv6Vk.js} +1 -1
  107. package/dist/assets/{outline-panel-85oiQ0XX.js → outline-panel-CHw9TjuQ.js} +1 -1
  108. package/dist/assets/{packages-panel-ClKIaP5S.js → packages-panel-CDb2_4Dc.js} +1 -1
  109. package/dist/assets/{packet-AYTQ26CC-st4ZYus8.js → packet-AYTQ26CC-BajGVcwf.js} +1 -1
  110. package/dist/assets/{panels-B48zp96D.js → panels-rdTyuwHQ.js} +3 -3
  111. package/dist/assets/{pegDiagram-XKGWAZYB-BTkTm4ej.js → pegDiagram-XKGWAZYB-D8QLsgnM.js} +1 -1
  112. package/dist/assets/{pie-WAS4IAKB-GwT5MHDl.js → pie-WAS4IAKB-8yOLd-eD.js} +1 -1
  113. package/dist/assets/{pieDiagram-E7YTZNPT-Bq6X88M1.js → pieDiagram-E7YTZNPT-DeJxGsNN.js} +1 -1
  114. package/dist/assets/{preload-helper-HclGiUj8.js → preload-helper-uBIymjUX.js} +1 -1
  115. package/dist/assets/{process-output-Cg2ta3vY.js → process-output-DqkSNdEt.js} +1 -1
  116. package/dist/assets/purify.es--06brOip.js +3 -0
  117. package/dist/assets/{quadrantDiagram-AXDQQJYC-D_wrOwLk.js → quadrantDiagram-AXDQQJYC-BOooPQcn.js} +1 -1
  118. package/dist/assets/{radar-RG4KPBEZ-h1Tdn-Oz.js → radar-RG4KPBEZ-CxHjJ3AF.js} +1 -1
  119. package/dist/assets/{railroad-74A4TZTK-r4Uf-msd.js → railroad-74A4TZTK-Bv_oZ8fK.js} +1 -1
  120. package/dist/assets/railroad-abnf-HS5TGJTU-fZMJYLPw.js +1 -0
  121. package/dist/assets/railroad-ebnf-LZEXJU2U-MXzdI5RK.js +1 -0
  122. package/dist/assets/railroad-peg-WCYAUIDC-9iJg5MJM.js +1 -0
  123. package/dist/assets/{railroadDiagram-O6MQD6OU-fv8HXW_g.js → railroadDiagram-O6MQD6OU-Cv1c_MPc.js} +1 -1
  124. package/dist/assets/{requirementDiagram-BXWQKSXE-DDOOMUfC.js → requirementDiagram-BXWQKSXE-C5vd9-4j.js} +1 -1
  125. package/dist/assets/{reveal-component-CR43gpTZ.js → reveal-component-Dctnn9_M.js} +1 -1
  126. package/dist/assets/{run-page-NR_KFWk8.js → run-page-BiThhUDc.js} +1 -1
  127. package/dist/assets/{sankeyDiagram-P5KCCOFB-CvvUY6tS.js → sankeyDiagram-P5KCCOFB-DpHoqt-1.js} +1 -1
  128. package/dist/assets/{save-worker-Dw8ybFWq.js → save-worker-C880NC3o.js} +5 -5
  129. package/dist/assets/{scratchpad-panel-DHc-oVb1.js → scratchpad-panel-C1fSG5vy.js} +1 -1
  130. package/dist/assets/{scroll-to-bottom-button-BSCkDXet.js → scroll-to-bottom-button-BLNi0TGS.js} +1 -1
  131. package/dist/assets/{secrets-panel-C-65ZjnM.js → secrets-panel-7_LH6R8A.js} +1 -1
  132. package/dist/assets/{select-BplWpfFo.js → select-CWHHoM53.js} +1 -1
  133. package/dist/assets/{sequenceDiagram-WJ2MYXX4-DdpBhQaS.js → sequenceDiagram-WJ2MYXX4-C22eqEIy.js} +1 -1
  134. package/dist/assets/{session-panel-DiwQqIbt.js → session-panel-DBsTbpC9.js} +1 -1
  135. package/dist/assets/{session-DXKMv4Bs.js → session-ztCnZJHI.js} +1 -1
  136. package/dist/assets/{snippets-panel-BLmXrneD.js → snippets-panel-ChI5aU42.js} +1 -1
  137. package/dist/assets/{state-Ozzur_f2.js → state-0NZOvqJz.js} +1 -1
  138. package/dist/assets/{stateDiagram-D77RDMKH-D3p19fac.js → stateDiagram-D77RDMKH-BRy9VFgk.js} +1 -1
  139. package/dist/assets/stateDiagram-v2-MP3YSRHH-CxpbMKE8.js +1 -0
  140. package/dist/assets/{strings-BHZPE0Mc.js → strings-LjhpYwmx.js} +1 -1
  141. package/dist/assets/{swimlanes-42K2YHIH-CLxCSvU4.js → swimlanes-42K2YHIH-CvQuAAYe.js} +1 -1
  142. package/dist/assets/swimlanesDiagram-VR7AAH4N-CANFdBys.js +8 -0
  143. package/dist/assets/{swiper-component-rqJChT_P.js → swiper-component-CCQgW-CG.js} +1 -1
  144. package/dist/assets/{terminal-CY4h1UmO.js → terminal-Ct69I5Rq.js} +1 -1
  145. package/dist/assets/{timeline-definition-24CTP7MA-Cw2PY--x.js → timeline-definition-24CTP7MA-CtEY04jV.js} +1 -1
  146. package/dist/assets/{toast-KNfsFUiB.js → toast-DXkezxWI.js} +1 -1
  147. package/dist/assets/{tooltip-PLkI_UfK.js → tooltip-BQ9qHrrN.js} +1 -1
  148. package/dist/assets/{tooltip-DR2Z2N4w.js → tooltip-CamoSiGF.js} +1 -1
  149. package/dist/assets/{tracing-Q8NAdlrA.js → tracing-B6lz41O5.js} +1 -1
  150. package/dist/assets/{tracing-panel-Ci4kY4dr.js → tracing-panel-Hd5F5hNF.js} +2 -2
  151. package/dist/assets/{treeView-Q6P3EWNA-DwYCsGZ1.js → treeView-Q6P3EWNA-BJ6U0Bh6.js} +1 -1
  152. package/dist/assets/{treemap-WGGIJYW6-BH3CfKBr.js → treemap-WGGIJYW6-DU7UqE3x.js} +1 -1
  153. package/dist/assets/{use-restore-focus-B98SEiGc.js → use-restore-focus-D0UtBPD6.js} +1 -1
  154. package/dist/assets/{useCellActionButton-DpYtVfFe.js → useCellActionButton-OertTn-H.js} +1 -1
  155. package/dist/assets/{useEventListener-BdZUApHd.js → useEventListener-CUPWI_1X.js} +1 -1
  156. package/dist/assets/{useInterval-ChchS0Rl.js → useInterval-DluQa5sq.js} +1 -1
  157. package/dist/assets/{useTheme-DcnXlv0_.js → useTheme-CnWB5G1X.js} +1 -1
  158. package/dist/assets/{vega-component-BpoSew4K.js → vega-component-C72lP8OY.js} +1 -1
  159. package/dist/assets/{vega-embed-container-BOJG8mCA.js → vega-embed-container-C0Dphqkx.js} +1 -1
  160. package/dist/assets/{vennDiagram-4TSXK5OY-D8bN6lVl.js → vennDiagram-4TSXK5OY-B_OWiVKd.js} +1 -1
  161. package/dist/assets/{wardley-WFR3VGLG-Cr2mp5U6.js → wardley-WFR3VGLG-Rssn0VIa.js} +1 -1
  162. package/dist/assets/{wardleyDiagram-VM6X3IG4-CbZdo0SA.js → wardleyDiagram-VM6X3IG4-CvpCKTJQ.js} +1 -1
  163. package/dist/assets/{worker-ByzyDs4N.js → worker-B5tVfGoh.js} +6 -6
  164. package/dist/assets/{write-secret-modal-BiG2tahJ.js → write-secret-modal-wFgr-1dA.js} +1 -1
  165. package/dist/assets/{xychartDiagram-S5SC5T6Z-DUUQ9tau.js → xychartDiagram-S5SC5T6Z-CqU92eUd.js} +1 -1
  166. package/dist/assets/{youtube-A9VT7NHb.js → youtube-Ck_NlGi9.js} +1 -1
  167. package/dist/index.html +35 -35
  168. package/package.json +7 -7
  169. package/src/components/chat/tool-call/__tests__/tool-result.test.tsx +56 -0
  170. package/src/components/chat/tool-call/tool-result.tsx +3 -3
  171. package/src/components/data-table/charts/__tests__/schemas.test.ts +25 -0
  172. package/src/components/data-table/charts/__tests__/spec.test.ts +26 -23
  173. package/src/components/data-table/charts/constants.ts +11 -10
  174. package/src/components/data-table/charts/types.ts +1 -0
  175. package/src/components/editor/actions/__tests__/useSetOutputsExpanded.test.ts +42 -0
  176. package/src/components/editor/actions/useNotebookActions.tsx +20 -0
  177. package/src/components/editor/actions/useSetOutputsExpanded.ts +67 -0
  178. package/src/core/edit-app.tsx +16 -0
  179. package/src/core/hotkeys/hotkeys.ts +12 -0
  180. package/src/core/wasm/__tests__/bootstrap.test.ts +33 -1
  181. package/src/core/wasm/worker/bootstrap.ts +22 -3
  182. package/src/css/katex.min.css +145 -144
  183. package/src/plugins/impl/CheckboxPlugin.tsx +1 -1
  184. package/src/plugins/impl/DatePickerPlugin.tsx +5 -3
  185. package/src/plugins/impl/DateRangePlugin.tsx +5 -3
  186. package/src/plugins/impl/DateTimePickerPlugin.tsx +5 -3
  187. package/src/plugins/impl/DropdownPlugin.tsx +1 -1
  188. package/src/plugins/impl/FileBrowserPlugin.tsx +45 -15
  189. package/src/plugins/impl/MultiselectPlugin.tsx +1 -1
  190. package/src/plugins/impl/NumberPlugin.tsx +1 -1
  191. package/src/plugins/impl/RadioPlugin.tsx +5 -1
  192. package/src/plugins/impl/RangeSliderPlugin.tsx +1 -1
  193. package/src/plugins/impl/SearchableSelect.tsx +1 -1
  194. package/src/plugins/impl/SliderPlugin.tsx +1 -1
  195. package/src/plugins/impl/SwitchPlugin.tsx +6 -1
  196. package/src/plugins/impl/__tests__/FileBrowserPlugin.test.tsx +85 -2
  197. package/src/plugins/impl/__tests__/widget-labels.test.tsx +122 -0
  198. package/src/plugins/impl/chat/ChatPlugin.tsx +1 -1
  199. package/src/plugins/impl/common/labeled.tsx +9 -3
  200. package/dist/assets/__vite-browser-external-Cw9Ccr_O.js +0 -1
  201. package/dist/assets/__vite-browser-external-DBuuG05M.js +0 -1
  202. package/dist/assets/architecture-7GRP2DOG-D_jUzZ2f.js +0 -1
  203. package/dist/assets/channel-CGdeorQk.js +0 -1
  204. package/dist/assets/chat-display-DevO4F8W.js +0 -1
  205. package/dist/assets/classDiagram-ZZMXUADV-CoNXKNMZ.js +0 -1
  206. package/dist/assets/classDiagram-v2-VYDZK3BY-CoNXKNMZ.js +0 -1
  207. package/dist/assets/eventmodeling-NTZA5JFV-DqXXj9CO.js +0 -1
  208. package/dist/assets/flowDiagram-HODETNUW-ncLciK2K.js +0 -1
  209. package/dist/assets/has-cJsIKK9t.js +0 -1
  210. package/dist/assets/mermaid-HWGCJPDP-UrYE0_I-.js +0 -1
  211. package/dist/assets/purify.es-CYRiAeUx.js +0 -3
  212. package/dist/assets/railroad-abnf-HS5TGJTU-BOoktJ2s.js +0 -1
  213. package/dist/assets/railroad-ebnf-LZEXJU2U-BzJtHsBe.js +0 -1
  214. package/dist/assets/railroad-peg-WCYAUIDC-C3wGFTzw.js +0 -1
  215. package/dist/assets/stateDiagram-v2-MP3YSRHH-CplsDaDl.js +0 -1
  216. package/dist/assets/swimlanesDiagram-VR7AAH4N-DPoIFx8T.js +0 -8
package/dist/index.html CHANGED
@@ -66,7 +66,7 @@
66
66
  <marimo-server-token data-token="{{ server_token }}" hidden></marimo-server-token>
67
67
  <!-- /TODO -->
68
68
  <title>{{ title }}</title>
69
- <script type="module" crossorigin src="./assets/index-DafnX1Xx.js"></script>
69
+ <script type="module" crossorigin src="./assets/index-DYVlDtsu.js"></script>
70
70
  <link rel="modulepreload" crossorigin href="./assets/rolldown-runtime-B0Z9INg1.js">
71
71
  <link rel="modulepreload" crossorigin href="./assets/react-CUdNIagt.js">
72
72
  <link rel="modulepreload" crossorigin href="./assets/compiler-runtime-BQ9S8nyo.js">
@@ -81,53 +81,53 @@
81
81
  <link rel="modulepreload" crossorigin href="./assets/_baseMerge-CQpUq7ep.js">
82
82
  <link rel="modulepreload" crossorigin href="./assets/objects-snlMn4yk.js">
83
83
  <link rel="modulepreload" crossorigin href="./assets/jsx-runtime-B74pBk57.js">
84
- <link rel="modulepreload" crossorigin href="./assets/useEventListener-BdZUApHd.js">
84
+ <link rel="modulepreload" crossorigin href="./assets/useEventListener-CUPWI_1X.js">
85
85
  <link rel="modulepreload" crossorigin href="./assets/invariant-Ci2dTZ72.js">
86
- <link rel="modulepreload" crossorigin href="./assets/config-BxZgoFvi.js">
86
+ <link rel="modulepreload" crossorigin href="./assets/config-BdH5RvM0.js">
87
87
  <link rel="modulepreload" crossorigin href="./assets/utils-B4K466FK.js">
88
- <link rel="modulepreload" crossorigin href="./assets/session-DXKMv4Bs.js">
88
+ <link rel="modulepreload" crossorigin href="./assets/session-ztCnZJHI.js">
89
89
  <link rel="modulepreload" crossorigin href="./assets/Deferred-CrTnjj37.js">
90
- <link rel="modulepreload" crossorigin href="./assets/config-DpGPGznL.js">
90
+ <link rel="modulepreload" crossorigin href="./assets/config-D7CP5wR5.js">
91
91
  <link rel="modulepreload" crossorigin href="./assets/clsx-DB0hHKMi.js">
92
92
  <link rel="modulepreload" crossorigin href="./assets/cn-ldLVeaqm.js">
93
- <link rel="modulepreload" crossorigin href="./assets/fullscreen-BmzAqMKq.js">
94
- <link rel="modulepreload" crossorigin href="./assets/dist-CyYN7zJg.js">
95
- <link rel="modulepreload" crossorigin href="./assets/menu-items-BBdeXCvU.js">
96
- <link rel="modulepreload" crossorigin href="./assets/use-restore-focus-B98SEiGc.js">
97
- <link rel="modulepreload" crossorigin href="./assets/button-BoklZTGL.js">
93
+ <link rel="modulepreload" crossorigin href="./assets/fullscreen-3wS6IaIC.js">
94
+ <link rel="modulepreload" crossorigin href="./assets/dist-DFI04FfI.js">
95
+ <link rel="modulepreload" crossorigin href="./assets/menu-items-D-vbZmqL.js">
96
+ <link rel="modulepreload" crossorigin href="./assets/use-restore-focus-D0UtBPD6.js">
97
+ <link rel="modulepreload" crossorigin href="./assets/button-qFeU84ax.js">
98
98
  <link rel="modulepreload" crossorigin href="./assets/createLucideIcon-rHn2EdoM.js">
99
99
  <link rel="modulepreload" crossorigin href="./assets/check-Wea4hZ6R.js">
100
100
  <link rel="modulepreload" crossorigin href="./assets/context-BFOBKCJB.js">
101
101
  <link rel="modulepreload" crossorigin href="./assets/useNumberFormatter-C4-_TnkF.js">
102
- <link rel="modulepreload" crossorigin href="./assets/select-BplWpfFo.js">
103
- <link rel="modulepreload" crossorigin href="./assets/circle-CeQt3rdW.js">
104
- <link rel="modulepreload" crossorigin href="./assets/toast-KNfsFUiB.js">
105
- <link rel="modulepreload" crossorigin href="./assets/tooltip-DR2Z2N4w.js">
102
+ <link rel="modulepreload" crossorigin href="./assets/select-CWHHoM53.js">
103
+ <link rel="modulepreload" crossorigin href="./assets/circle-CzTMKZwz.js">
104
+ <link rel="modulepreload" crossorigin href="./assets/toast-DXkezxWI.js">
105
+ <link rel="modulepreload" crossorigin href="./assets/tooltip-CamoSiGF.js">
106
106
  <link rel="modulepreload" crossorigin href="./assets/paths-CzfpItSz.js">
107
107
  <link rel="modulepreload" crossorigin href="./assets/useLifecycle-DKSBdWUf.js">
108
108
  <link rel="modulepreload" crossorigin href="./assets/toDate-BbJ1_N2T.js">
109
109
  <link rel="modulepreload" crossorigin href="./assets/database-zap-CrkOvbyN.js">
110
- <link rel="modulepreload" crossorigin href="./assets/alert-dialog-CeE3i3Qa.js">
110
+ <link rel="modulepreload" crossorigin href="./assets/alert-dialog-BsB0FYEL.js">
111
111
  <link rel="modulepreload" crossorigin href="./assets/arrays-BqUx5USx.js">
112
112
  <link rel="modulepreload" crossorigin href="./assets/once-Haz_uxEL.js">
113
- <link rel="modulepreload" crossorigin href="./assets/numbers-DsgsDslU.js">
113
+ <link rel="modulepreload" crossorigin href="./assets/numbers-DyJNv6Vk.js">
114
114
  <link rel="modulepreload" crossorigin href="./assets/useDebounce-DMbg9X18.js">
115
- <link rel="modulepreload" crossorigin href="./assets/input-BDakodZ2.js">
115
+ <link rel="modulepreload" crossorigin href="./assets/input-D4bMj5Nb.js">
116
116
  <link rel="modulepreload" crossorigin href="./assets/use-toast-CC89xOwH.js">
117
117
  <link rel="modulepreload" crossorigin href="./assets/requests-yTHMxhVa.js">
118
118
  <link rel="modulepreload" crossorigin href="./assets/uuid-k9DpjH68.js">
119
- <link rel="modulepreload" crossorigin href="./assets/write-secret-modal-BiG2tahJ.js">
119
+ <link rel="modulepreload" crossorigin href="./assets/write-secret-modal-wFgr-1dA.js">
120
120
  <link rel="modulepreload" crossorigin href="./assets/plus-gbN72xHe.js">
121
121
  <link rel="modulepreload" crossorigin href="./assets/trash-2-BJG-7Qob.js">
122
- <link rel="modulepreload" crossorigin href="./assets/preload-helper-HclGiUj8.js">
122
+ <link rel="modulepreload" crossorigin href="./assets/preload-helper-uBIymjUX.js">
123
123
  <link rel="modulepreload" crossorigin href="./assets/dist-BczecT6V.js">
124
124
  <link rel="modulepreload" crossorigin href="./assets/dist-BTskHGpb.js">
125
- <link rel="modulepreload" crossorigin href="./assets/capabilities-Bj3s1hGN.js">
125
+ <link rel="modulepreload" crossorigin href="./assets/capabilities-BqUNf14U.js">
126
126
  <link rel="modulepreload" crossorigin href="./assets/cjs-C49f7GXV.js">
127
- <link rel="modulepreload" crossorigin href="./assets/createReducer-BPvK7C_R.js">
127
+ <link rel="modulepreload" crossorigin href="./assets/createReducer-CI8rlZE9.js">
128
128
  <link rel="modulepreload" crossorigin href="./assets/dist-Ccyblc8N.js">
129
129
  <link rel="modulepreload" crossorigin href="./assets/marked.esm-B_3iMIUq.js">
130
- <link rel="modulepreload" crossorigin href="./assets/strings-BHZPE0Mc.js">
130
+ <link rel="modulepreload" crossorigin href="./assets/strings-LjhpYwmx.js">
131
131
  <link rel="modulepreload" crossorigin href="./assets/dist-BN-7G8qZ.js">
132
132
  <link rel="modulepreload" crossorigin href="./assets/badge-DFf033uX.js">
133
133
  <link rel="modulepreload" crossorigin href="./assets/dist-CiUBikfn.js">
@@ -136,19 +136,19 @@
136
136
  <link rel="modulepreload" crossorigin href="./assets/dist-DBqBVprh.js">
137
137
  <link rel="modulepreload" crossorigin href="./assets/dist-DueXZKz9.js">
138
138
  <link rel="modulepreload" crossorigin href="./assets/stex-CJTNBbet.js">
139
- <link rel="modulepreload" crossorigin href="./assets/useTheme-DcnXlv0_.js">
139
+ <link rel="modulepreload" crossorigin href="./assets/useTheme-CnWB5G1X.js">
140
140
  <link rel="modulepreload" crossorigin href="./assets/useAsyncData-DucTwMkf.js">
141
- <link rel="modulepreload" crossorigin href="./assets/purify.es-CYRiAeUx.js">
142
- <link rel="modulepreload" crossorigin href="./assets/cells-CzugpTQu.js">
141
+ <link rel="modulepreload" crossorigin href="./assets/purify.es--06brOip.js">
142
+ <link rel="modulepreload" crossorigin href="./assets/cells-BXPymufT.js">
143
143
  <link rel="modulepreload" crossorigin href="./assets/get-DjNf4SIX.js">
144
144
  <link rel="modulepreload" crossorigin href="./assets/copy-RyCOE8jo.js">
145
- <link rel="modulepreload" crossorigin href="./assets/copy-BhJktFeI.js">
146
- <link rel="modulepreload" crossorigin href="./assets/copy-icon-DFhUGBjO.js">
147
- <link rel="modulepreload" crossorigin href="./assets/ErrorBoundary-BeE1cdgM.js">
148
- <link rel="modulepreload" crossorigin href="./assets/config-B4VJJibu.js">
145
+ <link rel="modulepreload" crossorigin href="./assets/copy-B--GzTEX.js">
146
+ <link rel="modulepreload" crossorigin href="./assets/copy-icon-DQuttmjH.js">
147
+ <link rel="modulepreload" crossorigin href="./assets/ErrorBoundary-Dx6lhNls.js">
148
+ <link rel="modulepreload" crossorigin href="./assets/config-2Nts63h2.js">
149
149
  <link rel="modulepreload" crossorigin href="./assets/chevron-right-DOPs2jx8.js">
150
- <link rel="modulepreload" crossorigin href="./assets/dropdown-menu-VuyoeQOD.js">
151
- <link rel="modulepreload" crossorigin href="./assets/LazyAnyLanguageCodeMirror-B_IYTCX5.js">
150
+ <link rel="modulepreload" crossorigin href="./assets/dropdown-menu-Crx6knLg.js">
151
+ <link rel="modulepreload" crossorigin href="./assets/LazyAnyLanguageCodeMirror-CfdjWQov.js">
152
152
  <link rel="modulepreload" crossorigin href="./assets/hat-glasses-DVgK5i5l.js">
153
153
  <link rel="modulepreload" crossorigin href="./assets/package-BeYhVWvM.js">
154
154
  <link rel="modulepreload" crossorigin href="./assets/errors-D9vyuMar.js">
@@ -156,12 +156,12 @@
156
156
  <link rel="modulepreload" crossorigin href="./assets/precisionRound-Bq_nmf5u.js">
157
157
  <link rel="modulepreload" crossorigin href="./assets/defaultLocale-D5bOh7g6.js">
158
158
  <link rel="modulepreload" crossorigin href="./assets/vega-loader.browser-CLRkNgm7.js">
159
- <link rel="modulepreload" crossorigin href="./assets/tooltip-PLkI_UfK.js">
160
- <link rel="modulepreload" crossorigin href="./assets/filename-fxG7K_MU.js">
159
+ <link rel="modulepreload" crossorigin href="./assets/tooltip-BQ9qHrrN.js">
160
+ <link rel="modulepreload" crossorigin href="./assets/filename-DZ9xkzQn.js">
161
161
  <link rel="modulepreload" crossorigin href="./assets/micromark-factory-space-D9Dr-k4J.js">
162
- <link rel="modulepreload" crossorigin href="./assets/chunk-YOKDWASO-CaoEAGJk.js">
162
+ <link rel="modulepreload" crossorigin href="./assets/chunk-YOKDWASO-84E-_nIR.js">
163
163
  <link rel="stylesheet" crossorigin href="./assets/cells-0PFKL3SH.css">
164
- <link rel="stylesheet" crossorigin href="./assets/index--sT8xf-8.css">
164
+ <link rel="stylesheet" crossorigin href="./assets/index-C4-iduJO.css">
165
165
  </head>
166
166
  <body>
167
167
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/frontend",
3
- "version": "0.25.2-dev3",
3
+ "version": "0.25.2-dev31",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -99,7 +99,7 @@
99
99
  "date-fns": "^4.4.0",
100
100
  "dequal": "^2.0.3",
101
101
  "dnd-core": "^16.0.1",
102
- "dompurify": "^3.4.14",
102
+ "dompurify": "^3.4.16",
103
103
  "htm": "^3.1.1",
104
104
  "html-react-parser": "^5.2.17",
105
105
  "html-to-image": "1.11.13",
@@ -191,12 +191,12 @@
191
191
  "devDependencies": {
192
192
  "@codecov/vite-plugin": "^1.9.1",
193
193
  "@csstools/postcss-light-dark-function": "^2.0.11",
194
- "@playwright/test": "^1.62.1",
194
+ "@playwright/test": "^1.63.0",
195
195
  "@storybook/addon-docs": "^10.6.0",
196
196
  "@storybook/addon-links": "^10.6.0",
197
197
  "@storybook/react-vite": "^10.6.0",
198
198
  "@testing-library/jest-dom": "^7.0.1",
199
- "@testing-library/react": "^16.3.2",
199
+ "@testing-library/react": "^16.3.3",
200
200
  "@types/dompurify": "^3.2.0",
201
201
  "@types/lodash-es": "^4.17.12",
202
202
  "@types/node": "^24.13.3",
@@ -204,7 +204,7 @@
204
204
  "@types/react": "^19.2.18",
205
205
  "@types/react-dom": "^19.2.5",
206
206
  "@types/timestring": "^6.0.5",
207
- "@vitejs/plugin-react": "^6.1.0",
207
+ "@vitejs/plugin-react": "^6.1.1",
208
208
  "@vitest/coverage-v8": "4.1.11",
209
209
  "blob-polyfill": "^7.0.20220408",
210
210
  "cross-env": "^7.0.3",
@@ -214,7 +214,7 @@
214
214
  "oxc-transform-react": "0.145.0",
215
215
  "oxfmt": "^0.68.0",
216
216
  "oxlint": "^1.83.0",
217
- "postcss": "^8.5.26",
217
+ "postcss": "^8.5.28",
218
218
  "postcss-prefix-selector": "^2.2.0",
219
219
  "react": "^19.2.8",
220
220
  "react-dom": "^19.2.8",
@@ -223,7 +223,7 @@
223
223
  "stylelint-config-standard": "^36.0.1",
224
224
  "tailwindcss": "^4.3.3",
225
225
  "vega-typings": "^2.3.0",
226
- "vite": "^8.2.2",
226
+ "vite": "^8.3.0",
227
227
  "vite-plugin-wasm": "^3.6.0",
228
228
  "vitest": "^4.1.11",
229
229
  "yaml": "^2.9.0"
@@ -0,0 +1,56 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import { cleanup, render, screen } from "@testing-library/react";
4
+ import { afterEach, describe, expect, it } from "vitest";
5
+ import { ResultRenderer } from "../tool-result";
6
+
7
+ afterEach(cleanup);
8
+
9
+ describe("ResultRenderer", () => {
10
+ it.each([
11
+ { status: "success", message: "No output was returned." },
12
+ { status: "success", next_steps: ["Run the edited cells."] },
13
+ {
14
+ status: "success",
15
+ action_url: null,
16
+ next_steps: null,
17
+ meta: null,
18
+ message: "Finished",
19
+ },
20
+ {
21
+ status: "success",
22
+ action_url: "/notebook",
23
+ next_steps: ["Review the output."],
24
+ meta: { source: "notebook" },
25
+ cellsToOutput: { cell: { cellOutput: "Hello", consoleOutput: "" } },
26
+ },
27
+ ])("renders structured results with optional fields: %j", (result) => {
28
+ render(<ResultRenderer result={result} />);
29
+
30
+ expect(screen.getByRole("heading", { name: "Tool Result" })).toBeVisible();
31
+ expect(screen.getByText("success")).toBeVisible();
32
+ });
33
+
34
+ it("displays messages and tool-specific output without metadata", () => {
35
+ render(
36
+ <ResultRenderer
37
+ result={{
38
+ status: "success",
39
+ message: "Cells finished running.",
40
+ cellsToOutput: { cell: { cellOutput: "Hello", consoleOutput: "" } },
41
+ }}
42
+ />,
43
+ );
44
+
45
+ expect(screen.getByText("Cells finished running.")).toBeVisible();
46
+ expect(screen.getByText("cellsToOutput")).toBeVisible();
47
+ expect(screen.getByText(/"cellOutput": "Hello"/)).toBeVisible();
48
+ });
49
+
50
+ it("preserves the fallback for unstructured results", () => {
51
+ render(<ResultRenderer result="Plain text result" />);
52
+
53
+ expect(screen.queryByRole("heading", { name: "Tool Result" })).toBeNull();
54
+ expect(screen.getByText("Plain text result")).toBeVisible();
55
+ });
56
+ });
@@ -21,9 +21,9 @@ function isUninformative(value: unknown): boolean {
21
21
  const SuccessResultSchema = z.looseObject({
22
22
  status: z.string().default("success"),
23
23
  auth_required: z.boolean().default(false),
24
- action_url: z.any(),
25
- next_steps: z.any(),
26
- meta: z.any(),
24
+ action_url: z.any().optional(),
25
+ next_steps: z.any().optional(),
26
+ meta: z.any().optional(),
27
27
  message: z.string().nullish(),
28
28
  });
29
29
 
@@ -4,6 +4,31 @@ import { describe, expect, it } from "vitest";
4
4
  import { ChartSchema } from "../schemas";
5
5
 
6
6
  describe("ChartSchema", () => {
7
+ it.each(["hours", "yearmonthdatehours"] as const)(
8
+ "preserves the %s time unit in saved chart configurations",
9
+ (timeUnit) => {
10
+ const column = {
11
+ field: "timestamp",
12
+ selectedDataType: "temporal",
13
+ sort: "ascending",
14
+ timeUnit,
15
+ };
16
+ const config = {
17
+ general: {
18
+ xColumn: { ...column, aggregate: "none" },
19
+ yColumn: { ...column, aggregate: "none" },
20
+ facet: {
21
+ row: { ...column, linkYAxis: true, binned: true, maxbins: 6 },
22
+ column: { ...column, linkXAxis: true, binned: true, maxbins: 6 },
23
+ },
24
+ },
25
+ tooltips: { auto: true, fields: [] },
26
+ };
27
+
28
+ expect(ChartSchema.parse(config)).toEqual(config);
29
+ },
30
+ );
31
+
7
32
  it("keeps a known axis column type", () => {
8
33
  const result = ChartSchema.parse({
9
34
  general: { xColumn: { field: "count", type: "integer" } },
@@ -69,30 +69,33 @@ describe("getAxisEncoding", () => {
69
69
  });
70
70
  });
71
71
 
72
- it("should return correct encoding for temporal field with timeUnit", () => {
73
- const result = getAxisEncoding(
74
- {
75
- field: "date",
76
- selectedDataType: "temporal",
77
- aggregate: NONE_VALUE,
78
- timeUnit: "yearmonth",
79
- },
80
- undefined,
81
- "Date",
82
- undefined,
83
- ChartType.LINE,
84
- );
72
+ it.each(["yearmonth", "hours", "yearmonthdatehours"] as const)(
73
+ "should preserve the %s time unit in temporal axis encodings",
74
+ (timeUnit) => {
75
+ const result = getAxisEncoding(
76
+ {
77
+ field: "date",
78
+ selectedDataType: "temporal",
79
+ aggregate: NONE_VALUE,
80
+ timeUnit,
81
+ },
82
+ undefined,
83
+ "Date",
84
+ undefined,
85
+ ChartType.LINE,
86
+ );
85
87
 
86
- expect(result).toEqual({
87
- field: "date",
88
- type: "temporal",
89
- bin: undefined,
90
- title: "Date",
91
- stack: undefined,
92
- aggregate: undefined,
93
- timeUnit: "yearmonth",
94
- });
95
- });
88
+ expect(result).toEqual({
89
+ field: "date",
90
+ type: "temporal",
91
+ bin: undefined,
92
+ title: "Date",
93
+ stack: undefined,
94
+ aggregate: undefined,
95
+ timeUnit,
96
+ });
97
+ },
98
+ );
96
99
 
97
100
  it("should return correct encoding for categorical field", () => {
98
101
  const result = getAxisEncoding(
@@ -147,17 +147,18 @@ export const TIME_UNIT_DESCRIPTIONS: Record<
147
147
  [title: string, description: string]
148
148
  > = {
149
149
  year: ["Year", "2025"],
150
- quarter: ["Quarter", "Q1 2025"],
151
- month: ["Month", "Jan 2025"],
152
- week: ["Week", "Jan 01, 2025"],
153
- day: ["Day", "Jan 01, 2025"],
154
- hours: ["Hour", "Jan 01, 2025 12:00"],
155
- minutes: ["Minute", "Jan 01, 2025 12:34"],
156
- seconds: ["Second", "Jan 01, 2025 12:34:56"],
157
- milliseconds: ["Millisecond", "Jan 01, 2025 12:34:56.789"],
158
- date: ["Date", "Jan 01, 2025"],
159
- dayofyear: ["Day of Year", "Day 1 of 2025"],
150
+ quarter: ["Quarter of year", "Q1"],
151
+ month: ["Month of year", "Jan"],
152
+ week: ["Week of year", "Week 1"],
153
+ day: ["Day of week", "Sunday"],
154
+ hours: ["Hour of day", "12:00"],
155
+ minutes: ["Minute of hour", "34"],
156
+ seconds: ["Second of minute", "56"],
157
+ milliseconds: ["Millisecond of second", "789"],
158
+ date: ["Day of month", "1"],
159
+ dayofyear: ["Day of year", "Day 1"],
160
160
  yearmonth: ["Year Month", "Jan 2025"],
161
161
  yearmonthdate: ["Year Month Date", "Jan 01, 2025"],
162
+ yearmonthdatehours: ["Year Month Date Hours", "Jan 01, 2025 12:00"],
162
163
  monthdate: ["Month Date", "Jan 01"],
163
164
  };
@@ -40,6 +40,7 @@ export const SINGLE_TIME_UNITS = [
40
40
  export const COMBINED_TIME_UNITS = [
41
41
  "yearmonth",
42
42
  "yearmonthdate",
43
+ "yearmonthdatehours",
43
44
  "monthdate",
44
45
  ] as const;
45
46
  export const TIME_UNITS = [
@@ -0,0 +1,42 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import { describe, expect, it } from "vitest";
4
+ import { MockNotebook } from "@/__mocks__/notebook";
5
+ import type { OutputMessage } from "@/core/kernel/messages";
6
+ import { outputExpansionConfigs } from "../useSetOutputsExpanded";
7
+
8
+ const output: OutputMessage = {
9
+ channel: "output",
10
+ mimetype: "text/plain",
11
+ data: "hello",
12
+ timestamp: 0,
13
+ };
14
+
15
+ describe("outputExpansionConfigs", () => {
16
+ const [withOutput, withoutOutput, expanded, expandedWithoutOutput] =
17
+ MockNotebook.cellIds();
18
+ const notebook = MockNotebook.notebookState({
19
+ cellData: {
20
+ [withOutput]: {},
21
+ [withoutOutput]: {},
22
+ [expanded]: { config: { expand_output: true } },
23
+ [expandedWithoutOutput]: { config: { expand_output: true } },
24
+ },
25
+ cellRuntime: {
26
+ [withOutput]: { output },
27
+ [expanded]: { output },
28
+ },
29
+ });
30
+
31
+ it("expands clamped cells with output and skips cells without output", () => {
32
+ expect(outputExpansionConfigs(notebook, true)).toEqual({
33
+ [withOutput]: { expand_output: true },
34
+ });
35
+ });
36
+
37
+ it("clamps expanded cells with output and skips cells without output", () => {
38
+ expect(outputExpansionConfigs(notebook, false)).toEqual({
39
+ [expanded]: { expand_output: false },
40
+ });
41
+ });
42
+ });
@@ -7,6 +7,8 @@ import {
7
7
  CheckIcon,
8
8
  ChevronDownCircleIcon,
9
9
  ChevronRightCircleIcon,
10
+ ChevronsDownUpIcon,
11
+ ChevronsUpDownIcon,
10
12
  ClipboardCopyIcon,
11
13
  CodeIcon,
12
14
  CommandIcon,
@@ -100,6 +102,7 @@ import type { ActionButton } from "./types";
100
102
  import { useCopyNotebook } from "./useCopyNotebook";
101
103
  import { useRestartKernel } from "./useRestartKernel";
102
104
  import { useSetCodeVisibility } from "./useSetCodeVisibility";
105
+ import { useSetOutputsExpanded } from "./useSetOutputsExpanded";
103
106
 
104
107
  const NOOP_HANDLER = (event?: Event) => {
105
108
  event?.preventDefault();
@@ -118,6 +121,7 @@ export function useNotebookActions({
118
121
  const [viewState] = useAtom(viewStateAtom);
119
122
  const kioskMode = useAtomValue(kioskModeAtom);
120
123
  const setCodeVisibility = useSetCodeVisibility();
124
+ const setOutputsExpanded = useSetOutputsExpanded();
121
125
  const [resolvedConfig] = useResolvedMarimoConfig();
122
126
  const capabilities = useAtomValue(capabilitiesAtom);
123
127
  const aiEnabled = useAtomValue(aiEnabledAtom);
@@ -596,6 +600,22 @@ export function useNotebookActions({
596
600
  handle: () => setCodeVisibility(true, "markdown"),
597
601
  redundant: true,
598
602
  },
603
+ {
604
+ icon: <ChevronsUpDownIcon size={14} strokeWidth={1.5} />,
605
+ label: "Expand all outputs",
606
+ hotkey: "global.expandAllOutputs",
607
+ hidden: viewState.mode !== "edit",
608
+ handle: () => setOutputsExpanded(true),
609
+ redundant: true,
610
+ },
611
+ {
612
+ icon: <ChevronsDownUpIcon size={14} strokeWidth={1.5} />,
613
+ label: "Clamp all outputs",
614
+ hotkey: "global.clampAllOutputs",
615
+ hidden: viewState.mode !== "edit",
616
+ handle: () => setOutputsExpanded(false),
617
+ redundant: true,
618
+ },
599
619
  {
600
620
  icon: <ChevronRightCircleIcon size={14} strokeWidth={1.5} />,
601
621
  label: "Collapse all sections",
@@ -0,0 +1,67 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import { useCallback } from "react";
4
+ import {
5
+ getNotebook,
6
+ type NotebookState,
7
+ useCellActions,
8
+ } from "@/core/cells/cells";
9
+ import type { CellId } from "@/core/cells/ids";
10
+ import { isOutputEmpty } from "@/core/cells/outputs";
11
+ import { useRequestClient } from "@/core/network/requests";
12
+ import type { CellConfig } from "@/core/network/types";
13
+ import { Objects } from "@/utils/objects";
14
+
15
+ /**
16
+ * The `expand_output` config changes needed to expand or clamp every output.
17
+ *
18
+ * Both actions skip cells without output, so their source isn't annotated
19
+ * with a config that has no effect.
20
+ */
21
+ export function outputExpansionConfigs(
22
+ notebook: NotebookState,
23
+ expanded: boolean,
24
+ ): Record<CellId, Partial<CellConfig>> {
25
+ const configs: Record<CellId, Partial<CellConfig>> = {};
26
+ for (const cellId of notebook.cellIds.inOrderIds) {
27
+ const cell = notebook.cellData[cellId];
28
+ if (
29
+ cell === undefined ||
30
+ (cell.config.expand_output ?? false) === expanded
31
+ ) {
32
+ continue;
33
+ }
34
+ if (isOutputEmpty(notebook.cellRuntime[cellId]?.output)) {
35
+ continue;
36
+ }
37
+ configs[cellId] = { expand_output: expanded };
38
+ }
39
+ return configs;
40
+ }
41
+
42
+ /**
43
+ * Hook returning a callback that shows every cell's output in full, or clamps
44
+ * every output to a fixed height, by setting each cell's `expand_output` config.
45
+ */
46
+ export const useSetOutputsExpanded = () => {
47
+ const { updateCellConfig } = useCellActions();
48
+ const { saveCellConfig } = useRequestClient();
49
+
50
+ return useCallback(
51
+ async (expanded: boolean) => {
52
+ const newConfigs = outputExpansionConfigs(getNotebook(), expanded);
53
+
54
+ const entries = Objects.entries(newConfigs);
55
+ if (entries.length === 0) {
56
+ return;
57
+ }
58
+
59
+ await saveCellConfig({ configs: newConfigs });
60
+
61
+ for (const [cellId, config] of entries) {
62
+ updateCellConfig({ cellId, config });
63
+ }
64
+ },
65
+ [updateCellConfig, saveCellConfig],
66
+ );
67
+ };
@@ -23,6 +23,7 @@ import {
23
23
  useRunStaleCells,
24
24
  } from "../components/editor/cell/useRunCells";
25
25
  import { useSetCodeVisibility } from "../components/editor/actions/useSetCodeVisibility";
26
+ import { useSetOutputsExpanded } from "../components/editor/actions/useSetOutputsExpanded";
26
27
  import { CellArray } from "../components/editor/renderers/cell-array";
27
28
  import { CellsRenderer } from "../components/editor/renderers/cells-renderer";
28
29
  import { useHotkey } from "../hooks/useHotkey";
@@ -115,6 +116,7 @@ export const EditApp: React.FC<AppProps> = ({
115
116
  const runAllCells = useRunAllCells();
116
117
  const togglePresenting = useTogglePresenting();
117
118
  const setCodeVisibility = useSetCodeVisibility();
119
+ const setOutputsExpanded = useSetOutputsExpanded();
118
120
 
119
121
  // HOTKEYS
120
122
  useHotkey("global.runStale", () => {
@@ -141,6 +143,20 @@ export const EditApp: React.FC<AppProps> = ({
141
143
  useHotkey("global.hideAllMarkdownCode", () => {
142
144
  setCodeVisibility(true, "markdown");
143
145
  });
146
+ useHotkey(
147
+ "global.expandAllOutputs",
148
+ () => {
149
+ setOutputsExpanded(true);
150
+ },
151
+ { disabled: !isEditing },
152
+ );
153
+ useHotkey(
154
+ "global.clampAllOutputs",
155
+ () => {
156
+ setOutputsExpanded(false);
157
+ },
158
+ { disabled: !isEditing },
159
+ );
144
160
  useHotkey("global.collapseAllSections", () => {
145
161
  collapseAllCells();
146
162
  });
@@ -389,6 +389,18 @@ const DEFAULT_HOT_KEY = {
389
389
  group: "Editing",
390
390
  key: NOT_SET,
391
391
  },
392
+ "global.expandAllOutputs": {
393
+ name: "Expand all outputs",
394
+ group: "Editing",
395
+ key: NOT_SET,
396
+ additionalKeywords: ["show full output", "unclamp"],
397
+ },
398
+ "global.clampAllOutputs": {
399
+ name: "Clamp all outputs",
400
+ group: "Editing",
401
+ key: NOT_SET,
402
+ additionalKeywords: ["collapse outputs", "shrink outputs"],
403
+ },
392
404
  "global.collapseAllSections": {
393
405
  name: "Collapse all sections",
394
406
  group: "Editing",
@@ -3,7 +3,7 @@
3
3
  import { loadPyodide } from "pyodide";
4
4
  import type { PyodideInterface } from "pyodide";
5
5
  import { beforeEach, describe, expect, it, vi } from "vitest";
6
- import { DefaultWasmController } from "../worker/bootstrap";
6
+ import { DefaultWasmController, requirementName } from "../worker/bootstrap";
7
7
 
8
8
  vi.mock("pyodide", () => ({ loadPyodide: vi.fn() }));
9
9
  vi.mock("../worker/getMarimoWheel", () => ({
@@ -61,3 +61,35 @@ describe("WASM runtime sources", () => {
61
61
  expect(controller.requirePyodide).toBe(pyodide);
62
62
  });
63
63
  });
64
+
65
+ describe("requirementName", () => {
66
+ it("returns the distribution name for a bare requirement", () => {
67
+ expect(requirementName("pandas")).toBe("pandas");
68
+ });
69
+
70
+ it.each([
71
+ ["pandas==2.1.0", "pandas"],
72
+ ["pandas>=2", "pandas"],
73
+ ["pandas<=2", "pandas"],
74
+ ["pandas~=2.1", "pandas"],
75
+ ["pandas!=2.0", "pandas"],
76
+ ["nltools===0.6.0.dev2", "nltools"],
77
+ ])("cuts the specifier off %s", (requirement, expected) => {
78
+ expect(requirementName(requirement)).toBe(expected);
79
+ });
80
+
81
+ it("cuts extras and markers", () => {
82
+ expect(requirementName("rich[jupyter]>=13")).toBe("rich");
83
+ expect(requirementName('cowsay==6.1; sys_platform == "emscripten"')).toBe(
84
+ "cowsay",
85
+ );
86
+ });
87
+
88
+ it("cuts a URL requirement at the name", () => {
89
+ expect(requirementName("pkg @ https://example.com/pkg.whl")).toBe("pkg");
90
+ });
91
+
92
+ it("tolerates surrounding whitespace", () => {
93
+ expect(requirementName(" pandas >= 2 ")).toBe("pandas");
94
+ });
95
+ });