@marimo-team/islands 0.25.2-dev0 → 0.25.2-dev100

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 (366) hide show
  1. package/dist/{ConnectedDataExplorerComponent-C2d9ysUI.js → ConnectedDataExplorerComponent-BZmqc_F0.js} +11 -11
  2. package/dist/{ErrorBoundary-2usl042r.js → ErrorBoundary-Dcb6Zg4M.js} +8 -8
  3. package/dist/{abnfDiagram-VCTEODGH-AFhOQTt8.js → abnfDiagram-VCTEODGH-C_Lmaa2j.js} +3 -3
  4. package/dist/{any-language-editor-CycIVIeP.js → any-language-editor-BFzqhOBR.js} +5 -5
  5. package/dist/{apl-BYaaig9_.js → apl-GEW9-ZP1.js} +1 -1
  6. package/dist/{architectureDiagram-5GKGNRK7-BngksAAQ.js → architectureDiagram-5GKGNRK7-BKMataHB.js} +5 -5
  7. package/dist/{asciiarmor-GKQFJXQG.js → asciiarmor-BWNxzkG7.js} +1 -1
  8. package/dist/{asn1-BsSb7HP5.js → asn1-Bcn2QutK.js} +1 -1
  9. package/dist/assets/__vite-browser-external-BqAtzd2P.js +1 -0
  10. package/dist/assets/{worker-D7hWi02M.js → worker-Bf8dt6S-.js} +5 -5
  11. package/dist/{asterisk-B3I8SNb5.js → asterisk-lE36-hJK.js} +1 -1
  12. package/dist/{blockDiagram-I7D4REHJ-CvBmppdy.js → blockDiagram-I7D4REHJ-BeHOjyDk.js} +9 -9
  13. package/dist/{brainfuck-DXjk3bQe.js → brainfuck-BQCYDheZ.js} +1 -1
  14. package/dist/{button-DdXAm8iz.js → button-BtsM2UqM.js} +312 -283
  15. package/dist/{c4Diagram-7LVT6UL2-EceL4_jH.js → c4Diagram-7LVT6UL2-Bao10t_O.js} +7 -7
  16. package/dist/{capabilities-B3ce_GNu.js → capabilities-A5jrzjCJ.js} +1 -1
  17. package/dist/{cells-Cv93oav_.js → cells-DZi0ioak.js} +4330 -4313
  18. package/dist/{channel-z7HZXHwv.js → channel-BxCkvUgE.js} +1 -1
  19. package/dist/{chat-ui-fVyVOhYN.js → chat-ui-CwOWzoSO.js} +46 -46
  20. package/dist/{check-B7cIK6gb.js → check-CNP79M3A.js} +1 -1
  21. package/dist/{chunk-4HAMMTFA-BPTTOOC5.js → chunk-4HAMMTFA-CH7Gpamd.js} +5 -5
  22. package/dist/{chunk-75Z2AOVW-C4AOleKf.js → chunk-75Z2AOVW-AI7CvgKn.js} +1 -1
  23. package/dist/{chunk-DU6HZSFF-1TwWR6gh.js → chunk-DU6HZSFF-BSvuTkX4.js} +1 -1
  24. package/dist/{chunk-F27PBJKO-DMI1PBe4.js → chunk-F27PBJKO-CLshwT9T.js} +1 -1
  25. package/dist/{chunk-GMAD6QVW-vStrMz2P.js → chunk-GMAD6QVW-wnHcn-lH.js} +3 -3
  26. package/dist/{chunk-GVQU2GXP-2HwWgs4u.js → chunk-GVQU2GXP-7O2p8hut.js} +2 -2
  27. package/dist/{chunk-IMKFNOWR-UOVZuZVn.js → chunk-IMKFNOWR-Bu0Vh_Yi.js} +6 -6
  28. package/dist/{chunk-L3NEJ4N5-RhC7i0I2.js → chunk-L3NEJ4N5-B9_Alrxb.js} +5 -5
  29. package/dist/{chunk-OSK3NFVY-CZV09N-U.js → chunk-OSK3NFVY-PeQPH2fD.js} +6 -6
  30. package/dist/{chunk-P2QGCYS3-0TAWai9C.js → chunk-P2QGCYS3-D9twiFuU.js} +1 -1
  31. package/dist/{chunk-POPQ4Y6H-Cc3_56GX.js → chunk-POPQ4Y6H-BUiNs18s.js} +1 -1
  32. package/dist/{chunk-PWAF6VOD-lNxB9k8z.js → chunk-PWAF6VOD-D8S9NPCy.js} +1 -1
  33. package/dist/{chunk-SHT3W25Y-CrEPyWy1.js → chunk-SHT3W25Y-B2dyNZ31.js} +8 -8
  34. package/dist/{chunk-SVP7TREG-uIyyySp6.js → chunk-SVP7TREG-D7UPvB10.js} +2 -2
  35. package/dist/{chunk-TICWLB2K-DdXM3eg6.js → chunk-TICWLB2K-BNaGoadd.js} +6 -6
  36. package/dist/classDiagram-ZZMXUADV-Bbo2n384.js +30 -0
  37. package/dist/classDiagram-v2-VYDZK3BY-xR8cGP0r.js +30 -0
  38. package/dist/{clike-E2lFbGVj.js → clike-CxK9W55Z.js} +1 -1
  39. package/dist/{clojure-Dn_K4RlK.js → clojure-Dzcvwpxk.js} +1 -1
  40. package/dist/{cmake-DpN2Top5.js → cmake-DYr-71zp.js} +1 -1
  41. package/dist/{cobol-Chf22-GM.js → cobol-DC3g37Kq.js} +1 -1
  42. package/dist/{code-visibility-rUDTB2Ce.js → code-visibility-DTB0i3UU.js} +6 -6
  43. package/dist/{coffeescript-BVe1OiD9.js → coffeescript-C-eFwH5N.js} +1 -1
  44. package/dist/{common-BVErJKjc.js → common-CaVEr6tY.js} +11801 -11503
  45. package/dist/{commonlisp-DxoBG7fU.js → commonlisp-CyaNXrJR.js} +1 -1
  46. package/dist/{copy-icon-CLdENY__.js → copy-icon-BY7jgcaV.js} +3 -3
  47. package/dist/{crystal-DCM3yc4r.js → crystal-ih5ax5tQ.js} +1 -1
  48. package/dist/{css-DkZ9mMyI.js → css-CN_wP7_R.js} +1 -1
  49. package/dist/{cynefinDiagram-5FMLGOSQ-zknaAsGy.js → cynefinDiagram-5FMLGOSQ-CCDn4Z9e.js} +3 -3
  50. package/dist/{cypher-Drw_8U5I.js → cypher-CqGRcmZo.js} +1 -1
  51. package/dist/{d-CsVGcKMF.js → d-Cj0sOW2z.js} +1 -1
  52. package/dist/{dagre-GXQ25YYZ-BhMOoMGJ.js → dagre-GXQ25YYZ-BJiUO_SV.js} +10 -10
  53. package/dist/{data-grid-overlay-editor-7ANmo9c-.js → data-grid-overlay-editor-BzTuqI2T.js} +1 -1
  54. package/dist/{diagram-S7CK7UJ4-V5-Z-EDY.js → diagram-S7CK7UJ4-BZfxFNRR.js} +4 -4
  55. package/dist/{diagram-UQ7AKVKN-qw8AjDal.js → diagram-UQ7AKVKN-1xcsiIMg.js} +3 -3
  56. package/dist/{diagram-VSXAHHWV-CR7BJygZ.js → diagram-VSXAHHWV-DPAWJ9Nw.js} +2 -2
  57. package/dist/{diagram-VX7I27RA-DfuqFb1E.js → diagram-VX7I27RA-DmRsnHYY.js} +5 -5
  58. package/dist/{diagram-Z3DM3KII-DpWwlYZB.js → diagram-Z3DM3KII--b49ryKx.js} +3 -3
  59. package/dist/{dialog-CgNq6y9-.js → dialog-CmExhUDI.js} +26 -26
  60. package/dist/{diff-CBikYCUF.js → diff-B_hUkiat.js} +1 -1
  61. package/dist/{dist-Df0wKI0F.js → dist-BK4Oj99o.js} +1 -1
  62. package/dist/{dist-BVGtK7Ht.js → dist-BLfKmR-l.js} +1 -1
  63. package/dist/{dist-B8D7McG3.js → dist-BMQf5zIS.js} +46 -46
  64. package/dist/{dist-C2KzV-vf.js → dist-BorMD-uX.js} +2 -2
  65. package/dist/{dist-Cs2FijYk.js → dist-BuaRHxOc.js} +2 -2
  66. package/dist/{dist-DPcEtqmG.js → dist-Bvs24R_E.js} +47 -47
  67. package/dist/{dist-lA1Cttkb.js → dist-C8fAKSH1.js} +41 -41
  68. package/dist/{dist-DszxuxS1.js → dist-CLdpGQVr.js} +2 -2
  69. package/dist/{dist-CO1AwwG_.js → dist-CN8zI-XC.js} +209 -209
  70. package/dist/{dist-D1PpnuZB.js → dist-CN_BeG2I.js} +1 -1
  71. package/dist/{dist-CPGxfVGX.js → dist-CSJ0MDRw.js} +1 -1
  72. package/dist/{dist-Cm3iAFMD.js → dist-CSbh1PNP.js} +3 -3
  73. package/dist/{dist-9x1ZRe-e.js → dist-Cg7gzw-a.js} +2 -2
  74. package/dist/{dist-B1vYLK28.js → dist-CkTTIdBe.js} +345 -345
  75. package/dist/{dist-BRxfaJgs.js → dist-CrSP_H1M.js} +296 -296
  76. package/dist/{dist-C2wDlYdD.js → dist-D-wwqlzJ.js} +2 -2
  77. package/dist/{dist-BtKIs9N-.js → dist-D6d86eNJ.js} +1 -1
  78. package/dist/{dist-DHOTQar0.js → dist-DBtSl3sf.js} +1 -1
  79. package/dist/{dist-KzZ7WELx.js → dist-DiDibOYr.js} +120 -120
  80. package/dist/{dist-Kxgjxakw.js → dist-DoE4XJBC.js} +1277 -1222
  81. package/dist/{dist-BHCHt1NI.js → dist-F8Ep36rk.js} +1 -1
  82. package/dist/{dist-C8xMLVYi.js → dist-OR1OnN-y.js} +44 -44
  83. package/dist/{dist-1HDa70oE.js → dist-PXYI_yuP.js} +3 -3
  84. package/dist/{dist-CMh_W4y4.js → dist-diIx5qJW.js} +2 -2
  85. package/dist/{dockerfile-DJnSntVB.js → dockerfile-D0VKN500.js} +2 -2
  86. package/dist/dropdown-menu-Cz4TdOJh.js +4678 -0
  87. package/dist/{dtd-BHa4v0Bn.js → dtd-B8FGSWWe.js} +1 -1
  88. package/dist/{dylan-BypL2Zz8.js → dylan-DbIBYIrw.js} +1 -1
  89. package/dist/{ebnf-5guncNu-.js → ebnf-D-YbYLdk.js} +1 -1
  90. package/dist/{ebnfDiagram-PWID7BFC-C20OnNMZ.js → ebnfDiagram-PWID7BFC-rSwVyh4y.js} +3 -3
  91. package/dist/{ecl-iRcVIKYZ.js → ecl-DBmkdWAd.js} +1 -1
  92. package/dist/{eiffel-BEqF9aU4.js → eiffel-CcWSDDzK.js} +1 -1
  93. package/dist/{elm-DYcfNE9c.js → elm-MC-b8a6C.js} +1 -1
  94. package/dist/{erDiagram-RLTQ6QDP-DBXLWO9v.js → erDiagram-RLTQ6QDP-Bfd3iAoC.js} +12 -12
  95. package/dist/{erlang-BtAuIoF0.js → erlang-AdO1-xtV.js} +1 -1
  96. package/dist/error-banner-D30nA9nE.js +362 -0
  97. package/dist/{error-entries-DLl0XqoW.js → error-entries-BovkFYNy.js} +2 -2
  98. package/dist/{esm-BElI3qKH.js → esm-D2gTsXEV.js} +579 -579
  99. package/dist/{esm-h8f7-1CJ.js → esm-DAVrGVKP.js} +378 -372
  100. package/dist/{factor-3nzOwLuN.js → factor-Ys-13HOP.js} +2 -2
  101. package/dist/{fcl-C90TGnJJ.js → fcl-DnwditDr.js} +1 -1
  102. package/dist/{feedback-button-K1inEVfd.js → feedback-button-CHGz2EXX.js} +10 -10
  103. package/dist/flowDiagram-HODETNUW-D7IBKS12.js +16 -0
  104. package/dist/{formats-Cl_67ghI.js → formats-DhhbdyAH.js} +3 -3
  105. package/dist/{forth-DEaRrLUi.js → forth-DiMuIXFe.js} +1 -1
  106. package/dist/{fortran-Bv6JRUjY.js → fortran-hkrF2eM4.js} +1 -1
  107. package/dist/{ganttDiagram-EL5Y4UJY-cRRaDt88.js → ganttDiagram-EL5Y4UJY-B4m_YsKa.js} +2 -2
  108. package/dist/{gas-JNerWj3-.js → gas-DlhqN9k8.js} +1 -1
  109. package/dist/{gherkin-CSrl-H70.js → gherkin-0SlhEZ3t.js} +1 -1
  110. package/dist/{gitGraphDiagram-WWUBYQGX-Pox5k9-Y.js → gitGraphDiagram-WWUBYQGX-QRBbvWXh.js} +2 -2
  111. package/dist/{glide-data-editor-D2fDO5aG.js → glide-data-editor-WxMsJlmb.js} +11 -11
  112. package/dist/{glide-utils-B3rUT5PI.js → glide-utils-BVJ4fkxX.js} +3 -3
  113. package/dist/{globals-NylFP0CX.js → globals-BROokniw.js} +3 -3
  114. package/dist/{groovy-X7euO_vE.js → groovy-YhcTMyvX.js} +1 -1
  115. package/dist/{haskell-C48Z70Az.js → haskell-CodLxrtT.js} +1 -1
  116. package/dist/{haxe-CAUWMmwR.js → haxe-CiRWNFkH.js} +1 -1
  117. package/dist/{html-to-image-CmkwfNkf.js → html-to-image-Cn1_16-x.js} +543 -565
  118. package/dist/{http-BrSBnhDH.js → http-Bh6HhdNR.js} +1 -1
  119. package/dist/{idl-BXuPleZv.js → idl-DZgBq75I.js} +1 -1
  120. package/dist/{infoDiagram-27XIBGKW-ntpxMfrq.js → infoDiagram-27XIBGKW-DVQFYvhg.js} +2 -2
  121. package/dist/{ishikawaDiagram-5VMMS53U-BllIlHE5.js → ishikawaDiagram-5VMMS53U-viPND-nm.js} +3 -3
  122. package/dist/{javascript-B4EPWJf_.js → javascript-BfNytHiM.js} +1 -1
  123. package/dist/{journeyDiagram-3NMN7TZE-EPJDPlt0.js → journeyDiagram-3NMN7TZE-BeeJdJo3.js} +2 -2
  124. package/dist/{julia-ke9Kh8b7.js → julia--tLIAG7q.js} +1 -1
  125. package/dist/{kanban-definition-UXKFOSKX-GYtNMjtS.js → kanban-definition-UXKFOSKX-Dcl_ECO9.js} +9 -9
  126. package/dist/{label-BslhXqL6.js → label-DQO1jFjf.js} +96 -93
  127. package/dist/{livescript-Ce4uqGAC.js → livescript-CVPfYnY_.js} +1 -1
  128. package/dist/{loader-DEZSzvma.js → loader-Cm-ATtou.js} +1 -1
  129. package/dist/{lua-D6fti_Jk.js → lua-4Fa-T-qq.js} +1 -1
  130. package/dist/main.js +6966 -6827
  131. package/dist/{mathematica-DcEpZ3Vj.js → mathematica-CtYAy6GG.js} +1 -1
  132. package/dist/{mbox-DFBbOu0X.js → mbox-D0w9Ah1C.js} +1 -1
  133. package/dist/{mermaid-Dnzoxjt1.js → mermaid-BfhcnSj-.js} +54 -54
  134. package/dist/{mindmap-definition-YA3MSWOX-Cth76xgH.js → mindmap-definition-YA3MSWOX-BdxxhF-5.js} +11 -11
  135. package/dist/{mirc-CqeibO3N.js → mirc-De9aSAZM.js} +1 -1
  136. package/dist/{mllike-D54QZYTP.js → mllike-BbugeaY_.js} +1 -1
  137. package/dist/{modelica-DuML2-8V.js → modelica-BjJwWw1F.js} +1 -1
  138. package/dist/{mscgen-CJmKwp3b.js → mscgen-DwiRH5ma.js} +1 -1
  139. package/dist/{mumps-DaVgFtkd.js → mumps--plbDM9o.js} +1 -1
  140. package/dist/{nginx-BXN1rqI0.js → nginx-C4Df7REc.js} +1 -1
  141. package/dist/{nsis-CMfRqf0V.js → nsis-fiiOqLc3.js} +7 -7
  142. package/dist/{ntriples-BiOGlMDR.js → ntriples-jV77I4k8.js} +1 -1
  143. package/dist/{number-overlay-editor-B4XyCoMu.js → number-overlay-editor-DCj0MZgn.js} +1 -1
  144. package/dist/{octave-CgVnzxKk.js → octave-Cztd01tF.js} +1 -1
  145. package/dist/{oz-B2mky97X.js → oz-Bl8o3BDl.js} +1 -1
  146. package/dist/{pascal-BoZhBf6s.js → pascal-BO5JqysR.js} +1 -1
  147. package/dist/{pegDiagram-XKGWAZYB-Cu4uOXii.js → pegDiagram-XKGWAZYB-Du5p2s0w.js} +3 -3
  148. package/dist/{perl-DjzMqXtt.js → perl-Drlh9s6m.js} +1 -1
  149. package/dist/{pieDiagram-E7YTZNPT-Bh3eDa9s.js → pieDiagram-E7YTZNPT-DJg-SOIq.js} +3 -3
  150. package/dist/{pig-B2mB-01d.js → pig-BWGR8wZw.js} +1 -1
  151. package/dist/{powershell-D0zT88Aj.js → powershell-DT99xlz_.js} +1 -1
  152. package/dist/{process-output-CYN5E-iO.js → process-output-CUG57KRp.js} +4 -4
  153. package/dist/{properties-3_5qCgOj.js → properties-Q-rkxld0.js} +1 -1
  154. package/dist/{protobuf-Dgoxfi1H.js → protobuf-DKyWZbs7.js} +1 -1
  155. package/dist/{pug-CNRdd8oG.js → pug-42ZJUbEC.js} +2 -2
  156. package/dist/{puppet-DzILxZfz.js → puppet-B4UozHhh.js} +1 -1
  157. package/dist/purify.es-DMv5zIkJ.js +866 -0
  158. package/dist/{python-AfVdMn_l.js → python-DREjAV__.js} +1 -1
  159. package/dist/{q-C6p-CGWh.js → q-Bi63IpBO.js} +1 -1
  160. package/dist/{quadrantDiagram-AXDQQJYC--kqzFC3w.js → quadrantDiagram-AXDQQJYC-keLfFx9f.js} +1 -1
  161. package/dist/{r-CzKF1D2X.js → r-DSwXWKMR.js} +1 -1
  162. package/dist/{railroadDiagram-O6MQD6OU-DG-M6Rnc.js → railroadDiagram-O6MQD6OU-C0ojm-6_.js} +3 -3
  163. package/dist/{requirementDiagram-BXWQKSXE-DCwsThh0.js → requirementDiagram-BXWQKSXE-CNwNBmI3.js} +11 -11
  164. package/dist/{reveal-component-Dtm5GH3p.js → reveal-component-CSY54dq4.js} +10 -10
  165. package/dist/{rpm-Bx7FkjTO.js → rpm-DPb1DeKM.js} +1 -1
  166. package/dist/{ruby-BMzgq2bf.js → ruby-U7fZA4DP.js} +2 -2
  167. package/dist/{sankeyDiagram-P5KCCOFB-BdzhT0BM.js → sankeyDiagram-P5KCCOFB-Bh4EsJox.js} +1 -1
  168. package/dist/{sas-ClGVnK3F.js → sas-CLk1JpTn.js} +1 -1
  169. package/dist/{scheme-C0MXqXep.js → scheme-CT-2k2Tl.js} +1 -1
  170. package/dist/select-Bs-nmvm6.js +1344 -0
  171. package/dist/{sequenceDiagram-WJ2MYXX4-CbXB1_PU.js → sequenceDiagram-WJ2MYXX4-DQaW5qBG.js} +4 -4
  172. package/dist/{shell-CiQZv6oG.js → shell-BLO7fcsk.js} +1 -1
  173. package/dist/{sieve-BiIMePvV.js → sieve-nG3C7WNH.js} +1 -1
  174. package/dist/{simple-mode-8ETW2RS6.js → simple-mode-C683Q7or.js} +1 -1
  175. package/dist/{smalltalk-9-llftyG.js → smalltalk-BROcZybA.js} +1 -1
  176. package/dist/{solr-CxCKEuwq.js → solr-mVltHNc5.js} +1 -1
  177. package/dist/{sparql-BRmy7pzx.js → sparql-Cv1Ksr4v.js} +1 -1
  178. package/dist/{spec-DQBRQSba.js → spec-DVsoMvYT.js} +116 -135
  179. package/dist/{spreadsheet-UCNUIGsn.js → spreadsheet-BwTnp5K_.js} +1 -1
  180. package/dist/{sql-D0hSGZ-H.js → sql-CjLt0122.js} +1 -1
  181. package/dist/{stateDiagram-D77RDMKH-A-Zf3Sb2.js → stateDiagram-D77RDMKH-BDa515QC.js} +13 -13
  182. package/dist/stateDiagram-v2-MP3YSRHH-ChNddepZ.js +30 -0
  183. package/dist/{stex-UeT_Aofp.js → stex-Btf3omL8.js} +1 -1
  184. package/dist/style.css +1 -1
  185. package/dist/{stylus-Fi4waA2H.js → stylus-Dt4VvLXL.js} +1 -1
  186. package/dist/{swift-NqPyaBye.js → swift-DHsn_CVI.js} +1 -1
  187. package/dist/{swimlanes-42K2YHIH-B_pMf0J4.js → swimlanes-42K2YHIH-M4IdGi8J.js} +10 -10
  188. package/dist/swimlanesDiagram-VR7AAH4N-FUSwmzEp.js +30 -0
  189. package/dist/{swiper-component-IOUowglM.js → swiper-component-CpN-hewZ.js} +2 -2
  190. package/dist/{tcl-B4f0xfmM.js → tcl-CV0OLBOl.js} +1 -1
  191. package/dist/{textile-CnNbnPTe.js → textile-D320oKVM.js} +1 -1
  192. package/dist/{tiddlywiki-CSGSOg38.js → tiddlywiki-BVVNvfy4.js} +1 -1
  193. package/dist/{tiki-9F02WBA6.js → tiki-BF2aDPlB.js} +1 -1
  194. package/dist/{timeline-definition-24CTP7MA-DTXFjTTM.js → timeline-definition-24CTP7MA-DH-kvakg.js} +3 -3
  195. package/dist/{toDate-C67bxMWn.js → toDate-vEi5kTfY.js} +4 -5
  196. package/dist/{toast-DvY70eFX.js → toast-DfEpJedt.js} +157 -161
  197. package/dist/{toml-AesZ6RBt.js → toml-CaUN7UHo.js} +1 -1
  198. package/dist/{tooltip-qB8NlSqV.js → tooltip-CuNWg2ay.js} +543 -579
  199. package/dist/{troff-DlfvveK1.js → troff-DQUFcClZ.js} +1 -1
  200. package/dist/{ttcn--YVSkGs_.js → ttcn-CQL1duJS.js} +1 -1
  201. package/dist/{ttcn-cfg-Bb1Knl_J.js → ttcn-cfg-BMmEFJPu.js} +1 -1
  202. package/dist/{turtle-DC24v1bz.js → turtle-C3esgsRr.js} +1 -1
  203. package/dist/{use-restore-focus-D5D9xEjZ.js → use-restore-focus-kmgwrL8q.js} +1833 -1625
  204. package/dist/{useAsyncData-BD6AStMt.js → useAsyncData-rkAlR_vh.js} +1 -1
  205. package/dist/{useDateFormatter-BXQGu86d.js → useDateFormatter-C-tz65rD.js} +52 -31
  206. package/dist/{useDeepCompareMemoize-D_HNdyvI.js → useDeepCompareMemoize-BlHFBj5_.js} +1 -1
  207. package/dist/{useIframeCapabilities-CVtNkI3Y.js → useIframeCapabilities-C1Bt04Iz.js} +1 -1
  208. package/dist/{useLifecycle-DPgiiwwU.js → useLifecycle-B68iY077.js} +3 -3
  209. package/dist/{useTheme-DzXmYZ5V.js → useTheme-BwSgeAFb.js} +2 -2
  210. package/dist/{vb-Dpc8vhvF.js → vb-RK1eDXRl.js} +1 -1
  211. package/dist/{vbscript-B-Y1XnZe.js → vbscript-BCOeM0de.js} +1 -1
  212. package/dist/{vega-component-tFOzgarw.js → vega-component-C-bPttRN.js} +9 -9
  213. package/dist/{velocity-DHMu9kc-.js → velocity-CZKOFbOI.js} +1 -1
  214. package/dist/{vennDiagram-4TSXK5OY-BPHjZo0R.js → vennDiagram-4TSXK5OY-d5g7XeiI.js} +3 -3
  215. package/dist/{verilog-DhiEaoUl.js → verilog-DqQTzVn8.js} +1 -1
  216. package/dist/{vhdl-D4X23YKO.js → vhdl-vQr2bfmi.js} +1 -1
  217. package/dist/{wardleyDiagram-VM6X3IG4-6fTLYBuD.js → wardleyDiagram-VM6X3IG4-BfX3bSzR.js} +3 -3
  218. package/dist/{webidl-SyzNxWpJ.js → webidl-DzX7N40e.js} +1 -1
  219. package/dist/{xquery-BC2R4Hk6.js → xquery-Cw_Q_hGR.js} +1 -1
  220. package/dist/{xychartDiagram-S5SC5T6Z-BYjwjrzE.js → xychartDiagram-S5SC5T6Z-C1QsLZg7.js} +5 -5
  221. package/dist/{yacas-DLNXPMmH.js → yacas-DiC4jJBE.js} +1 -1
  222. package/dist/{z80-CDXWHOO6.js → z80-CUOQDEJO.js} +1 -1
  223. package/package.json +24 -23
  224. package/src/__tests__/mount.test.ts +6 -6
  225. package/src/components/chat/__tests__/chat-history-popover.test.tsx +157 -0
  226. package/src/components/chat/chat-history-popover.tsx +98 -17
  227. package/src/components/chat/chat-panel.tsx +29 -0
  228. package/src/components/chat/tool-call/__tests__/tool-result.test.tsx +56 -0
  229. package/src/components/chat/tool-call/tool-result.tsx +3 -3
  230. package/src/components/data-table/TableTopBar.tsx +4 -0
  231. package/src/components/data-table/__tests__/export-actions.test.tsx +1111 -14
  232. package/src/components/data-table/__tests__/pagination.test.tsx +85 -1
  233. package/src/components/data-table/__tests__/schemas.test.ts +57 -0
  234. package/src/components/data-table/charts/__tests__/schemas.test.ts +25 -0
  235. package/src/components/data-table/charts/__tests__/slider-field.test.tsx +54 -0
  236. package/src/components/data-table/charts/__tests__/spec.test.ts +26 -23
  237. package/src/components/data-table/charts/components/form-fields.tsx +3 -1
  238. package/src/components/data-table/charts/constants.ts +11 -10
  239. package/src/components/data-table/charts/types.ts +1 -0
  240. package/src/components/data-table/data-table.tsx +3 -0
  241. package/src/components/data-table/export-actions.tsx +365 -81
  242. package/src/components/data-table/pagination.tsx +16 -2
  243. package/src/components/data-table/range-focus/__tests__/atoms.test.ts +11 -11
  244. package/src/components/data-table/schemas.ts +90 -14
  245. package/src/components/editor/actions/__tests__/pair-with-agent-commands.test.ts +32 -46
  246. package/src/components/editor/actions/__tests__/pair-with-agent-modal.test.tsx +29 -40
  247. package/src/components/editor/actions/__tests__/useSetOutputsExpanded.test.ts +42 -0
  248. package/src/components/editor/actions/pair-with-agent-commands.ts +3 -4
  249. package/src/components/editor/actions/pair-with-agent-modal.tsx +4 -7
  250. package/src/components/editor/actions/useNotebookActions.tsx +20 -0
  251. package/src/components/editor/actions/useRestartKernel.tsx +2 -2
  252. package/src/components/editor/actions/useSetOutputsExpanded.ts +67 -0
  253. package/src/components/editor/alerts/__tests__/connection-notice.test.tsx +224 -17
  254. package/src/components/editor/alerts/connection-details.tsx +61 -0
  255. package/src/components/editor/alerts/connection-notice.tsx +46 -53
  256. package/src/components/editor/alerts/startup-progress.tsx +73 -129
  257. package/src/components/editor/app-container.tsx +2 -2
  258. package/src/components/editor/boundary/__tests__/ErrorBoundary.test.tsx +2 -2
  259. package/src/components/editor/cell/CreateCellButton.tsx +2 -2
  260. package/src/components/editor/cell/DeleteButton.tsx +2 -2
  261. package/src/components/editor/cell/RunButton.tsx +3 -3
  262. package/src/components/editor/cell/StopButton.tsx +2 -2
  263. package/src/components/editor/chrome/components/__tests__/feedback-button.test.tsx +4 -4
  264. package/src/components/editor/chrome/components/feedback-button.tsx +3 -3
  265. package/src/components/editor/chrome/panels/__tests__/packages-panel.test.tsx +8 -8
  266. package/src/components/editor/chrome/panels/__tests__/{sandbox-details.test.tsx → runtime-details.test.tsx} +94 -22
  267. package/src/components/editor/chrome/panels/__tests__/sandbox-recovery.test.tsx +4 -4
  268. package/src/components/editor/chrome/panels/packages-panel.tsx +8 -29
  269. package/src/components/editor/chrome/panels/{sandbox-details-state.ts → runtime-details-state.ts} +1 -1
  270. package/src/components/editor/chrome/panels/{sandbox-panel.tsx → runtime-panel.tsx} +38 -66
  271. package/src/components/editor/chrome/panels/runtime-status-toggle.tsx +56 -0
  272. package/src/components/editor/chrome/panels/sandbox-controller.tsx +2 -2
  273. package/src/components/editor/chrome/wrapper/app-chrome.tsx +3 -3
  274. package/src/components/editor/chrome/wrapper/footer-items/machine-stats.tsx +2 -2
  275. package/src/components/editor/controls/Controls.tsx +3 -3
  276. package/src/components/editor/controls/__tests__/notebook-menu-dropdown.test.tsx +2 -2
  277. package/src/components/editor/header/__tests__/status.test.tsx +4 -4
  278. package/src/components/editor/header/app-header.tsx +2 -2
  279. package/src/components/editor/header/status.tsx +3 -3
  280. package/src/components/editor/navigation/__tests__/navigation.test.ts +8 -8
  281. package/src/components/tracing/tracing.test.tsx +30 -30
  282. package/src/components/ui/__tests__/slider.test.tsx +37 -0
  283. package/src/components/ui/progress-stages.tsx +114 -0
  284. package/src/components/ui/slider.tsx +2 -0
  285. package/src/core/ai/__tests__/state.test.ts +120 -0
  286. package/src/core/ai/state.ts +36 -10
  287. package/src/core/codemirror/lsp/__tests__/notebook-lsp.test.ts +106 -5
  288. package/src/core/codemirror/lsp/notebook-lsp.ts +16 -2
  289. package/src/core/codemirror/readonly/__tests__/extension.test.ts +6 -6
  290. package/src/core/codemirror/readonly/extension.ts +2 -2
  291. package/src/core/config/pair.ts +0 -1
  292. package/src/core/datasets/__tests__/data-source-discovery.test.ts +2 -2
  293. package/src/core/edit-app.tsx +21 -1
  294. package/src/core/export/hooks.ts +2 -2
  295. package/src/core/hotkeys/hotkeys.ts +12 -0
  296. package/src/core/islands/bootstrap.ts +1 -0
  297. package/src/core/kernel/session.ts +9 -0
  298. package/src/core/network/__tests__/connection.test.ts +3 -3
  299. package/src/core/network/connection-notice.ts +5 -5
  300. package/src/core/network/connection.ts +9 -9
  301. package/src/core/network/requests-lazy.ts +2 -2
  302. package/src/core/packages/__tests__/useSandboxController.test.tsx +2 -2
  303. package/src/core/packages/useSandboxController.ts +6 -6
  304. package/src/core/runtime/__tests__/adapter.test.ts +6 -6
  305. package/src/core/runtime/adapter.ts +7 -7
  306. package/src/core/runtime/config.ts +2 -2
  307. package/src/core/saving/filename.ts +2 -2
  308. package/src/core/saving/save-component.tsx +5 -5
  309. package/src/core/saving/useAutoSave.ts +2 -2
  310. package/src/core/wasm/__tests__/bootstrap.test.ts +33 -1
  311. package/src/core/wasm/worker/bootstrap.ts +22 -3
  312. package/src/core/websocket/__tests__/useMarimoKernelConnection.hook.test.tsx +30 -25
  313. package/src/core/websocket/__tests__/useMarimoKernelConnection.test.ts +5 -5
  314. package/src/core/websocket/connection-utils.ts +21 -21
  315. package/src/core/websocket/types.ts +8 -9
  316. package/src/core/websocket/useMarimoKernelConnection.tsx +33 -22
  317. package/src/css/katex-css.test.ts +166 -0
  318. package/src/css/katex.min.css +169 -168
  319. package/src/mount.tsx +2 -2
  320. package/src/plugins/core/__test__/registerReactComponent.test.ts +55 -0
  321. package/src/plugins/core/registerReactComponent.tsx +3 -1
  322. package/src/plugins/impl/CheckboxPlugin.tsx +1 -1
  323. package/src/plugins/impl/DataTablePlugin.tsx +23 -2
  324. package/src/plugins/impl/DatePickerPlugin.tsx +5 -3
  325. package/src/plugins/impl/DateRangePlugin.tsx +5 -3
  326. package/src/plugins/impl/DateTimePickerPlugin.tsx +5 -3
  327. package/src/plugins/impl/DropdownPlugin.tsx +1 -1
  328. package/src/plugins/impl/FileBrowserPlugin.tsx +45 -15
  329. package/src/plugins/impl/MultiselectPlugin.tsx +1 -1
  330. package/src/plugins/impl/NumberPlugin.tsx +1 -1
  331. package/src/plugins/impl/RadioPlugin.tsx +5 -1
  332. package/src/plugins/impl/RangeSliderPlugin.tsx +1 -1
  333. package/src/plugins/impl/SearchableSelect.tsx +1 -1
  334. package/src/plugins/impl/SliderPlugin.tsx +5 -1
  335. package/src/plugins/impl/SwitchPlugin.tsx +6 -1
  336. package/src/plugins/impl/TextAreaPlugin.tsx +23 -4
  337. package/src/plugins/impl/TextInputPlugin.tsx +10 -2
  338. package/src/plugins/impl/__test__/slider-labels.test.tsx +136 -0
  339. package/src/plugins/impl/__test__/text-labels.test.tsx +141 -0
  340. package/src/plugins/impl/__tests__/DataTablePlugin.test.tsx +65 -8
  341. package/src/plugins/impl/__tests__/FileBrowserPlugin.test.tsx +85 -2
  342. package/src/plugins/impl/__tests__/widget-labels.test.tsx +122 -0
  343. package/src/plugins/impl/chat/ChatPlugin.tsx +1 -1
  344. package/src/plugins/impl/common/labeled.tsx +9 -3
  345. package/src/plugins/impl/data-frames/DataFramePlugin.tsx +15 -3
  346. package/src/plugins/impl/data-frames/forms/__tests__/__snapshots__/form.test.tsx.snap +0 -22
  347. package/src/stories/cell.stories.tsx +2 -2
  348. package/src/stories/dataframe.stories.tsx +7 -0
  349. package/src/stories/layout/vertical/one-column.stories.tsx +5 -5
  350. package/src/stories/progress-stages.stories.tsx +62 -0
  351. package/src/stories/runtime-existing.stories.tsx +44 -0
  352. package/src/stories/runtime-maintenance.stories.tsx +40 -0
  353. package/src/stories/runtime-pixi.stories.tsx +28 -0
  354. package/src/stories/{sandbox.stories.tsx → runtime-story.tsx} +191 -152
  355. package/src/stories/runtime-uv.stories.tsx +56 -0
  356. package/dist/assets/__vite-browser-external-C9iR87Zl.js +0 -1
  357. package/dist/classDiagram-ZZMXUADV-BiATbBE4.js +0 -30
  358. package/dist/classDiagram-v2-VYDZK3BY-JnH97GYw.js +0 -30
  359. package/dist/dropdown-menu-CZy06LAq.js +0 -4502
  360. package/dist/error-banner-B94dcDmP.js +0 -391
  361. package/dist/flowDiagram-HODETNUW-DL52nMkt.js +0 -16
  362. package/dist/purify.es-DgKyQviY.js +0 -805
  363. package/dist/select-C6plhmZr.js +0 -970
  364. package/dist/stateDiagram-v2-MP3YSRHH-D9YMnUGx.js +0 -30
  365. package/dist/swimlanesDiagram-VR7AAH4N-Ctgy-yGP.js +0 -30
  366. package/src/components/editor/chrome/panels/sandbox-toggle.tsx +0 -52
