@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
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { PopoverClose } from "@radix-ui/react-popover";
|
|
5
5
|
import type { Column, ColumnDef } from "@tanstack/react-table";
|
|
6
6
|
import { formatDate } from "date-fns";
|
|
7
|
+
import { WithLocale } from "@/core/i18n/with-locale";
|
|
7
8
|
import type { DataType } from "@/core/kernel/messages";
|
|
8
9
|
import type { CalculateTopKRows } from "@/plugins/impl/DataTablePlugin";
|
|
9
10
|
import { cn } from "@/utils/cn";
|
|
@@ -16,6 +17,7 @@ import { JsonOutput } from "../editor/output/JsonOutput";
|
|
|
16
17
|
import { Button } from "../ui/button";
|
|
17
18
|
import { Checkbox } from "../ui/checkbox";
|
|
18
19
|
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover";
|
|
20
|
+
import { Tooltip } from "../ui/tooltip";
|
|
19
21
|
import { DataTableColumnHeader } from "./column-header";
|
|
20
22
|
import type { ColumnChartSpecModel } from "./column-summary/chart-spec-model";
|
|
21
23
|
import { TableColumnSummary } from "./column-summary/column-summary";
|
|
@@ -102,6 +104,7 @@ export function generateColumns<T>({
|
|
|
102
104
|
chartSpecModel,
|
|
103
105
|
textJustifyColumns,
|
|
104
106
|
wrappedColumns,
|
|
107
|
+
headerTooltip,
|
|
105
108
|
showDataTypes,
|
|
106
109
|
calculateTopKRows,
|
|
107
110
|
}: {
|
|
@@ -111,6 +114,7 @@ export function generateColumns<T>({
|
|
|
111
114
|
chartSpecModel?: ColumnChartSpecModel<unknown>;
|
|
112
115
|
textJustifyColumns?: Record<string, "left" | "center" | "right">;
|
|
113
116
|
wrappedColumns?: string[];
|
|
117
|
+
headerTooltip?: Record<string, string>;
|
|
114
118
|
showDataTypes?: boolean;
|
|
115
119
|
calculateTopKRows?: CalculateTopKRows;
|
|
116
120
|
}): Array<ColumnDef<T>> {
|
|
@@ -164,6 +168,7 @@ export function generateColumns<T>({
|
|
|
164
168
|
header: ({ column }) => {
|
|
165
169
|
const stats = chartSpecModel?.getColumnStats(key);
|
|
166
170
|
const dtype = column.columnDef.meta?.dtype;
|
|
171
|
+
const headerTitle = headerTooltip?.[key];
|
|
167
172
|
const dtypeHeader =
|
|
168
173
|
showDataTypes && dtype ? (
|
|
169
174
|
<div className="flex flex-row gap-1">
|
|
@@ -178,14 +183,29 @@ export function generateColumns<T>({
|
|
|
178
183
|
|
|
179
184
|
const headerWithType = (
|
|
180
185
|
<div className="flex flex-col">
|
|
181
|
-
<span
|
|
186
|
+
<span
|
|
187
|
+
className={cn(
|
|
188
|
+
"font-bold",
|
|
189
|
+
headerTitle && "underline decoration-dotted",
|
|
190
|
+
)}
|
|
191
|
+
>
|
|
192
|
+
{key === "" ? " " : key}
|
|
193
|
+
</span>
|
|
182
194
|
{dtypeHeader}
|
|
183
195
|
</div>
|
|
184
196
|
);
|
|
185
197
|
|
|
198
|
+
const headerWithTooltip = headerTitle ? (
|
|
199
|
+
<Tooltip content={headerTitle} delayDuration={300}>
|
|
200
|
+
{headerWithType}
|
|
201
|
+
</Tooltip>
|
|
202
|
+
) : (
|
|
203
|
+
headerWithType
|
|
204
|
+
);
|
|
205
|
+
|
|
186
206
|
const dataTableColumnHeader = (
|
|
187
207
|
<DataTableColumnHeader
|
|
188
|
-
header={
|
|
208
|
+
header={headerWithTooltip}
|
|
189
209
|
column={column}
|
|
190
210
|
calculateTopKRows={calculateTopKRows}
|
|
191
211
|
/>
|
|
@@ -227,13 +247,13 @@ export function generateColumns<T>({
|
|
|
227
247
|
isCellSelected,
|
|
228
248
|
);
|
|
229
249
|
|
|
230
|
-
const renderedCell = renderCellValue(
|
|
250
|
+
const renderedCell = renderCellValue({
|
|
231
251
|
column,
|
|
232
252
|
renderValue,
|
|
233
253
|
getValue,
|
|
234
254
|
selectCell,
|
|
235
255
|
cellStyles,
|
|
236
|
-
);
|
|
256
|
+
});
|
|
237
257
|
|
|
238
258
|
// Row headers are bold
|
|
239
259
|
if (rowHeadersSet.has(key)) {
|
|
@@ -403,18 +423,25 @@ function renderAny(value: unknown): string {
|
|
|
403
423
|
}
|
|
404
424
|
}
|
|
405
425
|
|
|
406
|
-
function renderDate(
|
|
407
|
-
value
|
|
408
|
-
dataType
|
|
409
|
-
dtype
|
|
410
|
-
format
|
|
411
|
-
|
|
426
|
+
function renderDate({
|
|
427
|
+
value,
|
|
428
|
+
dataType,
|
|
429
|
+
dtype,
|
|
430
|
+
format,
|
|
431
|
+
locale,
|
|
432
|
+
}: {
|
|
433
|
+
value: Date;
|
|
434
|
+
dataType?: DataType;
|
|
435
|
+
dtype?: string;
|
|
436
|
+
format?: DateFormat | null;
|
|
437
|
+
locale: string;
|
|
438
|
+
}): React.ReactNode {
|
|
412
439
|
const type = dataType === "date" ? "date" : "datetime";
|
|
413
440
|
const timezone = extractTimezone(dtype);
|
|
414
441
|
|
|
415
442
|
const exactValue = format
|
|
416
443
|
? formatDate(value, format)
|
|
417
|
-
: exactDateTime(value, timezone);
|
|
444
|
+
: exactDateTime(value, timezone, locale);
|
|
418
445
|
|
|
419
446
|
return (
|
|
420
447
|
<DatePopover date={value} type={type}>
|
|
@@ -423,13 +450,19 @@ function renderDate(
|
|
|
423
450
|
);
|
|
424
451
|
}
|
|
425
452
|
|
|
426
|
-
export function renderCellValue<TData, TValue>(
|
|
427
|
-
column
|
|
428
|
-
renderValue
|
|
429
|
-
getValue
|
|
430
|
-
selectCell
|
|
431
|
-
cellStyles
|
|
432
|
-
|
|
453
|
+
export function renderCellValue<TData, TValue>({
|
|
454
|
+
column,
|
|
455
|
+
renderValue,
|
|
456
|
+
getValue,
|
|
457
|
+
selectCell,
|
|
458
|
+
cellStyles,
|
|
459
|
+
}: {
|
|
460
|
+
column: Column<TData, TValue>;
|
|
461
|
+
renderValue: () => TValue | null;
|
|
462
|
+
getValue: () => TValue;
|
|
463
|
+
selectCell?: () => void;
|
|
464
|
+
cellStyles?: string;
|
|
465
|
+
}) {
|
|
433
466
|
const value = getValue();
|
|
434
467
|
const format = column.getColumnFormatting?.();
|
|
435
468
|
|
|
@@ -440,7 +473,13 @@ export function renderCellValue<TData, TValue>(
|
|
|
440
473
|
try {
|
|
441
474
|
const date = new Date(value);
|
|
442
475
|
const format = getDateFormat(value);
|
|
443
|
-
return
|
|
476
|
+
return (
|
|
477
|
+
<WithLocale>
|
|
478
|
+
{(locale) =>
|
|
479
|
+
renderDate({ value: date, dataType, dtype, format, locale })
|
|
480
|
+
}
|
|
481
|
+
</WithLocale>
|
|
482
|
+
);
|
|
444
483
|
} catch (error) {
|
|
445
484
|
Logger.error("Error parsing datetime, fallback to string", error);
|
|
446
485
|
}
|
|
@@ -448,7 +487,11 @@ export function renderCellValue<TData, TValue>(
|
|
|
448
487
|
|
|
449
488
|
if (value instanceof Date) {
|
|
450
489
|
// e.g. 2010-10-07 17:15:00
|
|
451
|
-
return
|
|
490
|
+
return (
|
|
491
|
+
<WithLocale>
|
|
492
|
+
{(locale) => renderDate({ value, dataType, dtype, locale })}
|
|
493
|
+
</WithLocale>
|
|
494
|
+
);
|
|
452
495
|
}
|
|
453
496
|
|
|
454
497
|
if (typeof value === "string") {
|
|
@@ -19,11 +19,13 @@ import {
|
|
|
19
19
|
useReactTable,
|
|
20
20
|
} from "@tanstack/react-table";
|
|
21
21
|
import React, { memo } from "react";
|
|
22
|
+
import { useLocale } from "react-aria";
|
|
22
23
|
|
|
23
24
|
import { Table } from "@/components/ui/table";
|
|
24
25
|
import type { GetRowIds } from "@/plugins/impl/DataTablePlugin";
|
|
25
26
|
import { cn } from "@/utils/cn";
|
|
26
27
|
import type { PanelType } from "../editor/chrome/panels/context-aware-panel/context-aware-panel";
|
|
28
|
+
import { CellHoverTemplateFeature } from "./cell-hover-template/feature";
|
|
27
29
|
import { CellSelectionFeature } from "./cell-selection/feature";
|
|
28
30
|
import type { CellSelectionState } from "./cell-selection/types";
|
|
29
31
|
import { CellStylingFeature } from "./cell-styling/feature";
|
|
@@ -63,6 +65,7 @@ interface DataTableProps<TData> extends Partial<DownloadActionProps> {
|
|
|
63
65
|
rowSelection?: RowSelectionState;
|
|
64
66
|
cellSelection?: CellSelectionState;
|
|
65
67
|
cellStyling?: CellStyleState | null;
|
|
68
|
+
hoverTemplate?: string | null;
|
|
66
69
|
onRowSelectionChange?: OnChangeFn<RowSelectionState>;
|
|
67
70
|
onCellSelectionChange?: OnChangeFn<CellSelectionState>;
|
|
68
71
|
getRowIds?: GetRowIds;
|
|
@@ -103,6 +106,7 @@ const DataTableInternal = <TData,>({
|
|
|
103
106
|
rowSelection,
|
|
104
107
|
cellSelection,
|
|
105
108
|
cellStyling,
|
|
109
|
+
hoverTemplate,
|
|
106
110
|
paginationState,
|
|
107
111
|
setPaginationState,
|
|
108
112
|
downloadAs,
|
|
@@ -131,6 +135,7 @@ const DataTableInternal = <TData,>({
|
|
|
131
135
|
}: DataTableProps<TData>) => {
|
|
132
136
|
const [isSearchEnabled, setIsSearchEnabled] = React.useState<boolean>(false);
|
|
133
137
|
const [showLoadingBar, setShowLoadingBar] = React.useState<boolean>(false);
|
|
138
|
+
const { locale } = useLocale();
|
|
134
139
|
|
|
135
140
|
const { columnPinning, setColumnPinning } = useColumnPinning(
|
|
136
141
|
freezeColumnsLeft,
|
|
@@ -176,6 +181,7 @@ const DataTableInternal = <TData,>({
|
|
|
176
181
|
ColumnFormattingFeature,
|
|
177
182
|
CellSelectionFeature,
|
|
178
183
|
CellStylingFeature,
|
|
184
|
+
CellHoverTemplateFeature,
|
|
179
185
|
CopyColumnFeature,
|
|
180
186
|
FocusRowFeature,
|
|
181
187
|
],
|
|
@@ -199,6 +205,7 @@ const DataTableInternal = <TData,>({
|
|
|
199
205
|
},
|
|
200
206
|
}
|
|
201
207
|
: {}),
|
|
208
|
+
locale: locale,
|
|
202
209
|
manualPagination: manualPagination,
|
|
203
210
|
getPaginationRowModel: getPaginationRowModel(),
|
|
204
211
|
// sorting
|
|
@@ -233,10 +240,11 @@ const DataTableInternal = <TData,>({
|
|
|
233
240
|
? {}
|
|
234
241
|
: // No pagination, show all rows
|
|
235
242
|
{ pagination: { pageIndex: 0, pageSize: data.length } }),
|
|
236
|
-
rowSelection,
|
|
237
|
-
cellSelection,
|
|
243
|
+
rowSelection: rowSelection ?? {},
|
|
244
|
+
cellSelection: cellSelection ?? [],
|
|
238
245
|
cellStyling,
|
|
239
246
|
columnPinning: columnPinning,
|
|
247
|
+
cellHoverTemplate: hoverTemplate,
|
|
240
248
|
},
|
|
241
249
|
});
|
|
242
250
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* Copyright 2024 Marimo. All rights reserved. */
|
|
2
2
|
import React from "react";
|
|
3
|
+
import { useDateFormatter, useLocale } from "react-aria";
|
|
3
4
|
import { Tooltip } from "@/components/ui/tooltip";
|
|
4
5
|
|
|
5
6
|
interface DatePopoverProps {
|
|
@@ -19,33 +20,17 @@ export const DatePopover: React.FC<DatePopoverProps> = ({
|
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
const dateObj = new Date(date);
|
|
22
|
-
const relativeTime = getRelativeTime(dateObj);
|
|
23
23
|
|
|
24
24
|
const content = (
|
|
25
25
|
<div className="min-w-[240px] p-1 text-sm">
|
|
26
|
-
<div className="text-muted-foreground mb-2">
|
|
26
|
+
<div className="text-muted-foreground mb-2">
|
|
27
|
+
<RelativeTime date={dateObj} />
|
|
28
|
+
</div>
|
|
27
29
|
<div className="space-y-1">
|
|
28
30
|
{type === "datetime" ? (
|
|
29
|
-
|
|
30
|
-
([timezone, formattedDate]) => (
|
|
31
|
-
<div
|
|
32
|
-
key={timezone}
|
|
33
|
-
className="grid grid-cols-[fit-content(40px)_1fr] gap-4 items-center justify-items-end"
|
|
34
|
-
>
|
|
35
|
-
<span className="bg-muted rounded-md py-1 px-2 w-fit ml-auto">
|
|
36
|
-
{timezone}
|
|
37
|
-
</span>
|
|
38
|
-
<span>{formattedDate}</span>
|
|
39
|
-
</div>
|
|
40
|
-
),
|
|
41
|
-
)
|
|
31
|
+
<TimezoneDisplay date={dateObj} />
|
|
42
32
|
) : (
|
|
43
|
-
<
|
|
44
|
-
{dateObj.toLocaleDateString("en-US", {
|
|
45
|
-
timeZone: "UTC",
|
|
46
|
-
dateStyle: "long",
|
|
47
|
-
})}
|
|
48
|
-
</span>
|
|
33
|
+
<DateDisplay date={dateObj} />
|
|
49
34
|
)}
|
|
50
35
|
</div>
|
|
51
36
|
</div>
|
|
@@ -58,57 +43,79 @@ export const DatePopover: React.FC<DatePopoverProps> = ({
|
|
|
58
43
|
);
|
|
59
44
|
};
|
|
60
45
|
|
|
61
|
-
|
|
62
|
-
const
|
|
63
|
-
|
|
46
|
+
const TimezoneDisplay = ({ date }: { date: Date }) => {
|
|
47
|
+
const { locale } = useLocale();
|
|
48
|
+
const localTimezone = Intl.DateTimeFormat(locale).resolvedOptions().timeZone;
|
|
64
49
|
const hasSubSeconds = date.getUTCMilliseconds() !== 0;
|
|
65
|
-
if (hasSubSeconds) {
|
|
66
|
-
return {
|
|
67
|
-
UTC: new Intl.DateTimeFormat("en-US", {
|
|
68
|
-
timeZone: "UTC",
|
|
69
|
-
year: "numeric",
|
|
70
|
-
month: "2-digit",
|
|
71
|
-
day: "2-digit",
|
|
72
|
-
hour: "2-digit",
|
|
73
|
-
minute: "2-digit",
|
|
74
|
-
second: "2-digit",
|
|
75
|
-
fractionalSecondDigits: 3,
|
|
76
|
-
}).format(date),
|
|
77
|
-
[localTimezone]: new Intl.DateTimeFormat("en-US", {
|
|
78
|
-
timeZone: localTimezone,
|
|
79
|
-
year: "numeric",
|
|
80
|
-
month: "2-digit",
|
|
81
|
-
day: "2-digit",
|
|
82
|
-
hour: "2-digit",
|
|
83
|
-
minute: "2-digit",
|
|
84
|
-
second: "2-digit",
|
|
85
|
-
fractionalSecondDigits: 3,
|
|
86
|
-
}).format(date),
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
50
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
51
|
+
const utcFormatter = useDateFormatter(
|
|
52
|
+
hasSubSeconds
|
|
53
|
+
? {
|
|
54
|
+
timeZone: "UTC",
|
|
55
|
+
year: "numeric",
|
|
56
|
+
month: "2-digit",
|
|
57
|
+
day: "2-digit",
|
|
58
|
+
hour: "2-digit",
|
|
59
|
+
minute: "2-digit",
|
|
60
|
+
second: "2-digit",
|
|
61
|
+
fractionalSecondDigits: 3,
|
|
62
|
+
}
|
|
63
|
+
: {
|
|
64
|
+
timeZone: "UTC",
|
|
65
|
+
dateStyle: "long",
|
|
66
|
+
timeStyle: "medium",
|
|
67
|
+
},
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
const localFormatter = useDateFormatter(
|
|
71
|
+
hasSubSeconds
|
|
72
|
+
? {
|
|
73
|
+
timeZone: localTimezone,
|
|
74
|
+
year: "numeric",
|
|
75
|
+
month: "2-digit",
|
|
76
|
+
day: "2-digit",
|
|
77
|
+
hour: "2-digit",
|
|
78
|
+
minute: "2-digit",
|
|
79
|
+
second: "2-digit",
|
|
80
|
+
fractionalSecondDigits: 3,
|
|
81
|
+
}
|
|
82
|
+
: {
|
|
83
|
+
timeZone: localTimezone,
|
|
84
|
+
dateStyle: "long",
|
|
85
|
+
timeStyle: "medium",
|
|
86
|
+
},
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
return (
|
|
90
|
+
<>
|
|
91
|
+
<div className="grid grid-cols-[fit-content(40px)_1fr] gap-4 items-center justify-items-end">
|
|
92
|
+
<span className="bg-muted rounded-md py-1 px-2 w-fit ml-auto">UTC</span>
|
|
93
|
+
<span>{utcFormatter.format(date)}</span>
|
|
94
|
+
</div>
|
|
95
|
+
<div className="grid grid-cols-[fit-content(40px)_1fr] gap-4 items-center justify-items-end">
|
|
96
|
+
<span className="bg-muted rounded-md py-1 px-2 w-fit ml-auto">
|
|
97
|
+
{localTimezone}
|
|
98
|
+
</span>
|
|
99
|
+
<span>{localFormatter.format(date)}</span>
|
|
100
|
+
</div>
|
|
101
|
+
</>
|
|
102
|
+
);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const DateDisplay = ({ date }: { date: Date }) => {
|
|
106
|
+
const dateFormatter = useDateFormatter({
|
|
107
|
+
timeZone: "UTC",
|
|
108
|
+
dateStyle: "long",
|
|
109
|
+
});
|
|
103
110
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
//
|
|
111
|
-
const relativeTimeFormatter = new Intl.RelativeTimeFormat(
|
|
111
|
+
return <span>{dateFormatter.format(date)}</span>;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const RelativeTime = ({ date }: { date: Date }) => {
|
|
115
|
+
const { locale } = useLocale();
|
|
116
|
+
|
|
117
|
+
// Initialize relative time formatter with current locale and "auto" numeric style
|
|
118
|
+
const relativeTimeFormatter = new Intl.RelativeTimeFormat(locale, {
|
|
112
119
|
numeric: "auto",
|
|
113
120
|
});
|
|
114
121
|
|
|
@@ -117,7 +124,6 @@ function getRelativeTime(date: Date): string {
|
|
|
117
124
|
const differenceInSeconds = (currentTime.getTime() - date.getTime()) / 1000;
|
|
118
125
|
|
|
119
126
|
// Define time units with their thresholds and conversion factors
|
|
120
|
-
// Format: [threshold before next unit, seconds in this unit, unit name]
|
|
121
127
|
const timeUnits: Array<[number, number, string]> = [
|
|
122
128
|
[60, 1, "second"], // Less than 60 seconds
|
|
123
129
|
[60, 60, "minute"], // Less than 60 minutes
|
|
@@ -134,13 +140,17 @@ function getRelativeTime(date: Date): string {
|
|
|
134
140
|
// Convert to fixed decimal and negate since RelativeTimeFormat expects
|
|
135
141
|
// negative values for past times and positive for future times
|
|
136
142
|
const roundedValue = -Number(valueInUnits.toFixed(1));
|
|
137
|
-
return
|
|
138
|
-
|
|
139
|
-
|
|
143
|
+
return (
|
|
144
|
+
<span>
|
|
145
|
+
{relativeTimeFormatter.format(
|
|
146
|
+
roundedValue,
|
|
147
|
+
unitName as Intl.RelativeTimeFormatUnit,
|
|
148
|
+
)}
|
|
149
|
+
</span>
|
|
140
150
|
);
|
|
141
151
|
}
|
|
142
152
|
}
|
|
143
153
|
|
|
144
154
|
// Should never reach here due to Infinity threshold, but provide fallback
|
|
145
|
-
return relativeTimeFormatter.format(0, "second")
|
|
146
|
-
}
|
|
155
|
+
return <span>{relativeTimeFormatter.format(0, "second")}</span>;
|
|
156
|
+
};
|
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
Table,
|
|
8
8
|
} from "@tanstack/react-table";
|
|
9
9
|
import { XIcon } from "lucide-react";
|
|
10
|
+
import { type DateFormatter, useDateFormatter } from "react-aria";
|
|
10
11
|
import { logNever } from "@/utils/assertNever";
|
|
11
12
|
import { Badge } from "../ui/badge";
|
|
12
13
|
import type { ColumnFilterValue } from "./filters";
|
|
@@ -18,12 +19,21 @@ interface Props<TData> {
|
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
export const FilterPills = <TData,>({ filters, table }: Props<TData>) => {
|
|
22
|
+
const timeFormatter = useDateFormatter({
|
|
23
|
+
hour: "2-digit",
|
|
24
|
+
minute: "2-digit",
|
|
25
|
+
second: "2-digit",
|
|
26
|
+
});
|
|
27
|
+
|
|
21
28
|
if (!filters || filters.length === 0) {
|
|
22
29
|
return null;
|
|
23
30
|
}
|
|
24
31
|
|
|
25
32
|
function renderFilterPill(filter: ColumnFilter) {
|
|
26
|
-
const formattedValue = formatValue(
|
|
33
|
+
const formattedValue = formatValue(
|
|
34
|
+
filter.value as ColumnFilterValue,
|
|
35
|
+
timeFormatter,
|
|
36
|
+
);
|
|
27
37
|
if (!formattedValue) {
|
|
28
38
|
return null;
|
|
29
39
|
}
|
|
@@ -52,7 +62,7 @@ export const FilterPills = <TData,>({ filters, table }: Props<TData>) => {
|
|
|
52
62
|
);
|
|
53
63
|
};
|
|
54
64
|
|
|
55
|
-
function formatValue(value: ColumnFilterValue) {
|
|
65
|
+
function formatValue(value: ColumnFilterValue, timeFormatter: DateFormatter) {
|
|
56
66
|
if (!("type" in value)) {
|
|
57
67
|
return;
|
|
58
68
|
}
|
|
@@ -71,14 +81,9 @@ function formatValue(value: ColumnFilterValue) {
|
|
|
71
81
|
return formatMinMax(value.min?.toISOString(), value.max?.toISOString());
|
|
72
82
|
}
|
|
73
83
|
if (value.type === "time") {
|
|
74
|
-
const formatTime = new Intl.DateTimeFormat("en-US", {
|
|
75
|
-
hour: "2-digit",
|
|
76
|
-
minute: "2-digit",
|
|
77
|
-
second: "2-digit",
|
|
78
|
-
});
|
|
79
84
|
return formatMinMax(
|
|
80
|
-
value.min ?
|
|
81
|
-
value.max ?
|
|
85
|
+
value.min ? timeFormatter.format(value.min) : undefined,
|
|
86
|
+
value.max ? timeFormatter.format(value.max) : undefined,
|
|
82
87
|
);
|
|
83
88
|
}
|
|
84
89
|
if (value.type === "datetime") {
|
|
@@ -34,6 +34,7 @@ import { NAMELESS_COLUMN_PREFIX } from "./columns";
|
|
|
34
34
|
|
|
35
35
|
export function renderFormatOptions<TData, TValue>(
|
|
36
36
|
column: Column<TData, TValue>,
|
|
37
|
+
locale: string,
|
|
37
38
|
) {
|
|
38
39
|
const dataType: DataType | undefined = column.columnDef.meta?.dataType;
|
|
39
40
|
const columnFormatOptions = dataType ? formatOptions[dataType] : [];
|
|
@@ -51,6 +52,9 @@ export function renderFormatOptions<TData, TValue>(
|
|
|
51
52
|
</DropdownMenuSubTrigger>
|
|
52
53
|
<DropdownMenuPortal>
|
|
53
54
|
<DropdownMenuSubContent>
|
|
55
|
+
<div className="text-xs text-muted-foreground px-2 py-1">
|
|
56
|
+
Locale: {locale}
|
|
57
|
+
</div>
|
|
54
58
|
{Boolean(currentFormat) && (
|
|
55
59
|
<>
|
|
56
60
|
<DropdownMenuItem
|
|
@@ -72,7 +76,7 @@ export function renderFormatOptions<TData, TValue>(
|
|
|
72
76
|
{option}
|
|
73
77
|
</span>
|
|
74
78
|
<span className="ml-auto pl-5 text-xs text-muted-foreground">
|
|
75
|
-
{formattingExample(option)}
|
|
79
|
+
{formattingExample(option, locale)}
|
|
76
80
|
</span>
|
|
77
81
|
</DropdownMenuItem>
|
|
78
82
|
))}
|
|
@@ -9,8 +9,10 @@ import {
|
|
|
9
9
|
ChevronsLeft,
|
|
10
10
|
ChevronsRight,
|
|
11
11
|
} from "lucide-react";
|
|
12
|
+
import { useLocale } from "react-aria";
|
|
12
13
|
import { Button } from "@/components/ui/button";
|
|
13
14
|
import { Events } from "@/utils/events";
|
|
15
|
+
import { prettyNumber } from "@/utils/numbers";
|
|
14
16
|
import { PluralWord } from "@/utils/pluralize";
|
|
15
17
|
import {
|
|
16
18
|
Select,
|
|
@@ -40,6 +42,8 @@ export const DataTablePagination = <TData,>({
|
|
|
40
42
|
tableLoading,
|
|
41
43
|
showPageSizeSelector,
|
|
42
44
|
}: DataTablePaginationProps<TData>) => {
|
|
45
|
+
const { locale } = useLocale();
|
|
46
|
+
|
|
43
47
|
const renderTotal = () => {
|
|
44
48
|
const { rowSelection, cellSelection } = table.getState();
|
|
45
49
|
let selected = Object.keys(rowSelection).length;
|
|
@@ -58,7 +62,7 @@ export const DataTablePagination = <TData,>({
|
|
|
58
62
|
if (isAllPageSelected && !isAllSelected) {
|
|
59
63
|
return (
|
|
60
64
|
<>
|
|
61
|
-
<span>{prettyNumber(selected)} selected</span>
|
|
65
|
+
<span>{prettyNumber(selected, locale)} selected</span>
|
|
62
66
|
<Button
|
|
63
67
|
size="xs"
|
|
64
68
|
data-testid="select-all-button"
|
|
@@ -73,7 +77,7 @@ export const DataTablePagination = <TData,>({
|
|
|
73
77
|
}
|
|
74
78
|
}}
|
|
75
79
|
>
|
|
76
|
-
Select all {prettyNumber(numRows)}
|
|
80
|
+
Select all {prettyNumber(numRows, locale)}
|
|
77
81
|
</Button>
|
|
78
82
|
</>
|
|
79
83
|
);
|
|
@@ -82,7 +86,7 @@ export const DataTablePagination = <TData,>({
|
|
|
82
86
|
if (selected) {
|
|
83
87
|
return (
|
|
84
88
|
<>
|
|
85
|
-
<span>{prettyNumber(selected)} selected</span>
|
|
89
|
+
<span>{prettyNumber(selected, locale)} selected</span>
|
|
86
90
|
<Button
|
|
87
91
|
size="xs"
|
|
88
92
|
data-testid="clear-selection-button"
|
|
@@ -107,7 +111,11 @@ export const DataTablePagination = <TData,>({
|
|
|
107
111
|
);
|
|
108
112
|
}
|
|
109
113
|
|
|
110
|
-
const rowColumnCount = prettifyRowColumnCount(
|
|
114
|
+
const rowColumnCount = prettifyRowColumnCount(
|
|
115
|
+
numRows,
|
|
116
|
+
totalColumns,
|
|
117
|
+
locale,
|
|
118
|
+
);
|
|
111
119
|
return <span>{rowColumnCount}</span>;
|
|
112
120
|
};
|
|
113
121
|
const currentPage = Math.min(
|
|
@@ -199,7 +207,9 @@ export const DataTablePagination = <TData,>({
|
|
|
199
207
|
handlePageChange(() => table.setPageIndex(page))
|
|
200
208
|
}
|
|
201
209
|
/>
|
|
202
|
-
<span className="shrink-0">
|
|
210
|
+
<span className="shrink-0">
|
|
211
|
+
of {prettyNumber(totalPages, locale)}
|
|
212
|
+
</span>
|
|
203
213
|
</div>
|
|
204
214
|
<Button
|
|
205
215
|
size="xs"
|
|
@@ -232,10 +242,6 @@ export const DataTablePagination = <TData,>({
|
|
|
232
242
|
);
|
|
233
243
|
};
|
|
234
244
|
|
|
235
|
-
function prettyNumber(value: number): string {
|
|
236
|
-
return new Intl.NumberFormat().format(value);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
245
|
export const PageSelector = ({
|
|
240
246
|
currentPage,
|
|
241
247
|
totalPages,
|
|
@@ -313,17 +319,18 @@ export const PageSelector = ({
|
|
|
313
319
|
);
|
|
314
320
|
};
|
|
315
321
|
|
|
316
|
-
export function prettifyRowCount(rowCount: number): string {
|
|
317
|
-
return `${prettyNumber(rowCount)} ${new PluralWord("row").pluralize(rowCount)}`;
|
|
322
|
+
export function prettifyRowCount(rowCount: number, locale: string): string {
|
|
323
|
+
return `${prettyNumber(rowCount, locale)} ${new PluralWord("row").pluralize(rowCount)}`;
|
|
318
324
|
}
|
|
319
325
|
|
|
320
326
|
export const prettifyRowColumnCount = (
|
|
321
327
|
numRows: number | "too_many",
|
|
322
328
|
totalColumns: number,
|
|
329
|
+
locale: string,
|
|
323
330
|
): string => {
|
|
324
331
|
const rowsLabel =
|
|
325
|
-
numRows === "too_many" ? "Unknown" : prettifyRowCount(numRows);
|
|
326
|
-
const columnsLabel = `${prettyNumber(totalColumns)} ${new PluralWord("column").pluralize(totalColumns)}`;
|
|
332
|
+
numRows === "too_many" ? "Unknown" : prettifyRowCount(numRows, locale);
|
|
333
|
+
const columnsLabel = `${prettyNumber(totalColumns, locale)} ${new PluralWord("column").pluralize(totalColumns)}`;
|
|
327
334
|
|
|
328
335
|
return [rowsLabel, columnsLabel].join(", ");
|
|
329
336
|
};
|