@marimo-team/frontend 0.21.2-dev5 → 0.21.2-dev52
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.
- package/dist/assets/{CellStatus-CDSBsjjF.js → CellStatus-DX8MnBMk.js} +1 -1
- package/dist/assets/{ConnectedDataExplorerComponent-Buaffg3u.js → ConnectedDataExplorerComponent-7yXYooWG.js} +1 -1
- package/dist/assets/{DeferredRequestRegistry-O6RDJKs0.js → DeferredRequestRegistry-B8jPCuU1.js} +1 -1
- package/dist/assets/{ImperativeModal-qEtcJ95s.js → ImperativeModal-C3CD5-Aq.js} +1 -1
- package/dist/assets/JsonOutput-DqjAyzM8.js +46 -0
- package/dist/assets/{LazyAnyLanguageCodeMirror-m8w66E4s.js → LazyAnyLanguageCodeMirror-CcCHIX38.js} +2 -2
- package/dist/assets/{MarimoErrorOutput-az74f3Mp.js → MarimoErrorOutput-Dat_S09q.js} +5 -5
- package/dist/assets/RenderHTML-C7XM39M2.js +1 -0
- package/dist/assets/{add-cell-with-ai-DUn4LN4W.js → add-cell-with-ai-y2xroEGf.js} +9 -9
- package/dist/assets/{add-connection-dialog-CBz0AUVX.js → add-connection-dialog-QDBOmil3.js} +23 -23
- package/dist/assets/{agent-panel-u83dsDsM.js → agent-panel-DziFrEjJ.js} +6 -6
- package/dist/assets/ai-model-dropdown-CiJpv5wN.js +5 -0
- package/dist/assets/{alert-dialog-9WfvUF7e.js → alert-dialog-ebk_-wsU.js} +1 -1
- package/dist/assets/{any-language-editor-DwQMnAM3.js → any-language-editor-DZYnKlJB.js} +1 -1
- package/dist/assets/{app-config-button-rDu-lCIB.js → app-config-button-CpAv9Tiu.js} +1 -1
- package/dist/assets/{architectureDiagram-VXUJARFQ-DfMHHFZ3.js → architectureDiagram-VXUJARFQ-DKmk99ac.js} +1 -1
- package/dist/assets/{azure-BTXHztTw.js → azure-Dw5gKmUz.js} +1 -1
- package/dist/assets/{blockDiagram-VD42YOAC-CuEDwbg7.js → blockDiagram-VD42YOAC-TpAhP5OQ.js} +1 -1
- package/dist/assets/{c4Diagram-YG6GDRKO-CD9uz7WG.js → c4Diagram-YG6GDRKO-Dg8hCyKf.js} +1 -1
- package/dist/assets/{cache-panel-qIxnndwr.js → cache-panel-D0OsHk_D.js} +1 -1
- package/dist/assets/cell-editor-RbAVpSFb.js +22 -0
- package/dist/assets/{cell-link-Q_UEP94Z.js → cell-link-CNgO3c-T.js} +1 -1
- package/dist/assets/{cells-fq1RMGX_.js → cells-39RE4UzS.js} +77 -76
- package/dist/assets/channel-D1wPYhc9.js +1 -0
- package/dist/assets/{chat-display-D_Fuuy6r.js → chat-display-BPUVrlA6.js} +1 -1
- package/dist/assets/{chat-panel-BO-JoQSp.js → chat-panel-esz5TfF-.js} +2 -2
- package/dist/assets/{chunk-5FQGJX7Z-CM1a_K7I.js → chunk-5FQGJX7Z-sGWxL7Ey.js} +3 -3
- package/dist/assets/{chunk-ABZYJK2D-D_Wumzom.js → chunk-ABZYJK2D-DXJ7hnjx.js} +1 -1
- package/dist/assets/{chunk-ATLVNIR6-BZ0lTgIn.js → chunk-ATLVNIR6-CTEqcLEc.js} +1 -1
- package/dist/assets/{chunk-B4BG7PRW-Dw1S6osV.js → chunk-B4BG7PRW-CkAIqtPf.js} +1 -1
- package/dist/assets/{chunk-DI55MBZ5-Q63FTCPP.js → chunk-DI55MBZ5-C4F9vu8o.js} +1 -1
- package/dist/assets/{chunk-EXTU4WIE-CfkJ_R7W.js → chunk-EXTU4WIE-BT0Py-4P.js} +1 -1
- package/dist/assets/{chunk-JA3XYJ7Z-B41fGeoj.js → chunk-JA3XYJ7Z-CGd7jja_.js} +1 -1
- package/dist/assets/{chunk-JZLCHNYA-D43EJxQw.js → chunk-JZLCHNYA-CqY-RYTj.js} +1 -1
- package/dist/assets/{chunk-N4CR4FBY-DCtw0-ni.js → chunk-N4CR4FBY-aUDjVzN7.js} +2 -2
- package/dist/assets/{chunk-QN33PNHL-CLA2rsaS.js → chunk-QN33PNHL-DHnCb5-U.js} +1 -1
- package/dist/assets/{chunk-QXUST7PY-De1DpbnL.js → chunk-QXUST7PY-CRO5kYCE.js} +1 -1
- package/dist/assets/{chunk-S3R3BYOJ-qrwvlUdq.js → chunk-S3R3BYOJ-CSHQgcuP.js} +1 -1
- package/dist/assets/{chunk-TZMSLE5B-C4KcThb0.js → chunk-TZMSLE5B-CE7o9asH.js} +1 -1
- package/dist/assets/classDiagram-2ON5EDUG-BDIQSKYv.js +1 -0
- package/dist/assets/classDiagram-v2-WZHVMYZB-Cdh4cVOB.js +1 -0
- package/dist/assets/{code-block-37QAKDTI-D4FF4cnN.js → code-block-37QAKDTI-DMpe1jNG.js} +1 -1
- package/dist/assets/{column-preview-WsubyItX.js → column-preview-BUKHsglA.js} +1 -1
- package/dist/assets/{command-rfxSsiHU.js → command-DmzEbs6L.js} +1 -1
- package/dist/assets/{command-palette-Bez4BqJF.js → command-palette-BX5gNpUr.js} +1 -1
- package/dist/assets/{common-BYwO983A.js → common-B4yshY-H.js} +1 -1
- package/dist/assets/{components-Ozq0825a.js → components-DCqJqyys.js} +1 -1
- package/dist/assets/{components-Bpgzv_5_.js → components-oKCjx6cN.js} +1 -1
- package/dist/assets/{config-3Aq84phF.js → config-DqxNMQDN.js} +1 -1
- package/dist/assets/{context-CIAP2NOh.js → context-CRmPPhx9.js} +1 -1
- package/dist/assets/{context-aware-panel-CfsfBlhO.js → context-aware-panel-DC0Te9Hj.js} +2 -2
- package/dist/assets/copy-KjcPgPw9.js +1 -0
- package/dist/assets/{copy-icon-BgmMM9Zg.js → copy-icon-P0kzz1Pr.js} +1 -1
- package/dist/assets/{dagre-6UL2VRFP-BhMnPhuU.js → dagre-6UL2VRFP-XqoNLMQ3.js} +1 -1
- package/dist/assets/{data-grid-overlay-editor-kbv73SQ7.js → data-grid-overlay-editor-Cus1-BFN.js} +1 -1
- package/dist/assets/{datasource-F9sJtuof.js → datasource-DKHG39NV.js} +2 -2
- package/dist/assets/{dates-CHaNfieI.js → dates-CTqMeMGY.js} +1 -1
- package/dist/assets/{dependency-graph-panel-AOBcX2tP.js → dependency-graph-panel-7GKT3dyD.js} +4 -4
- package/dist/assets/{diagram-PSM6KHXK-Cr2t4zul.js → diagram-PSM6KHXK-BuzKNNcN.js} +1 -1
- package/dist/assets/{diagram-QEK2KX5R-DLU_hSO4.js → diagram-QEK2KX5R-A5LBQS11.js} +1 -1
- package/dist/assets/{diagram-S2PKOQOG-C7EkNAO3.js → diagram-S2PKOQOG-dkJE8SA0.js} +1 -1
- package/dist/assets/{dialog-CVN1lcMF.js → dialog-1_jIyAb_.js} +1 -1
- package/dist/assets/{dist-DJBpXGro.js → dist-6P6vjf93.js} +1 -1
- package/dist/assets/dist-BWGxTsTP.js +1 -0
- package/dist/assets/{dist-CblX3KGI.js → dist-B_buFm3B.js} +1 -1
- package/dist/assets/{dist-CXLJUPFl.js → dist-BatEf-0f.js} +1 -1
- package/dist/assets/dist-C3AnARPE.js +1 -0
- package/dist/assets/{dist-BNC_tnlW.js → dist-C6ohaMKU.js} +1 -1
- package/dist/assets/{dist-BoDHthoc.js → dist-CO9Pg2Rc.js} +1 -1
- package/dist/assets/{dist-By6zhkxZ.js → dist-CSV6H5w_.js} +1 -1
- package/dist/assets/{dist-6FIAeDIu.js → dist-CYs1oP7g.js} +1 -1
- package/dist/assets/{dist-DbK_4_qo.js → dist-DD9ZJMK5.js} +1 -1
- package/dist/assets/{dist-DlTbNRBn.js → dist-DReDpc2z.js} +1 -1
- package/dist/assets/dist-DSlq5ZeQ.js +1 -0
- package/dist/assets/{dist-DrceDAhM.js → dist-DXyIIB32.js} +1 -1
- package/dist/assets/{dist-CcGcwrUD.js → dist-DkaderFA.js} +1 -1
- package/dist/assets/{dist-BiZQlfhr.js → dist-Dq3BlK4R.js} +1 -1
- package/dist/assets/{dist-ClzRAVN-.js → dist-Dxov2ltb.js} +1 -1
- package/dist/assets/{dist-BXXPfIam.js → dist-EtGG9C1A.js} +1 -1
- package/dist/assets/{dist-C3MmXcLA.js → dist-NjId5Gdz.js} +1 -1
- package/dist/assets/dist-ZM59OWYL.js +1 -0
- package/dist/assets/dist-_TwZ4tIe.js +1 -0
- package/dist/assets/dist-f9b2H4q_.js +1 -0
- package/dist/assets/{dist-mxGLXOFm.js → dist-feWVQ4dq.js} +1 -1
- package/dist/assets/{documentation-panel-D28MpqbI.js → documentation-panel-D5d_BbHV.js} +1 -1
- package/dist/assets/{download-B9_ToVd4.js → download-B1vXaivj.js} +4 -4
- package/dist/assets/{dropdown-menu-DdPu5Kfu.js → dropdown-menu-BehqiLFL.js} +1 -1
- package/dist/assets/{edit-page-otS-QvnC.js → edit-page-B5cAZdO7.js} +7 -7
- package/dist/assets/{en-US-BO8E69bZ.js → en-US-f8tajDx1.js} +1 -1
- package/dist/assets/{erDiagram-Q2GNP2WA-DqlEo_Us.js → erDiagram-Q2GNP2WA-CgH6udOW.js} +1 -1
- package/dist/assets/{error-banner-BRG6IPhC.js → error-banner-J5F3weEj.js} +1 -1
- package/dist/assets/{error-panel-RRoj_iOR.js → error-panel-DnhKJ5Ou.js} +1 -1
- package/dist/assets/{es-CzkousWe.js → es-DYI7U61K.js} +1 -1
- package/dist/assets/{esm-CBkHtTOV.js → esm-BC1J92im.js} +1 -1
- package/dist/assets/{esm-DhTsVMLM.js → esm-DKLLCu3N.js} +1 -1
- package/dist/assets/{field-B1jGbQlH.js → field-B08lvxnl.js} +1 -1
- package/dist/assets/file-explorer-panel-BUk69TND.js +26 -0
- package/dist/assets/{file-icons-CWLHDa1J.js → file-icons-3DTS8ZM7.js} +1 -1
- package/dist/assets/{floating-outline-BvQKiC0F.js → floating-outline-DmugATcB.js} +1 -1
- package/dist/assets/{flowDiagram-NV44I4VS-CQlIJ12H.js → flowDiagram-NV44I4VS-D85BL4rA.js} +1 -1
- package/dist/assets/{focus-DYwTiH9-.js → focus-DlJH7sfh.js} +1 -1
- package/dist/assets/{form-CrQYrsUC.js → form-760_EqmF.js} +2 -2
- package/dist/assets/{formats-rhOJovGE.js → formats-wYuh1bqp.js} +1 -1
- package/dist/assets/{formatting-B4ZCH3ol.js → formatting-CraOPe94.js} +1 -1
- package/dist/assets/{gallery-page-eRea0yic.js → gallery-page--paiPvYX.js} +1 -1
- package/dist/assets/{ganttDiagram-JELNMOA3-B3EGIuZL.js → ganttDiagram-JELNMOA3-DzCOXWlF.js} +1 -1
- package/dist/assets/{gitGraphDiagram-V2S2FVAM-h5SlguJK.js → gitGraphDiagram-V2S2FVAM-BUHURX6t.js} +1 -1
- package/dist/assets/{glide-data-editor-xt5xNZeV.js → glide-data-editor-DYdoQTO5.js} +4 -4
- package/dist/assets/{globals-BsV5fVR-.js → globals-7M5DRsIb.js} +1 -1
- package/dist/assets/home-page-CxQ1e98h.js +4 -0
- package/dist/assets/{hooks-CHx5dUUq.js → hooks-C3jEff2O.js} +1 -1
- package/dist/assets/html-to-image-DTFXm6_Z.js +2 -0
- package/dist/assets/{index-GjXovVsl.css → index-BmoocKR0.css} +1 -1
- package/dist/assets/index-DNchElHl.js +38 -0
- package/dist/assets/{infoDiagram-HS3SLOUP-pzpClObZ.js → infoDiagram-HS3SLOUP-GG5r0Y5G.js} +1 -1
- package/dist/assets/{input-CUwqpKjd.js → input-CN1ZeRYm.js} +1 -1
- package/dist/assets/{isValid-BGe7pJXT.js → isValid-DY4Mgbr7.js} +1 -1
- package/dist/assets/{journeyDiagram-XKPGCS4Q-BrdRi92v.js → journeyDiagram-XKPGCS4Q-B1dvnV4D.js} +1 -1
- package/dist/assets/{kanban-definition-3W4ZIXB7-B6WqgFqh.js → kanban-definition-3W4ZIXB7-CefbrXQv.js} +1 -1
- package/dist/assets/{kiosk-mode-DNjEnIWb.js → kiosk-mode-CyTnrzwK.js} +1 -1
- package/dist/assets/{layout-CwFtCyW8.js → layout-3b3tzmbb.js} +3 -3
- package/dist/assets/{linear-BP9rwmWK.js → linear-BDnrHGYO.js} +1 -1
- package/dist/assets/{links-CIQwYQ48.js → links-CptYD1FP.js} +1 -1
- package/dist/assets/{logs-panel-BU1tNEVc.js → logs-panel-C4k_2IHW.js} +1 -1
- package/dist/assets/{markdown-renderer-MR9df58W.js → markdown-renderer-DSy5IuAx.js} +1 -1
- package/dist/assets/{menu-items-UxKrm8hS.js → menu-items-BpHXKv51.js} +1 -1
- package/dist/assets/mermaid-4DMBBIKO-g7AL4SLJ.js +1 -0
- package/dist/assets/{mermaid-Djr3jUAB.js → mermaid-C43VbdrM.js} +3 -3
- package/dist/assets/{mermaid-parser.core-DR82IMb2.js → mermaid-parser.core-CdM8D_p_.js} +1 -1
- package/dist/assets/{mindmap-definition-VGOIOE7T-DAmJpbPM.js → mindmap-definition-VGOIOE7T-CcV7D-wF.js} +1 -1
- package/dist/assets/{mode-AcL8c6qH.js → mode-D-iRbN9x.js} +1 -1
- package/dist/assets/{multi-map-Pp1P2DOX.js → multi-map-C8RbwBrw.js} +1 -1
- package/dist/assets/{name-cell-input-DVFEv_aO.js → name-cell-input-Dyb0ZO4X.js} +1 -1
- package/dist/assets/{number-overlay-editor-D__AflXQ.js → number-overlay-editor-BBJO1mf8.js} +1 -1
- package/dist/assets/{outline-panel-CP0oIuiU.js → outline-panel-D7CJwO8u.js} +1 -1
- package/dist/assets/{packages-panel-CzRELimG.js → packages-panel-Bp1SYjgc.js} +1 -1
- package/dist/assets/{panels-wTweRyIv.js → panels-D0aw6jdc.js} +1 -1
- package/dist/assets/{pieDiagram-ADFJNKIX-DbGIFRoq.js → pieDiagram-ADFJNKIX-C1fBf15W.js} +1 -1
- package/dist/assets/{popover-BPGG2gPG.js → popover-Bvoif-Mg.js} +1 -1
- package/dist/assets/{precisionRound-BOmLQIKI.js → precisionRound-CCOoIlcP.js} +1 -1
- package/dist/assets/{process-output-CTVsT--B.js → process-output-BxPWHcIi.js} +1 -1
- package/dist/assets/{quadrantDiagram-AYHSOK5B-CLAtyple.js → quadrantDiagram-AYHSOK5B-RVooN-fX.js} +1 -1
- package/dist/assets/{react-vega-BZav_-2n.js → react-vega-BKRQSy0g.js} +1 -1
- package/dist/assets/react-vega-DXESF7qN.js +1 -0
- package/dist/assets/{readonly-python-code-DH-1xZGq.js → readonly-python-code-D95oshJa.js} +1 -1
- package/dist/assets/{renderShortcut-CnD1Dah5.js → renderShortcut-BYvKm38e.js} +1 -1
- package/dist/assets/{request-registry-B-7cIM_I.js → request-registry-XB2EzJHm.js} +1 -1
- package/dist/assets/{requirementDiagram-UZGBJVZJ-DDDTB1LD.js → requirementDiagram-UZGBJVZJ-DtqOYJpH.js} +1 -1
- package/dist/assets/{run-page-FCvGnICa.js → run-page-B7CASued.js} +1 -1
- package/dist/assets/{sankeyDiagram-TZEHDZUN-DAWPOfBw.js → sankeyDiagram-TZEHDZUN-DmcooLA8.js} +1 -1
- package/dist/assets/{scratchpad-panel-k9lrm-rC.js → scratchpad-panel-BIVRgYOU.js} +1 -1
- package/dist/assets/{secrets-panel-B1Z-6dmz.js → secrets-panel-C24hZEiO.js} +1 -1
- package/dist/assets/{select-CxT2Geqr.js → select-Cnd3vm9n.js} +1 -1
- package/dist/assets/{sequenceDiagram-WL72ISMW-D_qAidD2.js → sequenceDiagram-WL72ISMW-S2qeLb7J.js} +1 -1
- package/dist/assets/{session-panel-WhN0qilM.js → session-panel-CNabBHQm.js} +1 -1
- package/dist/assets/{share-BdH_5I58.js → share-NjpZ54PJ.js} +1 -1
- package/dist/assets/{snippets-panel-BCDHUuku.js → snippets-panel-D1JAeJj1.js} +1 -1
- package/dist/assets/{spec-DbmSqx09.js → spec-DnVBmJUh.js} +1 -1
- package/dist/assets/{state-Ce7CVShi.js → state-BagvlaEz.js} +1 -1
- package/dist/assets/{state-3V5UxC3B.js → state-Cz_wrzCz.js} +1 -1
- package/dist/assets/{state-CBmCYWFH.js → state-DMQXxemS.js} +1 -1
- package/dist/assets/{stateDiagram-FKZM4ZOC-C7qgDrGA.js → stateDiagram-FKZM4ZOC-uuQ60pIl.js} +1 -1
- package/dist/assets/stateDiagram-v2-4FDKWEC3-D-GWhQTG.js +1 -0
- package/dist/assets/stex-CruVQx-P.js +1 -0
- package/dist/assets/{switch-CVKxYu_0.js → switch-Bwpd2AFq.js} +1 -1
- package/dist/assets/{terminal-Cr7wbEjz.js → terminal-Gl8Fi44y.js} +1 -1
- package/dist/assets/{time-D2GKc0U6.js → time-Bw8f15NM.js} +1 -1
- package/dist/assets/{timeline-definition-IT6M3QCI-hd6uJKGs.js → timeline-definition-IT6M3QCI-TKWeDnSQ.js} +1 -1
- package/dist/assets/{toggle-RCwU-rnE.js → toggle-C_gNjXg8.js} +1 -1
- package/dist/assets/{tooltip-D9723Brr.js → tooltip-CR_izE8Q.js} +1 -1
- package/dist/assets/tracing-DwAC7DWN.js +1 -0
- package/dist/assets/tracing-panel-D1iNgclL.js +2 -0
- package/dist/assets/{tree-Ch2-GuhG.js → tree-WVrWjdwv.js} +3 -3
- package/dist/assets/{useAddCell-YC7rpcmD.js → useAddCell-D6Q7JziZ.js} +1 -1
- package/dist/assets/{useBoolean-m1e6E3Ao.js → useBoolean-CrltYVhE.js} +1 -1
- package/dist/assets/{useCellActionButton-GUb2fXU8.js → useCellActionButton-B2G9OaX9.js} +1 -1
- package/dist/assets/{useDateFormatter-CpE7XQLs.js → useDateFormatter-DOoVZUts.js} +1 -1
- package/dist/assets/{useDeleteCell-DRUDRiy0.js → useDeleteCell-d8veThW7.js} +1 -1
- package/dist/assets/{useDependencyPanelTab-nFVMlEx0.js → useDependencyPanelTab-B3iIj3MO.js} +1 -1
- package/dist/assets/{useInstallPackage-C9V-on2J.js → useInstallPackage-CQEr5429.js} +1 -1
- package/dist/assets/{useNotebookActions-ChLHy-0O.js → useNotebookActions-SAEOWcBo.js} +1 -1
- package/dist/assets/{useNumberFormatter-DbDKSvEd.js → useNumberFormatter-BXZcbTzH.js} +1 -1
- package/dist/assets/{usePress-BHGkpw8X.js → usePress-alQ5Crny.js} +1 -1
- package/dist/assets/{useRunCells-5m6jCnyo.js → useRunCells-Dhl8ZTGh.js} +1 -1
- package/dist/assets/{useSplitCell-DGD9smMq.js → useSplitCell-BSnFazbH.js} +1 -1
- package/dist/assets/{utils-CdjCA1J8.js → utils-C24l2A1T.js} +1 -1
- package/dist/assets/{vega-component-CRbeDmeM.js → vega-component-9Pf4pVZL.js} +1 -1
- package/dist/assets/{vega-loader.browser-CZV6_g2i.js → vega-loader.browser-BJ9oKrvH.js} +1 -1
- package/dist/assets/{write-secret-modal-BCvuRAFb.js → write-secret-modal-BFCsWMoW.js} +1 -1
- package/dist/assets/{xychartDiagram-PRI3JC2R-CXlUBSbQ.js → xychartDiagram-PRI3JC2R-CIp-yeSa.js} +1 -1
- package/dist/index.html +125 -125
- package/package.json +1 -1
- package/src/__mocks__/notebook.ts +9 -9
- package/src/__tests__/branded.ts +20 -0
- package/src/components/app-config/user-config-form.tsx +5 -4
- package/src/components/data-table/__tests__/utils.test.ts +138 -1
- package/src/components/data-table/charts/__tests__/storage.test.ts +7 -7
- package/src/components/data-table/context-menu.tsx +9 -5
- package/src/components/data-table/data-table.tsx +3 -0
- package/src/components/data-table/range-focus/__tests__/atoms.test.ts +8 -2
- package/src/components/data-table/range-focus/__tests__/test-utils.ts +2 -0
- package/src/components/data-table/range-focus/__tests__/utils.test.ts +82 -8
- package/src/components/data-table/range-focus/atoms.ts +2 -2
- package/src/components/data-table/range-focus/utils.ts +50 -12
- package/src/components/data-table/types.ts +7 -0
- package/src/components/data-table/utils.ts +87 -0
- package/src/components/editor/__tests__/data-attributes.test.tsx +8 -8
- package/src/components/editor/ai/__tests__/completion-utils.test.ts +15 -15
- package/src/components/editor/navigation/__tests__/clipboard.test.ts +2 -2
- package/src/components/editor/navigation/__tests__/selection.test.ts +7 -6
- package/src/components/editor/navigation/__tests__/state.test.ts +8 -7
- package/src/components/editor/output/MarimoErrorOutput.tsx +7 -7
- package/src/components/editor/output/__tests__/traceback.test.tsx +4 -4
- package/src/components/editor/output/console/__tests__/ConsoleOutput.test.tsx +4 -4
- package/src/components/editor/renderers/vertical-layout/useFocusFirstEditor.ts +8 -1
- package/src/components/storage/storage-file-viewer.tsx +35 -1
- package/src/components/storage/storage-inspector.tsx +9 -4
- package/src/components/storage/storage-snippets.ts +3 -3
- package/src/components/tracing/tracing.tsx +3 -1
- package/src/components/ui/range-slider.tsx +108 -1
- package/src/core/ai/__tests__/staged-cells.test.ts +9 -8
- package/src/core/ai/context/providers/__tests__/cell-output.test.ts +31 -31
- package/src/core/ai/context/providers/__tests__/datasource.test.ts +3 -3
- package/src/core/ai/context/providers/__tests__/tables.test.ts +3 -2
- package/src/core/ai/context/providers/__tests__/variable.test.ts +84 -63
- package/src/core/ai/tools/__tests__/edit-notebook-tool.test.ts +10 -9
- package/src/core/ai/tools/__tests__/run-cells-tool.test.ts +6 -6
- package/src/core/ai/tools/edit-notebook-tool.ts +3 -3
- package/src/core/cells/__tests__/add-missing-import.test.ts +3 -3
- package/src/core/cells/__tests__/cells.test.ts +192 -135
- package/src/core/cells/__tests__/focus.test.ts +5 -4
- package/src/core/cells/__tests__/logs.test.ts +13 -12
- package/src/core/cells/__tests__/pending-delete-service.test.tsx +3 -3
- package/src/core/cells/__tests__/runs.test.ts +22 -21
- package/src/core/cells/__tests__/scrollCellIntoView.test.ts +8 -7
- package/src/core/cells/__tests__/session.test.ts +23 -22
- package/src/core/cells/cells.ts +1 -1
- package/src/core/cells/ids.ts +5 -5
- package/src/core/cells/logs.ts +2 -2
- package/src/core/cells/runs.ts +6 -8
- package/src/core/codemirror/__tests__/format.test.ts +34 -36
- package/src/core/codemirror/__tests__/setup.test.ts +2 -2
- package/src/core/codemirror/cells/__tests__/extensions.test.ts +114 -0
- package/src/core/codemirror/cells/__tests__/traceback-decorations.test.ts +33 -32
- package/src/core/codemirror/cells/extensions.ts +66 -23
- package/src/core/codemirror/completion/__tests__/keymap.test.ts +15 -35
- package/src/core/codemirror/completion/keymap.ts +14 -4
- package/src/core/codemirror/copilot/__tests__/getCodes.test.ts +12 -13
- package/src/core/codemirror/language/__tests__/utils.test.ts +3 -3
- package/src/core/codemirror/language/embedded/__tests__/embedded-python.test.ts +7 -8
- package/src/core/codemirror/language/languages/python.ts +4 -0
- package/src/core/codemirror/lsp/__tests__/notebook-lsp.test.ts +4 -3
- package/src/core/codemirror/lsp/notebook-lsp.ts +28 -2
- package/src/core/codemirror/reactive-references/__tests__/analyzer.test.ts +7 -6
- package/src/core/codemirror/reactive-references/analyzer.ts +2 -2
- package/src/core/codemirror/rtc/loro/__tests__/sync.test.ts +52 -0
- package/src/core/codemirror/rtc/loro/sync.ts +1 -0
- package/src/core/datasets/__tests__/data-source.test.ts +5 -6
- package/src/core/datasets/state.ts +1 -1
- package/src/core/errors/__tests__/errors.test.ts +2 -1
- package/src/core/export/__tests__/hooks.test.ts +37 -36
- package/src/core/islands/main.ts +2 -7
- package/src/core/kernel/__tests__/handlers.test.ts +5 -4
- package/src/core/kernel/handlers.ts +7 -4
- package/src/core/network/DeferredRequestRegistry.ts +2 -2
- package/src/core/network/__tests__/CachingRequestRegistry.test.ts +9 -10
- package/src/core/network/__tests__/DeferredRequestRegistry.test.ts +4 -6
- package/src/core/static/__tests__/virtual-file-tracker.test.ts +8 -8
- package/src/core/static/virtual-file-tracker.ts +1 -1
- package/src/core/storage/__tests__/state.test.ts +31 -21
- package/src/core/storage/state.ts +1 -1
- package/src/core/variables/__tests__/state.test.ts +6 -6
- package/src/core/variables/types.ts +2 -2
- package/src/core/wasm/__tests__/state.test.ts +8 -8
- package/src/core/websocket/useMarimoKernelConnection.tsx +12 -15
- package/src/css/md-tooltip.css +4 -39
- package/src/css/md.css +7 -0
- package/src/plugins/core/RenderHTML.tsx +17 -0
- package/src/plugins/core/__test__/RenderHTML.test.ts +45 -0
- package/src/plugins/core/sanitize-html.ts +25 -18
- package/src/plugins/impl/DataTablePlugin.tsx +23 -2
- package/src/plugins/impl/SliderPlugin.tsx +1 -3
- package/src/plugins/impl/__tests__/SliderPlugin.test.tsx +120 -0
- package/src/plugins/impl/anywidget/model.ts +1 -2
- package/src/stories/cell.stories.tsx +8 -8
- package/src/stories/layout/vertical/one-column.stories.tsx +9 -8
- package/src/stories/log-viewer.stories.tsx +8 -8
- package/src/stories/variables.stories.tsx +2 -2
- package/src/utils/__tests__/download.test.tsx +21 -20
- package/src/utils/copy.ts +18 -5
- package/src/utils/download.ts +4 -3
- package/src/utils/html-to-image.ts +6 -0
- package/src/utils/json/base64.ts +3 -3
- package/src/utils/traceback.ts +5 -3
- package/dist/assets/JsonOutput-DKXKGKvX.js +0 -46
- package/dist/assets/RenderHTML-DJ8khuob.js +0 -1
- package/dist/assets/ai-model-dropdown-DPTa_EpU.js +0 -5
- package/dist/assets/cell-editor-DX7IcqNr.js +0 -23
- package/dist/assets/channel-CkT8Qdo2.js +0 -1
- package/dist/assets/classDiagram-2ON5EDUG-BhMT_rTz.js +0 -1
- package/dist/assets/classDiagram-v2-WZHVMYZB-D-F4WEyb.js +0 -1
- package/dist/assets/copy-YwM0Pd7v.js +0 -1
- package/dist/assets/dist-BTqMkf4j.js +0 -1
- package/dist/assets/dist-DHw9sXeN.js +0 -1
- package/dist/assets/dist-Du0qZeXz.js +0 -1
- package/dist/assets/dist-a0FfbvMD.js +0 -1
- package/dist/assets/dist-cfkfP0ni.js +0 -1
- package/dist/assets/dist-pzQ9JG-p.js +0 -1
- package/dist/assets/file-explorer-panel-CB8vF5ob.js +0 -26
- package/dist/assets/home-page-itW0tRmv.js +0 -4
- package/dist/assets/html-to-image-BnSc-Wa0.js +0 -2
- package/dist/assets/index-0n92c_W7.js +0 -38
- package/dist/assets/mermaid-4DMBBIKO-PoHnhmy8.js +0 -1
- package/dist/assets/react-vega-Da-Ps9UW.js +0 -1
- package/dist/assets/stateDiagram-v2-4FDKWEC3-CEqeIlM0.js +0 -1
- package/dist/assets/stex-BBWVYm-R.js +0 -1
- package/dist/assets/tracing-DUVd0jtl.js +0 -1
- package/dist/assets/tracing-panel-CuTxPn_x.js +0 -2
- /package/dist/assets/{Combination-Cs9nbinQ.js → Combination-CSPK4t6z.js} +0 -0
- /package/dist/assets/{Deferred-BMfCOLaw.js → Deferred-CfyqLOPG.js} +0 -0
- /package/dist/assets/{SSRProvider-DC7ElCZZ.js → SSRProvider-CwqN9FWV.js} +0 -0
- /package/dist/assets/{badge-hTpPIsMT.js → badge-DImLVznf.js} +0 -0
- /package/dist/assets/{blob-CObhN-9g.js → blob-DgooIGjS.js} +0 -0
- /package/dist/assets/{bot-message-square-CK6eoGWy.js → bot-message-square-Dw41U6lL.js} +0 -0
- /package/dist/assets/{chart-no-axes-column-DV8gdCvH.js → chart-no-axes-column-a9XtWmzk.js} +0 -0
- /package/dist/assets/{check-BE0hEwVo.js → check-DZA_bRpw.js} +0 -0
- /package/dist/assets/{chevron-right-D0GQBpTb.js → chevron-right-CvVxySQk.js} +0 -0
- /package/dist/assets/{circle-check-gLIOLu8x.js → circle-check-CbaVeozR.js} +0 -0
- /package/dist/assets/{circle-play-DYGULlKZ.js → circle-play-DYn5nR6N.js} +0 -0
- /package/dist/assets/{circle-plus-CGG-gArM.js → circle-plus-nCze0-py.js} +0 -0
- /package/dist/assets/{clipboard-paste-DoYSN8Sv.js → clipboard-paste-EHXeKq9D.js} +0 -0
- /package/dist/assets/{code-xml-DwHPF_nL.js → code-xml-BlrJCgNZ.js} +0 -0
- /package/dist/assets/{copy-CkudG0Ej.js → copy-D6N1-xc1.js} +0 -0
- /package/dist/assets/{database-zap-DTWCDKdn.js → database-zap-BIGMFOfP.js} +0 -0
- /package/dist/assets/{defaultLocale-DK1MWd7f.js → defaultLocale-CGfP-Ye3.js} +0 -0
- /package/dist/assets/{defaultLocale-OkOxlkkM.js → defaultLocale-CuYNS33t.js} +0 -0
- /package/dist/assets/{dist-8UD0A5sU.js → dist-BF9S272t.js} +0 -0
- /package/dist/assets/{dist-apDpadc4.js → dist-Bk1itfBD.js} +0 -0
- /package/dist/assets/{dist-CQqv2gQL.js → dist-Dm11d0_A.js} +0 -0
- /package/dist/assets/{download-DBW9RXtT.js → download-nLboiTtW.js} +0 -0
- /package/dist/assets/{ellipsis-0_zJdF6H.js → ellipsis-d7eaKIFn.js} +0 -0
- /package/dist/assets/{ellipsis-vertical-CAB7tdza.js → ellipsis-vertical-DBQ5kWTo.js} +0 -0
- /package/dist/assets/{emotion-is-prop-valid.esm-D1keIaYa.js → emotion-is-prop-valid.esm-D7FeWASw.js} +0 -0
- /package/dist/assets/{errors-Bfogio62.js → errors-0IrrdfSG.js} +0 -0
- /package/dist/assets/{extends-DRbCSry7.js → extends-aq1t6BkR.js} +0 -0
- /package/dist/assets/{eye-off-vwi9L975.js → eye-off-CF3GmvXV.js} +0 -0
- /package/dist/assets/{file-DzHkbIdO.js → file-C-yMeaec.js} +0 -0
- /package/dist/assets/{file-headphone-B5q2Ow55.js → file-headphone-CPAP8asn.js} +0 -0
- /package/dist/assets/{file-plus-corner-lLQw9OnR.js → file-plus-corner-ks__N1mr.js} +0 -0
- /package/dist/assets/{github-BVtI-3F1.js → github-CRD4USKm.js} +0 -0
- /package/dist/assets/{image-DXfkah9d.js → image-CfyJzBP9.js} +0 -0
- /package/dist/assets/{link-Cf10mh3t.js → link-_dbp0XNB.js} +0 -0
- /package/dist/assets/{maps-OKerBHH8.js → maps-DQsjfyTy.js} +0 -0
- /package/dist/assets/{numbers-CYnquDho.js → numbers-Cno6K0UF.js} +0 -0
- /package/dist/assets/{objectWithoutPropertiesLoose-DP4vAkvg.js → objectWithoutPropertiesLoose-Dxmp_Bd_.js} +0 -0
- /package/dist/assets/{ordinal-BjO5SoTk.js → ordinal-CMAUv8ku.js} +0 -0
- /package/dist/assets/{paths-D2lG83Oh.js → paths-BVwhPRFT.js} +0 -0
- /package/dist/assets/{play-DKSqmedg.js → play-Bu_0ogGD.js} +0 -0
- /package/dist/assets/{plus-dVmh0yTy.js → plus-DJ99CUbx.js} +0 -0
- /package/dist/assets/{preload-helper-BW0IMuFq.js → preload-helper-y72bE5iF.js} +0 -0
- /package/dist/assets/{prop-types-RrUi-pOT.js → prop-types-DRf51_gT.js} +0 -0
- /package/dist/assets/{purify.es-BBn8CPhf.js → purify.es-Cf8RQecB.js} +0 -0
- /package/dist/assets/{range-DNqFcYmr.js → range-ClqUI25v.js} +0 -0
- /package/dist/assets/{refresh-ccw-DLpfIr8v.js → refresh-ccw-DQ6SJ8UC.js} +0 -0
- /package/dist/assets/{refresh-cw-CHAHPgkx.js → refresh-cw-Dg9tCj4k.js} +0 -0
- /package/dist/assets/{rotate-ccw-hLlF_82X.js → rotate-ccw-BCkZViUZ.js} +0 -0
- /package/dist/assets/{save-8fSvKYJT.js → save-CUdcv5qm.js} +0 -0
- /package/dist/assets/{session-BrEm7qNv.js → session-CByuQ-M-.js} +0 -0
- /package/dist/assets/{settings-CzQUw9rV.js → settings-B7nhfCat.js} +0 -0
- /package/dist/assets/{spinner-C5JoisA7.js → spinner-pCogyRyo.js} +0 -0
- /package/dist/assets/{square-CxAsQQ77.js → square-KVNDGpgy.js} +0 -0
- /package/dist/assets/{square-function-B006EYFX.js → square-function-BMNCw7Qb.js} +0 -0
- /package/dist/assets/{stex-0ac7Aukl.js → stex-C6JeW1YI.js} +0 -0
- /package/dist/assets/{table-BCnp9gKC.js → table-Od8PbuV-.js} +0 -0
- /package/dist/assets/{toDate-BqKH-Jd9.js → toDate-Cfp9W_O9.js} +0 -0
- /package/dist/assets/{trash-2-CAoNMkjq.js → trash-2-Bc_J7TQO.js} +0 -0
- /package/dist/assets/{trash-BZMAQneW.js → trash-Cxd189Vw.js} +0 -0
- /package/dist/assets/{triangle-alert-qZo1ox6x.js → triangle-alert-CzLrbLGN.js} +0 -0
- /package/dist/assets/{types-C1RN112u.js → types-CLOMZuqU.js} +0 -0
- /package/dist/assets/{use-toast-Hc8CXlvz.js → use-toast-BtZldTi5.js} +0 -0
- /package/dist/assets/{useDebounce-B0dx2Gp0.js → useDebounce-DwTO_rGp.js} +0 -0
- /package/dist/assets/{useTheme-BYXBU1of.js → useTheme-KDW4sktg.js} +0 -0
- /package/dist/assets/{uuid-ClFZlR7U.js → uuid-BukULOeS.js} +0 -0
- /package/dist/assets/{workflow-BmeqNuSH.js → workflow-BqHyyStM.js} +0 -0
- /package/dist/assets/{x-BI1M8X_v.js → x-CdLP7-v3.js} +0 -0
- /package/dist/assets/{youtube-DE-Ej6FR.js → youtube-CfU-SnDw.js} +0 -0
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
|
+
import type { Table } from "@tanstack/react-table";
|
|
3
4
|
import type { TableData } from "@/plugins/impl/DataTablePlugin";
|
|
4
5
|
import { vegaLoadData } from "@/plugins/impl/vega/loader";
|
|
5
6
|
import { jsonParseWithSpecialChar } from "@/utils/json/json-parser";
|
|
7
|
+
import { getMimeValues } from "./mime-cell";
|
|
6
8
|
import { INDEX_COLUMN_NAME } from "./types";
|
|
7
9
|
|
|
8
10
|
/**
|
|
@@ -32,6 +34,21 @@ export async function loadTableData<T = object>(
|
|
|
32
34
|
return tableData;
|
|
33
35
|
}
|
|
34
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Load both table and raw table data. Raw table data is typically when
|
|
39
|
+
* there is formatting applied to the table data.
|
|
40
|
+
*/
|
|
41
|
+
export async function loadTableAndRawData<T>(
|
|
42
|
+
tableData: TableData<T>,
|
|
43
|
+
rawTableData?: TableData<T> | null,
|
|
44
|
+
): Promise<[T[], T[] | undefined]> {
|
|
45
|
+
if (rawTableData) {
|
|
46
|
+
return Promise.all([loadTableData(tableData), loadTableData(rawTableData)]);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return [await loadTableData(tableData), undefined];
|
|
50
|
+
}
|
|
51
|
+
|
|
35
52
|
/**
|
|
36
53
|
* Get the stable row ID for a row.
|
|
37
54
|
*
|
|
@@ -87,3 +104,73 @@ export function stringifyUnknownValue(opts: {
|
|
|
87
104
|
}
|
|
88
105
|
return String(value);
|
|
89
106
|
}
|
|
107
|
+
|
|
108
|
+
function stripHtml(html: string): string {
|
|
109
|
+
const div = document.createElement("div");
|
|
110
|
+
div.innerHTML = html;
|
|
111
|
+
const text = (div.textContent || div.innerText || "").trim();
|
|
112
|
+
return text || html;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const HTML_MIMETYPES = new Set(["text/html", "text/markdown"]);
|
|
116
|
+
|
|
117
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
118
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Get clipboard-ready text and optional HTML for a cell.
|
|
123
|
+
*
|
|
124
|
+
* @param rawValue - The raw (unformatted) value, or undefined if not available.
|
|
125
|
+
* @param displayedValue - The displayed value (may be a mime bundle).
|
|
126
|
+
*/
|
|
127
|
+
export function getClipboardContent(
|
|
128
|
+
rawValue: unknown,
|
|
129
|
+
displayedValue: unknown,
|
|
130
|
+
): { text: string; html?: string } {
|
|
131
|
+
const mimeValues =
|
|
132
|
+
typeof displayedValue === "object" && displayedValue !== null
|
|
133
|
+
? getMimeValues(displayedValue)
|
|
134
|
+
: undefined;
|
|
135
|
+
|
|
136
|
+
let html: string | undefined;
|
|
137
|
+
if (mimeValues) {
|
|
138
|
+
// text/markdown from mo.md() contains rendered HTML
|
|
139
|
+
const htmlParts = mimeValues
|
|
140
|
+
.filter((v) => HTML_MIMETYPES.has(v.mimetype))
|
|
141
|
+
.map((v) => v.data);
|
|
142
|
+
html = htmlParts.length > 0 ? htmlParts.join("") : undefined;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
let text: string;
|
|
146
|
+
if (rawValue !== undefined && rawValue !== displayedValue) {
|
|
147
|
+
text = stringifyUnknownValue({ value: rawValue });
|
|
148
|
+
} else if (mimeValues) {
|
|
149
|
+
text = mimeValues
|
|
150
|
+
.map((v) => (HTML_MIMETYPES.has(v.mimetype) ? stripHtml(v.data) : v.data))
|
|
151
|
+
.join(", ");
|
|
152
|
+
} else {
|
|
153
|
+
text = stringifyUnknownValue({ value: displayedValue });
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return { text, html };
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Get the raw (unformatted) value for a row/column from the table,
|
|
161
|
+
* or undefined if raw data is not available.
|
|
162
|
+
*/
|
|
163
|
+
export function getRawValue<TData>(
|
|
164
|
+
table: Table<TData>,
|
|
165
|
+
rowIndex: number,
|
|
166
|
+
columnId: string,
|
|
167
|
+
): unknown {
|
|
168
|
+
const rawData = table.options.meta?.rawData;
|
|
169
|
+
if (rawData) {
|
|
170
|
+
const rawRow = rawData[rowIndex];
|
|
171
|
+
if (isRecord(rawRow)) {
|
|
172
|
+
return rawRow[columnId];
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return undefined;
|
|
176
|
+
}
|
|
@@ -5,9 +5,9 @@ import { beforeAll, describe, expect, it } from "vitest";
|
|
|
5
5
|
import { SetupMocks } from "@/__mocks__/common";
|
|
6
6
|
import { MockNotebook } from "@/__mocks__/notebook";
|
|
7
7
|
import { MockRequestClient } from "@/__mocks__/requests";
|
|
8
|
+
import { cellId } from "@/__tests__/branded";
|
|
8
9
|
import { TooltipProvider } from "@/components/ui/tooltip";
|
|
9
10
|
import { notebookAtom } from "@/core/cells/cells";
|
|
10
|
-
import type { CellId } from "@/core/cells/ids";
|
|
11
11
|
import { createCellRuntimeState } from "@/core/cells/types";
|
|
12
12
|
import type { UserConfig } from "@/core/config/config-schema";
|
|
13
13
|
import type { OutputMessage } from "@/core/kernel/messages";
|
|
@@ -39,7 +39,7 @@ describe("Cell data attributes", () => {
|
|
|
39
39
|
"present",
|
|
40
40
|
])("should render cell with data-cell-id and data-cell-name in %s mode", (mode) => {
|
|
41
41
|
const { store, wrapper } = createTestWrapper();
|
|
42
|
-
const
|
|
42
|
+
const cid = cellId("test");
|
|
43
43
|
const cellName = "test_cell";
|
|
44
44
|
|
|
45
45
|
const userConfig: UserConfig = {
|
|
@@ -83,7 +83,7 @@ describe("Cell data attributes", () => {
|
|
|
83
83
|
|
|
84
84
|
const notebook = MockNotebook.notebookState({
|
|
85
85
|
cellData: {
|
|
86
|
-
[
|
|
86
|
+
[cid]: {
|
|
87
87
|
code: "",
|
|
88
88
|
name: cellName,
|
|
89
89
|
edited: false,
|
|
@@ -97,7 +97,7 @@ describe("Cell data attributes", () => {
|
|
|
97
97
|
},
|
|
98
98
|
});
|
|
99
99
|
|
|
100
|
-
notebook.cellRuntime[
|
|
100
|
+
notebook.cellRuntime[cid] = createCellRuntimeState({
|
|
101
101
|
status: "idle",
|
|
102
102
|
output: null,
|
|
103
103
|
consoleOutputs: [],
|
|
@@ -117,7 +117,7 @@ describe("Cell data attributes", () => {
|
|
|
117
117
|
const { container } = render(
|
|
118
118
|
<TooltipProvider>
|
|
119
119
|
<Cell
|
|
120
|
-
cellId={
|
|
120
|
+
cellId={cid}
|
|
121
121
|
mode={mode as AppMode}
|
|
122
122
|
canDelete={true}
|
|
123
123
|
userConfig={userConfig}
|
|
@@ -131,7 +131,7 @@ describe("Cell data attributes", () => {
|
|
|
131
131
|
{ wrapper },
|
|
132
132
|
);
|
|
133
133
|
|
|
134
|
-
const cellElement = container.querySelector(`[data-cell-id="${
|
|
134
|
+
const cellElement = container.querySelector(`[data-cell-id="${cid}"]`);
|
|
135
135
|
expect(cellElement).toBeTruthy();
|
|
136
136
|
expect(cellElement?.getAttribute("data-cell-name")).toBe(cellName);
|
|
137
137
|
});
|
|
@@ -139,7 +139,7 @@ describe("Cell data attributes", () => {
|
|
|
139
139
|
|
|
140
140
|
describe("Output data attributes", () => {
|
|
141
141
|
it("should render output with data-cell-role", () => {
|
|
142
|
-
const
|
|
142
|
+
const cid = cellId("test");
|
|
143
143
|
const output: OutputMessage = {
|
|
144
144
|
channel: "output",
|
|
145
145
|
mimetype: "text/plain",
|
|
@@ -151,7 +151,7 @@ describe("Output data attributes", () => {
|
|
|
151
151
|
<TooltipProvider>
|
|
152
152
|
<OutputArea
|
|
153
153
|
output={output}
|
|
154
|
-
cellId={
|
|
154
|
+
cellId={cid}
|
|
155
155
|
stale={false}
|
|
156
156
|
loading={false}
|
|
157
157
|
allowExpand={true}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
import { beforeEach, describe, expect, it, type Mock, vi } from "vitest";
|
|
3
|
+
import { variableName } from "@/__tests__/branded";
|
|
3
4
|
import { getCodes } from "@/core/codemirror/copilot/getCodes";
|
|
4
5
|
import { dataSourceConnectionsAtom } from "@/core/datasets/data-source-connections";
|
|
5
6
|
import { DUCKDB_ENGINE } from "@/core/datasets/engines";
|
|
@@ -7,7 +8,6 @@ import { datasetsAtom } from "@/core/datasets/state";
|
|
|
7
8
|
import type { DatasetsState } from "@/core/datasets/types";
|
|
8
9
|
import { store } from "@/core/state/jotai";
|
|
9
10
|
import { variablesAtom } from "@/core/variables/state";
|
|
10
|
-
import type { Variable, VariableName } from "@/core/variables/types";
|
|
11
11
|
import { codeToCells, getAICompletionBody } from "../completion-utils";
|
|
12
12
|
|
|
13
13
|
// Mock getCodes function
|
|
@@ -205,16 +205,16 @@ describe("getAICompletionBody", () => {
|
|
|
205
205
|
|
|
206
206
|
it("should return the correct completion body with mentioned variables", () => {
|
|
207
207
|
// Set up test data in the Jotai store
|
|
208
|
-
const testVariables
|
|
209
|
-
["var1"
|
|
210
|
-
name: "var1"
|
|
208
|
+
const testVariables = {
|
|
209
|
+
[variableName("var1")]: {
|
|
210
|
+
name: variableName("var1"),
|
|
211
211
|
value: "string value",
|
|
212
212
|
dataType: "string",
|
|
213
213
|
declaredBy: [],
|
|
214
214
|
usedBy: [],
|
|
215
215
|
},
|
|
216
|
-
["var2"
|
|
217
|
-
name: "var2"
|
|
216
|
+
[variableName("var2")]: {
|
|
217
|
+
name: variableName("var2"),
|
|
218
218
|
value: "42",
|
|
219
219
|
dataType: "number",
|
|
220
220
|
declaredBy: [],
|
|
@@ -253,9 +253,9 @@ describe("getAICompletionBody", () => {
|
|
|
253
253
|
];
|
|
254
254
|
store.set(datasetsAtom, { tables: testDatasets } as DatasetsState);
|
|
255
255
|
|
|
256
|
-
const testVariables
|
|
257
|
-
["var1"
|
|
258
|
-
name: "var1"
|
|
256
|
+
const testVariables = {
|
|
257
|
+
[variableName("var1")]: {
|
|
258
|
+
name: variableName("var1"),
|
|
259
259
|
value: "string value",
|
|
260
260
|
dataType: "string",
|
|
261
261
|
declaredBy: [],
|
|
@@ -285,9 +285,9 @@ describe("getAICompletionBody", () => {
|
|
|
285
285
|
|
|
286
286
|
it("should handle non-existent variables", () => {
|
|
287
287
|
// Set up test data in the Jotai store
|
|
288
|
-
const testVariables
|
|
289
|
-
["existingVar"
|
|
290
|
-
name: "existingVar"
|
|
288
|
+
const testVariables = {
|
|
289
|
+
[variableName("existingVar")]: {
|
|
290
|
+
name: variableName("existingVar"),
|
|
291
291
|
value: "string value",
|
|
292
292
|
dataType: "string",
|
|
293
293
|
declaredBy: [],
|
|
@@ -322,9 +322,9 @@ describe("getAICompletionBody", () => {
|
|
|
322
322
|
];
|
|
323
323
|
store.set(datasetsAtom, { tables: testDatasets } as DatasetsState);
|
|
324
324
|
|
|
325
|
-
const testVariables
|
|
326
|
-
["conflict"
|
|
327
|
-
name: "conflict"
|
|
325
|
+
const testVariables = {
|
|
326
|
+
[variableName("conflict")]: {
|
|
327
|
+
name: variableName("conflict"),
|
|
328
328
|
value: "string value",
|
|
329
329
|
dataType: "string",
|
|
330
330
|
declaredBy: [],
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
import { act, renderHook } from "@testing-library/react";
|
|
5
5
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
6
6
|
import { asMock, MockModules, Mocks, SetupMocks } from "@/__mocks__/common";
|
|
7
|
+
import { cellId } from "@/__tests__/branded";
|
|
7
8
|
import type { CellActions, NotebookState } from "@/core/cells/cells";
|
|
8
|
-
import type { CellId } from "@/core/cells/ids";
|
|
9
9
|
import { useCellClipboard } from "../clipboard";
|
|
10
10
|
|
|
11
11
|
// Mock dependencies
|
|
@@ -179,7 +179,7 @@ describe("useCellClipboard", () => {
|
|
|
179
179
|
});
|
|
180
180
|
|
|
181
181
|
it("should filter out non-existent cells", async () => {
|
|
182
|
-
const nonExistentCellId = "non-existent"
|
|
182
|
+
const nonExistentCellId = cellId("non-existent");
|
|
183
183
|
|
|
184
184
|
const { result } = renderHook(() => useCellClipboard());
|
|
185
185
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
2
3
|
import { beforeEach, describe, expect, it } from "vitest";
|
|
3
|
-
import
|
|
4
|
+
import { cellId } from "@/__tests__/branded";
|
|
4
5
|
import { MultiColumn } from "@/utils/id-tree";
|
|
5
6
|
import type { CellSelectionState } from "../selection";
|
|
6
7
|
import { exportedForTesting } from "../selection";
|
|
@@ -8,11 +9,11 @@ import { exportedForTesting } from "../selection";
|
|
|
8
9
|
const { initialState, reducer, createActions } = exportedForTesting;
|
|
9
10
|
|
|
10
11
|
const CellIds = {
|
|
11
|
-
a: "a"
|
|
12
|
-
b: "b"
|
|
13
|
-
c: "c"
|
|
14
|
-
d: "d"
|
|
15
|
-
e: "e"
|
|
12
|
+
a: cellId("a"),
|
|
13
|
+
b: cellId("b"),
|
|
14
|
+
c: cellId("c"),
|
|
15
|
+
d: cellId("d"),
|
|
16
|
+
e: cellId("e"),
|
|
16
17
|
};
|
|
17
18
|
|
|
18
19
|
describe("cell selection reducer", () => {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
3
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
4
|
+
import { cellId } from "@/__tests__/branded";
|
|
4
5
|
import { type CellId, HTMLCellId } from "@/core/cells/ids";
|
|
5
6
|
|
|
6
7
|
const mockScrollCellIntoView = vi.fn();
|
|
@@ -14,12 +15,12 @@ vi.mock("../focus-utils", () => ({
|
|
|
14
15
|
type TemporarilyShownCodeState = Set<CellId>;
|
|
15
16
|
|
|
16
17
|
describe("temporarilyShownCodeActions", () => {
|
|
17
|
-
const
|
|
18
|
+
const cid = cellId("cell-1");
|
|
18
19
|
let cellElement: HTMLElement;
|
|
19
20
|
|
|
20
21
|
beforeEach(() => {
|
|
21
22
|
cellElement = document.createElement("div");
|
|
22
|
-
cellElement.id = HTMLCellId.create(
|
|
23
|
+
cellElement.id = HTMLCellId.create(cid);
|
|
23
24
|
document.body.append(cellElement);
|
|
24
25
|
cellElement.focus();
|
|
25
26
|
|
|
@@ -37,17 +38,17 @@ describe("temporarilyShownCodeActions", () => {
|
|
|
37
38
|
});
|
|
38
39
|
|
|
39
40
|
it("should scroll cell into view when removing cell causes layout shift", () => {
|
|
40
|
-
const state = new Set<CellId>([
|
|
41
|
-
removeCell(state,
|
|
41
|
+
const state = new Set<CellId>([cid]);
|
|
42
|
+
removeCell(state, cid);
|
|
42
43
|
|
|
43
|
-
expect(mockScrollCellIntoView).toHaveBeenCalledWith(
|
|
44
|
+
expect(mockScrollCellIntoView).toHaveBeenCalledWith(cid);
|
|
44
45
|
});
|
|
45
46
|
|
|
46
47
|
it("should not scroll when focused cell is not found", () => {
|
|
47
48
|
vi.spyOn(HTMLCellId, "findElementThroughShadowDOMs").mockReturnValue(null);
|
|
48
49
|
|
|
49
|
-
const state = new Set<CellId>([
|
|
50
|
-
removeCell(state,
|
|
50
|
+
const state = new Set<CellId>([cid]);
|
|
51
|
+
removeCell(state, cid);
|
|
51
52
|
|
|
52
53
|
expect(mockScrollCellIntoView).not.toHaveBeenCalled();
|
|
53
54
|
});
|
|
@@ -316,7 +316,7 @@ export const MarimoErrorOutput = ({
|
|
|
316
316
|
<ul className="list-disc">
|
|
317
317
|
{error.cells.map((cid, cidIdx) => (
|
|
318
318
|
<li className={liStyle} key={`cell-${cidIdx}`}>
|
|
319
|
-
<CellLinkError cellId={cid
|
|
319
|
+
<CellLinkError cellId={cid} />
|
|
320
320
|
</li>
|
|
321
321
|
))}
|
|
322
322
|
</ul>
|
|
@@ -491,7 +491,7 @@ export const MarimoErrorOutput = ({
|
|
|
491
491
|
) : (
|
|
492
492
|
<div>
|
|
493
493
|
{processTextForUrls(error.msg, `exception-${idx}`)}
|
|
494
|
-
<CellLinkError cellId={error.raising_cell
|
|
494
|
+
<CellLinkError cellId={error.raising_cell} />
|
|
495
495
|
</div>
|
|
496
496
|
)}
|
|
497
497
|
</li>
|
|
@@ -518,7 +518,7 @@ export const MarimoErrorOutput = ({
|
|
|
518
518
|
) : (
|
|
519
519
|
<div>
|
|
520
520
|
{error.msg}
|
|
521
|
-
<CellLinkError cellId={error.blamed_cell
|
|
521
|
+
<CellLinkError cellId={error.blamed_cell} />
|
|
522
522
|
</div>
|
|
523
523
|
)}
|
|
524
524
|
</li>
|
|
@@ -554,13 +554,13 @@ export const MarimoErrorOutput = ({
|
|
|
554
554
|
{error.msg}
|
|
555
555
|
{error.blamed_cell == null ? (
|
|
556
556
|
<span>
|
|
557
|
-
(<CellLinkError cellId={error.raising_cell
|
|
557
|
+
(<CellLinkError cellId={error.raising_cell} />)
|
|
558
558
|
</span>
|
|
559
559
|
) : (
|
|
560
560
|
<span>
|
|
561
|
-
(<CellLinkError cellId={error.raising_cell
|
|
561
|
+
(<CellLinkError cellId={error.raising_cell} />
|
|
562
562
|
blames
|
|
563
|
-
<CellLinkError cellId={error.blamed_cell
|
|
563
|
+
<CellLinkError cellId={error.blamed_cell} />)
|
|
564
564
|
</span>
|
|
565
565
|
)}
|
|
566
566
|
</div>
|
|
@@ -578,7 +578,7 @@ export const MarimoErrorOutput = ({
|
|
|
578
578
|
{ancestorStoppedErrors.map((error, idx) => (
|
|
579
579
|
<div key={`ancestor-stopped-${idx}`}>
|
|
580
580
|
{error.msg}
|
|
581
|
-
<CellLinkError cellId={error.raising_cell
|
|
581
|
+
<CellLinkError cellId={error.raising_cell} />
|
|
582
582
|
</div>
|
|
583
583
|
))}
|
|
584
584
|
{cellId && (
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
import { render } from "@testing-library/react";
|
|
4
4
|
import { beforeAll, beforeEach, describe, expect, test, vi } from "vitest";
|
|
5
5
|
import { Tracebacks } from "@/__mocks__/tracebacks";
|
|
6
|
+
import { cellId } from "@/__tests__/branded";
|
|
6
7
|
import { TooltipProvider } from "@/components/ui/tooltip";
|
|
7
|
-
import type { CellId } from "@/core/cells/ids";
|
|
8
8
|
import { initialModeAtom } from "@/core/mode";
|
|
9
9
|
import { store } from "@/core/state/jotai";
|
|
10
10
|
import { renderHTML } from "@/plugins/core/RenderHTML";
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
replaceTracebackPrefix,
|
|
15
15
|
} from "../MarimoTracebackOutput";
|
|
16
16
|
|
|
17
|
-
const
|
|
17
|
+
const cid = cellId("1");
|
|
18
18
|
|
|
19
19
|
describe("traceback component", () => {
|
|
20
20
|
beforeEach(() => {
|
|
@@ -25,7 +25,7 @@ describe("traceback component", () => {
|
|
|
25
25
|
test("extracts cell-link", () => {
|
|
26
26
|
const traceback = (
|
|
27
27
|
<TooltipProvider>
|
|
28
|
-
<MarimoTracebackOutput traceback={Tracebacks.raw} cellId={
|
|
28
|
+
<MarimoTracebackOutput traceback={Tracebacks.raw} cellId={cid} />
|
|
29
29
|
</TooltipProvider>
|
|
30
30
|
);
|
|
31
31
|
const { unmount, getAllByRole } = render(traceback);
|
|
@@ -45,7 +45,7 @@ describe("traceback component", () => {
|
|
|
45
45
|
test("renames File to Cell for relevant lines", () => {
|
|
46
46
|
const traceback = (
|
|
47
47
|
<TooltipProvider>
|
|
48
|
-
<MarimoTracebackOutput traceback={Tracebacks.raw} cellId={
|
|
48
|
+
<MarimoTracebackOutput traceback={Tracebacks.raw} cellId={cid} />
|
|
49
49
|
</TooltipProvider>
|
|
50
50
|
);
|
|
51
51
|
const { unmount, container } = render(traceback);
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
import { act, fireEvent, render, screen } from "@testing-library/react";
|
|
4
4
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
5
5
|
import { SetupMocks } from "@/__mocks__/common";
|
|
6
|
+
import { cellId } from "@/__tests__/branded";
|
|
6
7
|
import { TooltipProvider } from "@/components/ui/tooltip";
|
|
7
|
-
import type { CellId } from "@/core/cells/ids";
|
|
8
8
|
import type { WithResponse } from "@/core/cells/types";
|
|
9
9
|
import type { OutputMessage } from "@/core/kernel/messages";
|
|
10
10
|
import { CONSOLE_CLEAR_DEBOUNCE_MS, ConsoleOutput } from "../ConsoleOutput";
|
|
@@ -24,7 +24,7 @@ describe("ConsoleOutput integration", () => {
|
|
|
24
24
|
});
|
|
25
25
|
|
|
26
26
|
const defaultProps = {
|
|
27
|
-
cellId: "cell-1"
|
|
27
|
+
cellId: cellId("cell-1"),
|
|
28
28
|
cellName: "test_cell",
|
|
29
29
|
consoleOutputs: [] as WithResponse<OutputMessage>[],
|
|
30
30
|
stale: false,
|
|
@@ -55,7 +55,7 @@ describe("ConsoleOutput integration", () => {
|
|
|
55
55
|
|
|
56
56
|
describe("ConsoleOutput pdb history", () => {
|
|
57
57
|
const defaultProps = {
|
|
58
|
-
cellId: "cell-1"
|
|
58
|
+
cellId: cellId("cell-1"),
|
|
59
59
|
cellName: "test_cell",
|
|
60
60
|
consoleOutputs: [] as WithResponse<OutputMessage>[],
|
|
61
61
|
stale: false,
|
|
@@ -215,7 +215,7 @@ describe("ConsoleOutput debounced clearing", () => {
|
|
|
215
215
|
});
|
|
216
216
|
|
|
217
217
|
const defaultProps = {
|
|
218
|
-
cellId: "cell-1"
|
|
218
|
+
cellId: cellId("cell-1"),
|
|
219
219
|
cellName: "test_cell",
|
|
220
220
|
consoleOutputs: [] as WithResponse<OutputMessage>[],
|
|
221
221
|
stale: false,
|
|
@@ -91,7 +91,7 @@ function focusCellByName(cellName: string) {
|
|
|
91
91
|
|
|
92
92
|
// Look for an editor to focus
|
|
93
93
|
const { cellHandles } = getNotebook();
|
|
94
|
-
const cellId = cellElement
|
|
94
|
+
const cellId = extractCellIdFromDomElement(cellElement);
|
|
95
95
|
|
|
96
96
|
if (!cellId) {
|
|
97
97
|
Logger.error(`Missing cellId for cell with name ${cellName}`);
|
|
@@ -111,3 +111,10 @@ function focusCellByName(cellName: string) {
|
|
|
111
111
|
focusFirstEditor();
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
|
+
|
|
115
|
+
function extractCellIdFromDomElement(
|
|
116
|
+
cellElement: HTMLElement,
|
|
117
|
+
): CellId | undefined {
|
|
118
|
+
const cellIdStr = cellElement.dataset.cellId ?? undefined;
|
|
119
|
+
return cellIdStr as CellId | undefined;
|
|
120
|
+
}
|
|
@@ -4,27 +4,32 @@ import { FileIcon, LoaderCircle, RefreshCwIcon } from "lucide-react";
|
|
|
4
4
|
import type React from "react";
|
|
5
5
|
import { useCallback } from "react";
|
|
6
6
|
import { useLocale } from "react-aria";
|
|
7
|
+
import { useAddCodeToNewCell } from "@/components/editor/cell/useAddCell";
|
|
7
8
|
import { FilePreviewHeader } from "@/components/editor/file-tree/file-header";
|
|
8
9
|
import { renderFileIcon } from "@/components/editor/file-tree/file-icons";
|
|
9
10
|
import {
|
|
10
11
|
FileContentRenderer,
|
|
11
12
|
isMediaMime,
|
|
12
13
|
} from "@/components/editor/file-tree/renderers";
|
|
14
|
+
import { Tooltip } from "@/components/ui/tooltip";
|
|
13
15
|
import { toast } from "@/components/ui/use-toast";
|
|
14
16
|
import { DownloadStorage } from "@/core/storage/request-registry";
|
|
15
|
-
import type { StorageEntry } from "@/core/storage/types";
|
|
17
|
+
import type { StorageEntry, StorageNamespace } from "@/core/storage/types";
|
|
16
18
|
import { useAsyncData } from "@/hooks/useAsyncData";
|
|
17
19
|
import { downloadByURL } from "@/utils/download";
|
|
18
20
|
import { formatBytes } from "@/utils/formatting";
|
|
19
21
|
import { Logger } from "@/utils/Logger";
|
|
20
22
|
import { CopyClipboardIcon } from "../icons/copy-icon";
|
|
21
23
|
import { Button } from "../ui/button";
|
|
24
|
+
import { STORAGE_SNIPPETS } from "./storage-snippets";
|
|
22
25
|
|
|
23
26
|
const MAX_MEDIA_PREVIEW_SIZE = 100 * 1024 * 1024; // 100 MB
|
|
24
27
|
|
|
25
28
|
interface Props {
|
|
26
29
|
entry: StorageEntry;
|
|
27
30
|
namespace: string;
|
|
31
|
+
protocol: string;
|
|
32
|
+
backendType: StorageNamespace["backendType"];
|
|
28
33
|
onBack: () => void;
|
|
29
34
|
}
|
|
30
35
|
|
|
@@ -41,9 +46,12 @@ type PreviewData =
|
|
|
41
46
|
export const StorageFileViewer: React.FC<Props> = ({
|
|
42
47
|
entry,
|
|
43
48
|
namespace,
|
|
49
|
+
protocol,
|
|
50
|
+
backendType,
|
|
44
51
|
onBack,
|
|
45
52
|
}) => {
|
|
46
53
|
const { locale } = useLocale();
|
|
54
|
+
const addCodeToNewCell = useAddCodeToNewCell();
|
|
47
55
|
const name = displayName(entry.path);
|
|
48
56
|
const mime = entry.mimeType || "text/plain";
|
|
49
57
|
const isMedia = isMediaMime(mime);
|
|
@@ -111,12 +119,38 @@ export const StorageFileViewer: React.FC<Props> = ({
|
|
|
111
119
|
}
|
|
112
120
|
}, [namespace, entry.path, name]);
|
|
113
121
|
|
|
122
|
+
const snippetActions = STORAGE_SNIPPETS.map((snippet) => {
|
|
123
|
+
const code = snippet.getCode({
|
|
124
|
+
variableName: namespace,
|
|
125
|
+
protocol,
|
|
126
|
+
entry,
|
|
127
|
+
backendType,
|
|
128
|
+
});
|
|
129
|
+
if (code === null) {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
const Icon = snippet.icon;
|
|
133
|
+
return (
|
|
134
|
+
<Tooltip key={snippet.id} content={snippet.label}>
|
|
135
|
+
<Button
|
|
136
|
+
variant="text"
|
|
137
|
+
size="xs"
|
|
138
|
+
onClick={() => addCodeToNewCell(code)}
|
|
139
|
+
aria-label={snippet.label}
|
|
140
|
+
>
|
|
141
|
+
<Icon className="h-3.5 w-3.5" />
|
|
142
|
+
</Button>
|
|
143
|
+
</Tooltip>
|
|
144
|
+
);
|
|
145
|
+
});
|
|
146
|
+
|
|
114
147
|
const header = (
|
|
115
148
|
<FilePreviewHeader
|
|
116
149
|
filename={name}
|
|
117
150
|
filenameIcon={renderFileIcon(name)}
|
|
118
151
|
onBack={onBack}
|
|
119
152
|
onDownload={handleDownload}
|
|
153
|
+
actions={snippetActions}
|
|
120
154
|
/>
|
|
121
155
|
);
|
|
122
156
|
|
|
@@ -50,7 +50,6 @@ import type {
|
|
|
50
50
|
StoragePathKey,
|
|
51
51
|
} from "@/core/storage/types";
|
|
52
52
|
import { storagePathKey } from "@/core/storage/types";
|
|
53
|
-
import type { VariableName } from "@/core/variables/types";
|
|
54
53
|
import { cn } from "@/utils/cn";
|
|
55
54
|
import { copyToClipboard } from "@/utils/copy";
|
|
56
55
|
import { downloadByURL } from "@/utils/download";
|
|
@@ -65,6 +64,8 @@ import { STORAGE_SNIPPETS } from "./storage-snippets";
|
|
|
65
64
|
interface OpenFileInfo {
|
|
66
65
|
entry: StorageEntry;
|
|
67
66
|
namespace: string;
|
|
67
|
+
protocol: string;
|
|
68
|
+
backendType: StorageNamespace["backendType"];
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
// Pixels per depth level. Applied as paddingLeft on each full-width item
|
|
@@ -316,7 +317,7 @@ const StorageEntryRow: React.FC<{
|
|
|
316
317
|
if (isDir) {
|
|
317
318
|
setIsExpanded(!effectiveExpanded);
|
|
318
319
|
} else {
|
|
319
|
-
onOpenFile({ entry, namespace });
|
|
320
|
+
onOpenFile({ entry, namespace, protocol, backendType });
|
|
320
321
|
}
|
|
321
322
|
}}
|
|
322
323
|
>
|
|
@@ -362,7 +363,9 @@ const StorageEntryRow: React.FC<{
|
|
|
362
363
|
>
|
|
363
364
|
{!isDir && (
|
|
364
365
|
<DropdownMenuItem
|
|
365
|
-
onSelect={() =>
|
|
366
|
+
onSelect={() =>
|
|
367
|
+
onOpenFile({ entry, namespace, protocol, backendType })
|
|
368
|
+
}
|
|
366
369
|
>
|
|
367
370
|
<ViewIcon className={MENU_ITEM_ICON_CLASS} />
|
|
368
371
|
View
|
|
@@ -474,7 +477,7 @@ const StorageNamespaceSection: React.FC<{
|
|
|
474
477
|
<span>{namespace.displayName}</span>
|
|
475
478
|
{namespace.name && (
|
|
476
479
|
<span className="text-xs text-muted-foreground font-normal">
|
|
477
|
-
(<EngineVariable variableName={namespace.name
|
|
480
|
+
(<EngineVariable variableName={namespace.name} />)
|
|
478
481
|
</span>
|
|
479
482
|
)}
|
|
480
483
|
<RefreshIconButton
|
|
@@ -586,6 +589,8 @@ export const StorageInspector: React.FC = () => {
|
|
|
586
589
|
<StorageFileViewer
|
|
587
590
|
entry={openFile.entry}
|
|
588
591
|
namespace={openFile.namespace}
|
|
592
|
+
protocol={openFile.protocol}
|
|
593
|
+
backendType={openFile.backendType}
|
|
589
594
|
onBack={() => setOpenFile(null)}
|
|
590
595
|
/>
|
|
591
596
|
)}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
3
|
import type { LucideIcon } from "lucide-react";
|
|
4
|
-
import {
|
|
4
|
+
import { BookPlusIcon, FileSymlink } from "lucide-react";
|
|
5
5
|
import type { StorageEntry, StorageNamespace } from "@/core/storage/types";
|
|
6
6
|
|
|
7
7
|
type BackendType = StorageNamespace["backendType"];
|
|
@@ -31,7 +31,7 @@ export const STORAGE_SNIPPETS: StorageSnippet[] = [
|
|
|
31
31
|
{
|
|
32
32
|
id: "read-file",
|
|
33
33
|
label: "Insert read snippet",
|
|
34
|
-
icon:
|
|
34
|
+
icon: BookPlusIcon,
|
|
35
35
|
getCode: (ctx) => {
|
|
36
36
|
if (ctx.entry.kind === "directory") {
|
|
37
37
|
return null;
|
|
@@ -46,7 +46,7 @@ export const STORAGE_SNIPPETS: StorageSnippet[] = [
|
|
|
46
46
|
{
|
|
47
47
|
id: "download-file",
|
|
48
48
|
label: "Insert download snippet",
|
|
49
|
-
icon:
|
|
49
|
+
icon: FileSymlink,
|
|
50
50
|
getCode: (ctx) => {
|
|
51
51
|
if (ctx.entry.kind === "directory") {
|
|
52
52
|
return null;
|
|
@@ -243,7 +243,9 @@ const TraceBlockBody: React.FC<{
|
|
|
243
243
|
signalName: VEGA_HOVER_SIGNAL,
|
|
244
244
|
handler: (_name: string, value: unknown) => {
|
|
245
245
|
const signalValue = value as VegaHoverCellSignal;
|
|
246
|
-
const hoveredCell = signalValue.cell?.[0]
|
|
246
|
+
const hoveredCell = (signalValue.cell?.[0] ?? undefined) as
|
|
247
|
+
| CellId
|
|
248
|
+
| undefined;
|
|
247
249
|
setHoveredCellId(hoveredCell ?? null);
|
|
248
250
|
},
|
|
249
251
|
},
|