@@ -0,0 +1,136 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+ import { fireEvent, render, screen } from "@testing-library/react";
3
+ import { describe, expect, test, vi } from "vitest";
4
+ import { SetupMocks } from "@/__mocks__/common";
5
+ import { SliderPlugin } from "../SliderPlugin";
6
+
7
+ SetupMocks.resizeObserver();
8
+ const plugin = new SliderPlugin();
9
+ function props(label: string | null) {
10
+ return {
11
+ host: document.createElement("div"),
12
+ value: 5,
13
+ setValue: vi.fn(),
14
+ functions: {},
15
+ data: plugin.validator.parse({
16
+ initialValue: 5,
17
+ start: 0,
18
+ stop: 10,
19
+ step: 1,
20
+ steps: null,
21
+ label,
22
+ }),
23
+ };
24
+ }
25
+
26
+ describe("SliderPlugin accessible labels", () => {
27
+ test("names the actual thumb from formatted labels and updates its reference", () => {
28
+ const initial = props("<strong>Price &amp; tax</strong>");
29
+ const { rerender } = render(plugin.render(initial));
30
+ const thumb = screen.getByRole("slider", { name: "Price & tax" });
31
+ const labelId = thumb.getAttribute("aria-labelledby");
32
+ rerender(
33
+ plugin.render({
34
+ ...initial,
35
+ data: { ...initial.data, label: "Updated price" },
36
+ }),
37
+ );
38
+ const updatedThumb = screen.getByRole("slider", { name: "Updated price" });
39
+ expect(updatedThumb).toHaveAccessibleName("Updated price");
40
+ expect(updatedThumb).toHaveAttribute("aria-labelledby", labelId);
41
+ rerender(
42
+ plugin.render({ ...initial, data: { ...initial.data, label: null } }),
43
+ );
44
+ expect(screen.getByRole("slider")).toHaveAccessibleName("Slider");
45
+ expect(screen.getByRole("slider")).not.toHaveAttribute("aria-labelledby");
46
+ });
47
+
48
+ test.each([null, ""])("retains a fallback name for label %s", (label) => {
49
+ render(plugin.render(props(label)));
50
+ expect(screen.getByRole("slider")).toHaveAccessibleName("Slider");
51
+ });
52
+
53
+ test("keeps repeated widget labels independently associated", () => {
54
+ render(
55
+ <>
56
+ {plugin.render(props("Price"))}
57
+ {plugin.render(props("Price"))}
58
+ </>,
59
+ );
60
+ const thumbs = screen.getAllByRole("slider", { name: "Price" });
61
+ expect(thumbs).toHaveLength(2);
62
+ expect(thumbs[0].getAttribute("aria-labelledby")).not.toBe(
63
+ thumbs[1].getAttribute("aria-labelledby"),
64
+ );
65
+ });
66
+
67
+ test.each([false, true])(
68
+ "preserves keyboard commits with debounce=%s",
69
+ (debounce) => {
70
+ const initial = props("Price");
71
+ render(
72
+ plugin.render({ ...initial, data: { ...initial.data, debounce } }),
73
+ );
74
+ fireEvent.keyDown(screen.getByRole("slider"), { key: "ArrowRight" });
75
+ expect(initial.setValue).toHaveBeenCalledWith(6);
76
+ },
77
+ );
78
+
79
+ test("preserves maximum and minimum keyboard boundaries", () => {
80
+ const initial = props("Price");
81
+ const { rerender } = render(plugin.render({ ...initial, value: 10 }));
82
+ fireEvent.keyDown(screen.getByRole("slider"), { key: "ArrowRight" });
83
+ expect(initial.setValue).not.toHaveBeenCalled();
84
+ rerender(plugin.render({ ...initial, value: 0 }));
85
+ fireEvent.keyDown(screen.getByRole("slider"), { key: "ArrowLeft" });
86
+ expect(initial.setValue).not.toHaveBeenCalled();
87
+ });
88
+
89
+ test("retains the name while disabled and removes keyboard focusability", () => {
90
+ const initial = props("Price");
91
+ render(
92
+ plugin.render({ ...initial, data: { ...initial.data, disabled: true } }),
93
+ );
94
+ const thumb = screen.getByRole("slider", { name: "Price" });
95
+ expect(thumb).not.toHaveAttribute("tabindex");
96
+ expect(thumb).toHaveAttribute("data-disabled");
97
+ });
98
+
99
+ test("preserves vertical keyboard interaction", () => {
100
+ const initial = props("Price");
101
+ render(
102
+ plugin.render({
103
+ ...initial,
104
+ data: { ...initial.data, orientation: "vertical" },
105
+ }),
106
+ );
107
+ const thumb = screen.getByRole("slider", { name: "Price" });
108
+ expect(thumb).toHaveAttribute("aria-orientation", "vertical");
109
+ fireEvent.keyDown(thumb, { key: "ArrowUp" });
110
+ expect(initial.setValue).toHaveBeenCalledWith(6);
111
+ });
112
+
113
+ test("preserves mapped values while naming the index-space thumb", () => {
114
+ const initial = props("Mapped price");
115
+ render(
116
+ plugin.render({
117
+ ...initial,
118
+ value: 1,
119
+ data: {
120
+ ...initial.data,
121
+ start: 0,
122
+ stop: 2,
123
+ steps: [10, 20, 50],
124
+ showValue: true,
125
+ },
126
+ }),
127
+ );
128
+ expect(screen.getByText("20")).toBeInTheDocument();
129
+ fireEvent.keyDown(screen.getByRole("slider", { name: "Mapped price" }), {
130
+ key: "ArrowRight",
131
+ });
132
+ expect(initial.setValue).toHaveBeenCalledWith(2);
133
+ expect(screen.getByRole("slider")).toHaveAttribute("aria-valuenow", "2");
134
+ expect(screen.getByRole("tooltip")).toHaveTextContent("50");
135
+ });
136
+ });
@@ -0,0 +1,141 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+ import { act, fireEvent, render, screen } from "@testing-library/react";
3
+ import { expect, test, vi } from "vitest";
4
+ import type { IPlugin } from "../../types";
5
+ import { TextInputPlugin } from "../TextInputPlugin";
6
+ import { TextAreaPlugin } from "../TextAreaPlugin";
7
+
8
+ function testLabelBehavior<D extends { label: string | null }>(
9
+ plugin: IPlugin<string, D>,
10
+ ) {
11
+ for (const debounce of [false, true, 200]) {
12
+ test(`${plugin.tagName} associates formatted label with debounce=${debounce}`, () => {
13
+ const setValue = vi.fn();
14
+ const props = {
15
+ host: document.createElement("div"),
16
+ value: "",
17
+ setValue,
18
+ functions: {},
19
+ data: plugin.validator.parse({
20
+ initialValue: "",
21
+ placeholder: "",
22
+ label: "<strong>Notes &amp; details</strong>",
23
+ debounce,
24
+ }),
25
+ };
26
+ const { rerender } = render(plugin.render(props));
27
+ const control = screen.getByLabelText("Notes & details");
28
+ expect(control).toHaveAccessibleName("Notes & details");
29
+ const id = control.id;
30
+ rerender(
31
+ plugin.render({
32
+ ...props,
33
+ data: { ...props.data, label: "Updated notes" },
34
+ }),
35
+ );
36
+ expect(screen.getByLabelText("Updated notes").id).toBe(id);
37
+ rerender(
38
+ plugin.render({ ...props, data: { ...props.data, label: null } }),
39
+ );
40
+ expect(control).toHaveAccessibleName("");
41
+ });
42
+ test(`${plugin.tagName} preserves commit timing with debounce=${debounce}`, () => {
43
+ vi.useFakeTimers();
44
+ try {
45
+ const setValue = vi.fn();
46
+ const props = {
47
+ host: document.createElement("div"),
48
+ value: "",
49
+ setValue,
50
+ functions: {},
51
+ data: plugin.validator.parse({
52
+ initialValue: "",
53
+ placeholder: "",
54
+ label: "Notes",
55
+ debounce,
56
+ }),
57
+ };
58
+ render(plugin.render(props));
59
+ const control = screen.getByLabelText("Notes");
60
+ if (debounce === false) {
61
+ fireEvent.input(control, { target: { value: "hello" } });
62
+ } else {
63
+ fireEvent.change(control, { target: { value: "hello" } });
64
+ }
65
+ const immediateCalls = debounce === false ? 1 : 0;
66
+ expect(setValue).toHaveBeenCalledTimes(immediateCalls);
67
+ act(() => vi.advanceTimersByTime(199));
68
+ expect(setValue).toHaveBeenCalledTimes(immediateCalls);
69
+ if (debounce === true) {
70
+ fireEvent.blur(control);
71
+ } else if (typeof debounce === "number") {
72
+ act(() => vi.advanceTimersByTime(1));
73
+ }
74
+ expect(setValue).toHaveBeenCalledWith("hello");
75
+ } finally {
76
+ vi.useRealTimers();
77
+ }
78
+ });
79
+ }
80
+ }
81
+
82
+ for (const kind of ["text", "password", "email", "url"] as const) {
83
+ test(`native association preserves ${kind} input attributes`, () => {
84
+ const plugin = new TextInputPlugin();
85
+ render(
86
+ plugin.render({
87
+ host: document.createElement("div"),
88
+ value: "",
89
+ setValue: vi.fn(),
90
+ functions: {},
91
+ data: plugin.validator.parse({
92
+ initialValue: "",
93
+ placeholder: "",
94
+ label: "Account",
95
+ kind,
96
+ disabled: true,
97
+ minLength: 2,
98
+ maxLength: 30,
99
+ }),
100
+ }),
101
+ );
102
+ const control = screen.getByLabelText("Account");
103
+ expect(control).toHaveAttribute("type", kind);
104
+ expect(control).toBeDisabled();
105
+ expect(control).toBeRequired();
106
+ expect(control).toHaveAttribute("minlength", "2");
107
+ expect(control).toHaveAttribute("maxlength", "30");
108
+ });
109
+ }
110
+
111
+ function testMultipleInstances<D>(plugin: IPlugin<string, D>) {
112
+ test(`${plugin.tagName} keeps repeated labels independently associated`, () => {
113
+ const props = {
114
+ host: document.createElement("div"),
115
+ value: "",
116
+ setValue: vi.fn(),
117
+ functions: {},
118
+ data: plugin.validator.parse({
119
+ initialValue: "",
120
+ placeholder: "",
121
+ label: "Notes",
122
+ }),
123
+ };
124
+ render(
125
+ <>
126
+ {plugin.render(props)}
127
+ {plugin.render(props)}
128
+ </>,
129
+ );
130
+ const controls = screen.getAllByLabelText("Notes");
131
+ expect(controls).toHaveLength(2);
132
+ expect(controls[0].id).not.toBe(controls[1].id);
133
+ expect(controls[0]).toHaveAccessibleName("Notes");
134
+ expect(controls[1]).toHaveAccessibleName("Notes");
135
+ });
136
+ }
137
+
138
+ testLabelBehavior(new TextInputPlugin());
139
+ testLabelBehavior(new TextAreaPlugin());
140
+ testMultipleInstances(new TextInputPlugin());
141
+ testMultipleInstances(new TextAreaPlugin());
@@ -4,11 +4,17 @@ import { Tooltip } from "radix-ui";
4
4
 
