@marimo-team/islands 0.23.9-dev3 → 0.23.9-dev32
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/{ConnectedDataExplorerComponent-2lBNiUv6.js → ConnectedDataExplorerComponent-MJy-Ll40.js} +20 -20
- package/dist/ErrorBoundary-rULOrC_p.js +175 -0
- package/dist/{ImageComparisonComponent-CNHIsPDj.js → ImageComparisonComponent-CHrI72em.js} +1 -1
- package/dist/{Plot-4wn-lMVn.js → Plot-CAYS29h9.js} +1 -1
- package/dist/{_baseUniq-CxZRxRRo.js → _baseUniq-B_2Hw7zG.js} +3 -3
- package/dist/{any-language-editor-VWs_7v27.js → any-language-editor-DfdpyDv_.js} +23 -23
- package/dist/architecture-7HQA4BMR-Kyc44TmC.js +6 -0
- package/dist/{architectureDiagram-VXUJARFQ-CXVJxFhH.js → architectureDiagram-VXUJARFQ-CT2SuxNw.js} +15 -15
- package/dist/{arrays-CldYf7p7.js → arrays-sEtDRoG4.js} +1 -1
- package/dist/assets/__vite-browser-external-BBEFRPue.js +1 -0
- package/dist/assets/{worker-CpBbwbQo.js → worker-BoAkAmaG.js} +2 -2
- package/dist/{blockDiagram-VD42YOAC-DGDaxR8I.js → blockDiagram-VD42YOAC-Dy7hlFla.js} +7 -7
- package/dist/{button-Dj4BTre0.js → button-C5K9fIPF.js} +2 -2
- package/dist/{c4Diagram-YG6GDRKO-C2hc6ne8.js → c4Diagram-YG6GDRKO-BXlAmZ8Z.js} +4 -4
- package/dist/{capabilities-C9rrYCzf.js → capabilities-BceAxrAW.js} +2 -2
- package/dist/{channel-BBoIVUrJ.js → channel-D_PHgcig.js} +1 -1
- package/dist/{chat-ui-D3XBept8.js → chat-ui-CpX2YcGy.js} +3084 -3057
- package/dist/{check-BcUIXnUT.js → check-DTbrK0zt.js} +1 -1
- package/dist/{chunk-4F5CHEZ2-BZq7Kom7.js → chunk-4F5CHEZ2-D9nGEHV8.js} +1 -1
- package/dist/{chunk-5FQGJX7Z-BOg95xG5.js → chunk-5FQGJX7Z-BNjes6Yx.js} +5 -5
- package/dist/{chunk-ABZYJK2D-D0cLy8Bb.js → chunk-ABZYJK2D-Dz0-H2B5.js} +1 -1
- package/dist/{chunk-ATLVNIR6-BXsEjlHF.js → chunk-ATLVNIR6-o0Z5MZLd.js} +1 -1
- package/dist/{chunk-B2363JML-D9-XOau1.js → chunk-B2363JML-KEJpLGGP.js} +1 -1
- package/dist/{chunk-B4BG7PRW-Q1usn6T3.js → chunk-B4BG7PRW-BL98U9B4.js} +4 -4
- package/dist/{chunk-DI55MBZ5-D1qLYNrb.js → chunk-DI55MBZ5-Dwkn0LWm.js} +4 -4
- package/dist/{chunk-EXTU4WIE-BKNXdLmD.js → chunk-EXTU4WIE-9sNjmQrB.js} +1 -1
- package/dist/{chunk-FRFDVMJY-BSBUAX7r.js → chunk-FRFDVMJY-DzQqMWrl.js} +1 -1
- package/dist/{chunk-JA3XYJ7Z-D6c6cOBG.js → chunk-JA3XYJ7Z-C32Y7Epf.js} +2 -2
- package/dist/{chunk-JZLCHNYA-BvsPHJmL.js → chunk-JZLCHNYA-C6ftyVMN.js} +4 -4
- package/dist/{chunk-N4CR4FBY-8ycT-O9a.js → chunk-N4CR4FBY-DUhGZhZs.js} +5 -5
- package/dist/{chunk-PL6DKKU2-B0MTXvyc.js → chunk-PL6DKKU2-D7km-08O.js} +1 -1
- package/dist/{chunk-QN33PNHL-Bb-eUBW3.js → chunk-QN33PNHL-0K6SDYn3.js} +1 -1
- package/dist/{chunk-QXUST7PY-DV8yRwBd.js → chunk-QXUST7PY-DMhsRpYK.js} +5 -5
- package/dist/{chunk-S3R3BYOJ-mQeCz5CE.js → chunk-S3R3BYOJ-oAe3dEbO.js} +3 -3
- package/dist/{chunk-SJTYNZTY-CEG4F0pB.js → chunk-SJTYNZTY-BkJrPRFC.js} +1 -1
- package/dist/{chunk-TCCFYFTB-d3HOqL2I.js → chunk-TCCFYFTB-D58KeXnC.js} +6 -6
- package/dist/{chunk-TQ3KTPDO-DiCtqVSi.js → chunk-TQ3KTPDO-D_yA_wAb.js} +1 -1
- package/dist/{chunk-TZMSLE5B-BqW10dHe.js → chunk-TZMSLE5B-yBKS_DQU.js} +1 -1
- package/dist/{chunk-UMXZTB3W-97iS1iEl.js → chunk-UMXZTB3W-D7uwvNjd.js} +1 -1
- package/dist/{classDiagram-2ON5EDUG--Yh__LHb.js → classDiagram-2ON5EDUG-QjoAcuFE.js} +10 -10
- package/dist/{classDiagram-v2-WZHVMYZB-BC7X7Xtc.js → classDiagram-v2-WZHVMYZB-bUCv4gu2.js} +10 -10
- package/dist/{clone-BuIIsfA8.js → clone-Q4Fqwn6q.js} +1 -1
- package/dist/{code-block-37QAKDTI-BsGy1AOJ.js → code-block-37QAKDTI-m92Yc8pv.js} +2 -2
- package/dist/{code-visibility-BKxrBMod.js → code-visibility-Bq6MzjHR.js} +8434 -8599
- package/dist/{constants-D0gkYoE2.js → constants-T20xxyNf.js} +2 -2
- package/dist/{copy-DLf4aN7I.js → copy-BuQpJEzp.js} +2 -2
- package/dist/{dagre-6UL2VRFP-DRBWoQUw.js → dagre-6UL2VRFP-J0JKgwOt.js} +11 -11
- package/dist/{dagre-VYEPqXIV.js → dagre-By_QsQgc.js} +11 -11
- package/dist/{data-grid-overlay-editor-efe5ZagF.js → data-grid-overlay-editor-mfEJ5475.js} +2 -2
- package/dist/{diagram-PSM6KHXK-H66ATWP2.js → diagram-PSM6KHXK-DYgJuNk9.js} +18 -18
- package/dist/{diagram-QEK2KX5R-DItl5Wns.js → diagram-QEK2KX5R-CKdBR2sb.js} +14 -14
- package/dist/{diagram-S2PKOQOG-CtuW_ZuL.js → diagram-S2PKOQOG-Dpi7mo5W.js} +14 -14
- package/dist/dist-0Fif7jnk.js +5 -0
- package/dist/{dist-Dh3wkoyH.js → dist-4j4c7bjm.js} +2 -2
- package/dist/{dist-CDFZi-QD.js → dist-B3P2fFpz.js} +1 -1
- package/dist/{dist-BNyrZfqT.js → dist-B3pZ0Ab6.js} +2 -2
- package/dist/dist-B5h_9sHB.js +6 -0
- package/dist/dist-B9M6R5ye.js +5 -0
- package/dist/dist-BCt3tnck.js +8 -0
- package/dist/{dist-BrBucRXs.js → dist-BTfv03uy.js} +2 -2
- package/dist/dist-BUIJwMwn.js +8 -0
- package/dist/{dist-CYEylvZA.js → dist-BbbIBDiQ.js} +1 -1
- package/dist/{dist-KnujRhFL.js → dist-BcuoonNH.js} +4 -4
- package/dist/{dist-DJ6zJQZ4.js → dist-Bde4a2kU.js} +2 -2
- package/dist/{dist-t_qL7eB8.js → dist-Bfwsv11D.js} +2 -2
- package/dist/{dist-CNtV21T_.js → dist-BhM8gdSO.js} +4 -4
- package/dist/{dist-nuW5EDYT.js → dist-BotSqB48.js} +2 -2
- package/dist/dist-BpquMd3k.js +5 -0
- package/dist/dist-BzJsqYfz.js +5 -0
- package/dist/{dist-D029TiHd.js → dist-Bz_sYWbr.js} +2 -2
- package/dist/{dist-D3ZI9nhS.js → dist-C1BYNeCR.js} +4 -4
- package/dist/{dist-Bc5pmZIw.js → dist-C5VC_yzu.js} +1 -1
- package/dist/dist-CA5ELXAf.js +6 -0
- package/dist/dist-CLBRs6Uv.js +5 -0
- package/dist/{dist-Dhk6FMb0.js → dist-CLJWPTX2.js} +3 -3
- package/dist/{dist-C34oIrQ9.js → dist-CLUtPrdy.js} +1 -1
- package/dist/dist-CStVCMbq.js +5 -0
- package/dist/{dist-B8RaFTRF.js → dist-CUCNs1ja.js} +2 -2
- package/dist/dist-CZRIEY3Y.js +8 -0
- package/dist/{dist-UcOPnRMa.js → dist-CcXxepx6.js} +3 -3
- package/dist/dist-CuUHbFD0.js +5 -0
- package/dist/{dist-B8BjrFUE.js → dist-Cy1WxgBD.js} +5 -5
- package/dist/{dist-WdPUFc56.js → dist-D4CewLk6.js} +1 -1
- package/dist/{dist-DMZNjfX4.js → dist-DRfcqpxJ.js} +2 -2
- package/dist/dist-DV7Iabxb.js +8 -0
- package/dist/{dist-usPCDYx8.js → dist-D_bzzWBm.js} +1 -1
- package/dist/{dist-BvCfQQQE.js → dist-DgnE8F-r.js} +1 -1
- package/dist/{dist-JEhxD_cn.js → dist-DhHh0jLg.js} +1 -1
- package/dist/{dist-DGAfI2rB.js → dist-DqAWR3CS.js} +2 -2
- package/dist/{dist--sWVZwjW.js → dist-Du8WkPuU.js} +1 -1
- package/dist/dist-DuEeHMvL.js +5 -0
- package/dist/{dist-BTyJtnNg.js → dist-DxvORzUR.js} +1 -1
- package/dist/{dist-B507mf_I.js → dist-RqXTaiir.js} +2 -2
- package/dist/{dist-Yrfc6L0I.js → dist-fQ0ViXGs.js} +3 -3
- package/dist/{dist-B4LJpMEg.js → dist-h2c8sZvT.js} +1 -1
- package/dist/{dist-C2ej4eOH.js → dist-luvabDEB.js} +2 -2
- package/dist/{dist-B52GXZbd.js → dist-p2qyWijU.js} +2 -2
- package/dist/{erDiagram-Q2GNP2WA--19X2kU5.js → erDiagram-Q2GNP2WA-BU-m41EQ.js} +10 -10
- package/dist/{error-banner-CVkfBUT3.js → error-banner-5bz0L9hS.js} +3 -3
- package/dist/{esm-CWp0KQeK.js → esm-BfhQmZjp.js} +4 -4
- package/dist/{esm-DjNnlmpf.js → esm-Duie8iU-.js} +23 -23
- package/dist/{extends-vAi97cpa.js → extends-BgdxCfYu.js} +6 -6
- package/dist/{flatten-CzBvFdvC.js → flatten-Bbw7g6-K.js} +1 -1
- package/dist/{flowDiagram-NV44I4VS-DQmWlo7f.js → flowDiagram-NV44I4VS-CRoXKjGq.js} +10 -10
- package/dist/{formats-Dsy9kkZu.js → formats-BIKFEOlR.js} +4 -4
- package/dist/{ganttDiagram-JELNMOA3-BOGXJ8Lk.js → ganttDiagram-JELNMOA3-7mq5f9cO.js} +7 -7
- package/dist/{gitGraph-G5XIXVHT-DGlbae5m.js → gitGraph-G5XIXVHT-DiniR35k.js} +3 -3
- package/dist/{gitGraphDiagram-V2S2FVAM-DjzxfF0P.js → gitGraphDiagram-V2S2FVAM-Dfuokq6w.js} +13 -13
- package/dist/{glide-data-editor-DucgdjRo.js → glide-data-editor-DjQd6fKp.js} +557 -557
- package/dist/{graphlib-CVPKjKCS.js → graphlib-Ns7y5crs.js} +5 -5
- package/dist/{hasIn-COs6vImh.js → hasIn-Deg7jl_j.js} +3 -3
- package/dist/{html-to-image-CpggM7u1.js → html-to-image-QL7QveRm.js} +115 -110
- package/dist/{info-VBDWY6EO-D2lvLLw5.js → info-VBDWY6EO-DVZvGhkQ.js} +3 -3
- package/dist/{infoDiagram-HS3SLOUP-ChNufFsP.js → infoDiagram-HS3SLOUP-CEnzWruK.js} +13 -13
- package/dist/{input-D4kjoQUB.js → input-Dh0iMVFM.js} +70 -67
- package/dist/{isEmpty-Dd8mx_WL.js → isEmpty-CJJMn-QP.js} +1 -1
- package/dist/{isSymbol-BvIfMnn6.js → isSymbol-CoUCgMCM.js} +1 -1
- package/dist/{journeyDiagram-XKPGCS4Q-BO_O4Ij1.js → journeyDiagram-XKPGCS4Q-8XYSU1GI.js} +3 -3
- package/dist/{kanban-definition-3W4ZIXB7-CPpiiiWk.js → kanban-definition-3W4ZIXB7--9pT9z1R.js} +7 -7
- package/dist/{label-BLqV33b1.js → label-LWtdw5i8.js} +3 -3
- package/dist/{linear-2NnK4cxi.js → linear-B5-AFRiR.js} +2 -2
- package/dist/{loader-Dr8Qem8p.js → loader-BWLPpjKK.js} +2 -2
- package/dist/main.js +1689 -1570
- package/dist/{memoize-C9ltv0Cw.js → memoize-BOtf2yFf.js} +1 -1
- package/dist/{merge-CHn7Yx0N.js → merge-Be1CqGnU.js} +1 -1
- package/dist/mermaid-4DMBBIKO-DIdL224_.js +6 -0
- package/dist/{mermaid-DO-Daq7u.js → mermaid-CAibas-0.js} +44 -44
- package/dist/{mermaid-parser.core-DreccfmS.js → mermaid-parser.core-C3XRsazI.js} +8 -8
- package/dist/{min-BNz2lZfk.js → min-Dtgc8txR.js} +4 -4
- package/dist/{mindmap-definition-VGOIOE7T-CC1_Vl0f.js → mindmap-definition-VGOIOE7T-B-4mnfFG.js} +9 -9
- package/dist/{now-Sgq5m3D-.js → now-Ch98bJO_.js} +2 -2
- package/dist/{number-overlay-editor-CpKi64Fy.js → number-overlay-editor-D-a0qCT8.js} +1 -1
- package/dist/{once-rJImu7SE.js → once-DPuqGUeo.js} +1 -1
- package/dist/{packet-DYOGHKS2-CmWtF3uO.js → packet-DYOGHKS2-34raHOiB.js} +3 -3
- package/dist/{pick-CRAXxDYn.js → pick-D1Qo8s2C.js} +4 -4
- package/dist/{pie-VRWISCQL-B6u8vus8.js → pie-VRWISCQL-BaLlzZa3.js} +3 -3
- package/dist/{pieDiagram-ADFJNKIX-Di34MOFQ.js → pieDiagram-ADFJNKIX-Cr3cNpZY.js} +15 -15
- package/dist/{precisionRound-CnHPY_5v.js → precisionRound-Tqb4mg-H.js} +1 -1
- package/dist/{process-output-X8TR20AK.js → process-output-C657UH7t.js} +36 -28
- package/dist/{quadrantDiagram-AYHSOK5B-B9kVk1ny.js → quadrantDiagram-AYHSOK5B-BuNL8Q93.js} +4 -4
- package/dist/{radar-ZZBFDIW7-XAmXSa8s.js → radar-ZZBFDIW7-Ci7bfoZa.js} +3 -3
- package/dist/{react-vega-Dh6-UKKe.js → react-vega-B0sAlDTL.js} +9 -9
- package/dist/react-vega-B6ncY2Tp.js +9 -0
- package/dist/{requirementDiagram-UZGBJVZJ-BxGfGYEx.js → requirementDiagram-UZGBJVZJ-BG2lLUN1.js} +9 -9
- package/dist/{reveal-component-BMyi2UMr.js → reveal-component-BQijUbYE.js} +33 -33
- package/dist/{sankeyDiagram-TZEHDZUN-D09PBJ-n.js → sankeyDiagram-TZEHDZUN-DMal8sps.js} +3 -3
- package/dist/{sequenceDiagram-WL72ISMW-t_Dpemj0.js → sequenceDiagram-WL72ISMW-DT6Tk-Eo.js} +4 -4
- package/dist/{spec-hVaaZsY5.js → spec-BKuFJIDz.js} +4 -4
- package/dist/{stateDiagram-FKZM4ZOC-B18gTP_j.js → stateDiagram-FKZM4ZOC-CB_lodq3.js} +12 -12
- package/dist/{stateDiagram-v2-4FDKWEC3-B6e_t14A.js → stateDiagram-v2-4FDKWEC3-E0RGjKsm.js} +10 -10
- package/dist/stex-KfRnSHzF.js +4 -0
- package/dist/{strings-BiIhGaI8.js → strings-Bu3vlb6W.js} +7 -7
- package/dist/style.css +1 -1
- package/dist/{swiper-component-DlD2GU2g.js → swiper-component-B2t5sN1q.js} +3 -3
- package/dist/{time-C1SGcFMH.js → time-CsmIF9YZ.js} +3 -3
- package/dist/{timeline-definition-IT6M3QCI-DJnh1ks5.js → timeline-definition-IT6M3QCI-NfSKRvH0.js} +2 -2
- package/dist/{toDate-CIpC_34u.js → toDate-BeKbrOvs.js} +5 -5
- package/dist/{tooltip-DRaMBu06.js → tooltip-C5FYOpQc.js} +4 -4
- package/dist/{treemap-GDKQZRPO-Du95DV6u.js → treemap-GDKQZRPO-Cl6OQh8D.js} +3 -3
- package/dist/{types-Dzuoc3LN.js → types-CVvp1fKr.js} +2 -9
- package/dist/{useAsyncData-C56Khv_R.js → useAsyncData-yp6n17kh.js} +2 -2
- package/dist/{useDateFormatter-B_9k85Ex.js → useDateFormatter-BA4FCquG.js} +2 -2
- package/dist/{useDeepCompareMemoize-Dt98v2ua.js → useDeepCompareMemoize-DJvAHUIC.js} +1 -1
- package/dist/{useIframeCapabilities-BkYHTrss.js → useIframeCapabilities-C4JTXTIh.js} +1 -1
- package/dist/{useLifecycle-BF6-z62y.js → useLifecycle-CsYXf0Ln.js} +4 -4
- package/dist/{useTheme-DykuNHR2.js → useTheme-CK_R9Mn8.js} +24 -21
- package/dist/{vega-component-cSdqoAxe.js → vega-component-ikfBfkZO.js} +18 -18
- package/dist/{vega-loader.browser-3_z8GoFC.js → vega-loader.browser-CZ-J8Py3.js} +3 -3
- package/dist/{xychartDiagram-PRI3JC2R-Dk2d_bX0.js → xychartDiagram-PRI3JC2R-BvwftqMA.js} +9 -9
- package/dist/{zod-BWkcDORu.js → zod-CoBiJ5v4.js} +3 -3
- package/package.json +1 -1
- package/src/components/ai/__tests__/ai-utils.test.ts +43 -38
- package/src/components/ai/ai-model-dropdown.tsx +2 -2
- package/src/components/app-config/ai-config.tsx +73 -1
- package/src/components/app-config/user-config-form.tsx +37 -1
- package/src/components/chat/__tests__/chat-utils.test.ts +269 -0
- package/src/components/chat/chat-panel.tsx +36 -3
- package/src/components/chat/chat-utils.ts +14 -58
- package/src/components/data-table/TableBottomBar.tsx +27 -6
- package/src/components/data-table/TableTopBar.tsx +7 -1
- package/src/components/data-table/__tests__/TableBottomBar.test.tsx +73 -0
- package/src/components/data-table/__tests__/column-explorer.test.tsx +128 -0
- package/src/components/data-table/__tests__/column-header.test.tsx +110 -277
- package/src/components/data-table/__tests__/data-table.test.tsx +52 -1
- package/src/components/data-table/__tests__/date-filter-inputs.test.tsx +33 -0
- package/src/components/data-table/__tests__/filter-pill-editor.test.tsx +75 -38
- package/src/components/data-table/__tests__/filter-pills.test.tsx +287 -0
- package/src/components/data-table/__tests__/filter-test-utils.ts +47 -0
- package/src/components/data-table/__tests__/filters.test.ts +5 -5
- package/src/components/data-table/__tests__/header-items.test.tsx +47 -1
- package/src/components/data-table/__tests__/useColumnVisibility.test.ts +42 -0
- package/src/components/data-table/add-filter-button.tsx +85 -0
- package/src/components/data-table/column-explorer-panel/column-explorer.tsx +98 -26
- package/src/components/data-table/column-header.tsx +94 -691
- package/src/components/data-table/columns.tsx +3 -4
- package/src/components/data-table/context-menu.tsx +26 -12
- package/src/components/data-table/data-table.tsx +125 -56
- package/src/components/data-table/date-filter-inputs.tsx +13 -10
- package/src/components/data-table/export-actions.tsx +17 -6
- package/src/components/data-table/filter-by-values-picker.tsx +13 -19
- package/src/components/data-table/filter-editor-context.tsx +34 -0
- package/src/components/data-table/filter-pill-editor.tsx +152 -175
- package/src/components/data-table/filter-pills.tsx +190 -153
- package/src/components/data-table/filters/builders.ts +102 -0
- package/src/components/data-table/filters/defaults.ts +31 -0
- package/src/components/data-table/filters/format.ts +131 -0
- package/src/components/data-table/filters/guards.ts +51 -0
- package/src/components/data-table/filters/index.ts +7 -0
- package/src/components/data-table/filters/operators.ts +76 -0
- package/src/components/data-table/filters/serialize.ts +186 -0
- package/src/components/data-table/filters/types.ts +33 -0
- package/src/components/data-table/header-items.tsx +25 -85
- package/src/components/data-table/hooks/use-column-visibility.ts +56 -0
- package/src/components/data-table/pagination.tsx +16 -3
- package/src/components/data-table/table-explorer-panel/table-explorer-panel.tsx +16 -6
- package/src/components/data-table/value-chips.tsx +52 -0
- package/src/components/databases/display.tsx +2 -0
- package/src/components/datasources/__tests__/utils.test.ts +82 -0
- package/src/components/datasources/utils.ts +16 -15
- package/src/components/editor/actions/pair-with-agent-modal.tsx +1 -0
- package/src/components/editor/errors/mangled-local-chip.tsx +50 -0
- package/src/components/editor/output/MarimoErrorOutput.tsx +110 -27
- package/src/components/editor/output/MarimoTracebackOutput.tsx +51 -34
- package/src/components/editor/renderers/slides-layout/slides-layout.tsx +1 -1
- package/src/components/slides/reveal-component.tsx +3 -3
- package/src/components/slides/slide-form.tsx +11 -3
- package/src/components/ui/number-field.tsx +13 -1
- package/src/core/ai/__tests__/model-registry.test.ts +72 -60
- package/src/core/ai/model-registry.ts +33 -28
- package/src/core/cells/__tests__/actions.test.ts +48 -0
- package/src/core/cells/actions.ts +5 -6
- package/src/core/codemirror/__tests__/setup.test.ts +29 -0
- package/src/core/codemirror/cells/traceback-decorations.ts +1 -1
- package/src/core/codemirror/cm.ts +3 -2
- package/src/core/codemirror/format.ts +1 -0
- package/src/core/codemirror/keymaps/vim.ts +63 -0
- package/src/core/codemirror/language/languages/sql/sql.ts +1 -0
- package/src/core/codemirror/language/languages/sql/utils.ts +2 -0
- package/src/core/config/__tests__/config-schema.test.ts +2 -0
- package/src/core/config/config-schema.ts +2 -0
- package/src/css/app/Cell.css +0 -1
- package/src/plugins/impl/DataTablePlugin.tsx +94 -33
- package/src/plugins/impl/__tests__/DataTablePlugin.test.tsx +1 -0
- package/src/plugins/impl/chat/ChatPlugin.tsx +7 -1
- package/src/plugins/impl/chat/__tests__/chat-ui.test.ts +278 -0
- package/src/plugins/impl/chat/chat-ui.tsx +106 -59
- package/src/plugins/impl/chat/types.ts +5 -0
- package/src/plugins/impl/data-frames/DataFramePlugin.tsx +8 -6
- package/src/stories/dataframe.stories.tsx +1 -0
- package/src/utils/__tests__/local-variables.test.ts +132 -0
- package/src/utils/dates.ts +39 -0
- package/src/utils/local-variables.ts +67 -0
- package/dist/ErrorBoundary-D3wrPNma.js +0 -167
- package/dist/architecture-7HQA4BMR-CS9jOrqM.js +0 -6
- package/dist/assets/__vite-browser-external-CAdMKBac.js +0 -1
- package/dist/dist-21ButRCu.js +0 -8
- package/dist/dist-B--tLnAP.js +0 -5
- package/dist/dist-BoHGySTM.js +0 -5
- package/dist/dist-ByAz19Qc.js +0 -5
- package/dist/dist-C1Ap5CYU.js +0 -5
- package/dist/dist-C93EysN4.js +0 -5
- package/dist/dist-CY-lVor6.js +0 -8
- package/dist/dist-CYDuv4bR.js +0 -8
- package/dist/dist-Cfo5EE2t.js +0 -6
- package/dist/dist-CjivSDvN.js +0 -5
- package/dist/dist-Cqwx-MH7.js +0 -5
- package/dist/dist-DbpcoFAV.js +0 -6
- package/dist/dist-FUNenbiQ.js +0 -5
- package/dist/dist-zhSud5X3.js +0 -8
- package/dist/mermaid-4DMBBIKO-B7VQMwJx.js +0 -6
- package/dist/react-vega-Cavbrg4l.js +0 -9
- package/dist/stex-ChDHQs3R.js +0 -4
- package/src/components/data-table/__tests__/column-header.test.ts +0 -65
- package/src/components/data-table/filters.ts +0 -386
- /package/dist/{_baseFor-BGiY-cm1.js → _baseFor-4jw-lnCC.js} +0 -0
- /package/dist/{clsx-CyyyQ8Ue.js → clsx-CIWA5tNO.js} +0 -0
- /package/dist/{defaultLocale-DoeErsX2.js → defaultLocale-BoHTsDG6.js} +0 -0
- /package/dist/{defaultLocale-BpsHxBd7.js → defaultLocale-u-3osm0P.js} +0 -0
- /package/dist/{dist-CCADb07R.js → dist-DNdhYsgW.js} +0 -0
- /package/dist/{emotion-is-prop-valid.esm-DtW2o230.js → emotion-is-prop-valid.esm-DzSb5hsH.js} +0 -0
- /package/dist/{invariant-UcGKQEhF.js → invariant-wRzNXIsJ.js} +0 -0
- /package/dist/{jsx-runtime-COBk7ree.js → jsx-runtime-DebpN0FN.js} +0 -0
- /package/dist/{main-CThhXnXU.js → main-Tj_-QTyF.js} +0 -0
- /package/dist/{micromark-factory-space-CwHmg6iz.js → micromark-factory-space-DF2w36zS.js} +0 -0
- /package/dist/{ordinal-B43ZeR68.js → ordinal-ArJavP1Q.js} +0 -0
- /package/dist/{purify.es-DT70lfR0.js → purify.es-H92eMd9-.js} +0 -0
- /package/dist/{range-BOiA8qqU.js → range-C-rmrM1O.js} +0 -0
- /package/dist/{react-dom-BWRJ_g_k.js → react-dom-BTJzcVJ9.js} +0 -0
- /package/dist/{stex-DrxP7bb3.js → stex-BIsgBmK4.js} +0 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import type { OperatorType } from "@/plugins/impl/data-frames/utils/operators";
|
|
4
|
+
import type { ColumnFilterValue, MembershipFilterType } from "./builders";
|
|
5
|
+
import {
|
|
6
|
+
COMPARISON_OPS,
|
|
7
|
+
type MembershipOp,
|
|
8
|
+
type NullishOp,
|
|
9
|
+
OPERATORS_BY_TYPE,
|
|
10
|
+
TEXT_SCALAR_OPS,
|
|
11
|
+
} from "./operators";
|
|
12
|
+
import type { FilterType } from "./types";
|
|
13
|
+
|
|
14
|
+
const makeOpGuard = <T extends OperatorType>(ops: readonly T[]) => {
|
|
15
|
+
const set = new Set<OperatorType>(ops);
|
|
16
|
+
return (op: OperatorType): op is T => set.has(op);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const isComparisonOp = makeOpGuard(COMPARISON_OPS);
|
|
20
|
+
export const isTextScalarOp = makeOpGuard(TEXT_SCALAR_OPS);
|
|
21
|
+
|
|
22
|
+
export function isMembershipOp(op: OperatorType): op is MembershipOp {
|
|
23
|
+
return op === "in" || op === "not_in";
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function isNullishFilter(
|
|
27
|
+
filter: ColumnFilterValue,
|
|
28
|
+
): filter is Extract<ColumnFilterValue, { operator: NullishOp }> {
|
|
29
|
+
return filter.operator === "is_null" || filter.operator === "is_not_null";
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type DateLikeFilterType = Extract<
|
|
33
|
+
FilterType,
|
|
34
|
+
"date" | "datetime" | "time"
|
|
35
|
+
>;
|
|
36
|
+
|
|
37
|
+
const DATE_LIKE_TYPES: ReadonlySet<FilterType> = new Set([
|
|
38
|
+
"date",
|
|
39
|
+
"datetime",
|
|
40
|
+
"time",
|
|
41
|
+
]);
|
|
42
|
+
|
|
43
|
+
export const isDateLikeType = (type: FilterType): type is DateLikeFilterType =>
|
|
44
|
+
DATE_LIKE_TYPES.has(type);
|
|
45
|
+
|
|
46
|
+
export function isMembershipFilterType(
|
|
47
|
+
type: FilterType,
|
|
48
|
+
): type is MembershipFilterType {
|
|
49
|
+
const ops = OPERATORS_BY_TYPE[type];
|
|
50
|
+
return ops.includes("in") || ops.includes("not_in");
|
|
51
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import type { OperatorType } from "@/plugins/impl/data-frames/utils/operators";
|
|
4
|
+
import type { FilterType } from "./types";
|
|
5
|
+
|
|
6
|
+
// Primitive operator groups — each describes one shape of filter value.
|
|
7
|
+
export const NULLISH_OPS = ["is_null", "is_not_null"] as const;
|
|
8
|
+
export const MEMBERSHIP_OPS = ["in", "not_in"] as const;
|
|
9
|
+
export const COMPARISON_OPS = ["==", "!=", ">", ">=", "<", "<="] as const;
|
|
10
|
+
export const TEXT_SCALAR_OPS = [
|
|
11
|
+
"contains",
|
|
12
|
+
"equals",
|
|
13
|
+
"does_not_equal",
|
|
14
|
+
"regex",
|
|
15
|
+
"starts_with",
|
|
16
|
+
"ends_with",
|
|
17
|
+
] as const;
|
|
18
|
+
export const BOOLEAN_VALUE_OPS = ["is_true", "is_false"] as const;
|
|
19
|
+
export const EMPTY_OPS = ["is_empty"] as const;
|
|
20
|
+
|
|
21
|
+
// Operators that carry no payload — `{ operator }` with no other field.
|
|
22
|
+
export const UNARY_OPS = [
|
|
23
|
+
...NULLISH_OPS,
|
|
24
|
+
...BOOLEAN_VALUE_OPS,
|
|
25
|
+
...EMPTY_OPS,
|
|
26
|
+
] as const;
|
|
27
|
+
|
|
28
|
+
// Per-type op lists used by the editor and validators.
|
|
29
|
+
export const BOOLEAN_OPS = [...BOOLEAN_VALUE_OPS, ...NULLISH_OPS] as const;
|
|
30
|
+
export const NUMBER_OPS = [
|
|
31
|
+
"between",
|
|
32
|
+
...COMPARISON_OPS,
|
|
33
|
+
...MEMBERSHIP_OPS,
|
|
34
|
+
...NULLISH_OPS,
|
|
35
|
+
] as const;
|
|
36
|
+
export const TEXT_OPS = [
|
|
37
|
+
...TEXT_SCALAR_OPS,
|
|
38
|
+
...MEMBERSHIP_OPS,
|
|
39
|
+
...EMPTY_OPS,
|
|
40
|
+
...NULLISH_OPS,
|
|
41
|
+
] as const;
|
|
42
|
+
export const DATETIME_OPS = [
|
|
43
|
+
"between",
|
|
44
|
+
...COMPARISON_OPS,
|
|
45
|
+
...NULLISH_OPS,
|
|
46
|
+
] as const;
|
|
47
|
+
|
|
48
|
+
export type NullishOp = (typeof NULLISH_OPS)[number];
|
|
49
|
+
export type MembershipOp = (typeof MEMBERSHIP_OPS)[number];
|
|
50
|
+
export type ComparisonOp = (typeof COMPARISON_OPS)[number];
|
|
51
|
+
export type TextScalarOp = (typeof TEXT_SCALAR_OPS)[number];
|
|
52
|
+
export type BooleanValueOp = (typeof BOOLEAN_VALUE_OPS)[number];
|
|
53
|
+
export type BooleanOp = (typeof BOOLEAN_OPS)[number];
|
|
54
|
+
|
|
55
|
+
export const OPERATORS_BY_TYPE: Record<
|
|
56
|
+
FilterType,
|
|
57
|
+
ReadonlyArray<OperatorType>
|
|
58
|
+
> = {
|
|
59
|
+
number: NUMBER_OPS,
|
|
60
|
+
text: TEXT_OPS,
|
|
61
|
+
boolean: BOOLEAN_OPS,
|
|
62
|
+
date: DATETIME_OPS,
|
|
63
|
+
datetime: DATETIME_OPS,
|
|
64
|
+
time: DATETIME_OPS,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const DEFAULT_OPERATOR_FOR_TYPE: Record<FilterType, OperatorType> = {
|
|
68
|
+
number: "between",
|
|
69
|
+
text: "contains",
|
|
70
|
+
boolean: "is_true",
|
|
71
|
+
date: "==",
|
|
72
|
+
datetime: "==",
|
|
73
|
+
time: "between",
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export const OPERATORS_WITHOUT_VALUE = new Set<OperatorType>(UNARY_OPS);
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import type { ColumnFiltersState } from "@tanstack/react-table";
|
|
4
|
+
import type {
|
|
5
|
+
FilterConditionType,
|
|
6
|
+
FilterGroupType,
|
|
7
|
+
} from "@/plugins/impl/data-frames/schema";
|
|
8
|
+
import type { ColumnId } from "@/plugins/impl/data-frames/types";
|
|
9
|
+
import { assertNever } from "@/utils/assertNever";
|
|
10
|
+
import {
|
|
11
|
+
dateToLocalISODate,
|
|
12
|
+
dateToLocalISODateTime,
|
|
13
|
+
dateToLocalISOTime,
|
|
14
|
+
} from "@/utils/dates";
|
|
15
|
+
import type { ColumnFilterValue } from "./builders";
|
|
16
|
+
import { isNullishFilter } from "./guards";
|
|
17
|
+
|
|
18
|
+
export function filterToFilterCondition(
|
|
19
|
+
columnIdString: string,
|
|
20
|
+
filter: ColumnFilterValue | undefined,
|
|
21
|
+
): FilterConditionType[] {
|
|
22
|
+
if (!filter) {
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
const columnId = columnIdString as ColumnId;
|
|
26
|
+
|
|
27
|
+
if (isNullishFilter(filter)) {
|
|
28
|
+
return [
|
|
29
|
+
{
|
|
30
|
+
column_id: columnId,
|
|
31
|
+
operator: filter.operator,
|
|
32
|
+
type: "condition",
|
|
33
|
+
negate: false,
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
switch (filter.type) {
|
|
39
|
+
case "number":
|
|
40
|
+
switch (filter.operator) {
|
|
41
|
+
case "between":
|
|
42
|
+
return [
|
|
43
|
+
{
|
|
44
|
+
column_id: columnId,
|
|
45
|
+
operator: "between",
|
|
46
|
+
value: { min: filter.min, max: filter.max },
|
|
47
|
+
type: "condition",
|
|
48
|
+
negate: false,
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
case "==":
|
|
52
|
+
case "!=":
|
|
53
|
+
case ">":
|
|
54
|
+
case ">=":
|
|
55
|
+
case "<":
|
|
56
|
+
case "<=":
|
|
57
|
+
return [
|
|
58
|
+
{
|
|
59
|
+
column_id: columnId,
|
|
60
|
+
operator: filter.operator,
|
|
61
|
+
value: filter.value,
|
|
62
|
+
type: "condition",
|
|
63
|
+
negate: false,
|
|
64
|
+
},
|
|
65
|
+
];
|
|
66
|
+
case "in":
|
|
67
|
+
case "not_in":
|
|
68
|
+
return [
|
|
69
|
+
{
|
|
70
|
+
column_id: columnId,
|
|
71
|
+
operator: filter.operator,
|
|
72
|
+
value: filter.values,
|
|
73
|
+
type: "condition",
|
|
74
|
+
negate: false,
|
|
75
|
+
},
|
|
76
|
+
];
|
|
77
|
+
default:
|
|
78
|
+
assertNever(filter);
|
|
79
|
+
}
|
|
80
|
+
case "text":
|
|
81
|
+
switch (filter.operator) {
|
|
82
|
+
case "contains":
|
|
83
|
+
case "equals":
|
|
84
|
+
case "does_not_equal":
|
|
85
|
+
case "regex":
|
|
86
|
+
case "starts_with":
|
|
87
|
+
case "ends_with":
|
|
88
|
+
return [
|
|
89
|
+
{
|
|
90
|
+
column_id: columnId,
|
|
91
|
+
operator: filter.operator,
|
|
92
|
+
value: filter.text,
|
|
93
|
+
type: "condition",
|
|
94
|
+
negate: false,
|
|
95
|
+
},
|
|
96
|
+
];
|
|
97
|
+
case "in":
|
|
98
|
+
case "not_in":
|
|
99
|
+
return [
|
|
100
|
+
{
|
|
101
|
+
column_id: columnId,
|
|
102
|
+
operator: filter.operator,
|
|
103
|
+
value: filter.values,
|
|
104
|
+
type: "condition",
|
|
105
|
+
negate: false,
|
|
106
|
+
},
|
|
107
|
+
];
|
|
108
|
+
case "is_empty":
|
|
109
|
+
return [
|
|
110
|
+
{
|
|
111
|
+
column_id: columnId,
|
|
112
|
+
operator: "is_empty",
|
|
113
|
+
type: "condition",
|
|
114
|
+
negate: false,
|
|
115
|
+
},
|
|
116
|
+
];
|
|
117
|
+
default:
|
|
118
|
+
assertNever(filter);
|
|
119
|
+
}
|
|
120
|
+
case "date":
|
|
121
|
+
case "datetime":
|
|
122
|
+
case "time": {
|
|
123
|
+
const encode =
|
|
124
|
+
filter.type === "date"
|
|
125
|
+
? dateToLocalISODate
|
|
126
|
+
: filter.type === "time"
|
|
127
|
+
? dateToLocalISOTime
|
|
128
|
+
: dateToLocalISODateTime;
|
|
129
|
+
switch (filter.operator) {
|
|
130
|
+
case "between":
|
|
131
|
+
return [
|
|
132
|
+
{
|
|
133
|
+
column_id: columnId,
|
|
134
|
+
operator: "between",
|
|
135
|
+
value: { min: encode(filter.min), max: encode(filter.max) },
|
|
136
|
+
type: "condition",
|
|
137
|
+
negate: false,
|
|
138
|
+
},
|
|
139
|
+
];
|
|
140
|
+
case "==":
|
|
141
|
+
case "!=":
|
|
142
|
+
case ">":
|
|
143
|
+
case ">=":
|
|
144
|
+
case "<":
|
|
145
|
+
case "<=":
|
|
146
|
+
return [
|
|
147
|
+
{
|
|
148
|
+
column_id: columnId,
|
|
149
|
+
operator: filter.operator,
|
|
150
|
+
value: encode(filter.value),
|
|
151
|
+
type: "condition",
|
|
152
|
+
negate: false,
|
|
153
|
+
},
|
|
154
|
+
];
|
|
155
|
+
default:
|
|
156
|
+
assertNever(filter);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
case "boolean":
|
|
160
|
+
return [
|
|
161
|
+
{
|
|
162
|
+
column_id: columnId,
|
|
163
|
+
operator: filter.operator,
|
|
164
|
+
type: "condition",
|
|
165
|
+
negate: false,
|
|
166
|
+
},
|
|
167
|
+
];
|
|
168
|
+
default:
|
|
169
|
+
assertNever(filter);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export function filtersToFilterGroup(
|
|
174
|
+
columnFilters: ColumnFiltersState,
|
|
175
|
+
): FilterGroupType {
|
|
176
|
+
const conditions = columnFilters.flatMap((filter) =>
|
|
177
|
+
filterToFilterCondition(filter.id, filter.value as ColumnFilterValue),
|
|
178
|
+
);
|
|
179
|
+
// To maintain existing behavior "and" all the conditions
|
|
180
|
+
return {
|
|
181
|
+
type: "group",
|
|
182
|
+
operator: "and",
|
|
183
|
+
children: conditions,
|
|
184
|
+
negate: false,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import type { RowData } from "@tanstack/react-table";
|
|
4
|
+
import type { DataType } from "@/core/kernel/messages";
|
|
5
|
+
|
|
6
|
+
declare module "@tanstack/react-table" {
|
|
7
|
+
//allows us to define custom properties for our columns
|
|
8
|
+
interface ColumnMeta<TData extends RowData, TValue> {
|
|
9
|
+
rowHeader?: boolean;
|
|
10
|
+
dtype?: string;
|
|
11
|
+
dataType?: DataType;
|
|
12
|
+
filterType?: FilterType;
|
|
13
|
+
minFractionDigits?: number;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const FILTER_TYPES = [
|
|
18
|
+
"text",
|
|
19
|
+
"number",
|
|
20
|
+
"date",
|
|
21
|
+
"datetime",
|
|
22
|
+
"time",
|
|
23
|
+
"boolean",
|
|
24
|
+
] as const;
|
|
25
|
+
export type FilterType = (typeof FILTER_TYPES)[number];
|
|
26
|
+
|
|
27
|
+
export const EDITABLE_FILTER_TYPES: ReadonlySet<FilterType> = new Set(
|
|
28
|
+
FILTER_TYPES,
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
export type FormattedFilter =
|
|
32
|
+
| { kind: "scalar"; operator: string; value?: string }
|
|
33
|
+
| { kind: "list"; operator: string; items: string[] };
|
|
@@ -8,10 +8,8 @@ import {
|
|
|
8
8
|
ArrowUpNarrowWideIcon,
|
|
9
9
|
ChevronsUpDown,
|
|
10
10
|
CopyIcon,
|
|
11
|
+
EyeOffIcon,
|
|
11
12
|
FilterX,
|
|
12
|
-
FunnelPlusIcon,
|
|
13
|
-
ListFilterIcon,
|
|
14
|
-
ListFilterPlusIcon,
|
|
15
13
|
PinOffIcon,
|
|
16
14
|
WrapTextIcon,
|
|
17
15
|
} from "lucide-react";
|
|
@@ -27,7 +25,6 @@ import type { DataType } from "@/core/kernel/messages";
|
|
|
27
25
|
import { cn } from "@/utils/cn";
|
|
28
26
|
import { copyToClipboard } from "@/utils/copy";
|
|
29
27
|
import { DATA_TYPE_ICON } from "../datasets/icons";
|
|
30
|
-
import { Button } from "../ui/button";
|
|
31
28
|
import { formattingExample } from "./column-formatting/feature";
|
|
32
29
|
import { formatOptions } from "./column-formatting/types";
|
|
33
30
|
import { NAMELESS_COLUMN_PREFIX } from "./columns";
|
|
@@ -143,6 +140,23 @@ export function renderColumnPinning<TData, TValue>(
|
|
|
143
140
|
);
|
|
144
141
|
}
|
|
145
142
|
|
|
143
|
+
export function HideColumn<TData, TValue>({
|
|
144
|
+
column,
|
|
145
|
+
}: {
|
|
146
|
+
column: Column<TData, TValue>;
|
|
147
|
+
}) {
|
|
148
|
+
if (!column.getCanHide()) {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return (
|
|
153
|
+
<DropdownMenuItem onClick={() => column.toggleVisibility(false)}>
|
|
154
|
+
<EyeOffIcon className="mo-dropdown-icon" />
|
|
155
|
+
Hide column
|
|
156
|
+
</DropdownMenuItem>
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
146
160
|
export function renderCopyColumn<TData, TValue>(column: Column<TData, TValue>) {
|
|
147
161
|
if (!column.getCanCopy?.()) {
|
|
148
162
|
return null;
|
|
@@ -237,31 +251,22 @@ export function renderSorts<TData, TValue>(
|
|
|
237
251
|
{sortDirection === "desc" && renderSortIndex()}
|
|
238
252
|
</DropdownMenuItem>
|
|
239
253
|
{renderClearSort()}
|
|
240
|
-
<DropdownMenuSeparator />
|
|
241
254
|
</>
|
|
242
255
|
);
|
|
243
256
|
}
|
|
244
257
|
|
|
245
|
-
export function
|
|
246
|
-
column: Column<TData, TValue>,
|
|
247
|
-
) {
|
|
258
|
+
export function renderSortIcon<TData, TValue>(column: Column<TData, TValue>) {
|
|
248
259
|
if (!column.getCanSort()) {
|
|
249
260
|
return null;
|
|
250
261
|
}
|
|
251
262
|
|
|
252
263
|
const isSorted = column.getIsSorted();
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
Icon = FunnelPlusIcon;
|
|
260
|
-
} else if (isSorted) {
|
|
261
|
-
Icon = isSorted === "desc" ? DescIcon : AscIcon;
|
|
262
|
-
} else {
|
|
263
|
-
Icon = ChevronsUpDown;
|
|
264
|
-
}
|
|
264
|
+
|
|
265
|
+
const Icon: React.FC<React.SVGProps<SVGSVGElement>> = isSorted
|
|
266
|
+
? isSorted === "desc"
|
|
267
|
+
? DescIcon
|
|
268
|
+
: AscIcon
|
|
269
|
+
: ChevronsUpDown;
|
|
265
270
|
|
|
266
271
|
return <Icon className="h-3 w-3" />;
|
|
267
272
|
}
|
|
@@ -292,68 +297,3 @@ export const ClearFilterMenuItem = <TData, TValue>({
|
|
|
292
297
|
Clear filter
|
|
293
298
|
</DropdownMenuItem>
|
|
294
299
|
);
|
|
295
|
-
|
|
296
|
-
export function renderFilterByValues<TData, TValue>(
|
|
297
|
-
column: Column<TData, TValue>,
|
|
298
|
-
setIsFilterValueOpen: (open: boolean) => void,
|
|
299
|
-
) {
|
|
300
|
-
const canFilter = column.getCanFilter();
|
|
301
|
-
if (!canFilter) {
|
|
302
|
-
return null;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
const columnType = column.columnDef.meta?.dataType;
|
|
306
|
-
// skip boolean as this can be easily filtered through normal filters
|
|
307
|
-
if (columnType === "boolean") {
|
|
308
|
-
return null;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
// there are some edge cases which do not support filtering (eg. dicts with None values)
|
|
312
|
-
const filterType = column.columnDef.meta?.filterType;
|
|
313
|
-
if (!filterType) {
|
|
314
|
-
return null;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
return (
|
|
318
|
-
<DropdownMenuSub>
|
|
319
|
-
<DropdownMenuItem onClick={() => setIsFilterValueOpen(true)}>
|
|
320
|
-
<ListFilterIcon className="mo-dropdown-icon" />
|
|
321
|
-
Filter by values
|
|
322
|
-
</DropdownMenuItem>
|
|
323
|
-
</DropdownMenuSub>
|
|
324
|
-
);
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
export const FilterButtons = ({
|
|
328
|
-
onApply,
|
|
329
|
-
onClear,
|
|
330
|
-
clearButtonDisabled,
|
|
331
|
-
applyButtonDisabled,
|
|
332
|
-
}: {
|
|
333
|
-
onApply: () => void;
|
|
334
|
-
onClear: () => void;
|
|
335
|
-
clearButtonDisabled?: boolean;
|
|
336
|
-
applyButtonDisabled?: boolean;
|
|
337
|
-
}) => {
|
|
338
|
-
return (
|
|
339
|
-
<div className="flex gap-2 px-2 justify-between">
|
|
340
|
-
<Button
|
|
341
|
-
variant="link"
|
|
342
|
-
size="sm"
|
|
343
|
-
onClick={onApply}
|
|
344
|
-
disabled={applyButtonDisabled}
|
|
345
|
-
>
|
|
346
|
-
Apply
|
|
347
|
-
</Button>
|
|
348
|
-
<Button
|
|
349
|
-
variant="linkDestructive"
|
|
350
|
-
size="sm"
|
|
351
|
-
className=""
|
|
352
|
-
onClick={onClear}
|
|
353
|
-
disabled={clearButtonDisabled}
|
|
354
|
-
>
|
|
355
|
-
Clear
|
|
356
|
-
</Button>
|
|
357
|
-
</div>
|
|
358
|
-
);
|
|
359
|
-
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
"use no memo";
|
|
3
|
+
|
|
4
|
+
import { useInternalStateWithSync } from "@/hooks/useInternalStateWithSync";
|
|
5
|
+
import type { Table, VisibilityState } from "@tanstack/react-table";
|
|
6
|
+
import { dequal as isDeepEqual } from "dequal";
|
|
7
|
+
import type React from "react";
|
|
8
|
+
|
|
9
|
+
interface UseColumnVisibilityResult {
|
|
10
|
+
columnVisibility: VisibilityState;
|
|
11
|
+
setColumnVisibility: React.Dispatch<React.SetStateAction<VisibilityState>>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function useColumnVisibility(
|
|
15
|
+
hiddenColumns?: string[],
|
|
16
|
+
): UseColumnVisibilityResult {
|
|
17
|
+
const [columnVisibility, setColumnVisibility] =
|
|
18
|
+
useInternalStateWithSync<VisibilityState>(
|
|
19
|
+
Object.fromEntries((hiddenColumns ?? []).map((c) => [c, false])),
|
|
20
|
+
isDeepEqual,
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
return { columnVisibility, setColumnVisibility };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface ColumnVisibilityCounts {
|
|
27
|
+
total: number;
|
|
28
|
+
visible: number;
|
|
29
|
+
hidden: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function getUserColumnVisibilityCounts<TData>(
|
|
33
|
+
table: Table<TData>,
|
|
34
|
+
): ColumnVisibilityCounts {
|
|
35
|
+
const userColumns = table.getAllLeafColumns().filter((c) => c.getCanHide());
|
|
36
|
+
const visible = userColumns.filter((c) => c.getIsVisible()).length;
|
|
37
|
+
return {
|
|
38
|
+
total: userColumns.length,
|
|
39
|
+
visible,
|
|
40
|
+
hidden: userColumns.length - visible,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// When columns are clipped server-side, the TanStack instance only holds the
|
|
45
|
+
// rendered subset, so visible/hidden math must use that subset's total. The
|
|
46
|
+
// dataset-wide value is still correct for the no-hidden "N columns" label.
|
|
47
|
+
export function getColumnCountForDisplay<TData>(
|
|
48
|
+
table: Table<TData>,
|
|
49
|
+
datasetTotalColumns: number,
|
|
50
|
+
): { totalColumns: number; hiddenColumns: number } {
|
|
51
|
+
const counts = getUserColumnVisibilityCounts(table);
|
|
52
|
+
return {
|
|
53
|
+
totalColumns: counts.hidden > 0 ? counts.total : datasetTotalColumns,
|
|
54
|
+
hiddenColumns: counts.hidden,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
@@ -443,15 +443,28 @@ export function prettifyRowCount(rowCount: number, locale: string): string {
|
|
|
443
443
|
export const prettifyRowColumnCount = ({
|
|
444
444
|
numRows,
|
|
445
445
|
totalColumns,
|
|
446
|
+
hiddenColumns,
|
|
446
447
|
locale,
|
|
447
448
|
}: {
|
|
448
449
|
numRows: number | "too_many";
|
|
449
450
|
totalColumns: number;
|
|
451
|
+
hiddenColumns?: number;
|
|
450
452
|
locale: string;
|
|
451
|
-
}): string => {
|
|
453
|
+
}): { rowsAndColumns: string; hiddenSuffix: string | null } => {
|
|
452
454
|
const rowsLabel =
|
|
453
455
|
numRows === "too_many" ? "Unknown" : prettifyRowCount(numRows, locale);
|
|
454
|
-
const columnsLabel = `${prettyNumber(totalColumns, locale)} ${new PluralWord("column").pluralize(totalColumns)}`;
|
|
455
456
|
|
|
456
|
-
|
|
457
|
+
const hidden = hiddenColumns ?? 0;
|
|
458
|
+
const visibleColumns = totalColumns - hidden;
|
|
459
|
+
|
|
460
|
+
const columnsLabel =
|
|
461
|
+
hidden > 0
|
|
462
|
+
? `${prettyNumber(visibleColumns, locale)} visible`
|
|
463
|
+
: `${prettyNumber(totalColumns, locale)} ${new PluralWord("column").pluralize(totalColumns)}`;
|
|
464
|
+
|
|
465
|
+
return {
|
|
466
|
+
rowsAndColumns: [rowsLabel, columnsLabel].join(", "),
|
|
467
|
+
hiddenSuffix:
|
|
468
|
+
hidden > 0 ? `(${prettyNumber(hidden, locale)} hidden)` : null,
|
|
469
|
+
};
|
|
457
470
|
};
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
"use no memo";
|
|
3
|
+
|
|
4
|
+
// tanstack/table is not compatible with React compiler
|
|
5
|
+
// https://github.com/TanStack/table/issues/5567
|
|
2
6
|
|
|
3
7
|
import { Fill } from "@marimo-team/react-slotz";
|
|
4
|
-
import type {
|
|
5
|
-
|
|
8
|
+
import type {
|
|
9
|
+
OnChangeFn,
|
|
10
|
+
RowSelectionState,
|
|
11
|
+
Table,
|
|
12
|
+
} from "@tanstack/react-table";
|
|
6
13
|
import { Button } from "@/components/ui/button";
|
|
7
14
|
import { Tabs, TabsContent } from "@/components/ui/tabs";
|
|
8
15
|
import { SlotNames } from "@/core/slots/slots";
|
|
@@ -19,7 +26,7 @@ import { ColumnExplorerPanel } from "../column-explorer-panel/column-explorer";
|
|
|
19
26
|
import { RowViewerPanel } from "../row-viewer-panel/row-viewer";
|
|
20
27
|
import type { FieldTypesWithExternalType, TooManyRows } from "../types";
|
|
21
28
|
|
|
22
|
-
export interface TableExplorerPanelProps {
|
|
29
|
+
export interface TableExplorerPanelProps<TData> {
|
|
23
30
|
// Row viewer props
|
|
24
31
|
rowIdx: number;
|
|
25
32
|
setRowIdx: (rowIdx: number) => void;
|
|
@@ -33,6 +40,7 @@ export interface TableExplorerPanelProps {
|
|
|
33
40
|
previewColumn?: PreviewColumn;
|
|
34
41
|
totalColumns: number;
|
|
35
42
|
tableId: string;
|
|
43
|
+
table: Table<TData>;
|
|
36
44
|
// Visibility flags
|
|
37
45
|
showRowExplorer: boolean;
|
|
38
46
|
showColumnExplorer: boolean;
|
|
@@ -46,7 +54,7 @@ const tabTriggerClassName =
|
|
|
46
54
|
const activeClassName = "text-primary";
|
|
47
55
|
const inactiveClassName = "hover:text-foreground";
|
|
48
56
|
|
|
49
|
-
export
|
|
57
|
+
export function TableExplorerPanel<TData>({
|
|
50
58
|
// Row viewer
|
|
51
59
|
rowIdx,
|
|
52
60
|
setRowIdx,
|
|
@@ -60,13 +68,14 @@ export const TableExplorerPanel: React.FC<TableExplorerPanelProps> = ({
|
|
|
60
68
|
previewColumn,
|
|
61
69
|
totalColumns,
|
|
62
70
|
tableId,
|
|
71
|
+
table,
|
|
63
72
|
// Visibility
|
|
64
73
|
showRowExplorer,
|
|
65
74
|
showColumnExplorer,
|
|
66
75
|
// Tab state
|
|
67
76
|
activeTab,
|
|
68
77
|
onTabChange,
|
|
69
|
-
})
|
|
78
|
+
}: TableExplorerPanelProps<TData>) {
|
|
70
79
|
const showTabs = showRowExplorer && showColumnExplorer;
|
|
71
80
|
|
|
72
81
|
const rowViewer = (
|
|
@@ -89,6 +98,7 @@ export const TableExplorerPanel: React.FC<TableExplorerPanelProps> = ({
|
|
|
89
98
|
totalRows={totalRows}
|
|
90
99
|
totalColumns={totalColumns}
|
|
91
100
|
tableId={tableId}
|
|
101
|
+
table={table}
|
|
92
102
|
/>
|
|
93
103
|
);
|
|
94
104
|
|
|
@@ -158,4 +168,4 @@ export const TableExplorerPanel: React.FC<TableExplorerPanelProps> = ({
|
|
|
158
168
|
</TabsContent>
|
|
159
169
|
</Tabs>
|
|
160
170
|
);
|
|
161
|
-
}
|
|
171
|
+
}
|