@marimo-team/islands 0.24.3-dev4 → 0.24.3-dev40

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 (365) hide show
  1. package/dist/{ConnectedDataExplorerComponent-C9OF_75w.js → ConnectedDataExplorerComponent-KVhjDMSe.js} +1066 -1066
  2. package/dist/ErrorBoundary-CacTZz7K.js +200 -0
  3. package/dist/{ImageComparisonComponent-2a9TMMm2.js → ImageComparisonComponent-RspMflu6.js} +3 -3
  4. package/dist/{Plot-C-9MQeGP.js → Plot-CTyjbQDT.js} +21032 -20666
  5. package/dist/_baseMerge-BiGRwuqv.js +165 -0
  6. package/dist/{abnfDiagram-N423BO3Z-CQKwzX8t.js → abnfDiagram-VCTEODGH-CpN0FRda.js} +17 -18
  7. package/dist/{any-language-editor-DmQ7dyCx.js → any-language-editor-CycIVIeP.js} +17 -17
  8. package/dist/arc-7ra3iNdN.js +81 -0
  9. package/dist/architecture-7GRP2DOG-BWLylgiA.js +3 -0
  10. package/dist/{architectureDiagram-T3A2C74G-CncrDpfa.js → architectureDiagram-5GKGNRK7-DDyj5SRB.js} +25 -25
  11. package/dist/assets/__vite-browser-external-BajL8aoc.js +1 -0
  12. package/dist/assets/worker-BemUy60C.js +109 -0
  13. package/dist/blockDiagram-I7D4REHJ-BbXEXJRu.js +1922 -0
  14. package/dist/{button-CKBkqR9J.js → button-DdXAm8iz.js} +5 -5
  15. package/dist/{c4Diagram-5PPSVZJV-DarUk3Yq.js → c4Diagram-7LVT6UL2-DcLsbQmR.js} +696 -668
  16. package/dist/{capabilities-CMBBJTcc.js → capabilities-B3ce_GNu.js} +1 -1
  17. package/dist/{html-to-image-BhNoIBSU.js → cells-BSgNCBZ8.js} +6740 -10126
  18. package/dist/{channel-CyiYUzJv.js → channel-B5XnTarr.js} +1 -1
  19. package/dist/chat-ui-CygzVJ9s.js +5786 -0
  20. package/dist/{check-CHig47QV.js → check-B7cIK6gb.js} +1 -1
  21. package/dist/{chunk-2Q5K7J3B-BMuJl2jB.js → chunk-2Q5K7J3B-BMkUkeuy.js} +2 -2
  22. package/dist/chunk-4HAMMTFA-D2qv8E0X.js +4188 -0
  23. package/dist/{chunk-5VM5RSS4-Bcq0ftdy.js → chunk-5VM5RSS4-DKsmPCL6.js} +2 -2
  24. package/dist/{chunk-NSK5VX7P-CDTMcJB0.js → chunk-75Z2AOVW-5_HsvXwr.js} +23 -23
  25. package/dist/{chunk-I66GZJ75-BqyTCAPf.js → chunk-DU6HZSFF-BUgAHvnM.js} +21 -4
  26. package/dist/{chunk-2GRJ4B5K-DgO8Qudq.js → chunk-F27PBJKO-DHmYWZXr.js} +4 -4
  27. package/dist/{chunk-KEIR6QF5-C4KX3XYh.js → chunk-FOHPRMQF-BpYR8RqP.js} +4 -4
  28. package/dist/{chunk-WRU74C26-BpWsbiDK.js → chunk-GMAD6QVW-Czynz8aA.js} +486 -258
  29. package/dist/chunk-GVQU2GXP-yQEdulRS.js +37 -0
  30. package/dist/{chunk-5RXB4S5H-tLNUVDdO.js → chunk-IMKFNOWR-BfwTebD0.js} +11 -11
  31. package/dist/{chunk-JWPE2WC7-BJwjGUnF.js → chunk-JWPE2WC7-DJvv1t8U.js} +2 -2
  32. package/dist/chunk-L3NEJ4N5-DwRWnDDK.js +245 -0
  33. package/dist/{chunk-7Z6QIM7H-Dc18hFxH.js → chunk-OSK3NFVY-BBKU_Ign.js} +222 -144
  34. package/dist/{chunk-W5SLKNZC-DLnvpEtV.js → chunk-P2QGCYS3-C0iGU29N.js} +20 -20
  35. package/dist/{chunk-KBJHAD2P-BuqWqkcW.js → chunk-POPQ4Y6H-BCbS3Ozc.js} +4 -4
  36. package/dist/{chunk-4I5QYGJK-DpytHuZQ.js → chunk-PWAF6VOD-CTFCL0jI.js} +4 -4
  37. package/dist/{chunk-JQJVKLGR-CgqCwe8E.js → chunk-SHT3W25Y-BspJEJ5H.js} +109 -63
  38. package/dist/{chunk-6Q2QTUOP-DmTcEBMn.js → chunk-SVP7TREG-DX3rFNTe.js} +5 -5
  39. package/dist/{chunk-GF5L2VYU-B0wgCQgS.js → chunk-TICWLB2K-fVF7Uujg.js} +13 -13
  40. package/dist/{chunk-XXDRQBXY-D73H4IN0.js → chunk-XXDRQBXY-Dnl5VBqG.js} +3 -3
  41. package/dist/{chunk-Y2CYZVJY-DoegUj_e.js → chunk-Y2CYZVJY-DKKS1VyV.js} +1 -1
  42. package/dist/{chunk-5FQGJX7Z-B85XCPv6.js → chunk-YOKDWASO-DrWbKnxA.js} +6925 -5460
  43. package/dist/classDiagram-ZZMXUADV-Fe-V14Sc.js +30 -0
  44. package/dist/classDiagram-v2-VYDZK3BY-xTDg7lOs.js +30 -0
  45. package/dist/code-visibility-BBNwvBcV.js +138 -0
  46. package/dist/{common-BDlauhCU.js → common-DM3lblo7.js} +8853 -12653
  47. package/dist/{compiler-runtime-CAH9RLw2.js → compiler-runtime-Cj8ZWiNS.js} +2 -2
  48. package/dist/copy-icon-CLdENY__.js +190 -0
  49. package/dist/{cose-bilkent-JH36ORCC-FUWHkXFX.js → cose-bilkent-JH36ORCC-_LyRKVqm.js} +2 -2
  50. package/dist/cubic-OaEBhQPK.js +1404 -0
  51. package/dist/cynefin-OW5HDTMX-obq-i80l.js +3 -0
  52. package/dist/{cynefinDiagram-MW4NZA55-BXSFK93J.js → cynefinDiagram-5FMLGOSQ-CFQrqzSX.js} +10 -10
  53. package/dist/{dagre-CGyalH38.js → dagre-BGSfXNEb.js} +678 -537
  54. package/dist/dagre-GXQ25YYZ-xHNAUTyG.js +425 -0
  55. package/dist/{data-grid-overlay-editor-DZM4BAaI.js → data-grid-overlay-editor-DjRvSwGI.js} +8 -9
  56. package/dist/{data-grid-types-BnZwWG8z.js → data-grid-types-BucVmDDp.js} +1 -1
  57. package/dist/{defaultLocale-DKaU_opG.js → defaultLocale-JI_lnoCe.js} +1 -1
  58. package/dist/{diagram-7IWD3JNH-BjfzDNvj.js → diagram-S7CK7UJ4-Bt1rPbAx.js} +40 -39
  59. package/dist/{diagram-UB23O5K3-DDg-7wLA.js → diagram-UQ7AKVKN-D1sq5FoZ.js} +10 -10
  60. package/dist/{diagram-B4RE2ZJO-CKccR9eE.js → diagram-VSXAHHWV-BKpmG23x.js} +10 -10
  61. package/dist/{diagram-Q27KOJAE-Zhz01ss7.js → diagram-VX7I27RA-BMwGFVD6.js} +21 -21
  62. package/dist/{diagram-LBJQPF4R-CJ-bOruh.js → diagram-Z3DM3KII--KLDR9Pl.js} +10 -10
  63. package/dist/dialog-CgNq6y9-.js +94 -0
  64. package/dist/{dist-dAqZAPcF.js → dist-1HDa70oE.js} +3 -3
  65. package/dist/{dist-Re9sOPOx.js → dist-9x1ZRe-e.js} +2 -2
  66. package/dist/{dist-DEeLqRlU.js → dist-B1vYLK28.js} +1 -1
  67. package/dist/{dist-C5Bn52W4.js → dist-B8D7McG3.js} +3 -3
  68. package/dist/{dist-_XvgytiS.js → dist-BHCHt1NI.js} +1 -1
  69. package/dist/{dist-CRjAdnqF.js → dist-BRxfaJgs.js} +3 -3
  70. package/dist/{dist-Byj2bV8o.js → dist-BVGtK7Ht.js} +1 -1
  71. package/dist/{dist-BIN5LKyE.js → dist-BaHjhkpZ.js} +2 -2
  72. package/dist/{dist-DVFbIwc5.js → dist-BtKIs9N-.js} +1 -1
  73. package/dist/{dist-BrQGcfQ9.js → dist-C2KzV-vf.js} +2 -2
  74. package/dist/{dist-DJFiGP2k.js → dist-C2wDlYdD.js} +2 -2
  75. package/dist/{dist-BVRM2y1P.js → dist-C8xMLVYi.js} +2 -2
  76. package/dist/dist-CMh_W4y4.js +538 -0
  77. package/dist/{extends-BPB6_lTK.js → dist-CO1AwwG_.js} +516 -561
  78. package/dist/{dist-BzN60Z2s.js → dist-CPGxfVGX.js} +1 -1
  79. package/dist/{dist-C7v-9nUK.js → dist-Cm3iAFMD.js} +3 -3
  80. package/dist/{dist-CGAxEiaM.js → dist-Cs2FijYk.js} +2 -2
  81. package/dist/{dist-hXd65f0_.js → dist-D1PpnuZB.js} +1 -1
  82. package/dist/{dist-VdvbxG72.js → dist-DHOTQar0.js} +1 -1
  83. package/dist/{dist-DcgzXCfy.js → dist-DPcEtqmG.js} +2 -2
  84. package/dist/{dist-D4Z_qdP4.js → dist-Df0wKI0F.js} +1 -1
  85. package/dist/{dist-qhLI-SHd.js → dist-DszxuxS1.js} +2 -2
  86. package/dist/{dist-BEmkrGoQ.js → dist-Kxgjxakw.js} +1 -1
  87. package/dist/{dist-BbSMhhD2.js → dist-KzZ7WELx.js} +2 -2
  88. package/dist/{dist-jWUab2d1.js → dist-lA1Cttkb.js} +1 -1
  89. package/dist/dropdown-menu-CZgjYSAh.js +4502 -0
  90. package/dist/{ebnfDiagram-BXEA7PRR-Dm75pCAS.js → ebnfDiagram-PWID7BFC-WnG4cvSQ.js} +17 -18
  91. package/dist/{erDiagram-JOGREHBK-rVDG3VSQ.js → erDiagram-RLTQ6QDP-DhzKiYHc.js} +1037 -798
  92. package/dist/error-banner-B94dcDmP.js +391 -0
  93. package/dist/error-entries-iJn-Nryx.js +56 -0
  94. package/dist/{esm-CR1nhb1c.js → esm-BElI3qKH.js} +22 -22
  95. package/dist/{esm-C1d0g6Bv.js → esm-G4Fhsgng.js} +51 -37
  96. package/dist/{esm-CesmlDrs.js → esm-h8f7-1CJ.js} +423 -423
  97. package/dist/eventmodeling-NTZA5JFV-D7nP7Uyu.js +3 -0
  98. package/dist/feedback-button-BkFFL-wb.js +380 -0
  99. package/dist/flowDiagram-HODETNUW-6dMdB8pR.js +16 -0
  100. package/dist/{formats-CJMVUfb3.js → formats-BR5iGb4s.js} +8 -8
  101. package/dist/{ganttDiagram-PKOTCBZU-9D-LXF6P.js → ganttDiagram-EL5Y4UJY-DbzEBLbl.js} +15 -15
  102. package/dist/gitGraph-4MIJSDKK-Dy9uQXGh.js +3 -0
  103. package/dist/{gitGraphDiagram-DS77QQ5N-BfpsXTLf.js → gitGraphDiagram-WWUBYQGX-BMf0iKi1.js} +10 -10
  104. package/dist/{glide-data-editor-sPZ8fUFn.js → glide-data-editor-CeAOHG6x.js} +2143 -1910
  105. package/dist/{glide-utils-NShAPPtn.js → glide-utils-B3rUT5PI.js} +15 -15
  106. package/dist/globals-C74RodJy.js +19 -0
  107. package/dist/highlighted-body-KPVGNVTW-Ad3MKZ18.js +38 -0
  108. package/dist/html-to-image-kpuRfdfZ.js +3253 -0
  109. package/dist/info-A6RAGUB7-DKoayiHY.js +3 -0
  110. package/dist/{infoDiagram-6WML65LV-DqCTXHVy.js → infoDiagram-27XIBGKW-BagtCX_5.js} +7 -7
  111. package/dist/{ishikawaDiagram-WSZJBQD7-BCUYmZ1v.js → ishikawaDiagram-5VMMS53U-DByDehYy.js} +8 -8
  112. package/dist/{journeyDiagram-NVQOT4AX-BXB6M4zN.js → journeyDiagram-3NMN7TZE-D2LcKDUO.js} +8 -8
  113. package/dist/{jsx-runtime-CpoKNRgu.js → jsx-runtime-DgDPJV9S.js} +1 -1
  114. package/dist/{kanban-definition-27J2QSJJ-CGRhrDUX.js → kanban-definition-UXKFOSKX-BxwkbBI_.js} +29 -29
  115. package/dist/katex-DFBiSucW.js +21840 -0
  116. package/dist/{label-lwzzBHUW.js → label-BJ49YTvk.js} +6 -6
  117. package/dist/{linear-D5r_1YqD.js → linear-Cnaq3Tfb.js} +4 -4
  118. package/dist/{loader-VZ__bv4g.js → loader-D2W4oM-3.js} +15 -15
  119. package/dist/main.js +8105 -13485
  120. package/dist/mermaid-DPNuhemn.js +3084 -0
  121. package/dist/mermaid-HWGCJPDP-DYCzSILp.js +2 -0
  122. package/dist/mermaid-parser.core-DxuSfYwJ.js +638 -0
  123. package/dist/{mhchem-BjwrxcV-.js → mhchem-DWCF06w9.js} +1 -1
  124. package/dist/{micromark-factory-space-DruVGzeG.js → micromark-factory-space-DGxAzmw8.js} +2 -2
  125. package/dist/{mindmap-definition-FAOFIHXS-C9gRhzZq.js → mindmap-definition-YA3MSWOX-Cgvojw3y.js} +17 -17
  126. package/dist/{node-sql-parser-DesT1xNw.js → node-sql-parser-BiZOJ-FS.js} +0 -3
  127. package/dist/{number-overlay-editor-De2CabLL.js → number-overlay-editor-DDyIkEk3.js} +5 -5
  128. package/dist/objectWithoutPropertiesLoose-BRDcTsfB.js +23 -0
  129. package/dist/packet-AYTQ26CC-Yw7ajchJ.js +3 -0
  130. package/dist/{pegDiagram-VL7TDLO6-Df9IUjMD.js → pegDiagram-XKGWAZYB-DahHhYyN.js} +19 -20
  131. package/dist/{pick-SnHlmIBN.js → pick-CJeoxYOS.js} +1 -1
  132. package/dist/pie-WAS4IAKB-BKdKOAkL.js +3 -0
  133. package/dist/{pieDiagram-7S7Q4E2Y-BmRzQ8ZP.js → pieDiagram-E7YTZNPT-CCtX0oCK.js} +29 -31
  134. package/dist/{process-output-CpK6fX_C.js → process-output-DFe2tVIY.js} +7 -6
  135. package/dist/purify.es-DgKyQviY.js +805 -0
  136. package/dist/{quadrantDiagram-CIZ2JOQS-wFBvWcxS.js → quadrantDiagram-AXDQQJYC-DftINo6g.js} +5 -5
  137. package/dist/radar-RG4KPBEZ-ScR_D_Ts.js +3 -0
  138. package/dist/railroad-74A4TZTK-DQvPSdo5.js +3 -0
  139. package/dist/railroad-abnf-HS5TGJTU-CsJQG2O8.js +3 -0
  140. package/dist/railroad-ebnf-LZEXJU2U-BgEobkSn.js +3 -0
  141. package/dist/railroad-peg-WCYAUIDC-DjLAjofI.js +3 -0
  142. package/dist/{railroadDiagram-AXF67PYL-DxbIatiN.js → railroadDiagram-O6MQD6OU-Du5NsPUb.js} +17 -18
  143. package/dist/{react-dom-C94wmq5w.js → react-dom-BUgJ-ab_.js} +3 -3
  144. package/dist/{react-DMWcHin-.js → react-ofJbxM4x.js} +2 -2
  145. package/dist/{react-vega-DSD5aT7_.js → react-vega-5AcMW8gG.js} +10012 -9369
  146. package/dist/{requirementDiagram-LRYGKXZP-X_x-Y713.js → requirementDiagram-BXWQKSXE-0pmmxL6_.js} +20 -19
  147. package/dist/{reveal-component-BthxSdRc.js → reveal-component-CRy68FxJ.js} +1303 -1237
  148. package/dist/{sankeyDiagram-W5VNT64P-BYJALbbm.js → sankeyDiagram-P5KCCOFB-CDKR5TJH.js} +4 -4
  149. package/dist/{select-3qHpFKF9.js → select-C6plhmZr.js} +317 -562
  150. package/dist/{sequenceDiagram-SI44F4Z6-BiPBe3Sv.js → sequenceDiagram-WJ2MYXX4-DB-ChWwU.js} +11 -11
  151. package/dist/{sizeCapture-X5ZJPWSS-BKLDeh5H.js → sizeCapture-INFHLROL-Dx5SpkQF.js} +2 -2
  152. package/dist/{spec-CutWdqo3.js → spec-CAYwFeV6.js} +4 -4
  153. package/dist/{src-C31ngt98.js → src-CA_m4ONl.js} +298 -303
  154. package/dist/{stateDiagram-OKZ733FA-B7QyNBxH.js → stateDiagram-D77RDMKH-orN6AwMx.js} +19 -20
  155. package/dist/stateDiagram-v2-MP3YSRHH-o05_rJN8.js +30 -0
  156. package/dist/style.css +2 -2
  157. package/dist/{swimlanes-SLNWSIFB-B4f8VP3b.js → swimlanes-42K2YHIH-BkSDcqDT.js} +1501 -1591
  158. package/dist/swimlanesDiagram-VR7AAH4N-D_nFQfRc.js +30 -0
  159. package/dist/{swiper-component-C90YjhaV.js → swiper-component-IOUowglM.js} +39 -26
  160. package/dist/{time-aWGfjN8x.js → time-BieKwdYS.js} +42 -42
  161. package/dist/{timeline-definition-Z64GVDOM-Dacq_5lr.js → timeline-definition-24CTP7MA-BuqJUIRZ.js} +7 -7
  162. package/dist/{toDate-D-Rx3ux5.js → toDate-WXg1yLcI.js} +10 -9
  163. package/dist/toast-DvY70eFX.js +1834 -0
  164. package/dist/tooltip-qB8NlSqV.js +1742 -0
  165. package/dist/treeView-Q6P3EWNA-DuRV97YF.js +3 -0
  166. package/dist/treemap-WGGIJYW6-AsLq-uwC.js +3 -0
  167. package/dist/use-restore-focus-D5D9xEjZ.js +5946 -0
  168. package/dist/{use-vega-container-remeasure-DUW4tRxq.js → use-vega-container-remeasure-4DwJbPWu.js} +2 -2
  169. package/dist/{useAsyncData-CH6-CgJF.js → useAsyncData-BD6AStMt.js} +3 -3
  170. package/dist/{useDateFormatter-Cp9Jdxls.js → useDateFormatter-BRTPsUK7.js} +8 -8
  171. package/dist/{useDeepCompareMemoize-JC87C_jO.js → useDeepCompareMemoize-D_HNdyvI.js} +2 -2
  172. package/dist/{useIframeCapabilities-De3C-9b4.js → useIframeCapabilities-CVtNkI3Y.js} +2 -2
  173. package/dist/{useLifecycle-B4RGlyf0.js → useLifecycle-DPgiiwwU.js} +6 -6
  174. package/dist/useNumberFormatter-BfDpa21j.js +251 -0
  175. package/dist/useTheme-DzXmYZ5V.js +904 -0
  176. package/dist/{vega-component-CPehZbUb.js → vega-component-D0QXopU8.js} +34 -34
  177. package/dist/{vega-embed-container-TJ5z5dZw.js → vega-embed-container-CbnTccZi.js} +6 -6
  178. package/dist/vega-loader.browser-D95WfUcj.js +1139 -0
  179. package/dist/{vennDiagram-T6HMQDX7-D-Rcq3Iu.js → vennDiagram-4TSXK5OY-CTUlJ2PK.js} +9 -9
  180. package/dist/wardley-WFR3VGLG-Na-tFhQJ.js +3 -0
  181. package/dist/{wardleyDiagram-T6FBY63Y-Z-Og7_Wd.js → wardleyDiagram-VM6X3IG4-3evLUb0M.js} +10 -10
  182. package/dist/{xychartDiagram-ELKLHX3M-BDJ2dITA.js → xychartDiagram-S5SC5T6Z-DL2E3K8-.js} +248 -139
  183. package/package.json +54 -57
  184. package/src/__mocks__/requests.ts +7 -0
  185. package/src/__tests__/__snapshots__/CellStatus.test.tsx.snap +12 -12
  186. package/src/components/chat/acp/__tests__/agent-panel.test.tsx +270 -0
  187. package/src/components/chat/acp/agent-panel.tsx +45 -44
  188. package/src/components/data-table/column-explorer-panel/column-explorer.tsx +2 -6
  189. package/src/components/data-table/column-summary/chart-spec-model.tsx +1 -1
  190. package/src/components/data-table/column-visibility-dropdown.tsx +9 -3
  191. package/src/components/data-table/columns.tsx +64 -67
  192. package/src/components/datasources/components.tsx +4 -2
  193. package/src/components/editor/RecoveryButton.tsx +1 -0
  194. package/src/components/editor/alerts/connecting-alert.tsx +1 -66
  195. package/src/components/editor/alerts/connection-notice.tsx +140 -0
  196. package/src/components/editor/app-container.tsx +9 -3
  197. package/src/components/editor/boundary/ErrorBoundary.tsx +38 -16
  198. package/src/components/editor/boundary/__tests__/ErrorBoundary.test.tsx +311 -0
  199. package/src/components/editor/chrome/components/__tests__/feedback-button.test.tsx +94 -0
  200. package/src/components/editor/chrome/components/feedback-button.tsx +63 -42
  201. package/src/components/editor/chrome/panels/__tests__/packages-panel.test.tsx +114 -7
  202. package/src/components/editor/chrome/panels/__tests__/sandbox-recovery.test.tsx +165 -0
  203. package/src/components/editor/chrome/panels/packages-panel.tsx +93 -166
  204. package/src/components/editor/chrome/panels/sandbox-controller.tsx +106 -0
  205. package/src/components/editor/chrome/panels/sandbox-panel.tsx +173 -0
  206. package/src/components/editor/chrome/wrapper/footer-items/backend-status.tsx +3 -1
  207. package/src/components/editor/code/__tests__/readonly-diff.test.tsx +65 -0
  208. package/src/components/editor/code/readonly-diff.tsx +1 -1
  209. package/src/components/editor/file-tree/__tests__/tree-actions.test.tsx +54 -0
  210. package/src/components/editor/file-tree/tree-actions.tsx +11 -14
  211. package/src/components/editor/header/__tests__/status.test.tsx +8 -20
  212. package/src/components/editor/header/filename-input.tsx +2 -0
  213. package/src/components/editor/header/status.tsx +5 -3
  214. package/src/components/editor/notebook-cell.tsx +4 -2
  215. package/src/components/editor/output/JsonOutput.tsx +182 -632
  216. package/src/components/editor/output/Outputs.css +50 -17
  217. package/src/components/editor/output/__tests__/JsonOutput-interactions.test.tsx +254 -0
  218. package/src/components/editor/output/__tests__/JsonOutput-mimetype.test.tsx +41 -46
  219. package/src/components/editor/output/__tests__/{json-output.test.ts → json-output-formatting.test.ts} +113 -75
  220. package/src/components/editor/output/__tests__/json-output-pagination.test.ts +252 -0
  221. package/src/components/editor/output/json-output/formatting.ts +167 -0
  222. package/src/components/editor/output/json-output/pagination.ts +155 -0
  223. package/src/components/editor/output/json-output/renderers.tsx +196 -0
  224. package/src/components/editor/output/json-output/themes.ts +52 -0
  225. package/src/components/editor/renderers/cell-array.tsx +1 -5
  226. package/src/components/home/components.tsx +17 -0
  227. package/src/components/pages/gallery-page.tsx +2 -4
  228. package/src/components/pages/home-page.tsx +2 -4
  229. package/src/components/slides/slide-form.tsx +1 -0
  230. package/src/components/slides/slide-notes-editor.tsx +1 -0
  231. package/src/components/terminal/terminal.tsx +4 -4
  232. package/src/components/tracing/tracing-spec.ts +1 -1
  233. package/src/components/ui/table.tsx +1 -1
  234. package/src/components/ui/use-toast.ts +8 -0
  235. package/src/core/MarimoApp.tsx +0 -2
  236. package/src/core/cells/__tests__/cell.test.ts +61 -0
  237. package/src/core/cells/cell.ts +9 -1
  238. package/src/core/cells/pending-delete-service.ts +12 -16
  239. package/src/core/codemirror/language/__tests__/sql.test.ts +70 -2
  240. package/src/core/codemirror/language/languages/sql/sql.ts +16 -1
  241. package/src/core/codemirror/rtc/extension.ts +5 -2
  242. package/src/core/datasets/__tests__/data-source.test.ts +2 -0
  243. package/src/core/datasets/data-source-connections.ts +15 -10
  244. package/src/core/edit-app.tsx +8 -5
  245. package/src/core/errors/state.ts +1 -2
  246. package/src/core/islands/__tests__/parse.test.ts +140 -7
  247. package/src/core/islands/bootstrap.ts +1 -0
  248. package/src/core/islands/bridge.ts +3 -0
  249. package/src/core/islands/parse.ts +20 -0
  250. package/src/core/network/connection-notice.ts +84 -0
  251. package/src/core/network/requests-lazy.ts +3 -0
  252. package/src/core/network/requests-network.ts +12 -0
  253. package/src/core/network/requests-static.ts +3 -0
  254. package/src/core/network/requests-toasting.tsx +3 -0
  255. package/src/core/network/resolve.ts +2 -1
  256. package/src/core/network/types.ts +7 -0
  257. package/src/core/packages/__tests__/usePackageAction.test.tsx +129 -0
  258. package/src/core/packages/__tests__/useSandboxController.test.tsx +165 -0
  259. package/src/core/packages/package-data.ts +35 -0
  260. package/src/core/packages/sandbox-state.ts +15 -0
  261. package/src/core/packages/toast-components.tsx +11 -0
  262. package/src/core/packages/useInstallPackage.ts +1 -1
  263. package/src/core/packages/usePackageAction.ts +51 -0
  264. package/src/core/packages/usePackageDependencies.ts +22 -0
  265. package/src/core/packages/useSandboxController.ts +188 -0
  266. package/src/core/run-app.tsx +2 -0
  267. package/src/core/runtime/__tests__/runtime.test.ts +11 -0
  268. package/src/core/runtime/runtime.ts +7 -2
  269. package/src/core/wasm/bridge.ts +11 -0
  270. package/src/core/websocket/__tests__/useMarimoKernelConnection.hook.test.tsx +212 -2
  271. package/src/core/websocket/transports/transport.ts +1 -1
  272. package/src/core/websocket/transports/ws.ts +1 -1
  273. package/src/core/websocket/types.ts +11 -1
  274. package/src/core/websocket/useMarimoKernelConnection.tsx +43 -8
  275. package/src/css/app/Cell.css +2 -0
  276. package/src/hooks/useDebounce.ts +2 -0
  277. package/src/plugins/core/BadPlugin.tsx +3 -14
  278. package/src/plugins/core/RenderHTML.tsx +22 -2
  279. package/src/plugins/core/__test__/RenderHTML.test.ts +187 -0
  280. package/src/plugins/core/registerReactComponent.tsx +0 -1
  281. package/src/plugins/impl/FormPlugin.tsx +2 -0
  282. package/src/plugins/impl/MatrixPlugin.tsx +2 -0
  283. package/src/plugins/impl/RangeSliderPlugin.tsx +2 -0
  284. package/src/plugins/impl/SliderPlugin.tsx +2 -0
  285. package/src/plugins/impl/data-frames/panel.tsx +1 -0
  286. package/src/plugins/layout/AccordionPlugin.tsx +7 -2
  287. package/src/plugins/layout/JsonOutputPlugin.tsx +7 -10
  288. package/src/plugins/layout/__test__/AccordionPlugin.test.tsx +66 -0
  289. package/src/stories/sandbox.stories.tsx +308 -0
  290. package/dist/ErrorBoundary-CR-ZQN_c.js +0 -125
  291. package/dist/_baseMerge-Dv8bBloN.js +0 -73
  292. package/dist/_initCloneObject---vediN2.js +0 -95
  293. package/dist/arc-DOVLrCPd.js +0 -82
  294. package/dist/architecture-TIHT7OUA-MiJpPpQW.js +0 -3
  295. package/dist/array-CApNbSU9.js +0 -6
  296. package/dist/assets/__vite-browser-external-BdKGjRZ4.js +0 -1
  297. package/dist/assets/worker-DlIBfp9S.js +0 -98
  298. package/dist/blockDiagram-VBNYF7ZC-Bc--I65C.js +0 -3158
  299. package/dist/chat-ui-DjTMZRVP.js +0 -8455
  300. package/dist/chunk-3NCLNEKW-BIp_lB_4.js +0 -14
  301. package/dist/chunk-5FCAYU7R-C_HO9A1J.js +0 -23
  302. package/dist/chunk-5HE753X5-Bixm_MV-.js +0 -38
  303. package/dist/chunk-5JV3BV7I-CH5J3iZY.js +0 -54
  304. package/dist/chunk-5TONJI2A-DG6gDiSS.js +0 -62
  305. package/dist/chunk-7BUUIJ7U-5afmIPeo.js +0 -82
  306. package/dist/chunk-BIQX33UG-7TMBUf89.js +0 -23
  307. package/dist/chunk-CQNSW5MT-Cnqqsxt-.js +0 -38
  308. package/dist/chunk-CYSBUYHQ-BAbymFHR.js +0 -23
  309. package/dist/chunk-EMLP6XTP-Bsz-QL77.js +0 -23
  310. package/dist/chunk-J7OUQ5F2-CM_meqZH.js +0 -57
  311. package/dist/chunk-JG7HCLWE-DUnCDgPk.js +0 -62
  312. package/dist/chunk-MOZMSUNE-BG6IHvzT.js +0 -35
  313. package/dist/chunk-OSBZ3O6U-CYwj_bvR.js +0 -23
  314. package/dist/chunk-QBLGF6JB-B4vJ4j8J.js +0 -23
  315. package/dist/chunk-QR6OTTB3-D4wH2ldi.js +0 -3738
  316. package/dist/chunk-R7FJI6CG-Blf8FcmZ.js +0 -64
  317. package/dist/chunk-RYQCIY6F-BWbIlBIH.js +0 -241
  318. package/dist/chunk-U6XO7XAA-COw445DS.js +0 -63
  319. package/dist/chunk-UBXNYLIW-BHigVU4H.js +0 -32
  320. package/dist/chunk-YOTPTUD7-Dn044Q_d.js +0 -30
  321. package/dist/chunk-ZIRB5QZD-BR4TMfOa.js +0 -1153
  322. package/dist/classDiagram-JCYQIIEL-DmXSLxe_.js +0 -30
  323. package/dist/classDiagram-v2-OCEON4UE-CooqVexA.js +0 -30
  324. package/dist/click-outside-container-D_URcm3D.js +0 -167
  325. package/dist/code-block-37QAKDTI-CQrzBOr-.js +0 -107
  326. package/dist/copy-CD7S58CY.js +0 -141
  327. package/dist/cynefin-VYW2F7L2-CeHAxOEX.js +0 -3
  328. package/dist/dagre-VZM6K2ZE-CJggWPTJ.js +0 -328
  329. package/dist/dist-3_o3T78I.js +0 -1360
  330. package/dist/dist-ABQjhuek.js +0 -64
  331. package/dist/dist-CO5R6VMi.js +0 -538
  332. package/dist/dropdown-menu-DhCfcscX.js +0 -5858
  333. package/dist/emotion-is-prop-valid.esm-M57VsT8j.js +0 -14
  334. package/dist/error-banner-CsXbEEjo.js +0 -611
  335. package/dist/eventmodeling-45OFAUF4-B_lWZ-Pd.js +0 -3
  336. package/dist/flowDiagram-UKHOOZJN-g1AmrZzM.js +0 -17
  337. package/dist/gitGraph-TEB2WS4Q-Dj-eXUph.js +0 -3
  338. package/dist/info-DKCQHKI2-Bhb-pe2e.js +0 -3
  339. package/dist/line-CuKjIQa1.js +0 -34
  340. package/dist/map-BJpOfPlL.js +0 -149
  341. package/dist/math-BXtKgYah.js +0 -10
  342. package/dist/mermaid-4DMBBIKO-Ddp9TgNp.js +0 -2
  343. package/dist/mermaid-Bi23Ibnw.js +0 -1173
  344. package/dist/mermaid-parser.core-Din9FvSi.js +0 -99
  345. package/dist/packet-7NZHBO7P-fbkIIyKE.js +0 -3
  346. package/dist/path-BNHuHZP8.js +0 -87
  347. package/dist/pie-RZYD4A2V-CLRIsxY1.js +0 -3
  348. package/dist/purify.es-CB-YO1Hn.js +0 -774
  349. package/dist/radar-I7S5WNFK-BGzCbgXu.js +0 -3
  350. package/dist/railroad-3IZDKUUU-CvQIIcuU.js +0 -3
  351. package/dist/railroad-abnf-AHOZXSZD-CMwtlNtu.js +0 -3
  352. package/dist/railroad-ebnf-EBAXGLYW-n1QUOAsh.js +0 -3
  353. package/dist/railroad-peg-LSFZ7HO6-PjnrpmCs.js +0 -3
  354. package/dist/schemas-DzK6U94N.js +0 -6057
  355. package/dist/stateDiagram-v2-UEYNNEHI-BTRUs8Il.js +0 -30
  356. package/dist/step-CKczO72Q.js +0 -670
  357. package/dist/swimlanesDiagram-ULZ7WXOC-NBmgBl9G.js +0 -31
  358. package/dist/timer-DpDyj9G0.js +0 -596
  359. package/dist/tooltip-Dt77sBeT.js +0 -390
  360. package/dist/treeView-QDETBFTQ-DU8LwHuf.js +0 -3
  361. package/dist/treemap-6X3UGDF4-DUk4-k_O.js +0 -3
  362. package/dist/useTheme-CVJ0UOf2.js +0 -841
  363. package/dist/vega-loader.browser-DEggZzni.js +0 -1083
  364. package/dist/wardley-OPB4EBWU-Db-AaGas.js +0 -3
  365. package/src/components/editor/output/EmotionCacheProvider.tsx +0 -32
