@marimo-team/frontend 0.23.17-dev4 → 0.23.17-dev40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/{CellStatus-DIW20_Z8.js → CellStatus-XlxL4ctu.js} +1 -1
- package/dist/assets/{ConnectedDataExplorerComponent-C4zEgCZh.js → ConnectedDataExplorerComponent-BF5CJvB2.js} +1 -1
- package/dist/assets/{ErrorBoundary-DzTD8LVq.js → ErrorBoundary-BfMsWVQU.js} +1 -1
- package/dist/assets/ImageComparisonComponent-CukPDP1p.js +1 -0
- package/dist/assets/{ImperativeModal-fY-ZfT0b.js → ImperativeModal-Ci0icDPt.js} +1 -1
- package/dist/assets/{JsonOutput-Bk2exFh0.js → JsonOutput-CWfu9qbN.js} +13 -13
- package/dist/assets/{LazyAnyLanguageCodeMirror-A-Ant1Ad.js → LazyAnyLanguageCodeMirror-Dcvy_p3-.js} +2 -2
- package/dist/assets/{MarimoErrorOutput-L_o2Knzo.js → MarimoErrorOutput-B9QSRg6T.js} +5 -5
- package/dist/assets/{RSPContexts-WiCgGm__.js → RSPContexts-IrDQoFki.js} +1 -1
- package/dist/assets/{RenderHTML-BTDLQMKg.js → RenderHTML-CQC8I348.js} +1 -1
- package/dist/assets/{RunButton-DiHX9YjB.js → RunButton-DRxV8u_T.js} +1 -1
- package/dist/assets/add-cell-with-ai-GZi9Icll.js +107 -0
- package/dist/assets/{add-connection-dialog-BZaJAQCM.js → add-connection-dialog-D2WiF1f8.js} +31 -31
- package/dist/assets/{agent-panel-CRxiqCgP.js → agent-panel-BWIkm6ln.js} +6 -6
- package/dist/assets/ai-model-dropdown-BmcXWjub.js +5 -0
- package/dist/assets/{alert-dialog-Bb8Lz8ko.js → alert-dialog-DMh8_LWc.js} +1 -1
- package/dist/assets/{any-language-editor-BIeaxtdD.js → any-language-editor-DUQN91an.js} +1 -1
- package/dist/assets/{app-config-button-BS4LSo1l.js → app-config-button-QHaORuxs.js} +1 -1
- package/dist/assets/{blob-B9eg-RfN.js → blob-BzgGkt3B.js} +1 -1
- package/dist/assets/{button-DDGiD1NW.js → button-BB1AV4Rb.js} +1 -1
- package/dist/assets/{cache-panel-B2B1ePao.js → cache-panel-hpL5o4Y7.js} +1 -1
- package/dist/assets/{capabilities-DoEg0XwL.js → capabilities-LI6_PoMn.js} +1 -1
- package/dist/assets/{cell-editor-OC7h_nZ3.js → cell-editor-Cwor7oUx.js} +11 -11
- package/dist/assets/{cell-link-D0aELsL_.js → cell-link-uPmFMRTh.js} +1 -1
- package/dist/assets/cells-BE1kpmPF.css +2 -0
- package/dist/assets/{cells-DLYs3NiJ.js → cells-DxL32Atg.js} +60 -60
- package/dist/assets/chat-display-CH-dFAC3.js +1 -0
- package/dist/assets/chat-panel-DLgorYjE.js +4 -0
- package/dist/assets/chat-ui-DDkwFM3p.js +4 -0
- package/dist/assets/{column-preview-CnqeJb-x.js → column-preview-Dw1ASLnm.js} +1 -1
- package/dist/assets/{command-Dqxie4gq.js → command-CPFHYoYk.js} +1 -1
- package/dist/assets/command-palette--Mo9OaH2.js +1 -0
- package/dist/assets/{common-D_beLbpm.js → common-aHaDUD0-.js} +1 -1
- package/dist/assets/{components-CxEGXaTB.js → components-BQ3c1B_F.js} +1 -1
- package/dist/assets/components-Bm1d4vm9.js +1 -0
- package/dist/assets/config-Bm5B9wGP.js +1 -0
- package/dist/assets/{config-BJVx3eBW.js → config-Cbkt6Rb1.js} +1 -1
- package/dist/assets/{copy-Bxb1_Gtw.js → copy-B-LLR1Yy.js} +1 -1
- package/dist/assets/{copy-icon-neDQUo4Q.js → copy-icon-DWG8Y-xW.js} +1 -1
- package/dist/assets/{createReducer-DGx5Af-C.js → createReducer-DNehfY0t.js} +1 -1
- package/dist/assets/{datasource-Bfg8PKXp.js → datasource-DfQvKiJ1.js} +2 -2
- package/dist/assets/{dates-C2LWzsCZ.js → dates-BzOh4kS_.js} +1 -1
- package/dist/assets/defaultLocale-t77eoiwF.js +1 -0
- package/dist/assets/{dependency-graph-panel-CB5ie0zu.js → dependency-graph-panel-gbgUGtYS.js} +2 -2
- package/dist/assets/{diagram-PSM6KHXK-DIXxW5au.js → diagram-PSM6KHXK-CrTUa1Xy.js} +1 -1
- package/dist/assets/{dialog-BCVepWLJ.js → dialog-88bLE398.js} +1 -1
- package/dist/assets/{dist-CPjTeT8p.js → dist-6qzebh8f.js} +1 -1
- package/dist/assets/dist-BLqRx0W-.js +1 -0
- package/dist/assets/{dist-BP4hpPAE.js → dist-BVr4HQPR.js} +1 -1
- package/dist/assets/{dist-DnjsPBRJ.js → dist-BWXIz8tq.js} +1 -1
- package/dist/assets/{dist-Cros4IAo.js → dist-BWbS__vR.js} +1 -1
- package/dist/assets/dist-BZehnCk2.js +1 -0
- package/dist/assets/dist-BaRgF7DU.js +1 -0
- package/dist/assets/{dist-DYEuVkEX.js → dist-BblMEWTQ.js} +1 -1
- package/dist/assets/dist-BlMeFaGB.js +1 -0
- package/dist/assets/{dist-CrKffqgx.js → dist-BmYa2llD.js} +1 -1
- package/dist/assets/{dist-9o0Xjd5v.js → dist-Btp8vRFr.js} +1 -1
- package/dist/assets/{dist-C-3FVUQA.js → dist-BvMWjDxm.js} +1 -1
- package/dist/assets/{dist-DeJBvhAc.js → dist-ByfZ_2N7.js} +1 -1
- package/dist/assets/dist-C-g2AKOo.js +1 -0
- package/dist/assets/{dist-DQl27SFq.js → dist-C52BqSeO.js} +1 -1
- package/dist/assets/{dist-CiVShZKM.js → dist-C7rDfTPJ.js} +1 -1
- package/dist/assets/{dist-BKgHjzML.js → dist-C830fIIj.js} +1 -1
- package/dist/assets/{dist-fLBYOt9R.js → dist-CHN_sQZw.js} +1 -1
- package/dist/assets/dist-CLFhXj8x.js +1 -0
- package/dist/assets/{dist-D47O3FBX.js → dist-CLQWOmD7.js} +1 -1
- package/dist/assets/dist-CO4dulTL.js +1 -0
- package/dist/assets/dist-CPw3iq_l.js +1 -0
- package/dist/assets/dist-CQtN-vVI.js +1 -0
- package/dist/assets/dist-CZE9FE_5.js +1 -0
- package/dist/assets/dist-CexuM4NA.js +1 -0
- package/dist/assets/{dist-DJuRuTXr.js → dist-CfiLpZZj.js} +1 -1
- package/dist/assets/dist-CjSt6gRp.js +1 -0
- package/dist/assets/dist-Cr4q2U0d.js +1 -0
- package/dist/assets/{dist-C6_DArtj.js → dist-CxaoIFrU.js} +1 -1
- package/dist/assets/{dist-aRc_dRed.js → dist-D5nYeU7Q.js} +1 -1
- package/dist/assets/{dist-BJZAIIze.js → dist-DX04AOlt.js} +1 -1
- package/dist/assets/dist-DkZos4_s.js +1 -0
- package/dist/assets/{dist-DI1-Z60I.js → dist-DmCNk9gq.js} +1 -1
- package/dist/assets/{dist-kLs0VbW_.js → dist-DmjT6iaH.js} +1 -1
- package/dist/assets/{dist-CvWC93qL.js → dist-DrY8fZeD.js} +1 -1
- package/dist/assets/{dist-l4RTzHX-.js → dist-Drexw1Ir.js} +1 -1
- package/dist/assets/{dist-DrBqBDHF.js → dist-DtNSqHzW.js} +1 -1
- package/dist/assets/dist-DxQA7Dn1.js +1 -0
- package/dist/assets/{dist-BLN8PNJV.js → dist-Dza6FJtV.js} +1 -1
- package/dist/assets/{dist-8SH6SWEG.js → dist-HrXjBuXP.js} +1 -1
- package/dist/assets/dist-J00F7mRY.js +1 -0
- package/dist/assets/{dist-DcwTQG1A.js → dist-Jbd9zUbK.js} +1 -1
- package/dist/assets/{dist-CZvbHnyT.js → dist-bvfx5OQE.js} +1 -1
- package/dist/assets/{dist-12S8I4CH.js → dist-gUHullA_.js} +11 -11
- package/dist/assets/dist-nYKCNtEX.js +1 -0
- package/dist/assets/dist-oK8dffBy.js +1 -0
- package/dist/assets/{documentation-panel-Dii7ouzj.js → documentation-panel-DotG4o5W.js} +1 -1
- package/dist/assets/{download-DenADH0w.js → download-Tklnz6pn.js} +3 -3
- package/dist/assets/{dropdown-menu-dHmZR8bI.js → dropdown-menu-BGBlPKNz.js} +1 -1
- package/dist/assets/{edit-page-B0EhuiM-.js → edit-page-DhZPSJ6P.js} +6 -6
- package/dist/assets/{error-banner-BSxEOIn2.js → error-banner-BkIr-0dH.js} +1 -1
- package/dist/assets/{error-entries-4XYBryls.js → error-entries-BvUR_22-.js} +3 -3
- package/dist/assets/{error-panel-xYZ4lX0A.js → error-panel-Upmm4kG5.js} +1 -1
- package/dist/assets/{errors-PgHhDa-M.js → errors-DCPV979Q.js} +1 -1
- package/dist/assets/{es-gYgfF8y5.js → es-Dl2xAwTv.js} +1 -1
- package/dist/assets/{esm-B30N1GS0.js → esm-Bmzgrl_5.js} +1 -1
- package/dist/assets/{esm-BDGraAqp.js → esm-Nb9m4lqg.js} +1 -1
- package/dist/assets/{field-BsxD35VE.js → field-BFgvUZyh.js} +1 -1
- package/dist/assets/file-explorer-panel-BulU96v_.js +37 -0
- package/dist/assets/{file-icons-mgXTzM1c.js → file-icons-NkObNkr_.js} +1 -1
- package/dist/assets/{file-name-input-Dq7Z_QmU.js → file-name-input-BQJ9U9lU.js} +1 -1
- package/dist/assets/{floating-outline-ypOHt2wD.js → floating-outline-BHmregl1.js} +1 -1
- package/dist/assets/{focus-0L1nX7M9.js → focus-BBiJct2G.js} +1 -1
- package/dist/assets/{form-BsW7zr4t.js → form-BIUQB1NI.js} +1 -1
- package/dist/assets/{form-oz4Z280Z.js → form-D-Bo8F9Q.js} +1 -1
- package/dist/assets/{formats-DzmLpc9A.js → formats-DNYtnQk7.js} +1 -1
- package/dist/assets/{formatting-COz4XEaB.js → formatting-qNOrQYRN.js} +1 -1
- package/dist/assets/{fullscreen-CTDqNQr6.js → fullscreen-B51geQ_6.js} +1 -1
- package/dist/assets/{gallery-page-DbuxknAw.js → gallery-page-DBHHOraF.js} +1 -1
- package/dist/assets/{ganttDiagram-JELNMOA3-DaS60lKW.js → ganttDiagram-JELNMOA3-C9KBLmAA.js} +1 -1
- package/dist/assets/{glide-data-editor-CejKKgnN.js → glide-data-editor-CHN4-xUu.js} +1 -1
- package/dist/assets/{home-page-BOP1dDcM.js → home-page-Dvm2dFdU.js} +2 -2
- package/dist/assets/{html-to-image-D_C-hjtC.js → html-to-image-ChNWEUlR.js} +1 -1
- package/dist/assets/index-BPwg3EAk.js +38 -0
- package/dist/assets/index-Dttsymhw.css +2 -0
- package/dist/assets/{input-JxFwu-3G.js → input-_AaMXWgD.js} +1 -1
- package/dist/assets/{kiosk-mode-BvKMuigM.js → kiosk-mode-RTwj6XH4.js} +1 -1
- package/dist/assets/{label-CqjrpwRC.js → label-DUD3SZnk.js} +1 -1
- package/dist/assets/{layout-yfmf2ZBx.js → layout-D7Yzn4XY.js} +4 -4
- package/dist/assets/{linear-BPv4krGt.js → linear-B1ROUUtm.js} +1 -1
- package/dist/assets/{links-ClNQSIal.js → links-DBc28bsl.js} +1 -1
- package/dist/assets/{logs-panel-OMd1Z9CL.js → logs-panel-Cdcjc_fq.js} +1 -1
- package/dist/assets/markdown-export-CNu5ZTPR.js +1 -0
- package/dist/assets/{markdown-renderer-BfLNJGNj.js → markdown-renderer-DpskAUxO.js} +1 -1
- package/dist/assets/{menu-items-CCi6aOPm.js → menu-items-Db-bgz92.js} +1 -1
- package/dist/assets/{mermaid-B8gNHyGy.js → mermaid-OU2hLna0.js} +3 -3
- package/dist/assets/{name-cell-input-COtjRghz.js → name-cell-input-DoxL2EXI.js} +1 -1
- package/dist/assets/{numbers-rmawRqQP.js → numbers-D9g2ArIv.js} +1 -1
- package/dist/assets/{outline-panel-CIGf4SLb.js → outline-panel-BxjI-YSj.js} +1 -1
- package/dist/assets/{packages-panel-DLuMuNuG.js → packages-panel-IN-yS3e2.js} +1 -1
- package/dist/assets/{pair-with-agent-modal-C5OhJ8rX.js → pair-with-agent-modal-1b5Eh8Xo.js} +1 -1
- package/dist/assets/{panel-accordion-state-D1UP17Lk.js → panel-accordion-state-BkWYwckU.js} +1 -1
- package/dist/assets/{panels-B0w23XJS.js → panels-C5PIEySE.js} +2 -2
- package/dist/assets/{popover-Bcz1Zikb.js → popover-DHbixh3D.js} +1 -1
- package/dist/assets/{precisionRound-i2ImZxgc.js → precisionRound-DORAUfVY.js} +1 -1
- package/dist/assets/process-output-DJonUYp2.js +1 -0
- package/dist/assets/{quadrantDiagram-AYHSOK5B-DJuGB95-.js → quadrantDiagram-AYHSOK5B-Duf8sGaa.js} +1 -1
- package/dist/assets/{radio-group-BGXYy3u5.js → radio-group-ByLzIKjm.js} +1 -1
- package/dist/assets/react-vega-J-J2akIt.js +191 -0
- package/dist/assets/{readonly-code-display-DdABj8tH.js → readonly-code-display-B_ZHScA7.js} +1 -1
- package/dist/assets/{readonly-python-code-DUjqXwhi.js → readonly-python-code-C4GeGU7O.js} +1 -1
- package/dist/assets/{renderShortcut-Bl8_FVn8.js → renderShortcut-DnqsU4zj.js} +1 -1
- package/dist/assets/{reveal-component-BjgfnO81.js → reveal-component-BPaqYFXU.js} +2 -2
- package/dist/assets/{run-page-DDty5GvQ.js → run-page-kWVbQ6KV.js} +1 -1
- package/dist/assets/{runs-s9t2f_Tg.js → runs-C6avq6Gi.js} +1 -1
- package/dist/assets/scratchpad-panel-l1iGto9s.js +1 -0
- package/dist/assets/{scroll-to-bottom-button-C8yfT4wq.js → scroll-to-bottom-button-CRMPUjYZ.js} +1 -1
- package/dist/assets/{secrets-panel-Cz17_MLf.js → secrets-panel-DmAwH7vI.js} +1 -1
- package/dist/assets/{select-BP75_5jJ.js → select-Clmc8Hw2.js} +1 -1
- package/dist/assets/{session-BmukRjSi.js → session-BtBr2zr3.js} +1 -1
- package/dist/assets/{session-panel-aMoQPTCB.js → session-panel-CBmLYzFL.js} +1 -1
- package/dist/assets/{share-852X_cqy.js → share-DSOv_SvY.js} +1 -1
- package/dist/assets/{skeleton-CPuDx7yn.js → skeleton-DhhF_mJP.js} +1 -1
- package/dist/assets/{snippets-panel-DBDXr-XP.js → snippets-panel-l_HnIWUj.js} +1 -1
- package/dist/assets/{spec-C7opZZRp.js → spec-CdDzA5ef.js} +1 -1
- package/dist/assets/{state-DCtLlFJq.js → state-B4lC29et.js} +1 -1
- package/dist/assets/{state-C4kiwedg.js → state-BkoVfBqt.js} +1 -1
- package/dist/assets/{state-Brswj8bD.js → state-COqqdiUM.js} +1 -1
- package/dist/assets/{state-hlEqpZfH.js → state-D9xpDCxa.js} +2 -2
- package/dist/assets/{strings--BknHX9C.js → strings-DMKwTex-.js} +1 -1
- package/dist/assets/{swiper-component-DXW8snlt.js → swiper-component-pSAP3cRf.js} +1 -1
- package/dist/assets/switch-8FxRs-OU.js +1 -0
- package/dist/assets/{terminal-CaHTVNrz.js → terminal-DPQJ6hNg.js} +1 -1
- package/dist/assets/{textarea-DtCcemo9.js → textarea-BzWvGIrJ.js} +1 -1
- package/dist/assets/{time-p47i6wvp.js → time-BO-naW1O.js} +1 -1
- package/dist/assets/tooltip-BMi4WFDl.js +61 -0
- package/dist/assets/{tooltip-4bZlU7jl.js → tooltip-BcgbFR7q.js} +1 -1
- package/dist/assets/{tracing-CStM7RGI.js → tracing-DCuWLKnk.js} +1 -1
- package/dist/assets/{tracing-panel-BTLzu8L-.js → tracing-panel-dVtThkzL.js} +2 -2
- package/dist/assets/{tree-actions-BwwVyp3l.js → tree-actions-o2iyMmKN.js} +1 -1
- package/dist/assets/{useBoolean-DIi7jQLa.js → useBoolean-sASJEpGA.js} +1 -1
- package/dist/assets/{useCellActionButton-uxVyv3JK.js → useCellActionButton-CrFbi8en.js} +1 -1
- package/dist/assets/{useDeleteCell-Cy23OP4e.js → useDeleteCell-DH0weyin.js} +1 -1
- package/dist/assets/{useDependencyPanelTab-DNfjp_-X.js → useDependencyPanelTab-OeFV2bye.js} +1 -1
- package/dist/assets/{useEventListener-C0195JsF.js → useEventListener-B_wSLgFR.js} +1 -1
- package/dist/assets/{useHotkey-DLZvrRZT.js → useHotkey-DJyYmk5P.js} +1 -1
- package/dist/assets/{useIframeCapabilities-j6fR_dBA.js → useIframeCapabilities-D_6fB_8O.js} +1 -1
- package/dist/assets/{useInstallPackage-WiYBwhUO.js → useInstallPackage-DyNrAhrx.js} +1 -1
- package/dist/assets/{useInterval-CnQfyMa9.js → useInterval-CjGsg4ie.js} +1 -1
- package/dist/assets/useNotebookActions-CylmZilh.js +12 -0
- package/dist/assets/useRunCells-8xYRh7wH.js +1 -0
- package/dist/assets/{useSplitCell-BK5mnkkL.js → useSplitCell-BvgvIZaz.js} +1 -1
- package/dist/assets/{useTheme-Bxv9B31g.js → useTheme-BR31Gjbc.js} +1 -1
- package/dist/assets/utils-C5VWChv9.js +1 -0
- package/dist/assets/{vega-component-BGiCExka.js → vega-component-DG9G1qk2.js} +1 -1
- package/dist/assets/{vega-embed-container-DxSqUOCK.js → vega-embed-container-BJRQVehC.js} +1 -1
- package/dist/assets/vega-loader.browser-CAfmqKEc.js +6 -0
- package/dist/assets/{write-secret-modal-Dtm66yVf.js → write-secret-modal-DwCUuNRy.js} +1 -1
- package/dist/assets/{xychartDiagram-PRI3JC2R-B8A0hi-Q.js → xychartDiagram-PRI3JC2R-ClPpSFDI.js} +1 -1
- package/dist/assets/{zod-H_cgTO0M.js → zod-CIOjj3iA.js} +5 -5
- package/dist/index.html +87 -87
- package/package.json +6 -6
- package/src/__mocks__/requests.ts +5 -0
- package/src/components/app-config/user-config-form.tsx +26 -0
- package/src/components/chat/__tests__/chat-abort.test.ts +51 -0
- package/src/components/chat/chat-abort.ts +44 -0
- package/src/components/chat/chat-display.tsx +17 -0
- package/src/components/chat/chat-panel.tsx +85 -37
- package/src/components/chat/chat-utils.ts +1 -1
- package/src/components/data-table/charts/__tests__/schemas.test.ts +35 -0
- package/src/components/data-table/charts/schemas.ts +5 -2
- package/src/components/databases/icons/huggingface.svg +8 -0
- package/src/components/datasets/__tests__/icons.test.ts +21 -0
- package/src/components/datasets/icons.tsx +10 -0
- package/src/components/datasources/__tests__/components.test.tsx +29 -0
- package/src/components/datasources/components.tsx +8 -3
- package/src/components/editor/actions/export-dialog/__tests__/export-dialog.test.tsx +35 -0
- package/src/components/editor/actions/export-dialog/__tests__/state.test.ts +61 -0
- package/src/components/editor/actions/export-dialog/export-command.ts +4 -9
- package/src/components/editor/actions/export-dialog/export-dialog.tsx +27 -23
- package/src/components/editor/actions/export-dialog/format-notice.tsx +28 -0
- package/src/components/editor/actions/export-dialog/state.ts +23 -5
- package/src/components/editor/actions/export-dialog/use-export-dialog.ts +7 -15
- package/src/components/editor/actions/useConfigActions.tsx +24 -0
- package/src/components/editor/ai/add-cell-with-ai.tsx +2 -2
- package/src/components/editor/ai/ai-completion-editor.tsx +2 -2
- package/src/components/editor/chrome/panels/outline/__tests__/useActiveOutline.test.ts +26 -0
- package/src/components/editor/code/__tests__/readonly-python-code.test.tsx +114 -2
- package/src/components/editor/connections/storage/__tests__/__snapshots__/as-code.test.ts.snap +14 -0
- package/src/components/editor/connections/storage/__tests__/as-code.test.ts +20 -0
- package/src/components/editor/connections/storage/add-storage-form.tsx +10 -0
- package/src/components/editor/connections/storage/as-code.ts +19 -1
- package/src/components/editor/connections/storage/schemas.ts +19 -0
- package/src/components/storage/__tests__/storage-snippets.test.ts +88 -0
- package/src/components/storage/components.tsx +2 -0
- package/src/components/storage/storage-snippets.ts +58 -0
- package/src/core/__tests__/mode.test.ts +85 -0
- package/src/core/ai/constants.ts +7 -0
- package/src/core/ai/staged-cells.ts +3 -0
- package/src/core/codemirror/__tests__/setup.test.ts +1 -1
- package/src/core/codemirror/cm.ts +2 -2
- package/src/core/codemirror/code-lens/__tests__/extension.test.ts +4 -5
- package/src/core/codemirror/code-lens/extension.ts +3 -3
- package/src/core/codemirror/find-replace/search-highlight.ts +8 -3
- package/src/core/codemirror/language/languages/sql/__tests__/renderers.test.tsx +44 -0
- package/src/core/codemirror/language/languages/sql/renderers.tsx +3 -3
- package/src/core/codemirror/theme/__tests__/light.test.ts +59 -123
- package/src/core/codemirror/theme/dark.ts +6 -5
- package/src/core/codemirror/theme/light.ts +6 -4
- package/src/core/config/__tests__/config-schema.test.ts +2 -0
- package/src/core/config/config-schema.ts +1 -0
- package/src/core/config/feature-flag.tsx +0 -2
- package/src/core/dom/outline.ts +25 -2
- package/src/core/hotkeys/hotkeys.ts +2 -0
- package/src/core/mode.ts +11 -9
- package/src/core/network/__tests__/api.test.ts +132 -17
- package/src/core/network/__tests__/export-filename.test.ts +43 -0
- package/src/core/network/__tests__/requests-lazy.test.ts +1 -0
- package/src/core/network/api.ts +47 -12
- package/src/core/network/export-filename.ts +37 -0
- package/src/core/network/markdown-export.ts +19 -0
- package/src/core/network/requests-network.ts +29 -5
- package/src/core/network/types.ts +3 -0
- package/src/core/storage/types.ts +1 -0
- package/src/css/app/codemirror.css +11 -7
- package/src/css/globals.css +8 -0
- package/src/plugins/impl/DataEditorPlugin.tsx +2 -9
- package/src/plugins/impl/__tests__/DataEditorPlugin.test.ts +18 -0
- package/src/plugins/impl/chat/chat-ui.tsx +51 -3
- package/src/plugins/impl/data-frames/__tests__/schema.test.ts +30 -0
- package/src/plugins/impl/data-frames/schema.ts +4 -1
- package/src/plugins/impl/image-comparison/ImageComparisonComponent.tsx +20 -1
- package/src/plugins/impl/image-comparison/__tests__/ImageComparisonComponent.test.tsx +58 -0
- package/src/stories/theme.stories.tsx +71 -1
- package/dist/assets/ImageComparisonComponent-COvcNAUu.js +0 -1
- package/dist/assets/add-cell-with-ai-BU5EDuHt.js +0 -107
- package/dist/assets/ai-model-dropdown-CLCa-gsg.js +0 -5
- package/dist/assets/cells-BVzo2MHf.css +0 -2
- package/dist/assets/chat-display-7CzBSZRm.js +0 -1
- package/dist/assets/chat-panel-Dd5WiR1a.js +0 -4
- package/dist/assets/chat-ui-CYqqqoSC.js +0 -4
- package/dist/assets/command-palette-BBlSC8AZ.js +0 -1
- package/dist/assets/components-K_Mi0vdC.js +0 -1
- package/dist/assets/config-DAL-jiRM.js +0 -1
- package/dist/assets/defaultLocale-DOVIEEPN.js +0 -1
- package/dist/assets/dist-B99-E4qp.js +0 -1
- package/dist/assets/dist-Bfm9U3vp.js +0 -1
- package/dist/assets/dist-BiwuSVkx.js +0 -1
- package/dist/assets/dist-BrZjJXDA.js +0 -1
- package/dist/assets/dist-CaZf6AoY.js +0 -1
- package/dist/assets/dist-Cgoy5550.js +0 -1
- package/dist/assets/dist-Csf5i4KY.js +0 -1
- package/dist/assets/dist-D6Iobl3P.js +0 -1
- package/dist/assets/dist-D6WgndTj.js +0 -1
- package/dist/assets/dist-DcXy-1eJ.js +0 -1
- package/dist/assets/dist-DsfPGbgk.js +0 -1
- package/dist/assets/dist-DtbtRAqz.js +0 -1
- package/dist/assets/dist-I3qeQWuP.js +0 -1
- package/dist/assets/dist-aeKlrIMv.js +0 -1
- package/dist/assets/dist-gDi2I7IJ.js +0 -1
- package/dist/assets/dist-miDa4-cz.js +0 -1
- package/dist/assets/dist-nDEBxpL6.js +0 -1
- package/dist/assets/dist-oUL4XFdB.js +0 -1
- package/dist/assets/file-explorer-panel-4h-BKKaM.js +0 -26
- package/dist/assets/house-DS0r7dNZ.js +0 -1
- package/dist/assets/index-BXlfeAku.js +0 -38
- package/dist/assets/index-DYycoCjG.css +0 -2
- package/dist/assets/process-output-Cm_vuKBw.js +0 -1
- package/dist/assets/react-vega-BLc5RhC7.js +0 -188
- package/dist/assets/scratchpad-panel-DJkO5OrI.js +0 -1
- package/dist/assets/switch-CONP-vq2.js +0 -1
- package/dist/assets/tooltip-B7U4xkIN.js +0 -61
- package/dist/assets/useNotebookActions-BHaEvPEM.js +0 -12
- package/dist/assets/useRunCells-kmbsc2R5.js +0 -1
- package/dist/assets/utils-BWBBpCkT.js +0 -1
- package/dist/assets/vega-loader.browser-Dun7Qe4B.js +0 -6
- /package/dist/assets/{bundle.esm-D0TWQ6iT.js → bundle.esm-CvMga-X6.js} +0 -0
- /package/dist/assets/{icons-CIPE8AIY.js → icons-NFYKylj6.js} +0 -0
- /package/dist/assets/{useDeepCompareMemoize-CSMoa-ga.js → useDeepCompareMemoize-BLRnan2Y.js} +0 -0
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
@reference "../globals.css";
|
|
2
2
|
|
|
3
3
|
.light .cm-selectionBackground {
|
|
4
|
-
/*
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
/* Keep drawn selections visible when focus moves to find/replace or another editor. */
|
|
5
|
+
background-color: var(
|
|
6
|
+
--cm-selection-background,
|
|
7
|
+
var(--cm-selection-background-light)
|
|
8
|
+
) !important;
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
.dark .cm-selectionBackground {
|
|
11
|
-
background-color:
|
|
12
|
+
background-color: var(
|
|
13
|
+
--cm-selection-background,
|
|
14
|
+
var(--cm-selection-background-dark)
|
|
15
|
+
) !important;
|
|
12
16
|
}
|
|
13
17
|
|
|
14
18
|
.cm-focused.cm-focused {
|
|
@@ -125,7 +129,7 @@
|
|
|
125
129
|
/* -- Codeium -- */
|
|
126
130
|
|
|
127
131
|
.cm-codeium-cycle {
|
|
128
|
-
font-size:
|
|
132
|
+
font-size: 0.5625rem;
|
|
129
133
|
background-color: var(--sky-3);
|
|
130
134
|
padding: 2px;
|
|
131
135
|
border-radius: 2px;
|
|
@@ -133,7 +137,7 @@
|
|
|
133
137
|
}
|
|
134
138
|
|
|
135
139
|
.cm-codeium-cycle-key {
|
|
136
|
-
font-size:
|
|
140
|
+
font-size: 0.5625rem;
|
|
137
141
|
font-family: monospace;
|
|
138
142
|
display: inline-block;
|
|
139
143
|
padding: 2px;
|
package/src/css/globals.css
CHANGED
|
@@ -107,6 +107,14 @@
|
|
|
107
107
|
/* Codemirror editor */
|
|
108
108
|
--cm-background: light-dark(var(--background), #282c34);
|
|
109
109
|
--cm-comment: light-dark(#708090, #6b7280);
|
|
110
|
+
--cm-selection-background-light: #d7d4f0;
|
|
111
|
+
--cm-selection-background-dark: #1177cc80;
|
|
112
|
+
--cm-reactive-reference-color-light: #005f87;
|
|
113
|
+
--cm-reactive-reference-color-dark: #2a7aa5;
|
|
114
|
+
--cm-reactive-reference-border-color: #bad3de;
|
|
115
|
+
--cm-search-match-background-light: #99ff7780;
|
|
116
|
+
--cm-search-match-background-dark: #22bb0070;
|
|
117
|
+
--cm-search-match-selected-background-dark: #6199ff88;
|
|
110
118
|
}
|
|
111
119
|
|
|
112
120
|
.dark,
|
|
@@ -8,10 +8,10 @@ import { LoadingTable } from "@/components/data-table/loading-table";
|
|
|
8
8
|
import { type FieldTypes, toFieldTypes } from "@/components/data-table/types";
|
|
9
9
|
import { Alert, AlertTitle } from "@/components/ui/alert";
|
|
10
10
|
import { DelayMount } from "@/components/utils/delay-mount";
|
|
11
|
-
import { DATA_TYPES } from "@/core/kernel/messages";
|
|
12
11
|
import { useAsyncData } from "@/hooks/useAsyncData";
|
|
13
12
|
import { createPlugin } from "../core/builder";
|
|
14
13
|
import type { Setter } from "../types";
|
|
14
|
+
import { columnToFieldTypesSchema } from "./data-frames/schema";
|
|
15
15
|
import {
|
|
16
16
|
BulkEdit,
|
|
17
17
|
type DataEditorProps,
|
|
@@ -44,14 +44,7 @@ export const DataEditorPlugin = createPlugin<Edits>("marimo-data-editor", {
|
|
|
44
44
|
}),
|
|
45
45
|
label: z.string().nullable(),
|
|
46
46
|
data: z.union([z.string(), z.array(z.object({}).passthrough())]),
|
|
47
|
-
fieldTypes:
|
|
48
|
-
.array(
|
|
49
|
-
z.tuple([
|
|
50
|
-
z.coerce.string(),
|
|
51
|
-
z.tuple([z.enum(DATA_TYPES), z.string()]),
|
|
52
|
-
]),
|
|
53
|
-
)
|
|
54
|
-
.nullish(),
|
|
47
|
+
fieldTypes: columnToFieldTypesSchema.nullish(),
|
|
55
48
|
editableColumns: z.union([z.array(z.string()), z.literal("all")]),
|
|
56
49
|
columnSizingMode: z.enum(["auto", "fit"]).default("auto"), // TODO: Remove this
|
|
57
50
|
}),
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { describe, expect, it } from "vitest";
|
|
4
|
+
import { DataEditorPlugin } from "../DataEditorPlugin";
|
|
5
|
+
|
|
6
|
+
describe("DataEditorPlugin", () => {
|
|
7
|
+
it("normalizes an unrecognized field type", () => {
|
|
8
|
+
const result = DataEditorPlugin.validator.parse({
|
|
9
|
+
initialValue: { edits: [] },
|
|
10
|
+
label: null,
|
|
11
|
+
data: [],
|
|
12
|
+
fieldTypes: [["geom", ["geometry", "geometry"]]],
|
|
13
|
+
editableColumns: "all",
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
expect(result.fieldTypes).toEqual([["geom", ["unknown", "geometry"]]]);
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -26,6 +26,11 @@ import {
|
|
|
26
26
|
} from "lucide-react";
|
|
27
27
|
import React, { useEffect, useRef, useState } from "react";
|
|
28
28
|
import { z } from "zod";
|
|
29
|
+
import {
|
|
30
|
+
describeChatAbortReason,
|
|
31
|
+
getAbortReasonFromChunk,
|
|
32
|
+
resolveChatAbortReason,
|
|
33
|
+
} from "@/components/chat/chat-abort";
|
|
29
34
|
import { renderUIMessage } from "@/components/chat/chat-display";
|
|
30
35
|
import {
|
|
31
36
|
convertToFileUIPart,
|
|
@@ -168,6 +173,12 @@ export const Chatbot: React.FC<Props> = (props) => {
|
|
|
168
173
|
// different message_id are stale (from an aborted-but-not-yet-cancelled run
|
|
169
174
|
// on the kernel) and must be dropped
|
|
170
175
|
const activeRequestIdRef = useRef<string | null>(null);
|
|
176
|
+
const lastAbortReasonRef = useRef<string | null>(null);
|
|
177
|
+
const [abortNotice, setAbortNotice] = useState<string | null>(null);
|
|
178
|
+
const clearAbortState = () => {
|
|
179
|
+
lastAbortReasonRef.current = null;
|
|
180
|
+
setAbortNotice(null);
|
|
181
|
+
};
|
|
171
182
|
|
|
172
183
|
const { data: backendMessages } = useAsyncData(async () => {
|
|
173
184
|
const response = await props.get_chat_history({});
|
|
@@ -231,6 +242,7 @@ export const Chatbot: React.FC<Props> = (props) => {
|
|
|
231
242
|
// Client-generated id used to (a) route chunks back to this stream
|
|
232
243
|
// and (b) ask the kernel to cancel just this run on Stop.
|
|
233
244
|
const requestId = generateUUID();
|
|
245
|
+
clearAbortState();
|
|
234
246
|
|
|
235
247
|
const stream = new ReadableStream<UIMessageChunk>({
|
|
236
248
|
start(controller) {
|
|
@@ -297,15 +309,30 @@ export const Chatbot: React.FC<Props> = (props) => {
|
|
|
297
309
|
},
|
|
298
310
|
}),
|
|
299
311
|
messages: initialMessages,
|
|
300
|
-
onFinish: (
|
|
312
|
+
onFinish: ({ messages, isAbort, finishReason }) => {
|
|
301
313
|
setFiles(undefined);
|
|
302
314
|
|
|
303
315
|
if (fileInputRef.current) {
|
|
304
316
|
fileInputRef.current.value = "";
|
|
305
317
|
}
|
|
306
|
-
Logger.debug("Finished streaming message:",
|
|
318
|
+
Logger.debug("Finished streaming message:", { finishReason, isAbort });
|
|
319
|
+
|
|
320
|
+
if (isAbort) {
|
|
321
|
+
const reason = resolveChatAbortReason({
|
|
322
|
+
isAbort: true,
|
|
323
|
+
streamReason: lastAbortReasonRef.current,
|
|
324
|
+
});
|
|
325
|
+
clearAbortState();
|
|
326
|
+
if (reason != null) {
|
|
327
|
+
const description = describeChatAbortReason(reason);
|
|
328
|
+
Logger.debug("Chat stream aborted", { reason, finishReason });
|
|
329
|
+
setAbortNotice(description);
|
|
330
|
+
}
|
|
331
|
+
} else {
|
|
332
|
+
clearAbortState();
|
|
333
|
+
}
|
|
307
334
|
|
|
308
|
-
props.setValue(
|
|
335
|
+
props.setValue(messages);
|
|
309
336
|
},
|
|
310
337
|
onError: (error) => {
|
|
311
338
|
Logger.error("An error occurred:", error);
|
|
@@ -323,6 +350,17 @@ export const Chatbot: React.FC<Props> = (props) => {
|
|
|
323
350
|
if (!parsedMessage.success) {
|
|
324
351
|
return;
|
|
325
352
|
}
|
|
353
|
+
// Only record abort reasons for the active request. Late chunks from a
|
|
354
|
+
// cancelled run must not overwrite the next turn's reason
|
|
355
|
+
if (
|
|
356
|
+
parsedMessage.data.content &&
|
|
357
|
+
parsedMessage.data.message_id === activeRequestIdRef.current
|
|
358
|
+
) {
|
|
359
|
+
const abortReason = getAbortReasonFromChunk(parsedMessage.data.content);
|
|
360
|
+
if (abortReason !== undefined) {
|
|
361
|
+
lastAbortReasonRef.current = abortReason;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
326
364
|
routeIncomingChatChunk(parsedMessage.data, {
|
|
327
365
|
controllerRef: frontendStreamControllerRef,
|
|
328
366
|
activeRequestIdRef,
|
|
@@ -340,6 +378,9 @@ export const Chatbot: React.FC<Props> = (props) => {
|
|
|
340
378
|
setMessages(newMessages);
|
|
341
379
|
|
|
342
380
|
props.setValue(newMessages);
|
|
381
|
+
if (newMessages.length === 0) {
|
|
382
|
+
clearAbortState();
|
|
383
|
+
}
|
|
343
384
|
}
|
|
344
385
|
};
|
|
345
386
|
|
|
@@ -389,6 +430,7 @@ export const Chatbot: React.FC<Props> = (props) => {
|
|
|
389
430
|
props.setValue([]);
|
|
390
431
|
props.delete_chat_history({});
|
|
391
432
|
clearError();
|
|
433
|
+
clearAbortState();
|
|
392
434
|
};
|
|
393
435
|
|
|
394
436
|
return (
|
|
@@ -483,6 +525,12 @@ export const Chatbot: React.FC<Props> = (props) => {
|
|
|
483
525
|
</Button>
|
|
484
526
|
</div>
|
|
485
527
|
)}
|
|
528
|
+
|
|
529
|
+
{abortNotice && !isLoading && !error && (
|
|
530
|
+
<div className="flex justify-center py-2">
|
|
531
|
+
<span className="text-xs text-muted-foreground">{abortNotice}</span>
|
|
532
|
+
</div>
|
|
533
|
+
)}
|
|
486
534
|
</div>
|
|
487
535
|
<form
|
|
488
536
|
onSubmit={async (evt) => {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { describe, expect, it } from "vitest";
|
|
4
|
+
import { columnToFieldTypesSchema } from "../schema";
|
|
5
|
+
|
|
6
|
+
describe("columnToFieldTypesSchema", () => {
|
|
7
|
+
it("keeps known field types", () => {
|
|
8
|
+
const result = columnToFieldTypesSchema.parse([
|
|
9
|
+
["count", ["integer", "int64"]],
|
|
10
|
+
["label", ["string", "object"]],
|
|
11
|
+
]);
|
|
12
|
+
|
|
13
|
+
expect(result).toEqual([
|
|
14
|
+
["count", ["integer", "int64"]],
|
|
15
|
+
["label", ["string", "object"]],
|
|
16
|
+
]);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("normalizes an unrecognized field type without discarding other fields", () => {
|
|
20
|
+
const result = columnToFieldTypesSchema.parse([
|
|
21
|
+
["geom", ["geometry", "geometry"]],
|
|
22
|
+
["label", ["string", "object"]],
|
|
23
|
+
]);
|
|
24
|
+
|
|
25
|
+
expect(result).toEqual([
|
|
26
|
+
["geom", ["unknown", "geometry"]],
|
|
27
|
+
["label", ["string", "object"]],
|
|
28
|
+
]);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
@@ -15,7 +15,10 @@ import {
|
|
|
15
15
|
} from "./utils/operators";
|
|
16
16
|
|
|
17
17
|
export const columnToFieldTypesSchema = z.array(
|
|
18
|
-
z.tuple([
|
|
18
|
+
z.tuple([
|
|
19
|
+
z.coerce.string(),
|
|
20
|
+
z.tuple([z.enum(DATA_TYPES).catch("unknown"), z.string()]),
|
|
21
|
+
]),
|
|
19
22
|
);
|
|
20
23
|
|
|
21
24
|
export const column_id = z
|
|
@@ -49,6 +49,18 @@ const ImageComparisonComponent: React.FC<ImageComparisonData> = ({
|
|
|
49
49
|
minHeight: "2rem",
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
+
// The slider's width="100%" images resolve against its shadow-DOM wrappers (circular),
|
|
53
|
+
// so size the images explicitly and letterbox with object-fit to keep them aligned.
|
|
54
|
+
// Treat empty strings as "not provided" (normalize_dimension passes them through).
|
|
55
|
+
const imageStyle: React.CSSProperties | undefined =
|
|
56
|
+
width || height
|
|
57
|
+
? {
|
|
58
|
+
width: width || undefined,
|
|
59
|
+
height: height || undefined,
|
|
60
|
+
objectFit: "contain",
|
|
61
|
+
}
|
|
62
|
+
: undefined;
|
|
63
|
+
|
|
52
64
|
// If an image fails to load, the slider collapses to nothing; surface a
|
|
53
65
|
// visible error instead of silently rendering an empty output.
|
|
54
66
|
if (failedSrcs.size > 0) {
|
|
@@ -67,12 +79,18 @@ const ImageComparisonComponent: React.FC<ImageComparisonData> = ({
|
|
|
67
79
|
|
|
68
80
|
return (
|
|
69
81
|
<div style={containerStyle}>
|
|
70
|
-
<ImgComparisonSlider
|
|
82
|
+
<ImgComparisonSlider
|
|
83
|
+
value={value}
|
|
84
|
+
direction={direction}
|
|
85
|
+
// inline-block leaves a baseline gap below the slider; align to top.
|
|
86
|
+
style={{ verticalAlign: "top" }}
|
|
87
|
+
>
|
|
71
88
|
<img
|
|
72
89
|
slot="first"
|
|
73
90
|
src={beforeSrc}
|
|
74
91
|
alt="Before"
|
|
75
92
|
width="100%"
|
|
93
|
+
style={imageStyle}
|
|
76
94
|
onError={() => handleError(beforeSrc)}
|
|
77
95
|
/>
|
|
78
96
|
<img
|
|
@@ -80,6 +98,7 @@ const ImageComparisonComponent: React.FC<ImageComparisonData> = ({
|
|
|
80
98
|
src={afterSrc}
|
|
81
99
|
alt="After"
|
|
82
100
|
width="100%"
|
|
101
|
+
style={imageStyle}
|
|
83
102
|
onError={() => handleError(afterSrc)}
|
|
84
103
|
/>
|
|
85
104
|
</ImgComparisonSlider>
|
|
@@ -68,4 +68,62 @@ describe("ImageComparisonComponent", () => {
|
|
|
68
68
|
expect(error?.textContent).toContain("…");
|
|
69
69
|
expect(error?.textContent).not.toContain("A".repeat(200));
|
|
70
70
|
});
|
|
71
|
+
|
|
72
|
+
it("sizes both images explicitly when dimensions are given", () => {
|
|
73
|
+
const { getAllByAltText } = render(
|
|
74
|
+
<ImageComparisonComponent {...baseProps} width="300px" height="300px" />,
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
for (const img of getAllByAltText(/Before|After/)) {
|
|
78
|
+
expect((img as HTMLElement).style.width).toBe("300px");
|
|
79
|
+
expect((img as HTMLElement).style.height).toBe("300px");
|
|
80
|
+
// Letterbox identically so the slider's clip stays aligned.
|
|
81
|
+
expect((img as HTMLElement).style.objectFit).toBe("contain");
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("applies a single dimension to both images when only one is given", () => {
|
|
86
|
+
const { getAllByAltText } = render(
|
|
87
|
+
<ImageComparisonComponent {...baseProps} width="300px" />,
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
for (const img of getAllByAltText(/Before|After/)) {
|
|
91
|
+
expect((img as HTMLElement).style.width).toBe("300px");
|
|
92
|
+
expect((img as HTMLElement).style.objectFit).toBe("contain");
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it("applies height-only sizing to both images", () => {
|
|
97
|
+
const { getAllByAltText } = render(
|
|
98
|
+
<ImageComparisonComponent {...baseProps} height="300px" />,
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
for (const img of getAllByAltText(/Before|After/)) {
|
|
102
|
+
expect((img as HTMLElement).style.height).toBe("300px");
|
|
103
|
+
expect((img as HTMLElement).style.objectFit).toBe("contain");
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it("treats empty-string dimensions as not provided", () => {
|
|
108
|
+
const { getAllByAltText } = render(
|
|
109
|
+
<ImageComparisonComponent {...baseProps} width="" height="" />,
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
for (const img of getAllByAltText(/Before|After/)) {
|
|
113
|
+
expect((img as HTMLElement).style.width).toBe("");
|
|
114
|
+
expect((img as HTMLElement).style.height).toBe("");
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("leaves images unstyled when no dimensions are given", () => {
|
|
119
|
+
const { getAllByAltText } = render(
|
|
120
|
+
<ImageComparisonComponent {...baseProps} />,
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
for (const img of getAllByAltText(/Before|After/)) {
|
|
124
|
+
// No explicit sizing: the slider keeps its intrinsic-size behavior.
|
|
125
|
+
expect((img as HTMLElement).style.width).toBe("");
|
|
126
|
+
expect((img as HTMLElement).style.height).toBe("");
|
|
127
|
+
}
|
|
128
|
+
});
|
|
71
129
|
});
|
|
@@ -4,11 +4,14 @@ import { python } from "@codemirror/lang-python";
|
|
|
4
4
|
import { EditorState, type Extension } from "@codemirror/state";
|
|
5
5
|
import { EditorView } from "@codemirror/view";
|
|
6
6
|
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
7
|
-
import React, { useEffect, useRef } from "react";
|
|
7
|
+
import React, { useEffect, useRef, useState } from "react";
|
|
8
|
+
import { ReadonlyCode } from "../components/editor/code/readonly-python-code";
|
|
8
9
|
import { basicBundle, type CodeMirrorSetupOpts } from "../core/codemirror/cm";
|
|
10
|
+
import { userConfigAtom } from "../core/config/config";
|
|
9
11
|
import { darkTheme } from "../core/codemirror/theme/dark";
|
|
10
12
|
import { lightTheme } from "../core/codemirror/theme/light";
|
|
11
13
|
import { OverridingHotkeyProvider } from "../core/hotkeys/hotkeys";
|
|
14
|
+
import { store } from "../core/state/jotai";
|
|
12
15
|
|
|
13
16
|
// Partial config for storybook demo
|
|
14
17
|
const demoConfig: Partial<CodeMirrorSetupOpts> = {
|
|
@@ -52,6 +55,11 @@ result = example.get_value()
|
|
|
52
55
|
size = example.data_size
|
|
53
56
|
`.trim();
|
|
54
57
|
|
|
58
|
+
const READONLY_CONTENT = Array.from(
|
|
59
|
+
{ length: 80 },
|
|
60
|
+
(_, index) => `value_${index + 1} = ${index + 1}`,
|
|
61
|
+
).join("\n");
|
|
62
|
+
|
|
55
63
|
const Editor = (opts: { extensions?: Extension[] }): React.ReactNode => {
|
|
56
64
|
const ref = useRef<HTMLDivElement>(null);
|
|
57
65
|
useEffect(() => {
|
|
@@ -110,3 +118,65 @@ export const ThemeComparison: Story = {
|
|
|
110
118
|
</div>
|
|
111
119
|
),
|
|
112
120
|
};
|
|
121
|
+
|
|
122
|
+
const ReadonlyCodeThemeFixture = (): React.ReactNode => {
|
|
123
|
+
const [theme, setTheme] = useState<"light" | "dark">("light");
|
|
124
|
+
const [initialTheme] = useState(
|
|
125
|
+
() => store.get(userConfigAtom).display.theme,
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
useEffect(() => {
|
|
129
|
+
store.set(userConfigAtom, (config) => ({
|
|
130
|
+
...config,
|
|
131
|
+
display: { ...config.display, theme },
|
|
132
|
+
}));
|
|
133
|
+
}, [theme]);
|
|
134
|
+
|
|
135
|
+
useEffect(() => {
|
|
136
|
+
// Leave Storybook's theme in the state it had before this fixture mounted.
|
|
137
|
+
return () => {
|
|
138
|
+
store.set(userConfigAtom, (config) => ({
|
|
139
|
+
...config,
|
|
140
|
+
display: { ...config.display, theme: initialTheme },
|
|
141
|
+
}));
|
|
142
|
+
};
|
|
143
|
+
}, [initialTheme]);
|
|
144
|
+
|
|
145
|
+
return (
|
|
146
|
+
<div className="max-w-3xl space-y-3" style={{ colorScheme: theme }}>
|
|
147
|
+
<div className="flex items-center justify-between gap-4">
|
|
148
|
+
<div>
|
|
149
|
+
<h3 className="text-lg font-semibold">ReadonlyCode fixture</h3>
|
|
150
|
+
<p className="text-sm text-muted-foreground">
|
|
151
|
+
Select text, scroll, then switch themes to check that both remain.
|
|
152
|
+
</p>
|
|
153
|
+
</div>
|
|
154
|
+
<div className="flex gap-2" role="group" aria-label="Theme">
|
|
155
|
+
{(["light", "dark"] as const).map((nextTheme) => (
|
|
156
|
+
<button
|
|
157
|
+
aria-pressed={theme === nextTheme}
|
|
158
|
+
className="rounded border px-3 py-1 text-sm"
|
|
159
|
+
key={nextTheme}
|
|
160
|
+
onClick={() => setTheme(nextTheme)}
|
|
161
|
+
type="button"
|
|
162
|
+
>
|
|
163
|
+
{nextTheme}
|
|
164
|
+
</button>
|
|
165
|
+
))}
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
168
|
+
<div className="h-64 overflow-hidden rounded border">
|
|
169
|
+
<ReadonlyCode
|
|
170
|
+
className="h-full [&_.cm-editor]:h-full [&_.cm-scroller]:h-full [&_.cm-theme-none]:h-full"
|
|
171
|
+
code={READONLY_CONTENT}
|
|
172
|
+
showCopyCode={false}
|
|
173
|
+
showHideCode={false}
|
|
174
|
+
/>
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
177
|
+
);
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
export const ReadonlyCodeThemeReconfiguration: Story = {
|
|
181
|
+
render: () => <ReadonlyCodeThemeFixture />,
|
|
182
|
+
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as A,t as C}from"./chunk-LvLJmgfZ.js";import{t as H}from"./react-Bj1aDYRI.js";import{t as j}from"./compiler-runtime-B3qBwwSJ.js";import{t as _}from"./jsx-runtime-Blw4afVn.js";var B=C((()=>{(()=>{var c={792:(o,a,i)=>{i.d(a,{Z:()=>h});var n=i(609),l=i.n(n)()((function(p){return p[1]}));l.push([o.id,':host{--divider-width: 1px;--divider-color: #fff;--divider-shadow: none;--default-handle-width: 50px;--default-handle-color: #fff;--default-handle-opacity: 1;--default-handle-shadow: none;--handle-position-start: 50%;position:relative;display:inline-block;overflow:hidden;line-height:0;direction:ltr}@media screen and (-webkit-min-device-pixel-ratio: 0)and (min-resolution: 0.001dpcm){:host{outline-offset:1px}}:host(:focus){outline:2px solid -webkit-focus-ring-color}::slotted(*){-webkit-user-drag:none;-khtml-user-drag:none;-moz-user-drag:none;-o-user-drag:none;user-drag:none;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.first{position:absolute;left:0;top:0;right:0;line-height:normal;font-size:100%;max-height:100%;height:100%;width:100%;--exposure: 50%;--keyboard-transition-time: 0ms;--default-transition-time: 0ms;--transition-time: var(--default-transition-time)}.first .first-overlay-container{position:relative;clip-path:inset(0 var(--exposure) 0 0);transition:clip-path var(--transition-time);height:100%}.first .first-overlay{overflow:hidden;height:100%}.first.focused{will-change:clip-path}.first.focused .first-overlay-container{will-change:clip-path}.second{position:relative}.handle-container{transform:translateX(50%);position:absolute;top:0;right:var(--exposure);height:100%;transition:right var(--transition-time),bottom var(--transition-time)}.focused .handle-container{will-change:right}.divider{position:absolute;height:100%;width:100%;left:0;top:0;display:flex;align-items:center;justify-content:center;flex-direction:column}.divider:after{content:" ";display:block;height:100%;border-left-width:var(--divider-width);border-left-style:solid;border-left-color:var(--divider-color);box-shadow:var(--divider-shadow)}.handle{position:absolute;top:var(--handle-position-start);pointer-events:none;box-sizing:border-box;margin-left:1px;transform:translate(calc(-50% - 0.5px), -50%);line-height:0}.default-handle{width:var(--default-handle-width);opacity:var(--default-handle-opacity);transition:all 1s;filter:drop-shadow(var(--default-handle-shadow))}.default-handle path{stroke:var(--default-handle-color)}.vertical .first-overlay-container{clip-path:inset(0 0 var(--exposure) 0)}.vertical .handle-container{transform:translateY(50%);height:auto;top:unset;bottom:var(--exposure);width:100%;left:0;flex-direction:row}.vertical .divider:after{height:1px;width:100%;border-top-width:var(--divider-width);border-top-style:solid;border-top-color:var(--divider-color);border-left:0}.vertical .handle{top:auto;left:var(--handle-position-start);transform:translate(calc(-50% - 0.5px), -50%) rotate(90deg)}',""]);let h=l},609:o=>{o.exports=function(a){var i=[];return i.toString=function(){return this.map((function(n){var l=a(n);return n[2]?`@media ${n[2]} {${l}}`:l})).join("")},i.i=function(n,l,h){typeof n=="string"&&(n=[[null,n,""]]);var p={};if(h)for(var f=0;f<this.length;f++){var v=this[f][0];v!=null&&(p[v]=!0)}for(var e=0;e<n.length;e++){var r=[].concat(n[e]);h&&p[r[0]]||(l&&(r[2]?r[2]=`${l} and ${r[2]}`:r[2]=l),i.push(r))}},i}}},t={};function u(o){var a=t[o];if(a!==void 0)return a.exports;var i=t[o]={id:o,exports:{}};return c[o](i,i.exports,u),i.exports}u.n=o=>{var a=o&&o.__esModule?()=>o.default:()=>o;return u.d(a,{a}),a},u.d=(o,a)=>{for(var i in a)u.o(a,i)&&!u.o(o,i)&&Object.defineProperty(o,i,{enumerable:!0,get:a[i]})},u.o=(o,a)=>Object.prototype.hasOwnProperty.call(o,a),(()=>{var o=u(792);let a="rendered",i=(e,r)=>{let s=e.getBoundingClientRect(),d,m;return r.type==="mousedown"?(d=r.clientX,m=r.clientY):(d=r.touches[0].clientX,m=r.touches[0].clientY),d>=s.x&&d<=s.x+s.width&&m>=s.y&&m<=s.y+s.height},n,l={ArrowLeft:-1,ArrowRight:1},h=["horizontal","vertical"],p=e=>({x:e.touches[0].pageX,y:e.touches[0].pageY}),f=e=>({x:e.pageX,y:e.pageY}),v=typeof window<"u"&&(window==null?void 0:window.HTMLElement);typeof window<"u"&&(window.document&&(n=document.createElement("template"),n.innerHTML='<div class="second" id="second"> <slot name="second"><slot name="before"></slot></slot> </div> <div class="first" id="first"> <div class="first-overlay"> <div class="first-overlay-container" id="firstImageContainer"> <slot name="first"><slot name="after"></slot></slot> </div> </div> <div class="handle-container"> <div class="divider"></div> <div class="handle" id="handle"> <slot name="handle"> <svg xmlns="http://www.w3.org/2000/svg" class="default-handle" viewBox="-8 -3 16 6"> <path d="M -5 -2 L -7 0 L -5 2 M 5 -2 L 7 0 L 5 2" fill="none" vector-effect="non-scaling-stroke"/> </svg> </slot> </div> </div> </div> '),window.customElements.define("img-comparison-slider",class extends v{constructor(){super(),this.exposure=this.hasAttribute("value")?parseFloat(this.getAttribute("value")):50,this.slideOnHover=!1,this.slideDirection="horizontal",this.keyboard="enabled",this.isMouseDown=!1,this.animationDirection=0,this.isFocused=!1,this.dragByHandle=!1,this.onMouseMove=s=>{if(this.isMouseDown||this.slideOnHover){let d=f(s);this.slideToPage(d)}},this.bodyUserSelectStyle="",this.bodyWebkitUserSelectStyle="",this.onMouseDown=s=>{if(this.slideOnHover||this.handle&&!i(this.handleElement,s))return;s.preventDefault(),window.addEventListener("mousemove",this.onMouseMove),window.addEventListener("mouseup",this.onWindowMouseUp),this.isMouseDown=!0,this.enableTransition();let d=f(s);this.slideToPage(d),this.focus(),this.bodyUserSelectStyle=window.document.body.style.userSelect,this.bodyWebkitUserSelectStyle=window.document.body.style.webkitUserSelect,window.document.body.style.userSelect="none",window.document.body.style.webkitUserSelect="none"},this.onWindowMouseUp=()=>{this.isMouseDown=!1,window.document.body.style.userSelect=this.bodyUserSelectStyle,window.document.body.style.webkitUserSelect=this.bodyWebkitUserSelectStyle,window.removeEventListener("mousemove",this.onMouseMove),window.removeEventListener("mouseup",this.onWindowMouseUp)},this.touchStartPoint=null,this.isTouchComparing=!1,this.hasTouchMoved=!1,this.onTouchStart=s=>{this.dragByHandle&&!i(this.handleElement,s)||(this.touchStartPoint=p(s),this.isFocused&&(this.enableTransition(),this.slideToPage(this.touchStartPoint)))},this.onTouchMove=s=>{if(this.touchStartPoint===null)return;let d=p(s);if(this.isTouchComparing)return this.slideToPage(d),s.preventDefault(),!1;if(!this.hasTouchMoved){let m=Math.abs(d.y-this.touchStartPoint.y),g=Math.abs(d.x-this.touchStartPoint.x);if(this.slideDirection==="horizontal"&&m<g||this.slideDirection==="vertical"&&m>g)return this.isTouchComparing=!0,this.focus(),this.slideToPage(d),s.preventDefault(),!1;this.hasTouchMoved=!0}},this.onTouchEnd=()=>{this.isTouchComparing=!1,this.hasTouchMoved=!1,this.touchStartPoint=null},this.onBlur=()=>{this.stopSlideAnimation(),this.isFocused=!1,this.firstElement.classList.remove("focused")},this.onFocus=()=>{this.isFocused=!0,this.firstElement.classList.add("focused")},this.onKeyDown=s=>{if(this.keyboard==="disabled")return;let d=l[s.key];this.animationDirection!==d&&d!==void 0&&(this.animationDirection=d,this.startSlideAnimation())},this.onKeyUp=s=>{if(this.keyboard==="disabled")return;let d=l[s.key];d!==void 0&&this.animationDirection===d&&this.stopSlideAnimation()},this.resetDimensions=()=>{this.imageWidth=this.offsetWidth,this.imageHeight=this.offsetHeight};let e=this.attachShadow({mode:"open"}),r=document.createElement("style");r.innerHTML=o.Z,this.getAttribute("nonce")&&r.setAttribute("nonce",this.getAttribute("nonce")),e.appendChild(r),e.appendChild(n.content.cloneNode(!0)),this.firstElement=e.getElementById("first"),this.handleElement=e.getElementById("handle")}set handle(e){this.dragByHandle=e.toString().toLowerCase()!=="false"}get handle(){return this.dragByHandle}get value(){return this.exposure}set value(e){let r=parseFloat(e);r!==this.exposure&&(this.exposure=r,this.enableTransition(),this.setExposure())}get hover(){return this.slideOnHover}set hover(e){this.slideOnHover=e.toString().toLowerCase()!=="false",this.removeEventListener("mousemove",this.onMouseMove),this.slideOnHover&&this.addEventListener("mousemove",this.onMouseMove)}get direction(){return this.slideDirection}set direction(e){this.slideDirection=e.toString().toLowerCase(),this.slide(0),this.firstElement.classList.remove(...h),h.includes(this.slideDirection)&&this.firstElement.classList.add(this.slideDirection)}static get observedAttributes(){return["hover","direction"]}connectedCallback(){this.hasAttribute("tabindex")||(this.tabIndex=0),this.addEventListener("dragstart",(e=>(e.preventDefault(),!1))),new ResizeObserver(this.resetDimensions).observe(this),this.setExposure(0),this.keyboard=this.hasAttribute("keyboard")&&this.getAttribute("keyboard")==="disabled"?"disabled":"enabled",this.addEventListener("keydown",this.onKeyDown),this.addEventListener("keyup",this.onKeyUp),this.addEventListener("focus",this.onFocus),this.addEventListener("blur",this.onBlur),this.addEventListener("touchstart",this.onTouchStart,{passive:!0}),this.addEventListener("touchmove",this.onTouchMove,{passive:!1}),this.addEventListener("touchend",this.onTouchEnd),this.addEventListener("mousedown",this.onMouseDown),this.handle=this.hasAttribute("handle")?this.getAttribute("handle"):this.dragByHandle,this.hover=this.hasAttribute("hover")?this.getAttribute("hover"):this.slideOnHover,this.direction=this.hasAttribute("direction")?this.getAttribute("direction"):this.slideDirection,this.resetDimensions(),this.classList.contains(a)||this.classList.add(a)}disconnectedCallback(){this.transitionTimer&&window.clearTimeout(this.transitionTimer)}attributeChangedCallback(e,r,s){e==="hover"&&(this.hover=s),e==="direction"&&(this.direction=s),e==="keyboard"&&(this.keyboard=s==="disabled"?"disabled":"enabled")}setExposure(e=0){var r;this.exposure=(r=this.exposure+e)<0?0:r>100?100:r,this.firstElement.style.setProperty("--exposure",100-this.exposure+"%")}slide(e=0){this.setExposure(e);let r=new Event("slide");this.dispatchEvent(r)}slideToPage(e){this.slideDirection==="horizontal"&&this.slideToPageX(e.x),this.slideDirection==="vertical"&&this.slideToPageY(e.y)}slideToPageX(e){this.exposure=(e-this.getBoundingClientRect().left-window.scrollX)/this.imageWidth*100,this.slide(0)}slideToPageY(e){this.exposure=(e-this.getBoundingClientRect().top-window.scrollY)/this.imageHeight*100,this.slide(0)}enableTransition(){this.firstElement.style.setProperty("--transition-time","100ms"),this.transitionTimer=window.setTimeout((()=>{this.firstElement.style.setProperty("--transition-time","var(--default-transition-time)"),this.transitionTimer=null}),100)}startSlideAnimation(){let e=null,r=this.animationDirection;this.firstElement.style.setProperty("--transition-time","var(--keyboard-transition-time)");let s=d=>{if(this.animationDirection===0||r!==this.animationDirection)return;e===null&&(e=d);let m=(d-e)/16.666666666666668*this.animationDirection;this.slide(m),setTimeout((()=>window.requestAnimationFrame(s)),0),e=d};window.requestAnimationFrame(s)}stopSlideAnimation(){this.animationDirection=0,this.firstElement.style.setProperty("--transition-time","var(--default-transition-time)")}}))})()})()})),U=C((c=>{var t=c&&c.__createBinding||(Object.create?(function(i,n,l,h){h===void 0&&(h=l),Object.defineProperty(i,h,{enumerable:!0,get:function(){return n[l]}})}):(function(i,n,l,h){h===void 0&&(h=l),i[h]=n[l]})),u=c&&c.__setModuleDefault||(Object.create?(function(i,n){Object.defineProperty(i,"default",{enumerable:!0,value:n})}):function(i,n){i.default=n}),o=c&&c.__importStar||function(i){if(i&&i.__esModule)return i;var n={};if(i!=null)for(var l in i)l!=="default"&&Object.prototype.hasOwnProperty.call(i,l)&&t(n,i,l);return u(n,i),n};Object.defineProperty(c,"__esModule",{value:!0}),c.ImgComparisonSlider=void 0;var a=H();typeof document<"u"&&Promise.resolve().then(()=>o(B())),c.ImgComparisonSlider=(0,a.forwardRef)(({children:i,onSlide:n,value:l,className:h,...p},f)=>{let v=(0,a.useRef)();return(0,a.useEffect)(()=>{l!==void 0&&(v.current.value=parseFloat(l.toString()))},[l,v]),(0,a.useEffect)(()=>{n&&v.current.addEventListener("slide",n)},[]),(0,a.useImperativeHandle)(f,()=>v.current,[v]),(0,a.createElement)("img-comparison-slider",Object.assign({class:h?`${h} rendered`:"rendered",tabIndex:0,ref:v},p),i)})})),F=j(),z=U(),O=A(H(),1),D=A(_(),1);function W(c){return c.length>100?`${c.slice(0,100)}\u2026`:c}var I=c=>{let t=(0,F.c)(34),{beforeSrc:u,afterSrc:o,value:a,direction:i,width:n,height:l}=c,[h,p]=O.useState(X),f;t[0]===Symbol.for("react.memo_cache_sentinel")?(f=()=>{p(new Set)},t[0]=f):f=t[0];let v;t[1]!==o||t[2]!==u?(v=[u,o],t[1]=o,t[2]=u,t[3]=v):v=t[3],O.useEffect(f,v);let e;t[4]===Symbol.for("react.memo_cache_sentinel")?(e=M=>{p(E=>new Set(E).add(M))},t[4]=e):e=t[4];let r=e,s=n||"100%",d=l||(i==="vertical"?"400px":"auto"),m;t[5]!==s||t[6]!==d?(m={width:s,height:d,maxWidth:"100%",minHeight:"2rem"},t[5]=s,t[6]=d,t[7]=m):m=t[7];let g=m;if(h.size>0){let M=h.size>1?"images":"image",E;t[8]===h?E=t[9]:(E=[...h].map(Y),t[8]=h,t[9]=E);let P=E.join(", "),T;t[10]!==M||t[11]!==P?(T=(0,D.jsxs)("span",{children:["Failed to load ",M,":"," ",P]}),t[10]=M,t[11]=P,t[12]=T):T=t[12];let L;return t[13]!==g||t[14]!==T?(L=(0,D.jsx)("div",{style:g,className:"flex items-center justify-center rounded border border-destructive/40 bg-destructive/5 p-3 text-sm text-destructive",children:T}),t[13]=g,t[14]=T,t[15]=L):L=t[15],L}let w;t[16]===u?w=t[17]:(w=()=>r(u),t[16]=u,t[17]=w);let b;t[18]!==u||t[19]!==w?(b=(0,D.jsx)("img",{slot:"first",src:u,alt:"Before",width:"100%",onError:w}),t[18]=u,t[19]=w,t[20]=b):b=t[20];let y;t[21]===o?y=t[22]:(y=()=>r(o),t[21]=o,t[22]=y);let x;t[23]!==o||t[24]!==y?(x=(0,D.jsx)("img",{slot:"second",src:o,alt:"After",width:"100%",onError:y}),t[23]=o,t[24]=y,t[25]=x):x=t[25];let S;t[26]!==i||t[27]!==x||t[28]!==b||t[29]!==a?(S=(0,D.jsxs)(z.ImgComparisonSlider,{value:a,direction:i,children:[b,x]}),t[26]=i,t[27]=x,t[28]=b,t[29]=a,t[30]=S):S=t[30];let k;return t[31]!==g||t[32]!==S?(k=(0,D.jsx)("div",{style:g,children:S}),t[31]=g,t[32]=S,t[33]=k):k=t[33],k};function X(){return new Set}function Y(c){return`"${W(c)}"`}export{I as default};
|