5
5
  const TooltipProvider = Tooltip.Provider;
6
6
 
7
- import { act, render, screen, waitFor } from "@testing-library/react";
7
+ import {
8
+ act,
9
+ fireEvent,
10
+ render,
11
+ screen,
12
+ waitFor,
13
+ } from "@testing-library/react";
8
14
  import { Provider } from "jotai";
9
15
  import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
10
16
  import { SetupMocks } from "@/__mocks__/common";
11
- import type { DownloadAsArgs } from "@/components/data-table/schemas";
17
+ import type { DownloadAsFunction } from "@/components/data-table/schemas";
12
18
  import type { FieldTypesWithExternalType } from "@/components/data-table/types";
13
19
  import { store } from "@/core/state/jotai";
14
20
  import {
@@ -19,6 +25,10 @@ import {
19
25
 
20
26
  // Default to normal (non-static) mode; individual tests flip this on.
21
27
  const mockIsStatic = vi.fn().mockReturnValue(false);
28
+ vi.mock("@/utils/download", () => ({
29
+ downloadByURL: vi.fn(),
30
+ withLoadingToast: vi.fn(async (_title, callback) => callback()),
31
+ }));
22
32
  vi.mock("@/core/static/static-state", async (importOriginal) => {
23
33
  const actual =
24
34
  await importOriginal<typeof import("@/core/static/static-state")>();
@@ -30,9 +40,15 @@ beforeAll(() => {
30
40
  });
31
41
 
32
42
  describe("LoadingDataTableComponent", () => {
33
- it("keeps data columns when inferred types include a row header", async () => {
43
+ it("keeps data columns and routes each export to its RPC", async () => {
34
44
  const host = document.createElement("div");
35
45
  const data = JSON.stringify([{ index: "first", value: 1 }]);
46
+ const downloadAs = vi
47
+ .fn()
48
+ .mockResolvedValue({ url: "export", filename: "table.csv" });
49
+ const downloadGeoJSON = vi
50
+ .fn()
51
+ .mockResolvedValue({ url: "export", filename: "table.geojson" });
36
52
 
37
53
  render(
38
54
  <Provider store={store}>
@@ -43,7 +59,7 @@ describe("LoadingDataTableComponent", () => {
43
59
  pagination={false}
44
60
  pageSize={10}
45
61
  selection={null}
46
- showDownload={false}
62
+ showDownload={true}
47
63
  showFilters={false}
48
64
  showColumnSummaries={false}
49
65
  showDataTypes={false}
@@ -68,7 +84,22 @@ describe("LoadingDataTableComponent", () => {
68
84
  cell_styles: null,
69
85
  cell_hover_texts: null,
70
86
  })}
71
- download_as={vi.fn() as DownloadAsArgs}
87
+ download_as={downloadAs}
88
+ download_geojson={downloadGeoJSON}
89
+ get_export_metadata={vi.fn().mockResolvedValue({
90
+ geometry_columns: [
91
+ { name: "value", encoding: "objects", crs: "EPSG:4326" },
92
+ ],
93
+ primary_geometry_column: "value",
94
+ default_geometry_column: "value",
95
+ formats: {
96
+ geojson: {
97
+ available: true,
98
+ reason: null,
99
+ missing_packages: [],
100
+ },
101
+ },
102
+ })}
72
103
  get_column_summaries={vi.fn()}
73
104
  get_data_url={vi.fn() as GetDataUrl}
74
105
  get_row_ids={vi.fn() as GetRowIds}
@@ -83,6 +114,26 @@ describe("LoadingDataTableComponent", () => {
83
114
  screen.getByRole("columnheader", { name: "value" }),
84
115
  ).toBeInTheDocument();
85
116
  });
117
+ fireEvent.click(screen.getByTestId("export-button"));
118
+ await screen.findByRole("dialog", { name: "Export table" });
119
+ await waitFor(() =>
120
+ expect(
121
+ screen.getByRole("button", { name: "Download GeoJSON" }),
122
+ ).toBeEnabled(),
123
+ );
124
+ fireEvent.click(screen.getByRole("button", { name: "Download GeoJSON" }));
125
+ await waitFor(() =>
126
+ expect(downloadGeoJSON).toHaveBeenCalledWith({
127
+ format: "geojson",
128
+ geometry_column: "value",
129
+ }),
130
+ );
131
+ expect(downloadAs).not.toHaveBeenCalled();
132
+ fireEvent.click(screen.getByRole("button", { name: "Download CSV" }));
133
+ await waitFor(() =>
134
+ expect(downloadAs).toHaveBeenCalledWith({ format: "csv" }),
135
+ );
136
+ expect(downloadGeoJSON).toHaveBeenCalledTimes(1);
86
137
  });
87
138
 
88
139
  it("does not log duplicate keys when a pivot becomes empty", async () => {
@@ -122,7 +173,9 @@ describe("LoadingDataTableComponent", () => {
122
173
  showSearch: false,
123
174
  value: [] as (number | string | { rowId: string; columnName?: string })[],
124
175
  setValue: vi.fn(),
125
- download_as: vi.fn() as DownloadAsArgs,
176
+ download_as: vi.fn() as DownloadAsFunction,
177
+ download_geojson: vi.fn(),
178
+ get_export_metadata: vi.fn(),
126
179
  get_column_summaries: vi.fn(),
127
180
  get_data_url: vi.fn() as GetDataUrl,
128
181
  get_row_ids: vi.fn() as GetRowIds,
@@ -263,7 +316,9 @@ describe("LoadingDataTableComponent", () => {
263
316
  showSearch: true,
264
317
  value: [] as (number | string | { rowId: string; columnName?: string })[],
265
318
  setValue,
266
- download_as: vi.fn() as DownloadAsArgs,
319
+ download_as: vi.fn() as DownloadAsFunction,
320
+ download_geojson: vi.fn(),
321
+ get_export_metadata: vi.fn(),
267
322
  get_column_summaries: vi.fn().mockResolvedValue({
268
323
  data: null,
269
324
  stats: {},
@@ -379,7 +434,9 @@ describe("static notebook control suppression", () => {
379
434
  cell_styles: null,
380
435
  cell_hover_texts: null,
381
436
  }),
382
- download_as: vi.fn() as DownloadAsArgs,
437
+ download_as: vi.fn() as DownloadAsFunction,
438
+ download_geojson: vi.fn(),
439
+ get_export_metadata: vi.fn(),
383
440
  get_column_summaries: vi.fn().mockResolvedValue({
384
441
  data: null,
385
442
  stats: {},
@@ -1,6 +1,12 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
- import { fireEvent, render, screen, waitFor } from "@testing-library/react";
3
+ import {
4
+ fireEvent,
5
+ render,
6
+ screen,
7
+ waitFor,
8
+ within,
9
+ } from "@testing-library/react";
4
10
  import { beforeAll, describe, expect, it, vi } from "vitest";
5
11
  import { SetupMocks } from "@/__mocks__/common";
6
12
  import { initialModeAtom } from "@/core/mode";
@@ -187,7 +193,7 @@ describe("FileBrowserPlugin keyboard accessibility", () => {
187
193
  const docsRow = docs.closest('[role="row"]')!;
188
194
  fireEvent.keyDown(docsRow, { key: "ArrowDown" }); // move active off the parent
189
195
  fireEvent.click(docs); // navigate into "docs"
190
- await screen.findByText("docs"); // listing reloads (mock returns same files)
196
+ await within(screen.getByRole("grid")).findByText("docs"); // listing reloads (mock returns same files)
191
197
  const rows = screen.getAllByRole("row");
192
198
  expect(rows[0]).toHaveAttribute("tabindex", "0");
193
199
  // the focused row must match the only tabbable row
@@ -361,3 +367,80 @@ describe("FileBrowserPlugin keyboard accessibility", () => {
361
367
  function rowFor(name: string): HTMLElement {
362
368
  return screen.getByText(name).closest('[role="row"]') as HTMLElement;
363
369
  }
370
+
371
+ describe("FileBrowserPlugin breadcrumbs", () => {
372
+ function breadcrumbs() {
373
+ return within(
374
+ screen.getByRole("navigation", { name: "Current directory" }),
375
+ );
376
+ }
377
+
378
+ it("renders a crumb per ancestor with the current directory last", async () => {
379
+ renderBrowser();
380
+ await screen.findByText("docs");
381
+ const items = breadcrumbs().getAllByRole("listitem");
382
+ expect(items.map((li) => li.textContent)).toEqual(["/", "home", "user"]);
383
+ expect(breadcrumbs().getByRole("button", { name: "user" })).toHaveAttribute(
384
+ "aria-current",
385
+ "page",
386
+ );
387
+ expect(
388
+ breadcrumbs().getByRole("button", { name: "home" }),
389
+ ).not.toHaveAttribute("aria-current");
390
+ });
391
+
392
+ it("keeps focus on a crumb after navigating to it", async () => {
393
+ const { listDirectory } = renderBrowser();
394
+ await screen.findByText("docs");
395
+ const home = breadcrumbs().getByRole("button", { name: "home" });
396
+ home.focus();
397
+ fireEvent.click(home);
398
+ await waitFor(() =>
399
+ expect(listDirectory).toHaveBeenLastCalledWith({ path: "/home" }),
400
+ );
401
+ const current = breadcrumbs().getByRole("button", { name: "home" });
402
+ expect(current).toHaveAttribute("aria-current", "page");
403
+ expect(current).toBe(home);
404
+ expect(current).toHaveFocus();
405
+ });
406
+
407
+ it("does not reload when the current crumb is clicked", async () => {
408
+ const { listDirectory } = renderBrowser();
409
+ await screen.findByText("docs");
410
+ fireEvent.click(breadcrumbs().getByRole("button", { name: "user" }));
411
+ expect(listDirectory).toHaveBeenCalledTimes(1);
412
+ });
413
+
414
+ it("navigates to an ancestor when a crumb is clicked", async () => {
415
+ const { listDirectory } = renderBrowser();
416
+ await screen.findByText("docs");
417
+ fireEvent.click(breadcrumbs().getByRole("button", { name: "home" }));
418
+ await waitFor(() =>
419
+ expect(listDirectory).toHaveBeenLastCalledWith({ path: "/home" }),
420
+ );
421
+ fireEvent.click(breadcrumbs().getByRole("button", { name: "/" }));
422
+ await waitFor(() =>
423
+ expect(listDirectory).toHaveBeenLastCalledWith({ path: "/" }),
424
+ );
425
+ });
426
+
427
+ it("hides ancestors outside the initial path when navigation is restricted", async () => {
428
+ render(
429
+ <FileBrowser
430
+ initialPath="/home/user"
431
+ filetypes={[]}
432
+ selectionMode="all"
433
+ multiple={true}
434
+ label={null}
435
+ restrictNavigation={true}
436
+ value={[]}
437
+ setValue={vi.fn()}
438
+ host={document.createElement("div")}
439
+ list_directory={mockListDirectory(FILES)}
440
+ />,
441
+ );
442
+ await screen.findByText("docs");
443
+ const items = breadcrumbs().getAllByRole("listitem");
444
+ expect(items.map((li) => li.textContent)).toEqual(["user"]);
445
+ });
446
+ });
@@ -0,0 +1,122 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import { render } from "@testing-library/react";
4
+ import { beforeEach, describe, expect, it, vi } from "vitest";
5
+ import { initialModeAtom } from "@/core/mode";
6
+ import { store } from "@/core/state/jotai";
7
+ import { DatePickerPlugin } from "../DatePickerPlugin";
8
+ import { DateRangePickerPlugin } from "../DateRangePlugin";
9
+ import { DateTimePickerPlugin } from "../DateTimePickerPlugin";
10
+
11
+ const sharedProps = () => ({
12
+ host: document.createElement("div"),
13
+ setValue: vi.fn(),
14
+ functions: {},
15
+ });
16
+
17
+ const widgets = [
18
+ {
19
+ name: "date",
20
+ role: "group",
21
+ fallback: "date picker",
22
+ render: (label: string | null, disabled = false) =>
23
+ new DatePickerPlugin().render({
24
+ ...sharedProps(),
25
+ value: "2026-10-02",
26
+ data: {
27
+ label,
28
+ disabled,
29
+ start: "2026-01-01",
30
+ stop: "2026-12-31",
31
+ fullWidth: false,
32
+ },
33
+ }),
34
+ },
35
+ {
36
+ name: "datetime",
37
+ role: "group",
38
+ fallback: "date time picker",
39
+ render: (label: string | null, disabled = false) =>
40
+ new DateTimePickerPlugin().render({
41
+ ...sharedProps(),
42
+ value: "2026-10-02T12:00:00",
43
+ data: {
44
+ label,
45
+ disabled,
46
+ start: "2026-01-01T00:00:00",
47
+ stop: "2026-12-31T23:59:59",
48
+ precision: "minute",
49
+ fullWidth: false,
50
+ },
51
+ }),
52
+ },
53
+ {
54
+ name: "date range",
55
+ role: "group",
56
+ fallback: "date range picker",
57
+ render: (label: string | null, disabled = false) =>
58
+ new DateRangePickerPlugin().render({
59
+ ...sharedProps(),
60
+ value: ["2026-10-02", "2026-10-03"],
61
+ data: {
62
+ label,
63
+ disabled,
64
+ start: "2026-01-01",
65
+ stop: "2026-12-31",
66
+ fullWidth: false,
67
+ },
68
+ }),
69
+ },
70
+ ];
71
+
72
+ beforeEach(() => store.set(initialModeAtom, "edit"));
73
+
74
+ describe.each(widgets)("$name accessible labels", (widget) => {
75
+ it("uses rendered formatting and decoded entities, and follows label updates", () => {
76
+ const { getByRole, rerender } = render(
77
+ widget.render("<span>Visit <strong>date</strong> &amp; time</span>"),
78
+ );
79
+ expect(getByRole(widget.role, { name: "Visit date & time" })).toBeTruthy();
80
+ rerender(widget.render("<span>Updated <em>label</em></span>"));
81
+ expect(getByRole(widget.role, { name: "Updated label" })).toBeTruthy();
82
+ rerender(widget.render(null));
83
+ expect(getByRole(widget.role, { name: widget.fallback })).toBeTruthy();
84
+ });
85
+
86
+ it.each([null, ""])("uses the fallback when label is %s", (label) => {
87
+ const { getByRole } = render(widget.render(label));
88
+ expect(getByRole(widget.role, { name: widget.fallback })).toBeTruthy();
89
+ });
90
+
91
+ it("names the calendar button and every editable segment", () => {
92
+ const { getByRole, getAllByRole } = render(
93
+ widget.render("<strong>Visit</strong> &amp; time"),
94
+ );
95
+ expect(getByRole("button", { name: "Calendar Visit & time" })).toBeTruthy();
96
+ for (const segment of getAllByRole("spinbutton")) {
97
+ expect(segment).toHaveAccessibleName(/Visit & time/);
98
+ }
99
+ });
100
+
101
+ it("preserves disabled controls with a formatted label", () => {
102
+ const { getByRole, getAllByRole } = render(
103
+ widget.render("<strong>Visit</strong>", true),
104
+ );
105
+ expect(getByRole("button", { name: "Calendar Visit" })).toBeDisabled();
106
+ for (const segment of getAllByRole("spinbutton")) {
107
+ expect(segment).toHaveAttribute("aria-disabled", "true");
108
+ }
109
+ });
110
+
111
+ it("keeps labels distinct for multiple widgets", () => {
112
+ const { getByRole } = render(
113
+ <>
114
+ {widget.render("First")}
115
+ {widget.render("Second")}
116
+ </>,
117
+ );
118
+ expect(getByRole(widget.role, { name: "First" })).not.toBe(
119
+ getByRole(widget.role, { name: "Second" }),
120
+ );
121
+ });
122
+ });
@@ -27,7 +27,7 @@ const messageSchema = z.array(
27
27
  role: z.enum(["system", "user", "assistant"]),
28
28
  content: z.string().nullable(),
29
29
  parts: z.array(z.any()),
30
- metadata: z.any().nullable(),
30
+ metadata: z.any().optional(),
31
31
  }),
32
32
  );
33
33
 
@@ -9,7 +9,8 @@ interface Props {
9
9
  label: string | null | undefined;
10
10
  className?: string;
11
11
  labelClassName?: string;
12
- id?: string;
12
+ labelId?: string;
13
+ controlId?: string;
13
14
  fullWidth?: boolean;
14
15
  /**
15
16
  * Align the label to the top, left, or right of the component.
@@ -27,8 +28,9 @@ export const Labeled: React.FC<PropsWithChildren<Props>> = ({
27
28
  align = "left",
28
29
  className,
29
30
  labelClassName,
31
+ labelId,
30
32
  fullWidth,
31
- id,
33
+ controlId,
32
34
  }) => {
33
35
  // If fullWidth is true, force align to be "top"
34
36
  if (fullWidth) {
@@ -45,7 +47,11 @@ export const Labeled: React.FC<PropsWithChildren<Props>> = ({
45
47
 
46
48
  const labelElement = (
47
49
  <div part="label" className="inline-flex items-center m-0 p-0">
48
- <Label htmlFor={id} className={cn("font-prose", labelClassName)}>
50
+ <Label
51
+ id={labelId}
52
+ htmlFor={controlId}
53
+ className={cn("font-prose", labelClassName)}
54
+ >
49
55
  {renderHTML({ html: label })}
50
56
  </Label>
51
57
  </div>