@@ -902,6 +902,18 @@ const AgentPanel: React.FC = () => {
902
902
  return;
903
903
  }
904
904
 
905
+ let absoluteFilename: string;
906
+ try {
907
+ absoluteFilename = getAbsoluteFilename();
908
+ } catch {
909
+ toast({
910
+ title: "Notebook must be named",
911
+ description: "Please name the notebook to use the agent",
912
+ variant: "danger",
913
+ });
914
+ return;
915
+ }
916
+
905
917
  logger.debug("Submitting prompt to agent", {
906
918
  sessionId: activeSessionId,
907
919
  });
@@ -914,62 +926,51 @@ const AgentPanel: React.FC = () => {
914
926
  setSessionState((prev) => updateSessionTitle(prev, prompt));
915
927
  }
916
928
 
917
- let absoluteFilename: string;
918
929
  try {
919
- absoluteFilename = getAbsoluteFilename();
920
- } catch {
921
- toast({
922
- title: "Notebook must be named",
923
- description: "Please name the notebook to use the agent",
924
- variant: "danger",
925
- });
926
- return;
927
- }
928
-
929
- const promptBlocks: ContentBlock[] = [{ type: "text", text: prompt }];
930
+ const promptBlocks: ContentBlock[] = [{ type: "text", text: prompt }];
930
931
 
