@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
|
@@ -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 2024 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 2024 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
|
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
prettyNumber,
|
|
17
17
|
prettyScientificNumber,
|
|
18
18
|
} from "@/utils/numbers";
|
|
19
|
+
import { memoizeLastValue } from "@/utils/once";
|
|
19
20
|
import type {
|
|
20
21
|
ColumnFormattingOptions,
|
|
21
22
|
ColumnFormattingState,
|
|
@@ -39,6 +40,7 @@ export const ColumnFormattingFeature: TableFeature = {
|
|
|
39
40
|
return {
|
|
40
41
|
enableColumnFormatting: true,
|
|
41
42
|
onColumnFormattingChange: makeStateUpdater("columnFormatting", table),
|
|
43
|
+
locale: navigator.language,
|
|
42
44
|
} as ColumnFormattingOptions;
|
|
43
45
|
},
|
|
44
46
|
|
|
@@ -74,36 +76,50 @@ export const ColumnFormattingFeature: TableFeature = {
|
|
|
74
76
|
const dataType = column.columnDef.meta?.dataType;
|
|
75
77
|
const format = column.getColumnFormatting?.();
|
|
76
78
|
if (format) {
|
|
77
|
-
return applyFormat(value, {
|
|
79
|
+
return applyFormat(value, {
|
|
80
|
+
format,
|
|
81
|
+
dataType,
|
|
82
|
+
locale: table.options.locale,
|
|
83
|
+
});
|
|
78
84
|
}
|
|
79
85
|
return value;
|
|
80
86
|
};
|
|
81
87
|
},
|
|
82
88
|
};
|
|
83
89
|
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
90
|
+
export const getFormatters = memoizeLastValue((locale: string) => {
|
|
91
|
+
const percentFormatter = new Intl.NumberFormat(locale, {
|
|
92
|
+
style: "percent",
|
|
93
|
+
minimumFractionDigits: 0,
|
|
94
|
+
maximumFractionDigits: 2,
|
|
95
|
+
});
|
|
89
96
|
|
|
90
|
-
const dateFormatter = new Intl.DateTimeFormat(
|
|
91
|
-
|
|
92
|
-
});
|
|
97
|
+
const dateFormatter = new Intl.DateTimeFormat(locale, {
|
|
98
|
+
dateStyle: "short", // 3/4/2024
|
|
99
|
+
});
|
|
93
100
|
|
|
94
|
-
const dateTimeFormatter = new Intl.DateTimeFormat(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
});
|
|
101
|
+
const dateTimeFormatter = new Intl.DateTimeFormat(locale, {
|
|
102
|
+
dateStyle: "short", // 3/4/2024
|
|
103
|
+
timeStyle: "long", // 3:04:05 PM
|
|
104
|
+
timeZone: "UTC",
|
|
105
|
+
});
|
|
99
106
|
|
|
100
|
-
const timeFormatter = new Intl.DateTimeFormat(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
});
|
|
107
|
+
const timeFormatter = new Intl.DateTimeFormat(locale, {
|
|
108
|
+
timeStyle: "long", // 3:04:05 PM
|
|
109
|
+
timeZone: "UTC",
|
|
110
|
+
});
|
|
104
111
|
|
|
105
|
-
const integerFormatter = new Intl.NumberFormat(
|
|
106
|
-
|
|
112
|
+
const integerFormatter = new Intl.NumberFormat(locale, {
|
|
113
|
+
maximumFractionDigits: 0, // 1,000,000
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
percentFormatter,
|
|
118
|
+
dateFormatter,
|
|
119
|
+
dateTimeFormatter,
|
|
120
|
+
timeFormatter,
|
|
121
|
+
integerFormatter,
|
|
122
|
+
};
|
|
107
123
|
});
|
|
108
124
|
|
|
109
125
|
// Apply formatting to a value given a format and data type
|
|
@@ -112,9 +128,18 @@ export const applyFormat = (
|
|
|
112
128
|
options: {
|
|
113
129
|
format: FormatOption;
|
|
114
130
|
dataType: DataType | undefined;
|
|
131
|
+
locale: string;
|
|
115
132
|
},
|
|
116
133
|
) => {
|
|
117
|
-
const { format, dataType } = options;
|
|
134
|
+
const { format, dataType, locale } = options;
|
|
135
|
+
const {
|
|
136
|
+
percentFormatter,
|
|
137
|
+
dateFormatter,
|
|
138
|
+
dateTimeFormatter,
|
|
139
|
+
timeFormatter,
|
|
140
|
+
integerFormatter,
|
|
141
|
+
} = getFormatters(locale);
|
|
142
|
+
|
|
118
143
|
// If the value is null, return an empty string
|
|
119
144
|
if (value === null || value === undefined || value === "") {
|
|
120
145
|
return "";
|
|
@@ -143,13 +168,13 @@ export const applyFormat = (
|
|
|
143
168
|
const num = Number.parseFloat(value as string);
|
|
144
169
|
switch (format) {
|
|
145
170
|
case "Auto":
|
|
146
|
-
return prettyNumber(num);
|
|
171
|
+
return prettyNumber(num, locale);
|
|
147
172
|
case "Percent":
|
|
148
173
|
return percentFormatter.format(num);
|
|
149
174
|
case "Scientific":
|
|
150
|
-
return prettyScientificNumber(num, { shouldRound: true });
|
|
175
|
+
return prettyScientificNumber(num, { shouldRound: true, locale });
|
|
151
176
|
case "Engineering":
|
|
152
|
-
return prettyEngineeringNumber(num);
|
|
177
|
+
return prettyEngineeringNumber(num, locale);
|
|
153
178
|
case "Integer":
|
|
154
179
|
return integerFormatter.format(num);
|
|
155
180
|
default:
|
|
@@ -198,32 +223,35 @@ export const applyFormat = (
|
|
|
198
223
|
|
|
199
224
|
export function formattingExample(
|
|
200
225
|
format: FormatOption,
|
|
226
|
+
locale: string,
|
|
201
227
|
): string | number | undefined | null {
|
|
202
228
|
switch (format) {
|
|
203
229
|
case "Date":
|
|
204
230
|
return String(
|
|
205
|
-
applyFormat(new Date(), { format: "Date", dataType: "date" }),
|
|
231
|
+
applyFormat(new Date(), { format: "Date", dataType: "date", locale }),
|
|
206
232
|
);
|
|
207
233
|
case "Datetime":
|
|
208
234
|
return String(
|
|
209
235
|
applyFormat(new Date(), {
|
|
210
236
|
format: "Datetime",
|
|
211
237
|
dataType: "date",
|
|
238
|
+
locale,
|
|
212
239
|
}),
|
|
213
240
|
);
|
|
214
241
|
case "Time":
|
|
215
242
|
return String(
|
|
216
|
-
applyFormat(new Date(), { format: "Time", dataType: "date" }),
|
|
243
|
+
applyFormat(new Date(), { format: "Time", dataType: "date", locale }),
|
|
217
244
|
);
|
|
218
245
|
case "Percent":
|
|
219
246
|
return String(
|
|
220
|
-
applyFormat(0.1234, { format: "Percent", dataType: "number" }),
|
|
247
|
+
applyFormat(0.1234, { format: "Percent", dataType: "number", locale }),
|
|
221
248
|
);
|
|
222
249
|
case "Scientific":
|
|
223
250
|
return String(
|
|
224
251
|
applyFormat(12_345_678_910, {
|
|
225
252
|
format: "Scientific",
|
|
226
253
|
dataType: "number",
|
|
254
|
+
locale,
|
|
227
255
|
}),
|
|
228
256
|
);
|
|
229
257
|
case "Engineering":
|
|
@@ -231,15 +259,20 @@ export function formattingExample(
|
|
|
231
259
|
applyFormat(12_345_678_910, {
|
|
232
260
|
format: "Engineering",
|
|
233
261
|
dataType: "number",
|
|
262
|
+
locale,
|
|
234
263
|
}),
|
|
235
264
|
);
|
|
236
265
|
case "Integer":
|
|
237
266
|
return String(
|
|
238
|
-
applyFormat(1234.567, {
|
|
267
|
+
applyFormat(1234.567, {
|
|
268
|
+
format: "Integer",
|
|
269
|
+
dataType: "number",
|
|
270
|
+
locale,
|
|
271
|
+
}),
|
|
239
272
|
);
|
|
240
273
|
case "Auto":
|
|
241
274
|
return String(
|
|
242
|
-
applyFormat(1234.567, { format: "Auto", dataType: "number" }),
|
|
275
|
+
applyFormat(1234.567, { format: "Auto", dataType: "number", locale }),
|
|
243
276
|
);
|
|
244
277
|
default:
|
|
245
278
|
return null;
|
|
@@ -28,6 +28,7 @@ export interface ColumnFormattingTableState {
|
|
|
28
28
|
|
|
29
29
|
// define types for column formatting's table options
|
|
30
30
|
export interface ColumnFormattingOptions {
|
|
31
|
+
locale: string;
|
|
31
32
|
enableColumnFormatting?: boolean;
|
|
32
33
|
onColumnFormattingChange?: OnChangeFn<ColumnFormattingState>;
|
|
33
34
|
}
|
|
@@ -5,6 +5,7 @@ import type { Column } from "@tanstack/react-table";
|
|
|
5
5
|
import { capitalize } from "lodash-es";
|
|
6
6
|
import { FilterIcon, MinusIcon, TextIcon, XIcon } from "lucide-react";
|
|
7
7
|
import { useMemo, useRef, useState } from "react";
|
|
8
|
+
import { useLocale } from "react-aria";
|
|
8
9
|
import {
|
|
9
10
|
DropdownMenu,
|
|
10
11
|
DropdownMenuContent,
|
|
@@ -76,6 +77,7 @@ export const DataTableColumnHeader = <TData, TValue>({
|
|
|
76
77
|
calculateTopKRows,
|
|
77
78
|
}: DataTableColumnHeaderProps<TData, TValue>) => {
|
|
78
79
|
const [isFilterValueOpen, setIsFilterValueOpen] = useState(false);
|
|
80
|
+
const { locale } = useLocale();
|
|
79
81
|
|
|
80
82
|
// No header
|
|
81
83
|
if (!header) {
|
|
@@ -119,7 +121,7 @@ export const DataTableColumnHeader = <TData, TValue>({
|
|
|
119
121
|
{renderCopyColumn(column)}
|
|
120
122
|
{renderColumnPinning(column)}
|
|
121
123
|
{renderColumnWrapping(column)}
|
|
122
|
-
{renderFormatOptions(column)}
|
|
124
|
+
{renderFormatOptions(column, locale)}
|
|
123
125
|
<DropdownMenuSeparator />
|
|
124
126
|
{renderMenuItemFilter(column)}
|
|
125
127
|
{renderFilterByValues(column, setIsFilterValueOpen)}
|
|
@@ -64,17 +64,34 @@ export class ColumnChartSpecModel<T> {
|
|
|
64
64
|
private dataSpec: TopLevelSpec["data"];
|
|
65
65
|
private sourceName: "data_0" | "source_0";
|
|
66
66
|
|
|
67
|
+
private readonly data: T[] | string;
|
|
68
|
+
private readonly fieldTypes: FieldTypes;
|
|
69
|
+
readonly stats: Record<ColumnName, Partial<ColumnHeaderStats>>;
|
|
70
|
+
readonly binValues: Record<ColumnName, BinValues>;
|
|
71
|
+
readonly valueCounts: Record<ColumnName, ValueCounts>;
|
|
72
|
+
private readonly opts: {
|
|
73
|
+
includeCharts: boolean;
|
|
74
|
+
usePreComputedValues?: boolean;
|
|
75
|
+
};
|
|
76
|
+
|
|
67
77
|
constructor(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
78
|
+
data: T[] | string,
|
|
79
|
+
fieldTypes: FieldTypes,
|
|
80
|
+
stats: Record<ColumnName, Partial<ColumnHeaderStats>>,
|
|
81
|
+
binValues: Record<ColumnName, BinValues>,
|
|
82
|
+
valueCounts: Record<ColumnName, ValueCounts>,
|
|
83
|
+
opts: {
|
|
74
84
|
includeCharts: boolean;
|
|
75
85
|
usePreComputedValues?: boolean;
|
|
76
86
|
},
|
|
77
87
|
) {
|
|
88
|
+
this.data = data;
|
|
89
|
+
this.fieldTypes = fieldTypes;
|
|
90
|
+
this.stats = stats;
|
|
91
|
+
this.binValues = binValues;
|
|
92
|
+
this.valueCounts = valueCounts;
|
|
93
|
+
this.opts = opts;
|
|
94
|
+
|
|
78
95
|
// Data may come in from a few different sources:
|
|
79
96
|
// - A URL
|
|
80
97
|
// - A CSV data URI (e.g. "data:text/csv;base64,...")
|
|
@@ -93,9 +110,9 @@ export class ColumnChartSpecModel<T> {
|
|
|
93
110
|
const decoded = typedAtob(base64);
|
|
94
111
|
|
|
95
112
|
if (decoded.startsWith(ARROW_MAGIC_NUMBER)) {
|
|
113
|
+
// @ts-expect-error vega-typings does not include arrow format
|
|
96
114
|
this.dataSpec = {
|
|
97
115
|
values: byteStringToBinary(decoded),
|
|
98
|
-
// @ts-expect-error vega-typings does not include arrow format
|
|
99
116
|
format: { type: "arrow" },
|
|
100
117
|
};
|
|
101
118
|
} else {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* Copyright 2024 Marimo. All rights reserved. */
|
|
2
2
|
import React, { Suspense } from "react";
|
|
3
|
+
import { useLocale } from "react-aria";
|
|
3
4
|
import { createBatchedLoader } from "@/plugins/impl/vega/batched";
|
|
4
5
|
import { useTheme } from "@/theme/useTheme";
|
|
5
6
|
import { logNever } from "@/utils/assertNever";
|
|
@@ -29,6 +30,8 @@ const batchedLoader = createBatchedLoader();
|
|
|
29
30
|
export const TableColumnSummary = <TData, TValue>({
|
|
30
31
|
columnId,
|
|
31
32
|
}: Props<TData, TValue>) => {
|
|
33
|
+
const { locale } = useLocale();
|
|
34
|
+
|
|
32
35
|
const chartSpecModel = React.use(ColumnChartContext);
|
|
33
36
|
const { theme } = useTheme();
|
|
34
37
|
const { spec, type, stats } = chartSpecModel.getHeaderSummary(columnId);
|
|
@@ -65,7 +68,7 @@ export const TableColumnSummary = <TData, TValue>({
|
|
|
65
68
|
) => {
|
|
66
69
|
return (
|
|
67
70
|
<DatePopover date={date} type={type}>
|
|
68
|
-
{prettyDate(date, type)}
|
|
71
|
+
{prettyDate(date, type, locale)}
|
|
69
72
|
</DatePopover>
|
|
70
73
|
);
|
|
71
74
|
};
|
|
@@ -84,7 +87,7 @@ export const TableColumnSummary = <TData, TValue>({
|
|
|
84
87
|
<div className="flex flex-col whitespace-pre">
|
|
85
88
|
<span>min: {renderDate(stats.min, type)}</span>
|
|
86
89
|
<span>max: {renderDate(stats.max, type)}</span>
|
|
87
|
-
<span>unique: {prettyNumber(stats.unique)}</span>
|
|
90
|
+
<span>unique: {prettyNumber(stats.unique, locale)}</span>
|
|
88
91
|
</div>
|
|
89
92
|
);
|
|
90
93
|
}
|
|
@@ -106,16 +109,22 @@ export const TableColumnSummary = <TData, TValue>({
|
|
|
106
109
|
<span>
|
|
107
110
|
min:{" "}
|
|
108
111
|
{typeof stats.min === "number"
|
|
109
|
-
? prettyScientificNumber(stats.min, {
|
|
112
|
+
? prettyScientificNumber(stats.min, {
|
|
113
|
+
shouldRound: true,
|
|
114
|
+
locale,
|
|
115
|
+
})
|
|
110
116
|
: stats.min}
|
|
111
117
|
</span>
|
|
112
118
|
<span>
|
|
113
119
|
max:{" "}
|
|
114
120
|
{typeof stats.max === "number"
|
|
115
|
-
? prettyScientificNumber(stats.max, {
|
|
121
|
+
? prettyScientificNumber(stats.max, {
|
|
122
|
+
shouldRound: true,
|
|
123
|
+
locale,
|
|
124
|
+
})
|
|
116
125
|
: stats.max}
|
|
117
126
|
</span>
|
|
118
|
-
<span>unique: {prettyNumber(stats.unique)}</span>
|
|
127
|
+
<span>unique: {prettyNumber(stats.unique, locale)}</span>
|
|
119
128
|
</div>
|
|
120
129
|
);
|
|
121
130
|
}
|
|
@@ -127,8 +136,8 @@ export const TableColumnSummary = <TData, TValue>({
|
|
|
127
136
|
if (!spec) {
|
|
128
137
|
return (
|
|
129
138
|
<div className="flex flex-col whitespace-pre">
|
|
130
|
-
<span>true: {prettyNumber(stats.true)}</span>
|
|
131
|
-
<span>false: {prettyNumber(stats.false)}</span>
|
|
139
|
+
<span>true: {prettyNumber(stats.true, locale)}</span>
|
|
140
|
+
<span>false: {prettyNumber(stats.false, locale)}</span>
|
|
132
141
|
</div>
|
|
133
142
|
);
|
|
134
143
|
}
|
|
@@ -140,7 +149,7 @@ export const TableColumnSummary = <TData, TValue>({
|
|
|
140
149
|
if (!spec) {
|
|
141
150
|
return (
|
|
142
151
|
<div className="flex flex-col whitespace-pre">
|
|
143
|
-
<span>unique: {prettyNumber(stats.unique)}</span>
|
|
152
|
+
<span>unique: {prettyNumber(stats.unique, locale)}</span>
|
|
144
153
|
</div>
|
|
145
154
|
);
|
|
146
155
|
}
|
|
@@ -148,7 +157,7 @@ export const TableColumnSummary = <TData, TValue>({
|
|
|
148
157
|
case "unknown":
|
|
149
158
|
return (
|
|
150
159
|
<div className="flex flex-col whitespace-pre">
|
|
151
|
-
<span>nulls: {prettyNumber(stats.nulls)}</span>
|
|
160
|
+
<span>nulls: {prettyNumber(stats.nulls, locale)}</span>
|
|
152
161
|
</div>
|
|
153
162
|
);
|
|
154
163
|
default:
|