@marimo-team/frontend 0.15.4 → 0.16.0-dev96986
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/ConnectedDataExplorerComponent-CNLoZkWr.js +19 -0
- package/dist/assets/{ImageComparisonComponent-CEXMKKA4.js → ImageComparisonComponent-SX7fDaTK.js} +1 -1
- package/dist/assets/{VegaLite-Bt14Ds9k.js → VegaLite-MJUW3b7C.js} +6 -6
- package/dist/assets/_baseEach-9_logFrf.js +1 -0
- package/dist/assets/_baseMap-NzEbKt5c.js +1 -0
- package/dist/assets/_baseUniq-C5LFcyNC.js +1 -0
- package/dist/assets/_createAggregator-ZRm2b6Zm.js +1 -0
- package/dist/assets/agent-panel-BBd11wNX.js +287 -0
- package/dist/assets/agent-panel-D92Mfy1i.css +1 -0
- package/dist/assets/{any-language-editor-DiwNT6zp.js → any-language-editor-DwAaEQfS.js} +1 -1
- package/dist/assets/architectureDiagram-W76B3OCA-BJmVXUoW.js +36 -0
- package/dist/assets/{between-horizontal-start-FyewyCGn.js → between-horizontal-start-KiwU-a3C.js} +1 -1
- package/dist/assets/{blockDiagram-QIGZ2CNN-BrOkAf_c.js → blockDiagram-QIGZ2CNN-DzxZjE7B.js} +1 -1
- package/dist/assets/{c4Diagram-FPNF74CW-BHPzDxE2.js → c4Diagram-FPNF74CW-DjmldG_J.js} +5 -5
- package/dist/assets/channel-DHcKBVM4.js +1 -0
- package/dist/assets/chat-panel-DgJZr0eS.js +3 -0
- package/dist/assets/{chunk-4BX2VUAB-DLxaCNYh.js → chunk-4BX2VUAB-EUTQThiZ.js} +1 -1
- package/dist/assets/{chunk-55IACEB6-DdzvO3HR.js → chunk-55IACEB6-DZAiDJxy.js} +1 -1
- package/dist/assets/{chunk-FMBD7UC4-R5o-nSiG.js → chunk-FMBD7UC4-Bd0Czs-J.js} +1 -1
- package/dist/assets/{chunk-K7UQS3LO-DxaMrGgG.js → chunk-K7UQS3LO-DEKMIknX.js} +1 -1
- package/dist/assets/{chunk-QN33PNHL-DqS9-FYm.js → chunk-QN33PNHL-E0jwHU_n.js} +1 -1
- package/dist/assets/{chunk-QZHKN3VN-BZ-TzajS.js → chunk-QZHKN3VN-BzaIHJbq.js} +1 -1
- package/dist/assets/{chunk-TVAH2DTR-BsgP2dyv.js → chunk-TVAH2DTR-CZFYvqnm.js} +1 -1
- package/dist/assets/{chunk-TZMSLE5B-D-h3ahXI.js → chunk-TZMSLE5B-BNqnFjtv.js} +1 -1
- package/dist/assets/{circle-play-CQtRZ-rT.js → circle-play-D3J_mYrF.js} +1 -1
- package/dist/assets/classDiagram-KNZD7YFC-D-xwLnlX.js +1 -0
- package/dist/assets/classDiagram-v2-RKCZMP56-D-xwLnlX.js +1 -0
- package/dist/assets/{clear-button-BY6Z_ViL.js → clear-button-ifzRuAR3.js} +1 -1
- package/dist/assets/clone-CSxIll62.js +1 -0
- package/dist/assets/command-palette-D2fdVSET.js +1 -0
- package/dist/assets/common-Ku-cF_2J.js +1 -0
- package/dist/assets/{compile-Ct_jzdKr.js → compile-BgZlHW1c.js} +1 -1
- package/dist/assets/cose-bilkent-S5V4N54A-CVM83SqK.js +1 -0
- package/dist/assets/dagre-5GWH7T2D-ouQPkxT3.js +4 -0
- package/dist/assets/{data-grid-overlay-editor-BN_wulc3.js → data-grid-overlay-editor-B47j5GJJ.js} +1 -1
- package/dist/assets/datasources-panel-Bt41Zir-.js +1 -0
- package/dist/assets/{dependency-graph-panel-BOmSCZf7.js → dependency-graph-panel-CZC_B7pK.js} +4 -4
- package/dist/assets/diagram-N5W7TBWH-CQ817ZdR.js +24 -0
- package/dist/assets/diagram-QEK2KX5R-DOK_psUO.js +43 -0
- package/dist/assets/diagram-S2PKOQOG-CVljmOW8.js +24 -0
- package/dist/assets/{documentation-panel-BxjJO_Gw.js → documentation-panel-C7yIvGg1.js} +1 -1
- package/dist/assets/edit-page-CyTMQV2u.js +129 -0
- package/dist/assets/{ellipsis-vertical-UHbmjI2n.js → ellipsis-vertical-C7FjlUsY.js} +1 -1
- package/dist/assets/{empty-state-BIBXzY_0.js → empty-state-DIOGM_CU.js} +1 -1
- package/dist/assets/{erDiagram-AWTI2OKA-E84mAle_.js → erDiagram-AWTI2OKA-DYu8cEdc.js} +1 -1
- package/dist/assets/{error-panel-MEvQ6K7h.js → error-panel-Ddb8RkFG.js} +1 -1
- package/dist/assets/file-explorer-panel-Oy9DbyFP.js +1 -0
- package/dist/assets/{flowDiagram-PVAE7QVJ-DfbIRSAW.js → flowDiagram-PVAE7QVJ-CmvW5iTb.js} +1 -1
- package/dist/assets/{ganttDiagram-OWAHRB6G-DR4HZ1z_.js → ganttDiagram-OWAHRB6G-BaKQlCaT.js} +4 -4
- package/dist/assets/gitGraphDiagram-NY62KEGX-CWO24eP6.js +65 -0
- package/dist/assets/{glide-data-editor-nNmo1lPq.js → glide-data-editor-CNDLEJ9a.js} +11 -11
- package/dist/assets/graph-BZKTtxsc.js +1 -0
- package/dist/assets/home-page-Bvwppn9N.js +9 -0
- package/dist/assets/{index-VPWqq2Pg.js → index-0XOUPdwT.js} +1 -1
- package/dist/assets/{index-uacyUula.js → index-BH7f3aiU.js} +1 -1
- package/dist/assets/{index-Dt9UWeWn.js → index-BJVyzkx5.js} +1 -1
- package/dist/assets/{index-BAH034Ue.js → index-B_d_JZGI.js} +1 -1
- package/dist/assets/{index-CB2pnVQG.js → index-BgXbBA39.js} +1 -1
- package/dist/assets/{index-B8llrTSo.js → index-Brf2DwUM.js} +1 -1
- package/dist/assets/{index-BLu5CX6z.js → index-CXrWwFX6.js} +1 -1
- package/dist/assets/{index-DyLSuOH1.js → index-CZaurnA9.js} +1 -1
- package/dist/assets/{index-BFSnz7iM.js → index-CerjupfZ.js} +1 -1
- package/dist/assets/{index-B7yXbrLa.js → index-D-tZfElD.js} +1 -1
- package/dist/assets/{index-c6If577Q.js → index-D3PqGupX.js} +1 -1
- package/dist/assets/{index-CSgxTUzD.js → index-DCkzth56.js} +1 -1
- package/dist/assets/{index-DWOaniGT.js → index-DFrGFNW1.js} +1 -1
- package/dist/assets/{index-CPN7TRA1.js → index-DZhOPkOB.js} +1 -1
- package/dist/assets/index-DadI618h.css +1 -0
- package/dist/assets/{index-DqzMPAC8.js → index-DkntzpX4.js} +2 -2
- package/dist/assets/{index-B1_GXGaP.js → index-DmgwT3sx.js} +1 -1
- package/dist/assets/index-PmY0x4Zd.js +578 -0
- package/dist/assets/{index-Bq516OmX.js → index-WXJFkQHg.js} +1 -1
- package/dist/assets/{index-DSU75csX.js → index-qE8lHQ-N.js} +1 -1
- package/dist/assets/{index-DMomwMcN.js → index-zrSUQXha.js} +1 -1
- package/dist/assets/infoDiagram-STP46IZ2-CAuVVehw.js +2 -0
- package/dist/assets/isEmpty-D1t7Gran.js +1 -0
- package/dist/assets/{journeyDiagram-BIP6EPQ6-BBiFyygf.js → journeyDiagram-BIP6EPQ6-D4Rp6H_h.js} +1 -1
- package/dist/assets/{kanban-definition-6OIFK2YF-DhgA6Nt6.js → kanban-definition-6OIFK2YF-DFt9DftA.js} +4 -4
- package/dist/assets/layout-D8WXi2_g.js +1 -0
- package/dist/assets/linear-BwY8e5hA.js +1 -0
- package/dist/assets/links-4B6ldZ5P.js +7 -0
- package/dist/assets/{logs-panel-B9SmTZAW.js → logs-panel-Dxiyt7dO.js} +1 -1
- package/dist/assets/{agent-panel-DpQ6muj-.css → markdown-renderer-ClyzDMmG.css} +1 -1
- package/dist/assets/markdown-renderer-VDu-NBKB.js +263 -0
- package/dist/assets/mermaid-B-O-Puyi.js +1 -0
- package/dist/assets/{mermaid.core-4nVOEVX3.js → mermaid.core-BFFCqfOn.js} +41 -41
- package/dist/assets/min-DtVSfYKl.js +1 -0
- package/dist/assets/{mindmap-definition-Q6HEUPPD-CVLQNn1q.js → mindmap-definition-Q6HEUPPD-kyvIY8Dg.js} +2 -2
- package/dist/assets/{number-overlay-editor-CzRzXLcd.js → number-overlay-editor-GjLB2UK4.js} +1 -1
- package/dist/assets/outline-panel-CMJjOoN7.js +1 -0
- package/dist/assets/packages-panel-nfXB-bKW.js +1 -0
- package/dist/assets/{pieDiagram-ADFJNKIX-C5IQ5DBZ.js → pieDiagram-ADFJNKIX-D8JFQcWR.js} +3 -3
- package/dist/assets/{quadrantDiagram-LMRXKWRM-CFXFnQxx.js → quadrantDiagram-LMRXKWRM-Nf8GzxXG.js} +1 -1
- package/dist/assets/{react-plotly-mzdv02_Y.js → react-plotly-CnW9p7ZA.js} +1 -1
- package/dist/assets/{requirementDiagram-4UW4RH46-D9bPC89T.js → requirementDiagram-4UW4RH46-CCUxF8BZ.js} +1 -1
- package/dist/assets/run-page-Bl4p3AbZ.js +1 -0
- package/dist/assets/sankeyDiagram-GR3RE2ED-Sr8kDwP1.js +10 -0
- package/dist/assets/scratchpad-panel-Ja1Mu-W3.js +1 -0
- package/dist/assets/secrets-panel-B-3fcSyP.js +1 -0
- package/dist/assets/{sequenceDiagram-C3RYC4MD-6N7_hY4k.js → sequenceDiagram-C3RYC4MD-CBJ152Q3.js} +4 -4
- package/dist/assets/{slides-component-DMjQomc3.css → slides-component-C-LoGC1U.css} +1 -1
- package/dist/assets/{slides-component-EcjC8sDK.js → slides-component-DGtsVP5o.js} +1 -1
- package/dist/assets/snippets-panel-ClNnwKBM.js +1 -0
- package/dist/assets/sortBy-D47H6Vyl.js +1 -0
- package/dist/assets/state-B_RCHTH5.js +1 -0
- package/dist/assets/stateDiagram-KXAO66HF-BlBFSAZr.js +1 -0
- package/dist/assets/stateDiagram-v2-UMBNRL4Z-DbA-iToo.js +1 -0
- package/dist/assets/storage-BNcWOH3-.js +26 -0
- package/dist/assets/terminal-CATzv5Hd.js +10 -0
- package/dist/assets/time-CsYqILfB.js +1 -0
- package/dist/assets/{timeline-definition-XQNQX7LJ-BEaynAiY.js → timeline-definition-XQNQX7LJ-CGrhjuAs.js} +1 -1
- package/dist/assets/tracing-DUbJtOyq.js +2 -0
- package/dist/assets/{tracing-panel-BmuHLPrY.js → tracing-panel-DmzqPUtc.js} +2 -2
- package/dist/assets/{trash-UBqfK4mR.js → trash-rxdjLzkf.js} +1 -1
- package/dist/assets/{tree-XiEycetl.js → tree-C2Ul1h1C.js} +1 -1
- package/dist/assets/{treemap-75Q7IDZK-CnuVFbBG.js → treemap-75Q7IDZK-N9hyUpyj.js} +20 -20
- package/dist/assets/{ts-tags-CloPe9IY.js → ts-tags-DxCDHihD.js} +1 -1
- package/dist/assets/variable-panel-BbgupOdG.js +1 -0
- package/dist/assets/{vega-component-DsTH4tuX.js → vega-component-CR_MHOBT.js} +1 -1
- package/dist/assets/worker-fHbtoWvT.js +1 -0
- package/dist/assets/{xychartDiagram-6GGTOJPD-Dcz3O-A3.js → xychartDiagram-6GGTOJPD-jdLZsMb2.js} +1 -1
- package/dist/index.html +2 -2
- package/package.json +10 -5
- package/src/__tests__/mocks.ts +43 -0
- package/src/components/app-config/user-config-form.tsx +78 -1
- package/src/components/chat/acp/__tests__/__snapshots__/prompt.test.ts.snap +116 -65
- package/src/components/chat/acp/__tests__/atoms.test.ts +1 -1
- package/src/components/chat/acp/__tests__/context-utils.test.ts +222 -0
- package/src/components/chat/acp/__tests__/prompt.test.ts +1 -1
- package/src/components/chat/acp/__tests__/state.test.ts +38 -42
- package/src/components/chat/acp/agent-docs.tsx +33 -6
- package/src/components/chat/acp/agent-panel.css +0 -18
- package/src/components/chat/acp/agent-panel.tsx +394 -72
- package/src/components/chat/acp/agent-selector.tsx +7 -1
- package/src/components/chat/acp/blocks.tsx +40 -10
- package/src/components/chat/acp/common.tsx +10 -2
- package/src/components/chat/acp/context-utils.ts +127 -0
- package/src/components/chat/acp/prompt.ts +96 -53
- package/src/components/chat/acp/state.ts +1 -1
- package/src/components/chat/acp/types.ts +8 -0
- package/src/components/chat/chat-panel.tsx +28 -89
- package/src/components/chat/chat-utils.ts +127 -1
- package/src/components/chat/markdown-renderer.css +39 -0
- package/src/components/chat/markdown-renderer.tsx +12 -47
- package/src/components/chat/tool-call-accordion.tsx +148 -26
- package/src/components/data-table/SearchBar.tsx +8 -7
- package/src/components/data-table/__tests__/column_formatting.test.ts +50 -35
- package/src/components/data-table/__tests__/data-table.test.tsx +39 -1
- package/src/components/data-table/cell-hover-template/feature.ts +14 -0
- package/src/components/data-table/cell-hover-template/types.ts +11 -0
- package/src/components/data-table/charts/components/form-fields.tsx +41 -37
- package/src/components/data-table/charts/forms/common-chart.tsx +2 -2
- package/src/components/data-table/column-explorer-panel/column-explorer.tsx +5 -2
- package/src/components/data-table/column-formatting/feature.ts +62 -29
- package/src/components/data-table/column-formatting/types.ts +1 -0
- package/src/components/data-table/column-header.tsx +3 -1
- package/src/components/data-table/column-summary/chart-spec-model.tsx +24 -7
- package/src/components/data-table/column-summary/column-summary.tsx +18 -9
- package/src/components/data-table/columns.tsx +42 -18
- package/src/components/data-table/data-table.tsx +10 -2
- package/src/components/data-table/date-popover.tsx +85 -75
- package/src/components/data-table/filter-pills.tsx +14 -9
- package/src/components/data-table/header-items.tsx +5 -1
- package/src/components/data-table/pagination.tsx +20 -13
- package/src/components/data-table/renderers.tsx +28 -0
- package/src/components/data-table/row-viewer-panel/row-viewer.tsx +10 -8
- package/src/components/datasources/column-preview.tsx +6 -2
- package/src/components/datasources/datasources.tsx +8 -12
- package/src/components/editor/Cell.tsx +6 -0
- package/src/components/editor/actions/name-cell-input.tsx +6 -1
- package/src/components/editor/actions/useCellActionButton.tsx +3 -1
- package/src/components/editor/ai/__tests__/completion-utils.test.ts +178 -1
- package/src/components/editor/ai/add-cell-with-ai.tsx +68 -66
- package/src/components/editor/ai/ai-completion-editor.tsx +29 -26
- package/src/components/editor/ai/completion-handlers.tsx +44 -6
- package/src/components/editor/ai/completion-utils.ts +92 -0
- package/src/components/editor/ai/transport/chat-transport.tsx +39 -0
- package/src/components/editor/cell/CellStatus.tsx +23 -20
- package/src/components/editor/cell/CreateCellButton.tsx +3 -4
- package/src/components/editor/cell/StagedAICell.tsx +51 -0
- package/src/components/editor/cell/cell-actions.tsx +2 -1
- package/src/components/editor/cell/code/language-toggle.tsx +3 -4
- package/src/components/editor/chrome/wrapper/footer-items/machine-stats.tsx +39 -28
- package/src/components/editor/controls/notebook-menu-dropdown.tsx +4 -2
- package/src/components/editor/file-tree/requesting-tree.tsx +14 -8
- package/src/components/editor/renderers/CellArray.tsx +3 -4
- package/src/components/editor/renderers/slides-layout/slides-layout.tsx +3 -3
- package/src/components/editor/renderers/slides-layout/types.ts +1 -0
- package/src/components/pages/home-page.tsx +4 -1
- package/src/components/slides/slides-component.tsx +1 -1
- package/src/components/slides/slides.css +6 -0
- package/src/components/terminal/__tests__/state.test.ts +207 -0
- package/src/components/terminal/hooks.ts +41 -0
- package/src/components/terminal/state.ts +75 -0
- package/src/components/terminal/terminal.tsx +334 -13
- package/src/components/terminal/theme.tsx +57 -0
- package/src/components/tracing/tracing-spec.ts +5 -4
- package/src/components/ui/range-slider.tsx +4 -2
- package/src/components/ui/slider.tsx +3 -1
- package/src/components/variables/variables-table.tsx +3 -0
- package/src/core/MarimoApp.tsx +9 -6
- package/src/core/ai/__tests__/staged-cells.test.ts +356 -0
- package/src/core/ai/context/__tests__/registry.test.ts +6 -4
- package/src/core/ai/context/providers/cell-output.ts +3 -2
- package/src/core/ai/context/providers/error.ts +3 -1
- package/src/core/ai/context/providers/file.ts +7 -2
- package/src/core/ai/context/providers/tables.ts +3 -2
- package/src/core/ai/context/providers/variable.ts +6 -4
- package/src/core/ai/staged-cells.ts +208 -0
- package/src/core/cells/cells.ts +1 -1
- package/src/core/cells/logs.ts +1 -1
- package/src/core/codemirror/find-replace/search-highlight.ts +3 -1
- package/src/core/codemirror/language/LanguageAdapters.ts +9 -3
- package/src/core/codemirror/lsp/federated-lsp.ts +1 -1
- package/src/core/codemirror/lsp/notebook-lsp.ts +8 -2
- package/src/core/codemirror/readonly/__tests__/extension.test.ts +1 -1
- package/src/core/codemirror/rtc/loro/awareness.ts +52 -17
- package/src/core/codemirror/rtc/loro/sync.ts +12 -4
- package/src/core/config/config-schema.ts +1 -0
- package/src/core/config/config.ts +4 -0
- package/src/core/hotkeys/hotkeys.ts +8 -4
- package/src/core/i18n/__tests__/locale-provider.test.tsx +176 -0
- package/src/core/i18n/locale-provider.tsx +35 -0
- package/src/core/i18n/with-locale.tsx +12 -0
- package/src/core/islands/components/web-components.tsx +13 -10
- package/src/core/islands/main.ts +2 -2
- package/src/core/kernel/RuntimeState.ts +4 -1
- package/src/core/kernel/messages.ts +8 -12
- package/src/core/network/DeferredRequestRegistry.ts +16 -4
- package/src/core/runtime/runtime.ts +5 -4
- package/src/core/saving/__tests__/filename.test.ts +37 -0
- package/src/core/static/__tests__/download-html.test.ts +43 -1
- package/src/core/wasm/bridge.ts +5 -1
- package/src/core/wasm/store.ts +4 -1
- package/src/core/wasm/worker/message-buffer.ts +3 -2
- package/src/core/websocket/types.ts +22 -16
- package/src/core/websocket/useMarimoWebSocket.tsx +2 -2
- package/src/css/app/Cell.css +11 -0
- package/src/hooks/useFormatting.ts +97 -0
- package/src/hooks/useTimer.ts +8 -5
- package/src/plugins/core/RenderHTML.tsx +36 -2
- package/src/plugins/core/__test__/RenderHTML.test.ts +72 -0
- package/src/plugins/core/registerReactComponent.tsx +44 -10
- package/src/plugins/impl/DataTablePlugin.tsx +4 -0
- package/src/plugins/impl/FileBrowserPlugin.tsx +8 -2
- package/src/plugins/impl/RangeSliderPlugin.tsx +5 -3
- package/src/plugins/impl/SliderPlugin.tsx +3 -1
- package/src/plugins/impl/anywidget/model.ts +16 -5
- package/src/plugins/impl/data-editor/types.ts +7 -5
- package/src/plugins/impl/data-explorer/components/column-summary.tsx +20 -13
- package/src/plugins/impl/panel/utils.ts +6 -4
- package/src/plugins/layout/OutlinePlugin.tsx +69 -0
- package/src/plugins/layout/StatPlugin.tsx +4 -1
- package/src/plugins/plugins.ts +2 -0
- package/src/stories/cell.stories.tsx +1 -1
- package/src/stories/layout/vertical/one-column.stories.tsx +1 -1
- package/src/utils/__tests__/cell-urls.test.ts +29 -0
- package/src/utils/__tests__/dates.test.ts +45 -24
- package/src/utils/__tests__/filenames.test.ts +18 -0
- package/src/utils/__tests__/numbers.test.ts +42 -30
- package/src/utils/__tests__/once.test.ts +187 -0
- package/src/utils/__tests__/path.test.ts +38 -0
- package/src/utils/__tests__/urls.test.ts +56 -1
- package/src/utils/dates.ts +15 -10
- package/src/utils/edit-distance.ts +8 -6
- package/src/utils/errors.ts +9 -0
- package/src/utils/id-tree.tsx +21 -10
- package/src/utils/localStorage.ts +13 -4
- package/src/utils/numbers.ts +11 -11
- package/src/utils/once.ts +32 -0
- package/src/utils/paths.ts +4 -1
- package/src/utils/pluralize.ts +12 -5
- package/src/utils/python-poet/poet.ts +30 -15
- package/src/utils/time.ts +5 -1
- package/dist/assets/ConnectedDataExplorerComponent-Cn5-l2X1.js +0 -19
- package/dist/assets/_baseEach-C1FLm7WW.js +0 -1
- package/dist/assets/_baseMap-DBVArUYD.js +0 -1
- package/dist/assets/_baseUniq-Dk7ZPJ3N.js +0 -1
- package/dist/assets/_createAggregator-Bn38fDd3.js +0 -1
- package/dist/assets/agent-panel-COUYnuIK.js +0 -475
- package/dist/assets/architectureDiagram-W76B3OCA-DBzWQKKu.js +0 -36
- package/dist/assets/channel-CjhbjOv4.js +0 -1
- package/dist/assets/chat-panel-BPXKoTnZ.js +0 -7
- package/dist/assets/chat-panel-Brrs_eeH.css +0 -1
- package/dist/assets/classDiagram-KNZD7YFC-DHs5cFzy.js +0 -1
- package/dist/assets/classDiagram-v2-RKCZMP56-DHs5cFzy.js +0 -1
- package/dist/assets/clone-DM1YNjEn.js +0 -1
- package/dist/assets/command-palette-S0bzQp7v.js +0 -1
- package/dist/assets/common-B8U9k2Ly.js +0 -1
- package/dist/assets/cose-bilkent-S5V4N54A-wz1Sfx7j.js +0 -1
- package/dist/assets/dagre-5GWH7T2D-BfpcVBgq.js +0 -4
- package/dist/assets/datasources-panel-DfuURLJw.js +0 -1
- package/dist/assets/diagram-N5W7TBWH-Bf0oqqQh.js +0 -24
- package/dist/assets/diagram-QEK2KX5R-ZTc3qikh.js +0 -43
- package/dist/assets/diagram-S2PKOQOG-tLScBy7Z.js +0 -24
- package/dist/assets/edit-page-DJ8kJZ9w.js +0 -129
- package/dist/assets/file-explorer-panel-CzNUJ63G.js +0 -1
- package/dist/assets/gitGraphDiagram-NY62KEGX-C1t6QtVa.js +0 -65
- package/dist/assets/graph-CssCVWIq.js +0 -1
- package/dist/assets/home-page-9eW6qida.js +0 -9
- package/dist/assets/index-CknhX2Vy.css +0 -1
- package/dist/assets/index-DcCIe7np.js +0 -28
- package/dist/assets/index-OC46250R.js +0 -570
- package/dist/assets/infoDiagram-STP46IZ2-CwiAoz9f.js +0 -2
- package/dist/assets/layout-DpQrxGW-.js +0 -1
- package/dist/assets/linear-NsreOeBF.js +0 -1
- package/dist/assets/links-CbvGxbsJ.js +0 -7
- package/dist/assets/mermaid-DSt0r6IQ.js +0 -1
- package/dist/assets/min-D259kI3t.js +0 -1
- package/dist/assets/outline-panel-uvsS-YEQ.js +0 -1
- package/dist/assets/packages-panel-xMz9W2hW.js +0 -1
- package/dist/assets/run-page-Bb68qdhQ.js +0 -1
- package/dist/assets/sankeyDiagram-GR3RE2ED-BSJOau8E.js +0 -10
- package/dist/assets/scratchpad-panel-BF4BO-U4.js +0 -1
- package/dist/assets/secrets-panel-CdIX44dQ.js +0 -1
- package/dist/assets/snippets-panel-Dco9h0rb.js +0 -1
- package/dist/assets/sortBy-aLGA-PGK.js +0 -1
- package/dist/assets/stateDiagram-KXAO66HF-Bd68WT3b.js +0 -1
- package/dist/assets/stateDiagram-v2-UMBNRL4Z-BXz_GSwb.js +0 -1
- package/dist/assets/storage-CGlP4lCF.js +0 -26
- package/dist/assets/terminal-CxkHubcu.js +0 -9
- package/dist/assets/time-D2nr1UgQ.js +0 -1
- package/dist/assets/tracing-kTqHxa7q.js +0 -2
- package/dist/assets/variable-panel-noTnH-AQ.js +0 -1
- package/dist/assets/worker-X5rxzQGQ.js +0 -1
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
/* Copyright 2024 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
3
|
import type { ToolUIPart } from "ai";
|
|
4
|
+
import { isEmpty } from "lodash-es";
|
|
4
5
|
import {
|
|
5
6
|
CheckCircleIcon,
|
|
7
|
+
InfoIcon,
|
|
6
8
|
Loader2,
|
|
7
9
|
WrenchIcon,
|
|
8
10
|
XCircleIcon,
|
|
9
11
|
} from "lucide-react";
|
|
10
12
|
import React from "react";
|
|
13
|
+
import { z } from "zod";
|
|
11
14
|
import {
|
|
12
15
|
Accordion,
|
|
13
16
|
AccordionContent,
|
|
@@ -16,12 +19,130 @@ import {
|
|
|
16
19
|
} from "@/components/ui/accordion";
|
|
17
20
|
import { cn } from "@/utils/cn";
|
|
18
21
|
|
|
22
|
+
// Zod schema matching the Python SuccessResult dataclass
|
|
23
|
+
const SuccessResultSchema = z
|
|
24
|
+
.object({
|
|
25
|
+
status: z.string().default("success"),
|
|
26
|
+
auth_required: z.boolean().default(false),
|
|
27
|
+
action_url: z.any(),
|
|
28
|
+
next_steps: z.any(),
|
|
29
|
+
meta: z.any(),
|
|
30
|
+
message: z.string().nullish(),
|
|
31
|
+
})
|
|
32
|
+
.passthrough();
|
|
33
|
+
|
|
34
|
+
type SuccessResult = z.infer<typeof SuccessResultSchema>;
|
|
35
|
+
|
|
36
|
+
const PrettySuccessResult: React.FC<{ data: SuccessResult }> = ({ data }) => {
|
|
37
|
+
const {
|
|
38
|
+
status,
|
|
39
|
+
auth_required,
|
|
40
|
+
action_url: _action_url,
|
|
41
|
+
meta: _meta,
|
|
42
|
+
next_steps: _next_steps,
|
|
43
|
+
message,
|
|
44
|
+
...rest
|
|
45
|
+
} = data;
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<div className="flex flex-col gap-1.5">
|
|
49
|
+
<div className="flex items-center justify-between">
|
|
50
|
+
<h3 className="text-xs font-semibold text-muted-foreground">
|
|
51
|
+
Tool Result
|
|
52
|
+
</h3>
|
|
53
|
+
<div className="flex items-center gap-2">
|
|
54
|
+
<span className="text-xs px-2 py-0.5 bg-[var(--grass-2)] text-[var(--grass-11)] rounded-full font-medium capitalize">
|
|
55
|
+
{status}
|
|
56
|
+
</span>
|
|
57
|
+
{auth_required && (
|
|
58
|
+
<span className="text-xs px-2 py-0.5 bg-[var(--amber-2)] text-[var(--amber-11)] rounded-full">
|
|
59
|
+
Auth Required
|
|
60
|
+
</span>
|
|
61
|
+
)}
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
|
|
65
|
+
{/* Message */}
|
|
66
|
+
{message && (
|
|
67
|
+
<div className="flex items-start gap-2">
|
|
68
|
+
<InfoIcon className="h-3 w-3 text-[var(--blue-11)] mt-0.5 flex-shrink-0" />
|
|
69
|
+
<div className="text-xs text-foreground">{message}</div>
|
|
70
|
+
</div>
|
|
71
|
+
)}
|
|
72
|
+
|
|
73
|
+
{/* Data */}
|
|
74
|
+
{rest && (
|
|
75
|
+
<div className="space-y-3">
|
|
76
|
+
{Object.entries(rest).map(([key, value]) => {
|
|
77
|
+
if (isEmpty(value)) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
return (
|
|
81
|
+
<div key={key} className="space-y-1.5">
|
|
82
|
+
<div className="text-xs font-medium text-muted-foreground capitalize flex items-center gap-2">
|
|
83
|
+
<div className="w-1.5 h-1.5 bg-[var(--blue-9)] rounded-full" />
|
|
84
|
+
{key}
|
|
85
|
+
</div>
|
|
86
|
+
<pre className="bg-[var(--slate-2)] p-2 text-muted-foreground border border-[var(--slate-4)] rounded text-xs overflow-auto scrollbar-thin max-h-64">
|
|
87
|
+
{JSON.stringify(value, null, 2)}
|
|
88
|
+
</pre>
|
|
89
|
+
</div>
|
|
90
|
+
);
|
|
91
|
+
})}
|
|
92
|
+
</div>
|
|
93
|
+
)}
|
|
94
|
+
</div>
|
|
95
|
+
);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const ResultRenderer: React.FC<{ result: unknown }> = ({ result }) => {
|
|
99
|
+
// Try to parse the result with our Zod schema
|
|
100
|
+
const parseResult = SuccessResultSchema.safeParse(result);
|
|
101
|
+
|
|
102
|
+
if (parseResult.success) {
|
|
103
|
+
// If it matches the SuccessResult schema, show the pretty UI
|
|
104
|
+
return <PrettySuccessResult data={parseResult.data} />;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Otherwise, fall back to the current JSON viewer
|
|
108
|
+
return (
|
|
109
|
+
<div className="text-xs font-medium text-muted-foreground mb-1">
|
|
110
|
+
{typeof result === "string" ? result : JSON.stringify(result, null, 2)}
|
|
111
|
+
</div>
|
|
112
|
+
);
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const ToolArgsRenderer: React.FC<{ input: unknown }> = ({ input }) => {
|
|
116
|
+
const hasinput = input && input !== null;
|
|
117
|
+
|
|
118
|
+
if (!hasinput) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const isObject =
|
|
123
|
+
typeof input === "object" &&
|
|
124
|
+
Object.keys(input as Record<string, unknown>).length > 0;
|
|
125
|
+
|
|
126
|
+
return (
|
|
127
|
+
<div className="space-y-2">
|
|
128
|
+
<h3 className="text-xs font-semibold text-muted-foreground">
|
|
129
|
+
Tool Request
|
|
130
|
+
</h3>
|
|
131
|
+
<pre className="bg-[var(--slate-2)] p-2 text-muted-foreground border border-[var(--slate-4)] rounded text-xs overflow-auto scrollbar-thin max-h-64">
|
|
132
|
+
{isObject ? JSON.stringify(input, null, 2) : String(input)}
|
|
133
|
+
</pre>
|
|
134
|
+
</div>
|
|
135
|
+
);
|
|
136
|
+
};
|
|
137
|
+
|
|
19
138
|
interface ToolCallAccordionProps {
|
|
20
139
|
toolName: string;
|
|
21
140
|
result: unknown;
|
|
22
141
|
error?: string;
|
|
23
142
|
index?: number;
|
|
24
143
|
state?: ToolUIPart["state"];
|
|
144
|
+
className?: string;
|
|
145
|
+
input?: unknown;
|
|
25
146
|
}
|
|
26
147
|
|
|
27
148
|
export const ToolCallAccordion: React.FC<ToolCallAccordionProps> = ({
|
|
@@ -30,6 +151,8 @@ export const ToolCallAccordion: React.FC<ToolCallAccordionProps> = ({
|
|
|
30
151
|
error,
|
|
31
152
|
index = 0,
|
|
32
153
|
state,
|
|
154
|
+
className,
|
|
155
|
+
input,
|
|
33
156
|
}) => {
|
|
34
157
|
const hasResult = state === "output-available" && (result || error);
|
|
35
158
|
const status = error ? "error" : hasResult ? "success" : "loading";
|
|
@@ -39,9 +162,9 @@ export const ToolCallAccordion: React.FC<ToolCallAccordionProps> = ({
|
|
|
39
162
|
case "loading":
|
|
40
163
|
return <Loader2 className="h-3 w-3 animate-spin" />;
|
|
41
164
|
case "error":
|
|
42
|
-
return <XCircleIcon className="h-3 w-3 text-
|
|
165
|
+
return <XCircleIcon className="h-3 w-3 text-[var(--red-11)]" />;
|
|
43
166
|
case "success":
|
|
44
|
-
return <CheckCircleIcon className="h-3 w-3 text-
|
|
167
|
+
return <CheckCircleIcon className="h-3 w-3 text-[var(--grass-11)]" />;
|
|
45
168
|
default:
|
|
46
169
|
return <WrenchIcon className="h-3 w-3" />;
|
|
47
170
|
}
|
|
@@ -49,13 +172,13 @@ export const ToolCallAccordion: React.FC<ToolCallAccordionProps> = ({
|
|
|
49
172
|
|
|
50
173
|
const getStatusText = () => {
|
|
51
174
|
if (status === "loading") {
|
|
52
|
-
return "Running
|
|
175
|
+
return "Running";
|
|
53
176
|
}
|
|
54
177
|
if (error) {
|
|
55
|
-
return "Failed
|
|
178
|
+
return "Failed";
|
|
56
179
|
}
|
|
57
180
|
if (hasResult) {
|
|
58
|
-
return "Done
|
|
181
|
+
return "Done";
|
|
59
182
|
}
|
|
60
183
|
return "Tool call";
|
|
61
184
|
};
|
|
@@ -65,46 +188,41 @@ export const ToolCallAccordion: React.FC<ToolCallAccordionProps> = ({
|
|
|
65
188
|
key={`tool-${index}`}
|
|
66
189
|
type="single"
|
|
67
190
|
collapsible={true}
|
|
68
|
-
className="w-full"
|
|
191
|
+
className={cn("w-full", className)}
|
|
69
192
|
>
|
|
70
193
|
<AccordionItem value="tool-call" className="border-0">
|
|
71
194
|
<AccordionTrigger
|
|
72
195
|
className={cn(
|
|
73
|
-
"h-6 text-xs border-border shadow-none! ring-0! bg-muted hover:bg-muted
|
|
74
|
-
status === "error" && "text-
|
|
75
|
-
status === "success" && "text-
|
|
196
|
+
"h-6 text-xs border-border shadow-none! ring-0! bg-muted/60 hover:bg-muted py-0 px-2 gap-1 rounded-sm [&[data-state=open]>svg]:rotate-180 hover:no-underline",
|
|
197
|
+
status === "error" && "text-[var(--red-11)]/80",
|
|
198
|
+
status === "success" && "text-[var(--grass-11)]/80",
|
|
76
199
|
)}
|
|
77
200
|
>
|
|
78
201
|
<span className="flex items-center gap-1">
|
|
79
202
|
{getStatusIcon()}
|
|
80
|
-
{getStatusText()}:
|
|
81
|
-
<code className="font-mono text-xs">
|
|
203
|
+
{getStatusText()}:
|
|
204
|
+
<code className="font-mono text-xs">
|
|
205
|
+
{formatToolName(toolName)}
|
|
206
|
+
</code>
|
|
82
207
|
</span>
|
|
83
208
|
</AccordionTrigger>
|
|
84
|
-
<AccordionContent className="
|
|
209
|
+
<AccordionContent className="py-2 px-2">
|
|
85
210
|
{/* Only show content when tool is complete */}
|
|
86
211
|
{hasResult && (
|
|
87
212
|
<div className="space-y-3">
|
|
213
|
+
<ToolArgsRenderer input={input} />
|
|
88
214
|
{result !== undefined && result !== null && (
|
|
89
|
-
<
|
|
90
|
-
<div className="text-xs font-medium text-muted-foreground mt-2 mb-1">
|
|
91
|
-
Result:
|
|
92
|
-
</div>
|
|
93
|
-
<div className="text-xs font-medium text-muted-foreground mb-1">
|
|
94
|
-
{typeof result === "string"
|
|
95
|
-
? result
|
|
96
|
-
: JSON.stringify(result, null, 2)}
|
|
97
|
-
</div>
|
|
98
|
-
</div>
|
|
215
|
+
<ResultRenderer result={result} />
|
|
99
216
|
)}
|
|
100
217
|
|
|
101
218
|
{/* Error */}
|
|
102
219
|
{error && (
|
|
103
|
-
<div>
|
|
104
|
-
<div className="text-xs font-
|
|
105
|
-
|
|
220
|
+
<div className="bg-[var(--red-2)] border border-[var(--red-6)] rounded-lg p-3">
|
|
221
|
+
<div className="text-xs font-semibold text-[var(--red-11)] mb-2 flex items-center gap-2">
|
|
222
|
+
<div className="w-1.5 h-1.5 bg-[var(--red-9)] rounded-full" />
|
|
223
|
+
Error
|
|
106
224
|
</div>
|
|
107
|
-
<div className="
|
|
225
|
+
<div className="text-sm text-[var(--red-11)] leading-relaxed">
|
|
108
226
|
{error}
|
|
109
227
|
</div>
|
|
110
228
|
</div>
|
|
@@ -116,3 +234,7 @@ export const ToolCallAccordion: React.FC<ToolCallAccordionProps> = ({
|
|
|
116
234
|
</Accordion>
|
|
117
235
|
);
|
|
118
236
|
};
|
|
237
|
+
|
|
238
|
+
function formatToolName(toolName: string) {
|
|
239
|
+
return toolName.replace("tool-", "");
|
|
240
|
+
}
|
|
@@ -31,13 +31,14 @@ export const SearchBar = ({
|
|
|
31
31
|
onSearch(debouncedSearch);
|
|
32
32
|
}, [debouncedSearch, onSearch]);
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
34
|
+
if (!hidden) {
|
|
35
|
+
ref.current?.focus();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Reset internal value when hidden becomes true
|
|
39
|
+
if (hidden && internalValue !== "") {
|
|
40
|
+
setInternalValue("");
|
|
41
|
+
}
|
|
41
42
|
|
|
42
43
|
return (
|
|
43
44
|
<div
|
|
@@ -6,37 +6,44 @@ import {
|
|
|
6
6
|
} from "@/utils/numbers";
|
|
7
7
|
import { applyFormat } from "../column-formatting/feature";
|
|
8
8
|
|
|
9
|
+
const locale = "en-US";
|
|
10
|
+
|
|
9
11
|
describe("applyFormat", () => {
|
|
10
12
|
it("should return an empty string for null, undefined, or empty string values", () => {
|
|
11
|
-
expect(
|
|
12
|
-
|
|
13
|
+
expect(
|
|
14
|
+
applyFormat(null, { format: "Date", dataType: "date", locale }),
|
|
15
|
+
).toBe("");
|
|
16
|
+
expect(
|
|
17
|
+
applyFormat(undefined, { format: "Date", dataType: "date", locale }),
|
|
18
|
+
).toBe("");
|
|
19
|
+
expect(applyFormat("", { format: "Date", dataType: "date", locale })).toBe(
|
|
13
20
|
"",
|
|
14
21
|
);
|
|
15
|
-
expect(applyFormat("", { format: "Date", dataType: "date" })).toBe("");
|
|
16
22
|
});
|
|
17
23
|
|
|
18
24
|
describe("date formatting", () => {
|
|
19
25
|
it("should format date values correctly", () => {
|
|
20
26
|
const date = "2023-10-01T12:00:00Z";
|
|
21
|
-
expect(
|
|
22
|
-
"
|
|
23
|
-
);
|
|
24
|
-
expect(
|
|
25
|
-
"
|
|
26
|
-
);
|
|
27
|
+
expect(
|
|
28
|
+
applyFormat(date, { format: "Date", dataType: "date", locale }),
|
|
29
|
+
).toBe("10/1/23");
|
|
30
|
+
expect(
|
|
31
|
+
applyFormat(date, { format: "Datetime", dataType: "date", locale }),
|
|
32
|
+
).toBe("10/1/23, 12:00:00 PM UTC");
|
|
27
33
|
});
|
|
28
34
|
|
|
29
35
|
it("should format time values correctly", () => {
|
|
30
36
|
const time = "12:00:00Z";
|
|
31
|
-
expect(
|
|
32
|
-
"
|
|
33
|
-
);
|
|
37
|
+
expect(
|
|
38
|
+
applyFormat(time, { format: "Time", dataType: "time", locale }),
|
|
39
|
+
).toBe("12:00:00Z");
|
|
34
40
|
});
|
|
35
41
|
|
|
36
42
|
it("should format datetime values correctly", () => {
|
|
37
43
|
const datetime = "2023-10-01T12:00:00Z";
|
|
38
44
|
expect(
|
|
39
45
|
applyFormat(datetime, {
|
|
46
|
+
locale,
|
|
40
47
|
format: "Datetime",
|
|
41
48
|
dataType: "datetime",
|
|
42
49
|
}),
|
|
@@ -47,26 +54,28 @@ describe("applyFormat", () => {
|
|
|
47
54
|
describe("number formatting", () => {
|
|
48
55
|
it("should format number values correctly", () => {
|
|
49
56
|
const number = "1234.567";
|
|
50
|
-
expect(applyFormat(number, { format: "Auto", dataType: "number" })).toBe(
|
|
51
|
-
"1,234.57",
|
|
52
|
-
);
|
|
53
57
|
expect(
|
|
54
|
-
applyFormat(number, { format: "
|
|
58
|
+
applyFormat(number, { format: "Auto", dataType: "number", locale }),
|
|
59
|
+
).toBe("1,234.57");
|
|
60
|
+
expect(
|
|
61
|
+
applyFormat(number, { format: "Percent", dataType: "number", locale }),
|
|
55
62
|
).toBe("123,456.7%");
|
|
56
63
|
expect(
|
|
57
64
|
applyFormat(number, {
|
|
65
|
+
locale,
|
|
58
66
|
format: "Scientific",
|
|
59
67
|
dataType: "number",
|
|
60
68
|
}),
|
|
61
|
-
).toBe(prettyScientificNumber(1234.567, { shouldRound: true }));
|
|
69
|
+
).toBe(prettyScientificNumber(1234.567, { shouldRound: true, locale }));
|
|
62
70
|
expect(
|
|
63
71
|
applyFormat(number, {
|
|
64
72
|
format: "Engineering",
|
|
65
73
|
dataType: "number",
|
|
74
|
+
locale,
|
|
66
75
|
}),
|
|
67
|
-
).toBe(prettyEngineeringNumber(1234.567));
|
|
76
|
+
).toBe(prettyEngineeringNumber(1234.567, locale));
|
|
68
77
|
expect(
|
|
69
|
-
applyFormat(number, { format: "Integer", dataType: "number" }),
|
|
78
|
+
applyFormat(number, { format: "Integer", dataType: "number", locale }),
|
|
70
79
|
).toBe("1,235");
|
|
71
80
|
});
|
|
72
81
|
});
|
|
@@ -75,41 +84,47 @@ describe("applyFormat", () => {
|
|
|
75
84
|
it("should format string values correctly", () => {
|
|
76
85
|
const str = "hello world";
|
|
77
86
|
expect(
|
|
78
|
-
applyFormat(str, { format: "Uppercase", dataType: "string" }),
|
|
87
|
+
applyFormat(str, { format: "Uppercase", dataType: "string", locale }),
|
|
79
88
|
).toBe("HELLO WORLD");
|
|
80
89
|
expect(
|
|
81
|
-
applyFormat(str, { format: "Lowercase", dataType: "string" }),
|
|
90
|
+
applyFormat(str, { format: "Lowercase", dataType: "string", locale }),
|
|
82
91
|
).toBe("hello world");
|
|
83
92
|
expect(
|
|
84
|
-
applyFormat(str, { format: "Capitalize", dataType: "string" }),
|
|
93
|
+
applyFormat(str, { format: "Capitalize", dataType: "string", locale }),
|
|
85
94
|
).toBe("Hello world");
|
|
86
|
-
expect(
|
|
87
|
-
"
|
|
88
|
-
);
|
|
95
|
+
expect(
|
|
96
|
+
applyFormat(str, { format: "Title", dataType: "string", locale }),
|
|
97
|
+
).toBe("Hello World");
|
|
89
98
|
});
|
|
90
99
|
});
|
|
91
100
|
|
|
92
101
|
describe("boolean formatting", () => {
|
|
93
102
|
it("should format boolean values correctly", () => {
|
|
94
|
-
expect(applyFormat(true, { format: "Yes/No", dataType: "boolean" })).toBe(
|
|
95
|
-
"Yes",
|
|
96
|
-
);
|
|
97
103
|
expect(
|
|
98
|
-
applyFormat(
|
|
104
|
+
applyFormat(true, { format: "Yes/No", dataType: "boolean", locale }),
|
|
105
|
+
).toBe("Yes");
|
|
106
|
+
expect(
|
|
107
|
+
applyFormat(false, { format: "Yes/No", dataType: "boolean", locale }),
|
|
99
108
|
).toBe("No");
|
|
100
|
-
expect(applyFormat(true, { format: "On/Off", dataType: "boolean" })).toBe(
|
|
101
|
-
"On",
|
|
102
|
-
);
|
|
103
109
|
expect(
|
|
104
|
-
applyFormat(
|
|
110
|
+
applyFormat(true, { format: "On/Off", dataType: "boolean", locale }),
|
|
111
|
+
).toBe("On");
|
|
112
|
+
expect(
|
|
113
|
+
applyFormat(false, { format: "On/Off", dataType: "boolean", locale }),
|
|
105
114
|
).toBe("Off");
|
|
106
115
|
});
|
|
107
116
|
});
|
|
108
117
|
|
|
109
118
|
it("should return the original value for unknown data types or formats", () => {
|
|
110
119
|
expect(
|
|
111
|
-
applyFormat("some value", {
|
|
120
|
+
applyFormat("some value", {
|
|
121
|
+
format: "Auto",
|
|
122
|
+
dataType: "unknown",
|
|
123
|
+
locale,
|
|
124
|
+
}),
|
|
112
125
|
).toBe("some value");
|
|
113
|
-
expect(
|
|
126
|
+
expect(
|
|
127
|
+
applyFormat(123, { format: "Auto", dataType: "unknown", locale }),
|
|
128
|
+
).toBe(123);
|
|
114
129
|
});
|
|
115
130
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* Copyright 2024 Marimo. All rights reserved. */
|
|
2
2
|
import type { ColumnDef, RowSelectionState } from "@tanstack/react-table";
|
|
3
|
-
import { render } from "@testing-library/react";
|
|
3
|
+
import { render, screen } from "@testing-library/react";
|
|
4
4
|
import { describe, expect, it, vi } from "vitest";
|
|
5
5
|
import { TooltipProvider } from "@/components/ui/tooltip";
|
|
6
6
|
import { DataTable } from "../data-table";
|
|
@@ -57,4 +57,42 @@ describe("DataTable", () => {
|
|
|
57
57
|
// Verify the rowSelection prop is maintained
|
|
58
58
|
expect(commonProps.rowSelection).toEqual(initialRowSelection);
|
|
59
59
|
});
|
|
60
|
+
|
|
61
|
+
it("applies hoverTemplate to the row title using row values", () => {
|
|
62
|
+
interface RowData {
|
|
63
|
+
id: number;
|
|
64
|
+
first: string;
|
|
65
|
+
last: string;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const testData: RowData[] = [
|
|
69
|
+
{ id: 1, first: "Michael", last: "Scott" },
|
|
70
|
+
{ id: 2, first: "Jim", last: "Halpert" },
|
|
71
|
+
];
|
|
72
|
+
|
|
73
|
+
const columns: Array<ColumnDef<RowData>> = [
|
|
74
|
+
{ accessorKey: "first", header: "First" },
|
|
75
|
+
{ accessorKey: "last", header: "Last" },
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
render(
|
|
79
|
+
<TooltipProvider>
|
|
80
|
+
<DataTable
|
|
81
|
+
data={testData}
|
|
82
|
+
columns={columns}
|
|
83
|
+
selection={null}
|
|
84
|
+
totalRows={2}
|
|
85
|
+
totalColumns={2}
|
|
86
|
+
pagination={false}
|
|
87
|
+
hoverTemplate={"{{first}} {{last}}"}
|
|
88
|
+
/>
|
|
89
|
+
</TooltipProvider>,
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
// Grab all rows and assert title attribute computed from template
|
|
93
|
+
const rows = screen.getAllByRole("row");
|
|
94
|
+
// The first row is header; subsequent rows correspond to data
|
|
95
|
+
expect(rows[1]).toHaveAttribute("title", "Michael Scott");
|
|
96
|
+
expect(rows[2]).toHaveAttribute("title", "Jim Halpert");
|
|
97
|
+
});
|
|
60
98
|
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/* Copyright 2025 Marimo. All rights reserved. */
|
|
2
|
+
"use no memo";
|
|
3
|
+
|
|
4
|
+
import type { InitialTableState, TableFeature } from "@tanstack/react-table";
|
|
5
|
+
import type { CellHoverTemplateTableState } from "./types";
|
|
6
|
+
|
|
7
|
+
export const CellHoverTemplateFeature: TableFeature = {
|
|
8
|
+
getInitialState: (state?: InitialTableState): CellHoverTemplateTableState => {
|
|
9
|
+
return {
|
|
10
|
+
...state,
|
|
11
|
+
cellHoverTemplate: null,
|
|
12
|
+
};
|
|
13
|
+
},
|
|
14
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/* Copyright 2025 Marimo. All rights reserved. */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-empty-interface */
|
|
3
|
+
|
|
4
|
+
export interface CellHoverTemplateTableState {
|
|
5
|
+
cellHoverTemplate: string | null;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// Use declaration merging to add our new feature APIs
|
|
9
|
+
declare module "@tanstack/react-table" {
|
|
10
|
+
interface TableState extends CellHoverTemplateTableState {}
|
|
11
|
+
}
|
|
@@ -342,7 +342,7 @@ interface SliderFieldProps {
|
|
|
342
342
|
fieldName: FieldName;
|
|
343
343
|
label: string;
|
|
344
344
|
className?: string;
|
|
345
|
-
|
|
345
|
+
defaultValue: number;
|
|
346
346
|
start: number;
|
|
347
347
|
stop: number;
|
|
348
348
|
step?: number;
|
|
@@ -351,53 +351,57 @@ interface SliderFieldProps {
|
|
|
351
351
|
export const SliderField = ({
|
|
352
352
|
fieldName,
|
|
353
353
|
label,
|
|
354
|
-
|
|
354
|
+
defaultValue,
|
|
355
355
|
start,
|
|
356
356
|
stop,
|
|
357
357
|
step,
|
|
358
358
|
className,
|
|
359
359
|
}: SliderFieldProps) => {
|
|
360
|
-
const [internalValue, setInternalValue] = React.useState(value);
|
|
361
360
|
const form = useFormContext();
|
|
362
361
|
|
|
363
|
-
// Update internal value on prop change
|
|
364
|
-
React.useEffect(() => {
|
|
365
|
-
setInternalValue(value);
|
|
366
|
-
}, [value]);
|
|
367
|
-
|
|
368
362
|
return (
|
|
369
363
|
<FormField
|
|
370
364
|
control={form.control}
|
|
371
365
|
name={fieldName}
|
|
372
|
-
render={({ field }) =>
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
366
|
+
render={({ field }) => {
|
|
367
|
+
const currentValue = field.value ?? defaultValue;
|
|
368
|
+
const numericValue = Number(currentValue);
|
|
369
|
+
|
|
370
|
+
const saveValue = (value: number | string) => {
|
|
371
|
+
if (typeof value === "string") {
|
|
372
|
+
value = Number(value);
|
|
373
|
+
}
|
|
374
|
+
field.onChange(value);
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
return (
|
|
378
|
+
<FormItem
|
|
379
|
+
className={cn("flex flex-row items-center gap-2 w-1/2", className)}
|
|
380
|
+
>
|
|
381
|
+
<FormLabel>{label}</FormLabel>
|
|
382
|
+
<FormControl>
|
|
383
|
+
<Slider
|
|
384
|
+
{...field}
|
|
385
|
+
id={fieldName}
|
|
386
|
+
className="relative flex items-center select-none"
|
|
387
|
+
value={[numericValue]}
|
|
388
|
+
min={start}
|
|
389
|
+
max={stop}
|
|
390
|
+
step={step}
|
|
391
|
+
// Triggered on slider drag
|
|
392
|
+
onValueChange={([nextValue]) => {
|
|
393
|
+
saveValue(nextValue);
|
|
394
|
+
}}
|
|
395
|
+
// Triggered on mouse up
|
|
396
|
+
onValueCommit={([nextValue]) => {
|
|
397
|
+
saveValue(nextValue);
|
|
398
|
+
}}
|
|
399
|
+
valueMap={(value) => value}
|
|
400
|
+
/>
|
|
401
|
+
</FormControl>
|
|
402
|
+
</FormItem>
|
|
403
|
+
);
|
|
404
|
+
}}
|
|
401
405
|
/>
|
|
402
406
|
);
|
|
403
407
|
};
|
|
@@ -102,7 +102,7 @@ export const StyleForm: React.FC = () => {
|
|
|
102
102
|
<SliderField
|
|
103
103
|
fieldName="xAxis.width"
|
|
104
104
|
label="Width"
|
|
105
|
-
|
|
105
|
+
defaultValue={400}
|
|
106
106
|
start={200}
|
|
107
107
|
stop={800}
|
|
108
108
|
/>
|
|
@@ -118,7 +118,7 @@ export const StyleForm: React.FC = () => {
|
|
|
118
118
|
<SliderField
|
|
119
119
|
fieldName="yAxis.height"
|
|
120
120
|
label="Height"
|
|
121
|
-
|
|
121
|
+
defaultValue={300}
|
|
122
122
|
start={150}
|
|
123
123
|
stop={600}
|
|
124
124
|
/>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* Copyright 2024 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
3
|
import { useState } from "react";
|
|
4
|
+
import { useLocale } from "react-aria";
|
|
4
5
|
import {
|
|
5
6
|
AddDataframeChart,
|
|
6
7
|
renderChart,
|
|
@@ -53,6 +54,7 @@ export const ColumnExplorerPanel = ({
|
|
|
53
54
|
tableId,
|
|
54
55
|
}: ColumnExplorerPanelProps) => {
|
|
55
56
|
const [searchValue, setSearchValue] = useState("");
|
|
57
|
+
const { locale } = useLocale();
|
|
56
58
|
const columns = fieldTypes?.filter(([columnName]) => {
|
|
57
59
|
if (
|
|
58
60
|
columnName === SELECT_COLUMN_ID ||
|
|
@@ -71,7 +73,7 @@ export const ColumnExplorerPanel = ({
|
|
|
71
73
|
return (
|
|
72
74
|
<div className="mt-5 mb-3">
|
|
73
75
|
<span className="text-xs font-semibold ml-2 flex">
|
|
74
|
-
{prettifyRowColumnCount(totalRows, totalColumns)}
|
|
76
|
+
{prettifyRowColumnCount(totalRows, totalColumns, locale)}
|
|
75
77
|
<CopyClipboardIcon
|
|
76
78
|
tooltip="Copy column names"
|
|
77
79
|
value={columns?.map(([columnName]) => columnName).join(",\n") || ""}
|
|
@@ -169,6 +171,7 @@ const ColumnPreview = ({
|
|
|
169
171
|
dataType: DataType;
|
|
170
172
|
}) => {
|
|
171
173
|
const { theme } = useTheme();
|
|
174
|
+
const { locale } = useLocale();
|
|
172
175
|
|
|
173
176
|
const {
|
|
174
177
|
data,
|
|
@@ -208,7 +211,7 @@ const ColumnPreview = ({
|
|
|
208
211
|
refetchPreview,
|
|
209
212
|
});
|
|
210
213
|
|
|
211
|
-
const previewStats = stats && renderStats(stats, dataType);
|
|
214
|
+
const previewStats = stats && renderStats(stats, dataType, locale);
|
|
212
215
|
|
|
213
216
|
const chart = chart_spec && renderChart(chart_spec, theme);
|
|
214
217
|
|