931
- // Parse context from the prompt
932
- const { contextBlocks, attachmentBlocks } =
933
- await parseContextFromPrompt(prompt);
934
- promptBlocks.push(...contextBlocks, ...attachmentBlocks);
932
+ // Parse context from the prompt
933
+ const { contextBlocks, attachmentBlocks } =
934
+ await parseContextFromPrompt(prompt);
935
+ promptBlocks.push(...contextBlocks, ...attachmentBlocks);
935
936
 
936
- // Add manually uploaded files as resource links
937
- if (files && files.length > 0) {
938
- const fileResourceLinks = await convertFilesToResourceLinks(files);
939
- promptBlocks.push(...fileResourceLinks);
940
- }
937
+ // Add manually uploaded files as resource links
938
+ if (files && files.length > 0) {
939
+ const fileResourceLinks = await convertFilesToResourceLinks(files);
940
+ promptBlocks.push(...fileResourceLinks);
941
+ }
941
942
 
942
- const hasGivenRules = notifications.some(
943
- (notification) =>
944
- notification.type === "session_notification" &&
945
- notification.data.update.sessionUpdate === "user_message_chunk",
946
- );
947
- if (!hasGivenRules) {
948
- promptBlocks.push(
949
- {
950
- type: "resource_link",
951
- uri: absoluteFilename,
952
- mimeType: "text/x-python",
953
- name: absoluteFilename,
954
- },
955
- {
956
- type: "resource",
957
- resource: {
958
- uri: "marimo_rules.md",
959
- mimeType: "text/plain",
960
- text: getAgentPrompt(absoluteFilename),
961
- },
962
- },
943
+ const hasGivenRules = notifications.some(
944
+ (notification) =>
945
+ notification.type === "session_notification" &&
946
+ notification.data.update.sessionUpdate === "user_message_chunk",
963
947
  );
964
- }
948
+ if (!hasGivenRules) {
949
+ promptBlocks.push(
950
+ {
951
+ type: "resource_link",
952
+ uri: absoluteFilename,
953
+ mimeType: "text/x-python",
954
+ name: absoluteFilename,
955
+ },
956
+ {
957
+ type: "resource",
958
+ resource: {
959
+ uri: "marimo_rules.md",
960
+ mimeType: "text/plain",
961
+ text: getAgentPrompt(absoluteFilename),
962
+ },
963
+ },
964
+ );
965
+ }
965
966
 
966
- try {
967
967
  await agent.prompt({
968
968
  sessionId: activeSessionId,
969
969
  prompt: promptBlocks,
970
970
  });
971
971
  } catch (error) {
972
972
  logger.error("Failed to send prompt", { error });
973
+ setError(error instanceof Error ? error : String(error));
973
974
  } finally {
974
975
  setIsLoading(false);
975
976
  }
@@ -10,7 +10,7 @@ import {
10
10
  EyeIcon,
11
11
  EyeOffIcon,
12
12
  } from "lucide-react";
13
- import { useMemo, useState } from "react";
13
+ import { useState } from "react";
14
14
  import { useLocale } from "react-aria";
15
15
  import {
16
16
  AddDataframeChart,
@@ -98,11 +98,7 @@ export function ColumnExplorerPanel<TData>({
98
98
  hiddenColumns: hiddenColumnCount,
99
99
  } = getColumnCountForDisplay(table, totalColumns);
100
100
  const { visible: visibleColumnCount } = getUserColumnVisibilityCounts(table);
101
- const columnVisibility = table.getState().columnVisibility;
102
- const showOnlyColumnState = useMemo(
103
- () => getShowOnlyColumnState(table),
104
- [table, columnVisibility],
105
- );
101
+ const showOnlyColumnState = getShowOnlyColumnState(table);
106
102
 
107
103
  const { rowsAndColumns, hiddenSuffix } = prettifyRowColumnCount({
108
104
  numRows: totalRows,
@@ -573,7 +573,7 @@ export class ColumnChartSpecModel<T> {
573
573
  };
574
574
  }
575
575
  case "boolean": {
576
- if (!stats?.true || !stats?.false) {
576
+ if (stats?.true == null || stats?.false == null) {
577
577
  return getLegacyBooleanSpec(column, base, MAX_BAR_HEIGHT);
578
578
  }
579
579
 
@@ -215,6 +215,11 @@ export const ColumnVisibilityDropdown = <TData,>({
215
215
  index === list.pinnedCount &&
216
216
  list.pinnedCount > 0 &&
217
217
  list.pinnedCount < list.visibleOptions.length;
218
+ const label = (
219
+ <span className="truncate" title={option.label}>
220
+ {option.label}
221
+ </span>
222
+ );
218
223
  return (
219
224
  <React.Fragment key={option.value}>
220
225
  {isSectionBoundary && <CommandSeparator />}
@@ -225,15 +230,16 @@ export const ColumnVisibilityDropdown = <TData,>({
225
230
  className="flex items-center gap-1.5 cursor-pointer"
226
231
  >
227
232
  {dataType === undefined ? (
228
- <span>{option.label}</span>
233
+ label
229
234
  ) : (
230
235
  <ColumnName
231
- columnName={option.label}
236
+ className="min-w-0"
237
+ columnName={label}
232
238
  dataType={dataType}
233
239
  />
234
240
  )}
235
241
  {!option.disabled && (
236
- <span className="ml-auto flex items-center gap-0.5">
242
+ <span className="ml-auto flex shrink-0 items-center gap-0.5">
237
243
  <ShowOnlyColumnButton
238
244
  table={table}
239
245
  columnIds={[option.value]}
@@ -20,7 +20,6 @@ import { Maps } from "@/utils/maps";
20
20
  import { maxFractionalDigits } from "@/utils/numbers";
21
21
  import { Objects } from "@/utils/objects";
22
22
  import { parseContent } from "@/utils/url-parser";
23
- import { EmotionCacheProvider } from "../editor/output/EmotionCacheProvider";
24
23
  import { JsonOutput } from "../editor/output/JsonOutput";
25
24
  import { CopyClipboardIcon } from "../icons/copy-icon";
26
25
  import { Button } from "../ui/button";
@@ -412,76 +411,74 @@ const PopoutColumn = ({
412
411
  : rawStringValue;
413
412
 
414
413
  return (
415
- <EmotionCacheProvider container={null}>
416
- <Popover>
417
- <PopoverTrigger
418
- ref={triggerRef}
419
- className={cn(cellStyles, "max-w-fit outline-hidden")}
420
- onClick={selectCell}
421
- onMouseDown={(e) => {
422
- // Prevent cell underneath from being selected
423
- e.stopPropagation();
424
- }}
425
- >
426
- <span
427
- className={cn(
428
- "cursor-pointer hover:text-link",
429
- wrapped && COLUMN_WRAPPING_STYLES,
430
- )}
431
- title={rawStringValue}
432
- >
433
- {edges ? <WhitespaceMarkers value={edges.leading} /> : null}
434
- {displayText}
435
- {edges ? <WhitespaceMarkers value={edges.trailing} /> : null}
436
- </span>
437
- </PopoverTrigger>
438
- <PopoverContent
414
+ <Popover>
415
+ <PopoverTrigger
416
+ ref={triggerRef}
417
+ className={cn(cellStyles, "max-w-fit outline-hidden")}
418
+ onClick={selectCell}
419
+ onMouseDown={(e) => {
420
+ // Prevent cell underneath from being selected
421
+ e.stopPropagation();
422
+ }}
423
+ >
424
+ <span
439
425
  className={cn(
440
- contentClassName,
441
- scrollable && "flex flex-col overflow-hidden",
426
+ "cursor-pointer hover:text-link",
427
+ wrapped && COLUMN_WRAPPING_STYLES,
442
428
  )}
443
- align="start"
444
- alignOffset={10}
445
- onInteractOutside={(event) => {
446
- // Radix sees the shadow host as the target. Resolve the original
447
- // target so pointer-down does not dismiss before click toggles.
448
- const target = Events.composedTarget(event.detail.originalEvent);
449
- if (triggerRef.current?.contains(target)) {
450
- event.preventDefault();
451
- }
452
- }}
429
+ title={rawStringValue}
453
430
  >
454
- <div
455
- className={cn(
456
- "flex -mt-3 -mr-2",
457
- scrollable ? "shrink-0 justify-end" : "float-right",
458
- )}
459
- >
460
- <CopyClipboardIcon
461
- value={rawStringValue}
462
- className="size-3 hover:text-link"
463
- buttonClassName="flex size-5 items-center justify-center"
464
- tooltip={false}
465
- />
466
- <PopoverClose asChild={true}>
467
- <Button
468
- variant="link"
469
- size="xs"
470
- className={cn("size-5 p-0", !buttonText && "ml-1.5 mr-1")}
471
- aria-label="Close"
472
- >
473
- {buttonText ?? "Close"}
474
- </Button>
475
- </PopoverClose>
476
- </div>
477
- {scrollable ? (
478
- <div className="min-h-0 overflow-auto">{children}</div>
479
- ) : (
480
- children
431
+ {edges ? <WhitespaceMarkers value={edges.leading} /> : null}
432
+ {displayText}
433
+ {edges ? <WhitespaceMarkers value={edges.trailing} /> : null}
434
+ </span>
435
+ </PopoverTrigger>
436
+ <PopoverContent
437
+ className={cn(
438
+ contentClassName,
439
+ scrollable && "flex flex-col overflow-hidden",
440
+ )}
441
+ align="start"
442
+ alignOffset={10}
443
+ onInteractOutside={(event) => {
444
+ // Radix sees the shadow host as the target. Resolve the original
445
+ // target so pointer-down does not dismiss before click toggles.
446
+ const target = Events.composedTarget(event.detail.originalEvent);
447
+ if (triggerRef.current?.contains(target)) {
448
+ event.preventDefault();
449
+ }
450
+ }}
451
+ >
452
+ <div
453
+ className={cn(
454
+ "flex -mt-3 -mr-2",
455
+ scrollable ? "shrink-0 justify-end" : "float-right",
481
456
  )}
482
- </PopoverContent>
483
- </Popover>
484
- </EmotionCacheProvider>
457
+ >
458
+ <CopyClipboardIcon
459
+ value={rawStringValue}
460
+ className="size-3 hover:text-link"
461
+ buttonClassName="flex size-5 items-center justify-center"
462
+ tooltip={false}
463
+ />
464
+ <PopoverClose asChild={true}>
465
+ <Button
466
+ variant="link"
467
+ size="xs"
468
+ className={cn("size-5 p-0", !buttonText && "ml-1.5 mr-1")}
469
+ aria-label="Close"
470
+ >
471
+ {buttonText ?? "Close"}
472
+ </Button>
473
+ </PopoverClose>
474
+ </div>
475
+ {scrollable ? (
476
+ <div className="min-h-0 overflow-auto">{children}</div>
477
+ ) : (
478
+ children
479
+ )}
480
+ </PopoverContent>
481
+ </Popover>
485
482
  );
486
483
  };
487
484
 
@@ -101,18 +101,20 @@ export const ColumnPreviewContainer: React.FC<{
101
101
  export const ColumnName = ({
102
102
  columnName,
103
103
  dataType,
104
+ className,
104
105
  }: {
105
106
  columnName: React.ReactNode;
106
107
  dataType: DataType;
108
+ className?: string;
107
109
  }) => {
108
110
  const resolvedDataType = resolveDataType(dataType);
109
111
  const Icon = DATA_TYPE_ICON[resolvedDataType];
110
112
  const color = getDataTypeColor(resolvedDataType);
111
113
 
112
114
  return (
113
- <div className="flex flex-row items-center gap-1.5">
115
+ <div className={cn("flex flex-row items-center gap-1.5", className)}>
114
116
  <Icon
115
- className={`w-4 h-4 p-0.5 rounded-sm stroke-card-foreground ${color}`}
117
+ className={`w-4 h-4 shrink-0 p-0.5 rounded-sm stroke-card-foreground ${color}`}
116
118
  />
117
119
  {columnName}
118
120
  </div>
@@ -60,6 +60,7 @@ const RecoveryModal = (props: {
60
60
  // NB: we use markdown class to have sane styling for list, paragraph
61
61
  return (
62
62
  <DialogContent className="w-fit">
63
+ {/* oxlint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -- Handle Escape from any control within the recovery form. */}
63
64
  <form
64
65
  onSubmit={(e) => {
65
66
  e.preventDefault();
@@ -1,76 +1,11 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
3
  import { useAtomValue } from "jotai";
4
- import { LoadingEllipsis } from "@/components/icons/loading-ellipsis";
5
- import { Spinner } from "@/components/icons/spinner";
6
4
  import { Button } from "@/components/ui/button";
7
- import { DelayMount } from "@/components/utils/delay-mount";
8
- import {
9
- isClosedAtom,
10
- isConnectingAtom,
11
- isNotStartedAtom,
12
- } from "@/core/network/connection";
5
+ import { isNotStartedAtom } from "@/core/network/connection";
13
6
  import { useConnectToRuntime } from "@/core/runtime/config";
14
- import { Banner } from "@/plugins/impl/common/error-banner";
15
- import { Tooltip } from "../../ui/tooltip";
16
7
  import { FloatingAlert } from "./floating-alert";
17
8
 
18
- const SHORT_DELAY_MS = 1000; // 1 second
19
- const LONG_DELAY_MS = 5000; // 5 seconds
20
-
21
- export const ConnectingAlert: React.FC = () => {
22
- const isConnecting = useAtomValue(isConnectingAtom);
23
- const isClosed = useAtomValue(isClosedAtom);
24
-
25
- if (isConnecting) {
26
- const subtleNotification = (
27
- <Tooltip content="Connecting to a marimo runtime">
28
- <div className="flex items-center">
29
- <LoadingEllipsis size={5} className="text-yellow-500" />
30
- </div>
31
- </Tooltip>
32
- );
33
-
34
- const longNotification = (
35
- <Banner
36
- kind="info"
37
- className="flex flex-col rounded py-2 px-4 animate-in slide-in-from-top w-fit"
38
- >
39
- <div className="flex flex-col gap-4 justify-between items-start text-muted-foreground text-base">
40
- <div className="flex items-center gap-2">
41
- <Spinner className="h-4 w-4" />
42
- <p>Connecting to a marimo runtime ...</p>
43
- </div>
44
- </div>
45
- </Banner>
46
- );
47
-
48
- // This waits for 1 second to show the subtle notification, then shows the long notification after 5 seconds.
49
- return (
50
- <DelayMount milliseconds={SHORT_DELAY_MS}>
51
- <div className="m-0 flex items-center min-h-[28px] fixed top-5 left-1/2 transform -translate-x-1/2 z-200">
52
- <DelayMount
53
- milliseconds={LONG_DELAY_MS}
54
- fallback={subtleNotification}
55
- >
56
- {longNotification}
57
- </DelayMount>
58
- </div>
59
- </DelayMount>
60
- );
61
- }
62
-
63
- if (isClosed) {
64
- return (
65
- <FloatingAlert show={isClosed} kind="danger">
66
- <div className="flex items-center gap-2">
67
- <p>Failed to connect.</p>
68
- </div>
69
- </FloatingAlert>
70
- );
71
- }
72
- };
73
-
74
9
  export const NotStartedConnectionAlert: React.FC = () => {
75
10
  const isNotStarted = useAtomValue(isNotStartedAtom);
76
11
  const connectToRuntime = useConnectToRuntime();
@@ -0,0 +1,140 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+ import { useAtomValue } from "jotai";
3
+ import { AlertCircleIcon, ArrowRightIcon } from "lucide-react";
4
+ import { useState } from "react";
5
+ import { Spinner } from "@/components/icons/spinner";
6
+ import { Button } from "@/components/ui/button";
7
+ import { hasCellsAtom } from "@/core/cells/cells";
8
+ import type { AppConfig } from "@/core/config/config-schema";
9
+ import { connectionAtom } from "@/core/network/connection";
10
+ import { connectionNoticeAtom } from "@/core/network/connection-notice";
11
+ import { WebSocketState } from "@/core/websocket/types";
12
+ import { useDelayElapsed } from "@/hooks/useDelayElapsed";
13
+ import { useInterval } from "@/hooks/useInterval";
14
+ import { cn } from "@/utils/cn";
15
+ import { SandboxErrorOutput } from "../chrome/panels/sandbox-panel";
16
+ import { chromeAtom, useChromeActions } from "../chrome/state";
17
+ import { VerticalLayoutWrapper } from "../renderers/vertical-layout/vertical-layout-wrapper";
18
+
19
+ export const ConnectionNotice = ({
20
+ appConfig,
21
+ onRetry,
22
+ }: {
23
+ appConfig: AppConfig;
24
+ onRetry: () => void;
25
+ }) => {
26
+ const notice = useAtomValue(connectionNoticeAtom);
27
+ const connection = useAtomValue(connectionAtom);
28
+ const hasCells = useAtomValue(hasCellsAtom);
29
+ const chrome = useAtomValue(chromeAtom);
30
+ const packagesOpen =
31
+ (chrome.isSidebarOpen && chrome.selectedPanel === "packages") ||
32
+ (chrome.isDeveloperPanelOpen &&
33
+ chrome.selectedDeveloperPanelTab === "packages");
34
+ const elapsed = useDelayElapsed(notice?.pending ? 500 : 0);
35
+ const { openApplication } = useChromeActions();
36
+
37
+ // Reconnection uses the footer indicator while existing cells stay visible.
38
+ if (
39
+ !notice ||
40
+ !elapsed ||
41
+ (hasCells &&
42
+ connection.state === WebSocketState.CONNECTING &&
43
+ connection.phase === "reconnecting")
44
+ ) {
45
+ return null;
46
+ }
47
+
48
+ return (
49
+ <VerticalLayoutWrapper
50
+ appConfig={appConfig}
51
+ className="shrink-0 pb-0 sm:pb-0 print:hidden"
52
+ innerClassName="pb-0 sm:pb-0 pr-4"
53
+ >
54
+ <section
55
+ aria-label="Notebook startup"
56
+ className={cn(
57
+ "text-muted-foreground",
58
+ hasCells
59
+ ? "mt-4 mb-8 border rounded-lg px-5 py-5"
60
+ : "max-w-sm mx-auto mt-16 sm:mt-24 px-4",
61
+ hasCells && !notice.pending && "border-(--red-7)",
62
+ )}
63
+ >
64
+ <div role="status" className="flex items-center gap-2.5">
65
+ {notice.pending ? (
66
+ <Spinner className="size-4 shrink-0" aria-hidden={true} />
67
+ ) : (
68
+ <AlertCircleIcon
69
+ className="size-4 shrink-0 text-(--red-11)"
70
+ aria-hidden={true}
71
+ />
72
+ )}
73
+ <h2
74
+ className={cn(
75
+ "text-base",
76
+ notice.pending
77
+ ? "font-normal text-foreground"
78
+ : "font-medium text-(--red-11)",
79
+ )}
80
+ >
81
+ {notice.title}
82
+ </h2>
83
+ </div>
84
+ <div className="ml-6.5">
85
+ <p
86
+ className={cn(
87
+ "mt-3 text-sm leading-7",
88
+ !notice.pending && "text-foreground",
89
+ )}
90
+ >
91
+ {notice.description}
92
+ </p>
93
+ {!notice.sandbox && notice.error && (
94
+ <SandboxErrorOutput error={notice.error} />
95
+ )}
96
+ <div className="mt-5 flex flex-wrap items-center gap-x-6 gap-y-3">
97
+ {!packagesOpen && (notice.sandbox || notice.pending) && (
98
+ <Button
99
+ variant="text"
100
+ size="xs"
101
+ className="h-auto p-0 text-xs gap-1.5"
102
+ onClick={() => openApplication("packages")}
103
+ >
104
+ {notice.pending ? "View setup details" : "Open Packages"}
105
+ <ArrowRightIcon className="size-3" aria-hidden={true} />
106
+ </Button>
107
+ )}
108
+ {!notice.pending && !notice.sandbox && (
109
+ <Button variant="outline" size="xs" onClick={onRetry}>
110
+ Try again
111
+ </Button>
112
+ )}
113
+ {notice.pending && <StartupElapsedTime />}
114
+ </div>
115
+ </div>
116
+ </section>
117
+ </VerticalLayoutWrapper>
118
+ );
119
+ };
120
+
121
+ function StartupElapsedTime() {
122
+ const [startedAt] = useState(Date.now);
123
+ const [seconds, setSeconds] = useState(0);
124
+ useInterval(() => setSeconds(Math.floor((Date.now() - startedAt) / 1000)), {
125
+ delayMs: 1000,
126
+ whenVisible: true,
127
+ });
128
+ const duration =
129
+ seconds < 60
130
+ ? `${seconds}s`
131
+ : `${Math.floor(seconds / 60)}m ${seconds % 60}s`;
132
+ return (
133
+ <span
134
+ className="text-xs text-muted-foreground/70 tabular-nums"
135
+ aria-live="off"
136
+ >
137
+ Elapsed {duration}
138
+ </span>
139
+ );
140
+ }
@@ -4,8 +4,11 @@ import type React from "react";
4
4
  import type { PropsWithChildren } from "react";
5
5
  import type { AppConfig } from "@/core/config/config-schema";
6
6
  import { PyodideLoader } from "@/core/wasm/PyodideLoader";
7
- import { isAppClosed } from "@/core/websocket/connection-utils";
8
- import type { ConnectionStatus } from "@/core/websocket/types";
7
+ import {
8
+ type ConnectionStatus,
9
+ WebSocketClosedReason,
10
+ WebSocketState,
11
+ } from "@/core/websocket/types";
9
12
  import { cn } from "@/utils/cn";
10
13
  import { DynamicFavicon } from "./dynamic-favicon";
11
14
  import { StatusOverlay } from "./header/status";
@@ -44,7 +47,10 @@ export const AppContainer: React.FC<PropsWithChildren<Props>> = ({
44
47
  data-connection-state={connectionState}
45
48
  className={cn(
46
49
  "mathjax_ignore",
47
- isAppClosed(connectionState) && "disconnected",
50
+ connection.state === WebSocketState.CLOSED &&
51
+ connection.code !==
52
+ WebSocketClosedReason.KERNEL_STARTUP_ERROR &&
53
+ "disconnected",
48
54
  "bg-background w-full h-full text-textColor",
49
55
  "flex flex-col overflow-y-auto",
50
56
  width === "full" && "config-width-full",