@marimo-team/frontend 0.16.0 → 0.16.2
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-B5cPvWoQ.js +19 -0
- package/dist/assets/{ImageComparisonComponent-fTHv1Ih0.js → ImageComparisonComponent-CqR26LSv.js} +1 -1
- package/dist/assets/{VegaLite-Bdi-TyfY.js → VegaLite-DvQDATwI.js} +1 -1
- package/dist/assets/_baseEach--KDTwKbG.js +1 -0
- package/dist/assets/_baseMap-Cu3o-eyO.js +1 -0
- package/dist/assets/{_baseUniq-CCgDNtZb.js → _baseUniq-y7ZXnMo1.js} +1 -1
- package/dist/assets/{_createAggregator-DcD0kTA5.js → _createAggregator-ZcHkHPNJ.js} +1 -1
- package/dist/assets/{agent-panel-Crv430aI.js → agent-panel-B91RoLct.js} +76 -57
- package/dist/assets/{any-language-editor-CQh552Wu.js → any-language-editor-CxfHcm5h.js} +1 -1
- package/dist/assets/{architectureDiagram-W76B3OCA-BAJeBxzt.js → architectureDiagram-W76B3OCA-BQsvK8uR.js} +1 -1
- package/dist/assets/{between-horizontal-start-Boxgxbt_.js → between-horizontal-start-BmYToIaM.js} +1 -1
- package/dist/assets/{blockDiagram-QIGZ2CNN-CL-1svEK.js → blockDiagram-QIGZ2CNN-r3HgCj4w.js} +1 -1
- package/dist/assets/{c4Diagram-FPNF74CW-BbEqbCTl.js → c4Diagram-FPNF74CW-BJbPNt41.js} +1 -1
- package/dist/assets/channel-DFaEx1fu.js +1 -0
- package/dist/assets/chat-panel-IoPMv8e2.js +3 -0
- package/dist/assets/{chunk-4BX2VUAB-C--8TXeE.js → chunk-4BX2VUAB-Dv4MZ9Hj.js} +1 -1
- package/dist/assets/{chunk-55IACEB6-Bj00HDqq.js → chunk-55IACEB6-CM4AHquB.js} +1 -1
- package/dist/assets/{chunk-FMBD7UC4-C-lhB6hN.js → chunk-FMBD7UC4-C_Zz0ENB.js} +1 -1
- package/dist/assets/{chunk-K7UQS3LO-B-pGTXPt.js → chunk-K7UQS3LO-DYSmiXYq.js} +1 -1
- package/dist/assets/{chunk-QN33PNHL-DqUzGhvm.js → chunk-QN33PNHL-QM4OPuQP.js} +1 -1
- package/dist/assets/{chunk-QZHKN3VN-TntJHfSk.js → chunk-QZHKN3VN-CfAsGyeB.js} +1 -1
- package/dist/assets/{chunk-TVAH2DTR-HUJb1psV.js → chunk-TVAH2DTR-6j_Cpjsi.js} +1 -1
- package/dist/assets/{chunk-TZMSLE5B-BK3C__t3.js → chunk-TZMSLE5B-BHslFJQE.js} +1 -1
- package/dist/assets/{circle-play-DBLOv1Yu.js → circle-play-CK3UZRYQ.js} +1 -1
- package/dist/assets/classDiagram-KNZD7YFC-BsZtvV5O.js +1 -0
- package/dist/assets/classDiagram-v2-RKCZMP56-BsZtvV5O.js +1 -0
- package/dist/assets/{clear-button-BeoFbEKH.js → clear-button-C4fDVSv8.js} +1 -1
- package/dist/assets/clone-YBEvPE-s.js +1 -0
- package/dist/assets/command-palette-D7hOfvf6.js +1 -0
- package/dist/assets/{common-C7oJcmCT.js → common-D-lbuUwz.js} +1 -1
- package/dist/assets/{compile-7L0MwhyI.js → compile-DVQe1Mzk.js} +1 -1
- package/dist/assets/{cose-bilkent-S5V4N54A-BMkGLcVC.js → cose-bilkent-S5V4N54A-D-IS7WC8.js} +1 -1
- package/dist/assets/{dagre-5GWH7T2D-BJtRienS.js → dagre-5GWH7T2D-lYu-tEWT.js} +1 -1
- package/dist/assets/{data-grid-overlay-editor-DBkmGtNs.js → data-grid-overlay-editor-C5peOCit.js} +1 -1
- package/dist/assets/datasources-panel-D3NA20uZ.js +1 -0
- package/dist/assets/{dependency-graph-panel-DEdOxp2X.js → dependency-graph-panel-BGVYOfkV.js} +1 -1
- package/dist/assets/{diagram-N5W7TBWH-CmECY3nb.js → diagram-N5W7TBWH-BnvIuYUp.js} +1 -1
- package/dist/assets/{diagram-QEK2KX5R-DMOVSNKD.js → diagram-QEK2KX5R-DemedRK3.js} +1 -1
- package/dist/assets/{diagram-S2PKOQOG-BiJ96PNQ.js → diagram-S2PKOQOG-iiY7AuyH.js} +1 -1
- package/dist/assets/{documentation-panel-xULhaEv3.js → documentation-panel-C3dSwOSQ.js} +1 -1
- package/dist/assets/edit-page-C5TsEeSo.js +129 -0
- package/dist/assets/{ellipsis-vertical-BBqXIlc2.js → ellipsis-vertical-CazJl8M7.js} +1 -1
- package/dist/assets/{empty-state-B3dA3G5P.js → empty-state-DW308mFO.js} +1 -1
- package/dist/assets/{erDiagram-AWTI2OKA-MP1DiFRo.js → erDiagram-AWTI2OKA-6wQ8Ugg0.js} +1 -1
- package/dist/assets/{error-panel-Cc1sv-Ag.js → error-panel-D1VnJ1yP.js} +1 -1
- package/dist/assets/file-explorer-panel-0oVd4t-D.js +1 -0
- package/dist/assets/{flowDiagram-PVAE7QVJ-BX7caPp7.js → flowDiagram-PVAE7QVJ-C55IUWjm.js} +1 -1
- package/dist/assets/{ganttDiagram-OWAHRB6G-B462g4Yf.js → ganttDiagram-OWAHRB6G-DmqCM6ME.js} +4 -4
- package/dist/assets/{gitGraphDiagram-NY62KEGX-CGgvZ9-9.js → gitGraphDiagram-NY62KEGX-DBvhAeM_.js} +1 -1
- package/dist/assets/{glide-data-editor-C0gUFZON.js → glide-data-editor-CHNuHidQ.js} +4 -4
- package/dist/assets/{graph-CHRVBzY5.js → graph-CG6BgUWQ.js} +1 -1
- package/dist/assets/home-page-dgivXuSR.js +9 -0
- package/dist/assets/{index-Clbi_Yaq.js → index-BTGpssVX.js} +1 -1
- package/dist/assets/{index-CQDrxQ0j.js → index-BYVZlBF8.js} +1 -1
- package/dist/assets/{index-lYa_leQE.js → index-BelfnXwL.js} +1 -1
- package/dist/assets/{index-DRMm6SNo.js → index-BneyUujp.js} +1 -1
- package/dist/assets/{index-BY93Ejhl.js → index-C02SqeRj.js} +1 -1
- package/dist/assets/{index-C-8WADat.js → index-C7dtgr9A.js} +1 -1
- package/dist/assets/{index-D9UKkrr2.js → index-CAQvMTzM.js} +1 -1
- package/dist/assets/index-CGDMlQfO.css +1 -0
- package/dist/assets/index-CelXfcd8.js +580 -0
- package/dist/assets/{index-vmICa5KN.js → index-Csd6QrCV.js} +1 -1
- package/dist/assets/{index-DoRmcrKM.js → index-CtPksxf0.js} +1 -1
- package/dist/assets/{index-C1v_Z9et.js → index-Cxyk7pt-.js} +1 -1
- package/dist/assets/{index-CpTPJo4k.js → index-DAZ-9ri2.js} +1 -1
- package/dist/assets/{index-DEQvTChO.js → index-DONRrmA2.js} +1 -1
- package/dist/assets/{index-C4Tn5NvJ.js → index-Db36XTG_.js} +1 -1
- package/dist/assets/{index-z9bohSQJ.js → index-DdIhdEVw.js} +1 -1
- package/dist/assets/{index-C-GhZ7ti.js → index-M_pBKDSe.js} +1 -1
- package/dist/assets/{index-C77h_TXN.js → index-_luCZMLM.js} +1 -1
- package/dist/assets/{index-D1vmG6DS.js → index-mkubqy9-.js} +1 -1
- package/dist/assets/{index-BVgAenPd.js → index-sbO9UaUU.js} +1 -1
- package/dist/assets/{index-CWMgowgL.js → index-z4krxQ4j.js} +1 -1
- package/dist/assets/infoDiagram-STP46IZ2-wTALjfPc.js +2 -0
- package/dist/assets/{isEmpty-DU_ogP_D.js → isEmpty-CqX_YTIf.js} +1 -1
- package/dist/assets/{journeyDiagram-BIP6EPQ6-C6EgLP_Q.js → journeyDiagram-BIP6EPQ6-Y5w_Tqe_.js} +1 -1
- package/dist/assets/{kanban-definition-6OIFK2YF-BXzYO1yj.js → kanban-definition-6OIFK2YF-DbXs5Rxi.js} +1 -1
- package/dist/assets/{layout-jihVw5-i.js → layout-BCNPDACj.js} +1 -1
- package/dist/assets/{linear-C4blANlC.js → linear-uO6UVhXt.js} +1 -1
- package/dist/assets/links-Drv7cJgN.js +7 -0
- package/dist/assets/{logs-panel-D401qzZh.js → logs-panel-BEQ1eRUp.js} +1 -1
- package/dist/assets/{markdown-renderer-Cd9eYyaL.js → markdown-renderer-Dmzbb00W.js} +20 -20
- package/dist/assets/{mermaid-BEVuRz_O.js → mermaid-qRc4MXIj.js} +1 -1
- package/dist/assets/{mermaid.core-CaSnaLH0.js → mermaid.core-CvvJtCRj.js} +4 -4
- package/dist/assets/min-DYUOb1RR.js +1 -0
- package/dist/assets/{mindmap-definition-Q6HEUPPD-BXUM5MT2.js → mindmap-definition-Q6HEUPPD-G5NognM-.js} +1 -1
- package/dist/assets/{number-overlay-editor-4uWXGlPG.js → number-overlay-editor-DPr5sHFu.js} +1 -1
- package/dist/assets/outline-panel-gxQXvVi4.js +1 -0
- package/dist/assets/{packages-panel-CJL0MVlj.js → packages-panel-B1T0VPlg.js} +1 -1
- package/dist/assets/{pieDiagram-ADFJNKIX-Dxt5PVNo.js → pieDiagram-ADFJNKIX-DK9SHkfc.js} +1 -1
- package/dist/assets/{quadrantDiagram-LMRXKWRM-D4pUaA31.js → quadrantDiagram-LMRXKWRM-D1DdWF8C.js} +1 -1
- package/dist/assets/{react-plotly-cJZ0VWBq.js → react-plotly-CTwajqCb.js} +1 -1
- package/dist/assets/{requirementDiagram-4UW4RH46-DVRTjgas.js → requirementDiagram-4UW4RH46-DnjDAypr.js} +1 -1
- package/dist/assets/{run-page-BUEnMC9w.js → run-page-CQY9im22.js} +1 -1
- package/dist/assets/{sankeyDiagram-GR3RE2ED-CVFnD9C-.js → sankeyDiagram-GR3RE2ED-B67Va-ER.js} +1 -1
- package/dist/assets/{scratchpad-panel-BIgRENkI.js → scratchpad-panel-DlDfcDtW.js} +1 -1
- package/dist/assets/{secrets-panel-xY5-V_BD.js → secrets-panel-BDGyuGZA.js} +1 -1
- package/dist/assets/{sequenceDiagram-C3RYC4MD-_lY4ZN_S.js → sequenceDiagram-C3RYC4MD-DiWgZPtN.js} +1 -1
- package/dist/assets/{slides-component-DMjQomc3.css → slides-component-C-LoGC1U.css} +1 -1
- package/dist/assets/{slides-component-Xjymwj7X.js → slides-component-DhpPRtQp.js} +1 -1
- package/dist/assets/snippets-panel-CLkBXhJ2.js +1 -0
- package/dist/assets/sortBy-D4OG7w4O.js +1 -0
- package/dist/assets/{state-C4NiC9tO.js → state-Dz_3JyED.js} +1 -1
- package/dist/assets/{stateDiagram-KXAO66HF-Da0JQWCn.js → stateDiagram-KXAO66HF-ByF2AULw.js} +1 -1
- package/dist/assets/stateDiagram-v2-UMBNRL4Z-CtBJqosP.js +1 -0
- package/dist/assets/storage-Dr0CC44z.js +26 -0
- package/dist/assets/{terminal-BPwTkXae.js → terminal-BtdissBf.js} +1 -1
- package/dist/assets/{time-Dv5_Ouz_.js → time-DKdOTnQg.js} +1 -1
- package/dist/assets/{timeline-definition-XQNQX7LJ-Dxh5Zu2e.js → timeline-definition-XQNQX7LJ-DzER9bf6.js} +1 -1
- package/dist/assets/tracing-Dpx5M-u3.js +2 -0
- package/dist/assets/{tracing-panel-DAzrzNmm.js → tracing-panel-hCjBkSER.js} +2 -2
- package/dist/assets/{trash-Dc6DSjz_.js → trash-C6Ko-g5q.js} +1 -1
- package/dist/assets/{tree-jheoerAX.js → tree-BHN2gcCF.js} +6 -6
- package/dist/assets/{treemap-75Q7IDZK-IgpxeGaf.js → treemap-75Q7IDZK-DR79Mhzt.js} +27 -27
- package/dist/assets/variable-panel-PFBCFz36.js +1 -0
- package/dist/assets/{vega-component-BpfpiPKI.js → vega-component-Db6-uY4C.js} +1 -1
- package/dist/assets/worker-fHbtoWvT.js +1 -0
- package/dist/assets/{xychartDiagram-6GGTOJPD-CmNigJ31.js → xychartDiagram-6GGTOJPD-DWzBP3tZ.js} +1 -1
- package/dist/index.html +2 -2
- package/package.json +5 -4
- package/src/__mocks__/requests.ts +1 -0
- package/src/components/app-config/user-config-form.tsx +46 -1
- package/src/components/chat/acp/__tests__/__snapshots__/prompt.test.ts.snap +62 -43
- package/src/components/chat/acp/__tests__/atoms.test.ts +1 -1
- package/src/components/chat/acp/__tests__/state.test.ts +36 -36
- package/src/components/chat/acp/agent-panel.tsx +24 -27
- package/src/components/chat/acp/blocks.tsx +6 -6
- package/src/components/chat/acp/prompt.ts +62 -43
- package/src/components/chat/chat-panel.tsx +5 -1
- package/src/components/chat/markdown-renderer.tsx +6 -10
- package/src/components/chat/tool-call-accordion.tsx +52 -20
- 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__/columns.test.tsx +38 -0
- 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 +63 -20
- 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 +36 -0
- package/src/components/data-table/row-viewer-panel/row-viewer.tsx +10 -8
- package/src/components/data-table/schemas.ts +16 -0
- package/src/components/datasources/column-preview.tsx +6 -2
- package/src/components/datasources/datasources.tsx +8 -12
- package/src/components/editor/Cell.tsx +2 -0
- package/src/components/editor/ai/transport/chat-transport.tsx +4 -1
- package/src/components/editor/cell/CellStatus.tsx +23 -20
- package/src/components/editor/cell/CreateCellButton.tsx +3 -4
- 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/errors/sql-validation-errors.tsx +34 -0
- package/src/components/editor/file-tree/requesting-tree.tsx +14 -8
- package/src/components/editor/output/ConsoleOutput.tsx +13 -1
- package/src/components/editor/output/MarimoErrorOutput.tsx +60 -1
- 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/theme.tsx +1 -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/context/__tests__/registry.test.ts +6 -4
- package/src/core/ai/context/providers/cell-output.ts +4 -20
- 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 +34 -1
- package/src/core/cells/__tests__/add-missing-import.test.ts +67 -22
- package/src/core/cells/add-missing-import.ts +24 -7
- package/src/core/cells/cells.ts +26 -27
- 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/language/__tests__/extension.test.ts +24 -0
- package/src/core/codemirror/language/__tests__/sql-validation.test.ts +133 -0
- package/src/core/codemirror/language/languages/sql/sql-mode.ts +20 -0
- package/src/core/codemirror/language/languages/sql/sql.ts +90 -3
- package/src/core/codemirror/language/languages/sql/validation-errors.ts +79 -0
- package/src/core/codemirror/language/panel/panel.tsx +8 -2
- package/src/core/codemirror/language/panel/sql.tsx +81 -4
- 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/config/feature-flag.tsx +3 -1
- package/src/core/datasets/request-registry.ts +17 -1
- 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/bridge.ts +1 -0
- package/src/core/islands/components/web-components.tsx +13 -10
- package/src/core/islands/main.ts +1 -0
- package/src/core/kernel/RuntimeState.ts +4 -1
- package/src/core/kernel/messages.ts +3 -2
- package/src/core/network/DeferredRequestRegistry.ts +16 -4
- package/src/core/network/requests-network.ts +7 -0
- package/src/core/network/requests-static.ts +1 -0
- package/src/core/network/requests-toasting.ts +1 -0
- package/src/core/network/types.ts +2 -0
- package/src/core/runtime/runtime.ts +5 -4
- package/src/core/wasm/bridge.ts +10 -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 +4 -0
- package/src/hooks/useFormatting.ts +97 -0
- package/src/hooks/useTimer.ts +8 -5
- package/src/plugins/core/registerReactComponent.tsx +39 -29
- package/src/plugins/impl/DataTablePlugin.tsx +15 -4
- 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/data-frames/DataFramePlugin.tsx +17 -5
- 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/dataframe.stories.tsx +2 -0
- package/src/utils/__tests__/dates.test.ts +45 -24
- package/src/utils/__tests__/dom.test.ts +167 -0
- package/src/utils/__tests__/numbers.test.ts +42 -30
- package/src/utils/__tests__/once.test.ts +187 -0
- package/src/utils/dates.ts +15 -10
- package/src/utils/dom.ts +55 -0
- package/src/utils/edit-distance.ts +8 -6
- package/src/utils/errors.ts +1 -1
- 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-BErMbWvG.js +0 -19
- package/dist/assets/_baseEach-CNBxBxvS.js +0 -1
- package/dist/assets/_baseMap-D1WHjKrd.js +0 -1
- package/dist/assets/channel-_2eNSz0n.js +0 -1
- package/dist/assets/chat-panel-CXh5Wl6C.js +0 -3
- package/dist/assets/classDiagram-KNZD7YFC-BGmh9POF.js +0 -1
- package/dist/assets/classDiagram-v2-RKCZMP56-BGmh9POF.js +0 -1
- package/dist/assets/clone-BFDSPAj3.js +0 -1
- package/dist/assets/command-palette-CXZiSv0I.js +0 -1
- package/dist/assets/datasources-panel-B7FbYLiy.js +0 -1
- package/dist/assets/edit-page-BrYda9VE.js +0 -129
- package/dist/assets/file-explorer-panel-Bw59Kva1.js +0 -1
- package/dist/assets/home-page-Fb2osjys.js +0 -9
- package/dist/assets/index-Cx0bsY1w.css +0 -1
- package/dist/assets/index-DKEudB02.js +0 -578
- package/dist/assets/infoDiagram-STP46IZ2-CVyrdLc8.js +0 -2
- package/dist/assets/links-D59GIweI.js +0 -7
- package/dist/assets/min-DUMu_zeK.js +0 -1
- package/dist/assets/outline-panel-DIzkvm2I.js +0 -1
- package/dist/assets/snippets-panel-CTPYW41n.js +0 -1
- package/dist/assets/sortBy-BNZKwiq_.js +0 -1
- package/dist/assets/stateDiagram-v2-UMBNRL4Z-D5lYZOOt.js +0 -1
- package/dist/assets/storage-CMdLzB_c.js +0 -26
- package/dist/assets/tracing-BCIurUfa.js +0 -2
- package/dist/assets/variable-panel-DYAiLBmF.js +0 -1
- package/dist/assets/worker-X5rxzQGQ.js +0 -1
|
@@ -52,7 +52,7 @@ export function getAgentPrompt(filename: string) {
|
|
|
52
52
|
## Best Practices
|
|
53
53
|
|
|
54
54
|
<data_handling>
|
|
55
|
-
- Use
|
|
55
|
+
- Use polars for data manipulation
|
|
56
56
|
- Implement proper data validation
|
|
57
57
|
- Handle missing values appropriately
|
|
58
58
|
- Use efficient data structures
|
|
@@ -62,7 +62,7 @@ export function getAgentPrompt(filename: string) {
|
|
|
62
62
|
<visualization>
|
|
63
63
|
- For matplotlib: use plt.gca() as the last expression instead of plt.show()
|
|
64
64
|
- For plotly: return the figure object directly
|
|
65
|
-
- For altair: return the chart object directly
|
|
65
|
+
- For altair: return the chart object directly. Add tooltips where appropriate. You can pass polars dataframes directly to altair.
|
|
66
66
|
- Include proper labels, titles, and color schemes
|
|
67
67
|
- Make visualizations interactive where appropriate
|
|
68
68
|
</visualization>
|
|
@@ -76,7 +76,7 @@ export function getAgentPrompt(filename: string) {
|
|
|
76
76
|
</ui_elements>
|
|
77
77
|
|
|
78
78
|
<sql>
|
|
79
|
-
- When writing duckdb, prefer using marimo's SQL cells, which start with
|
|
79
|
+
- When writing duckdb, prefer using marimo's SQL cells, which start with df = mo.sql(f"""<your query>""") for DuckDB, or df = mo.sql(f"""<your query>""", engine=engine) for other SQL engines.
|
|
80
80
|
- See the SQL with duckdb example for an example on how to do this
|
|
81
81
|
- Don't add comments in cells that use mo.sql()
|
|
82
82
|
- Consider using \`vega_datasets\` for common example datasets
|
|
@@ -144,7 +144,8 @@ export function getAgentPrompt(filename: string) {
|
|
|
144
144
|
${formatCells([
|
|
145
145
|
`
|
|
146
146
|
import marimo as mo
|
|
147
|
-
import
|
|
147
|
+
import altair as alt
|
|
148
|
+
import polars as pl
|
|
148
149
|
import numpy as np
|
|
149
150
|
`,
|
|
150
151
|
`
|
|
@@ -155,12 +156,18 @@ export function getAgentPrompt(filename: string) {
|
|
|
155
156
|
x = np.random.rand(n_points.value)
|
|
156
157
|
y = np.random.rand(n_points.value)
|
|
157
158
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
159
|
+
df = pl.DataFrame({"x": x, "y": y})
|
|
160
|
+
|
|
161
|
+
chart = alt.Chart(df).mark_circle(opacity=0.7).encode(
|
|
162
|
+
x=alt.X('x', title='X axis'),
|
|
163
|
+
y=alt.Y('y', title='Y axis')
|
|
164
|
+
).properties(
|
|
165
|
+
title=f"Scatter plot with {n_points.value} points",
|
|
166
|
+
width=400,
|
|
167
|
+
height=300
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
chart
|
|
164
171
|
`,
|
|
165
172
|
])}
|
|
166
173
|
</example>
|
|
@@ -169,11 +176,11 @@ export function getAgentPrompt(filename: string) {
|
|
|
169
176
|
${formatCells([
|
|
170
177
|
`
|
|
171
178
|
import marimo as mo
|
|
172
|
-
import
|
|
179
|
+
import polars as pl
|
|
173
180
|
from vega_datasets import data
|
|
174
181
|
`,
|
|
175
182
|
`
|
|
176
|
-
cars_df = data.cars()
|
|
183
|
+
cars_df = pl.DataFrame(data.cars())
|
|
177
184
|
mo.ui.data_explorer(cars_df)
|
|
178
185
|
`,
|
|
179
186
|
])}
|
|
@@ -183,43 +190,44 @@ export function getAgentPrompt(filename: string) {
|
|
|
183
190
|
${formatCells([
|
|
184
191
|
`
|
|
185
192
|
import marimo as mo
|
|
186
|
-
import
|
|
187
|
-
import
|
|
188
|
-
import seaborn as sns
|
|
193
|
+
import polars as pl
|
|
194
|
+
import altair as alt
|
|
189
195
|
`,
|
|
190
196
|
`
|
|
191
|
-
iris =
|
|
197
|
+
iris = pl.read_csv("hf://datasets/scikit-learn/iris/Iris.csv")
|
|
192
198
|
`,
|
|
193
199
|
`
|
|
194
200
|
species_selector = mo.ui.dropdown(
|
|
195
|
-
options=["All"] + iris["
|
|
201
|
+
options=["All"] + iris["Species"].unique().to_list(),
|
|
196
202
|
value="All",
|
|
197
|
-
label="Species"
|
|
203
|
+
label="Species",
|
|
198
204
|
)
|
|
199
205
|
x_feature = mo.ui.dropdown(
|
|
200
|
-
options=iris.
|
|
201
|
-
value="
|
|
202
|
-
label="X Feature"
|
|
206
|
+
options=iris.select(pl.col(pl.Float64, pl.Int64)).columns,
|
|
207
|
+
value="SepalLengthCm",
|
|
208
|
+
label="X Feature",
|
|
203
209
|
)
|
|
204
210
|
y_feature = mo.ui.dropdown(
|
|
205
|
-
options=iris.
|
|
206
|
-
value="
|
|
207
|
-
label="Y Feature"
|
|
211
|
+
options=iris.select(pl.col(pl.Float64, pl.Int64)).columns,
|
|
212
|
+
value="SepalWidthCm",
|
|
213
|
+
label="Y Feature",
|
|
208
214
|
)
|
|
209
215
|
mo.hstack([species_selector, x_feature, y_feature])
|
|
210
216
|
`,
|
|
211
217
|
`
|
|
212
|
-
filtered_data = iris if species_selector.value == "All" else iris
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
218
|
+
filtered_data = iris if species_selector.value == "All" else iris.filter(pl.col("Species") == species_selector.value)
|
|
219
|
+
|
|
220
|
+
chart = alt.Chart(filtered_data).mark_circle().encode(
|
|
221
|
+
x=alt.X(x_feature.value, title=x_feature.value),
|
|
222
|
+
y=alt.Y(y_feature.value, title=y_feature.value),
|
|
223
|
+
color='Species'
|
|
224
|
+
).properties(
|
|
225
|
+
title=f"{y_feature.value} vs {x_feature.value}",
|
|
226
|
+
width=500,
|
|
227
|
+
height=400
|
|
220
228
|
)
|
|
221
|
-
|
|
222
|
-
|
|
229
|
+
|
|
230
|
+
chart
|
|
223
231
|
`,
|
|
224
232
|
])}
|
|
225
233
|
</example>
|
|
@@ -242,14 +250,21 @@ export function getAgentPrompt(filename: string) {
|
|
|
242
250
|
`
|
|
243
251
|
import marimo as mo
|
|
244
252
|
import altair as alt
|
|
245
|
-
import
|
|
253
|
+
import polars as pl
|
|
246
254
|
`,
|
|
247
255
|
`# Load dataset
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
256
|
+
weather = pl.read_csv("https://raw.githubusercontent.com/vega/vega-datasets/refs/heads/main/data/weather.csv")
|
|
257
|
+
weather_dates = weather.with_columns(
|
|
258
|
+
pl.col("date").str.strptime(pl.Date, format="%Y-%m-%d")
|
|
259
|
+
)
|
|
260
|
+
_chart = (
|
|
261
|
+
alt.Chart(weather_dates)
|
|
262
|
+
.mark_point()
|
|
263
|
+
.encode(
|
|
264
|
+
x="date:T",
|
|
265
|
+
y="temp_max",
|
|
266
|
+
color="location",
|
|
267
|
+
)
|
|
253
268
|
)
|
|
254
269
|
`,
|
|
255
270
|
"chart = mo.ui.altair_chart(_chart)\nchart",
|
|
@@ -278,9 +293,13 @@ export function getAgentPrompt(filename: string) {
|
|
|
278
293
|
|
|
279
294
|
<example title="SQL with duckdb">
|
|
280
295
|
${formatCells([
|
|
281
|
-
"import marimo as mo\
|
|
282
|
-
`
|
|
283
|
-
`
|
|
296
|
+
"import marimo as mo\n import polars as pl",
|
|
297
|
+
`weather = pl.read_csv('https://raw.githubusercontent.com/vega/vega-datasets/refs/heads/main/data/weather.csv')`,
|
|
298
|
+
`seattle_weather_df = mo.sql(
|
|
299
|
+
f"""
|
|
300
|
+
SELECT * FROM weather WHERE location = 'Seattle';
|
|
301
|
+
"""
|
|
302
|
+
)`,
|
|
284
303
|
])}
|
|
285
304
|
</example>`;
|
|
286
305
|
}
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
SquareIcon,
|
|
19
19
|
} from "lucide-react";
|
|
20
20
|
import { memo, useEffect, useMemo, useRef, useState } from "react";
|
|
21
|
+
import { useLocale } from "react-aria";
|
|
21
22
|
import useEvent from "react-use-event-hook";
|
|
22
23
|
import { Button } from "@/components/ui/button";
|
|
23
24
|
import {
|
|
@@ -103,6 +104,7 @@ const ChatHeader: React.FC<ChatHeaderProps> = ({
|
|
|
103
104
|
}) => {
|
|
104
105
|
const { handleClick } = useOpenSettingsToTab();
|
|
105
106
|
const chatState = useAtomValue(chatStateAtom);
|
|
107
|
+
const { locale } = useLocale();
|
|
106
108
|
const chats = useMemo(() => {
|
|
107
109
|
return [...chatState.chats.values()].sort(
|
|
108
110
|
(a, b) => b.updatedAt - a.updatedAt,
|
|
@@ -159,7 +161,7 @@ const ChatHeader: React.FC<ChatHeaderProps> = ({
|
|
|
159
161
|
>
|
|
160
162
|
<div className="font-medium">{chat.title}</div>
|
|
161
163
|
<div className="text-sm text-muted-foreground">
|
|
162
|
-
{timeAgo(chat.updatedAt)}
|
|
164
|
+
{timeAgo(chat.updatedAt, locale)}
|
|
163
165
|
</div>
|
|
164
166
|
</button>
|
|
165
167
|
))}
|
|
@@ -236,6 +238,7 @@ const ChatMessageDisplay: React.FC<ChatMessageProps> = memo(
|
|
|
236
238
|
result={part.output}
|
|
237
239
|
className="my-2"
|
|
238
240
|
state={part.state}
|
|
241
|
+
input={part.input}
|
|
239
242
|
/>
|
|
240
243
|
);
|
|
241
244
|
}
|
|
@@ -267,6 +270,7 @@ const ChatMessageDisplay: React.FC<ChatMessageProps> = memo(
|
|
|
267
270
|
toolName={part.type}
|
|
268
271
|
result={part.output}
|
|
269
272
|
state={part.state}
|
|
273
|
+
input={part.input}
|
|
270
274
|
className="my-2"
|
|
271
275
|
/>
|
|
272
276
|
);
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { EditorView } from "@codemirror/view";
|
|
4
4
|
import { useAtomValue } from "jotai";
|
|
5
5
|
import { BetweenHorizontalStartIcon } from "lucide-react";
|
|
6
|
-
import { memo, Suspense,
|
|
6
|
+
import { memo, Suspense, useState } from "react";
|
|
7
7
|
import { Streamdown, type StreamdownProps } from "streamdown";
|
|
8
8
|
import { Button, type ButtonProps } from "@/components/ui/button";
|
|
9
9
|
import { maybeAddMarimoImport } from "@/core/cells/add-missing-import";
|
|
@@ -114,9 +114,9 @@ const CodeBlock = ({ code, language }: CodeBlockProps) => {
|
|
|
114
114
|
const { theme } = useTheme();
|
|
115
115
|
const [value, setValue] = useState(code);
|
|
116
116
|
|
|
117
|
-
|
|
117
|
+
if (value !== code) {
|
|
118
118
|
setValue(code);
|
|
119
|
-
}
|
|
119
|
+
}
|
|
120
120
|
|
|
121
121
|
const handleCopyCode = async () => {
|
|
122
122
|
await copyToClipboard(value);
|
|
@@ -150,18 +150,13 @@ const CodeBlock = ({ code, language }: CodeBlockProps) => {
|
|
|
150
150
|
const CopyButton: React.FC<ButtonProps> = ({ onClick, ...props }) => {
|
|
151
151
|
const [copied, setCopied] = useState(false);
|
|
152
152
|
|
|
153
|
-
useEffect(() => {
|
|
154
|
-
if (copied) {
|
|
155
|
-
setTimeout(() => setCopied(false), 1000);
|
|
156
|
-
}
|
|
157
|
-
}, [copied]);
|
|
158
|
-
|
|
159
153
|
return (
|
|
160
154
|
<Button
|
|
161
155
|
{...props}
|
|
162
156
|
onClick={(e) => {
|
|
163
157
|
onClick?.(e);
|
|
164
158
|
setCopied(true);
|
|
159
|
+
setTimeout(() => setCopied(false), 1000);
|
|
165
160
|
}}
|
|
166
161
|
>
|
|
167
162
|
{copied ? "Copied" : "Copy"}
|
|
@@ -175,10 +170,11 @@ const COMPONENTS: Components = {
|
|
|
175
170
|
code: ({ children, className }) => {
|
|
176
171
|
const language = className?.replace("language-", "");
|
|
177
172
|
if (language && typeof children === "string") {
|
|
173
|
+
const code = children.trim();
|
|
178
174
|
return (
|
|
179
175
|
<div>
|
|
180
176
|
<div className="text-xs text-muted-foreground pl-1">{language}</div>
|
|
181
|
-
<CodeBlock code={
|
|
177
|
+
<CodeBlock code={code} language={language} />
|
|
182
178
|
</div>
|
|
183
179
|
);
|
|
184
180
|
}
|
|
@@ -45,17 +45,21 @@ const PrettySuccessResult: React.FC<{ data: SuccessResult }> = ({ data }) => {
|
|
|
45
45
|
} = data;
|
|
46
46
|
|
|
47
47
|
return (
|
|
48
|
-
<div className="
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
Auth Required
|
|
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}
|
|
57
56
|
</span>
|
|
58
|
-
|
|
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>
|
|
59
63
|
</div>
|
|
60
64
|
|
|
61
65
|
{/* Message */}
|
|
@@ -68,17 +72,18 @@ const PrettySuccessResult: React.FC<{ data: SuccessResult }> = ({ data }) => {
|
|
|
68
72
|
|
|
69
73
|
{/* Data */}
|
|
70
74
|
{rest && (
|
|
71
|
-
<div className="
|
|
75
|
+
<div className="space-y-3">
|
|
72
76
|
{Object.entries(rest).map(([key, value]) => {
|
|
73
77
|
if (isEmpty(value)) {
|
|
74
78
|
return null;
|
|
75
79
|
}
|
|
76
80
|
return (
|
|
77
|
-
<div key={key}>
|
|
78
|
-
<div className="text-xs font-medium text-muted-foreground
|
|
79
|
-
|
|
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}
|
|
80
85
|
</div>
|
|
81
|
-
<pre className="bg-[var(--slate-2)] p-
|
|
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">
|
|
82
87
|
{JSON.stringify(value, null, 2)}
|
|
83
88
|
</pre>
|
|
84
89
|
</div>
|
|
@@ -107,6 +112,29 @@ const ResultRenderer: React.FC<{ result: unknown }> = ({ result }) => {
|
|
|
107
112
|
);
|
|
108
113
|
};
|
|
109
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
|
+
|
|
110
138
|
interface ToolCallAccordionProps {
|
|
111
139
|
toolName: string;
|
|
112
140
|
result: unknown;
|
|
@@ -114,6 +142,7 @@ interface ToolCallAccordionProps {
|
|
|
114
142
|
index?: number;
|
|
115
143
|
state?: ToolUIPart["state"];
|
|
116
144
|
className?: string;
|
|
145
|
+
input?: unknown;
|
|
117
146
|
}
|
|
118
147
|
|
|
119
148
|
export const ToolCallAccordion: React.FC<ToolCallAccordionProps> = ({
|
|
@@ -123,6 +152,7 @@ export const ToolCallAccordion: React.FC<ToolCallAccordionProps> = ({
|
|
|
123
152
|
index = 0,
|
|
124
153
|
state,
|
|
125
154
|
className,
|
|
155
|
+
input,
|
|
126
156
|
}) => {
|
|
127
157
|
const hasResult = state === "output-available" && (result || error);
|
|
128
158
|
const status = error ? "error" : hasResult ? "success" : "loading";
|
|
@@ -176,21 +206,23 @@ export const ToolCallAccordion: React.FC<ToolCallAccordionProps> = ({
|
|
|
176
206
|
</code>
|
|
177
207
|
</span>
|
|
178
208
|
</AccordionTrigger>
|
|
179
|
-
<AccordionContent className="
|
|
209
|
+
<AccordionContent className="py-2 px-2">
|
|
180
210
|
{/* Only show content when tool is complete */}
|
|
181
211
|
{hasResult && (
|
|
182
212
|
<div className="space-y-3">
|
|
213
|
+
<ToolArgsRenderer input={input} />
|
|
183
214
|
{result !== undefined && result !== null && (
|
|
184
215
|
<ResultRenderer result={result} />
|
|
185
216
|
)}
|
|
186
217
|
|
|
187
218
|
{/* Error */}
|
|
188
219
|
{error && (
|
|
189
|
-
<div>
|
|
190
|
-
<div className="text-xs font-
|
|
191
|
-
|
|
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
|
|
192
224
|
</div>
|
|
193
|
-
<div className="
|
|
225
|
+
<div className="text-sm text-[var(--red-11)] leading-relaxed">
|
|
194
226
|
{error}
|
|
195
227
|
</div>
|
|
196
228
|
</div>
|
|
@@ -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
|
});
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { render } from "@testing-library/react";
|
|
4
4
|
import { describe, expect, it, test } from "vitest";
|
|
5
|
+
import { TooltipProvider } from "@/components/ui/tooltip";
|
|
5
6
|
import { generateColumns, inferFieldTypes } from "../columns";
|
|
6
7
|
import { getMimeValues, isMimeValue, MimeCell } from "../mime-cell";
|
|
7
8
|
import type { FieldTypesWithExternalType } from "../types";
|
|
@@ -245,6 +246,43 @@ describe("generateColumns", () => {
|
|
|
245
246
|
expect(columns[0].id).toBe("name");
|
|
246
247
|
expect(columns[1].id).toBe("age");
|
|
247
248
|
});
|
|
249
|
+
|
|
250
|
+
it("should render header with tooltip when headerTooltip is provided", () => {
|
|
251
|
+
const columns = generateColumns({
|
|
252
|
+
rowHeaders: [],
|
|
253
|
+
selection: null,
|
|
254
|
+
fieldTypes,
|
|
255
|
+
headerTooltip: { name: "Custom Name Tooltip" },
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
// Get the header function for the first column
|
|
259
|
+
const headerFunction = columns[0].header;
|
|
260
|
+
expect(headerFunction).toBeTypeOf("function");
|
|
261
|
+
|
|
262
|
+
const mockColumn = {
|
|
263
|
+
id: "name",
|
|
264
|
+
getCanSort: () => false,
|
|
265
|
+
getCanFilter: () => false,
|
|
266
|
+
columnDef: {
|
|
267
|
+
meta: {
|
|
268
|
+
dtype: "string",
|
|
269
|
+
dataType: "string",
|
|
270
|
+
},
|
|
271
|
+
},
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
const { container } = render(
|
|
275
|
+
<TooltipProvider>
|
|
276
|
+
{/* @ts-expect-error: mock column and header function */}
|
|
277
|
+
{headerFunction({ column: mockColumn })}
|
|
278
|
+
</TooltipProvider>,
|
|
279
|
+
);
|
|
280
|
+
|
|
281
|
+
expect(container.textContent).toContain("name");
|
|
282
|
+
// The tooltip functionality is tested by verifying that the header renders correctly
|
|
283
|
+
// when headerTooltip is provided.
|
|
284
|
+
expect(container.firstChild).toBeTruthy();
|
|
285
|
+
});
|
|
248
286
|
});
|
|
249
287
|
|
|
250
288
|
describe("MimeCell", () => {
|