@marimo-team/frontend 0.25.3-dev39 → 0.25.3-dev40

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.
Files changed (183) hide show
  1. package/dist/assets/CellStatus-BGIWF94J.js +1 -0
  2. package/dist/assets/{ConnectedDataExplorerComponent-DMdJT25t.js → ConnectedDataExplorerComponent-D9UK8o9A.js} +1 -1
  3. package/dist/assets/{ErrorBoundary-D1ozl9e0.js → ErrorBoundary-hliG40Pk.js} +2 -2
  4. package/dist/assets/{JsonOutput-Dqg7qwkl.js → JsonOutput-9tmC-p6h.js} +6 -6
  5. package/dist/assets/{LazyAnyLanguageCodeMirror-B4fCknq1.js → LazyAnyLanguageCodeMirror-BPYE76jR.js} +2 -2
  6. package/dist/assets/{MarimoErrorOutput-BYSTEwo1.js → MarimoErrorOutput-BaHdbtck.js} +1 -1
  7. package/dist/assets/{RenderHTML-B18UiW8r.js → RenderHTML-B1FzB5NY.js} +1 -1
  8. package/dist/assets/{RunButton-CWvRnb98.js → RunButton-DpGokdF1.js} +1 -1
  9. package/dist/assets/{add-cell-with-ai-C4pN_ho7.js → add-cell-with-ai-BYWG0iKO.js} +2 -2
  10. package/dist/assets/{add-connection-dialog-BErVOfUV.js → add-connection-dialog-BWbUVPJk.js} +1 -1
  11. package/dist/assets/{agent-panel-QQDTP8Vb.js → agent-panel-DKNiQrAl.js} +1 -1
  12. package/dist/assets/ai-model-dropdown-CIg9eu47.js +13 -0
  13. package/dist/assets/{alert-dialog-BaPGzeOK.js → alert-dialog-C-sWmKva.js} +1 -1
  14. package/dist/assets/any-language-editor-DUMe1UCk.js +1 -0
  15. package/dist/assets/{app-config-button-DBHN-U2l.js → app-config-button-BvkL2eSY.js} +1 -1
  16. package/dist/assets/arrays-0R2reF2y.js +1 -0
  17. package/dist/assets/{blob-DY_W1wFZ.js → blob-BQfLiwKr.js} +1 -1
  18. package/dist/assets/{button-COI-NGrx.js → button-D8gVKwe-.js} +1 -1
  19. package/dist/assets/{cache-panel-DTY1dqvi.js → cache-panel-Byolv2ht.js} +1 -1
  20. package/dist/assets/{capabilities-BJvf-MD4.js → capabilities-Pq1YNPlK.js} +1 -1
  21. package/dist/assets/{cell-editor-CCFDuQIT.js → cell-editor-BKKUv4d5.js} +2 -2
  22. package/dist/assets/{cell-link-BOqoitvE.js → cell-link-B_QkRkm-.js} +1 -1
  23. package/dist/assets/{cells-CN1I_0eH.js → cells-CdH98VSn.js} +2 -2
  24. package/dist/assets/{chat-display-D1_UV6v7.js → chat-display-CNbRSebo.js} +1 -1
  25. package/dist/assets/{chat-panel-C4OJDIt6.js → chat-panel-HbEKDf0c.js} +1 -1
  26. package/dist/assets/{chat-ui-wuDYPZ-w.js → chat-ui-BwMev8Bf.js} +1 -1
  27. package/dist/assets/{circle-DXf-VWZG.js → circle-B6D_6D8w.js} +1 -1
  28. package/dist/assets/{code-visibility-CnU9xZw7.js → code-visibility-sQ37CBNo.js} +1 -1
  29. package/dist/assets/{column-preview-z4bqk4HW.js → column-preview-CsEBzIUE.js} +1 -1
  30. package/dist/assets/{command-palette-TblDi15Q.js → command-palette-BzZ86pUz.js} +1 -1
  31. package/dist/assets/{common-Cbk0KIh7.js → common-S2v8dsEy.js} +1 -1
  32. package/dist/assets/{components-C88UxBXz.js → components-D-TnFWjo.js} +1 -1
  33. package/dist/assets/{components-CskjK6xZ.js → components-DrU8dOzy.js} +1 -1
  34. package/dist/assets/{components-YBmtV0p6.js → components-lDm0qi2t.js} +1 -1
  35. package/dist/assets/{config-DEzFV5-l.js → config-BoBwH7CU.js} +1 -1
  36. package/dist/assets/{config-MaHeMC9o.js → config-CYsbZpwa.js} +2 -2
  37. package/dist/assets/{config-CA1V-wjh.js → config-DGX7JYor.js} +1 -1
  38. package/dist/assets/{copy-D8O_CYCG.js → copy-KlhazlhB.js} +1 -1
  39. package/dist/assets/{copy-icon-BIiRXh_3.js → copy-icon-8-a5vovc.js} +1 -1
  40. package/dist/assets/{createReducer-DgRODTW6.js → createReducer-HKXUbqyz.js} +1 -1
  41. package/dist/assets/{datasource-DZJ6qqVI.js → datasource-BA7YF4eo.js} +1 -1
  42. package/dist/assets/{dates-CfmdTL6B.js → dates-CQMwFko2.js} +1 -1
  43. package/dist/assets/{dependency-graph-panel-DeZ66gIo.js → dependency-graph-panel-DsjI61Qa.js} +1 -1
  44. package/dist/assets/{dist-iaThVDkA.js → dist-jlhMTKo_.js} +1 -1
  45. package/dist/assets/{documentation-panel-Tl5G1cPt.js → documentation-panel-hk3IdeXy.js} +1 -1
  46. package/dist/assets/{download-s8iwxGDb.js → download-CCZkq0y4.js} +1 -1
  47. package/dist/assets/{dropdown-menu-C1rnl-0o.js → dropdown-menu-DS6umAnH.js} +1 -1
  48. package/dist/assets/{edit-page-CjoAJvyN.js → edit-page-BgS6tjth.js} +4 -4
  49. package/dist/assets/{error-banner-COZ7SfYV.js → error-banner-B5kzVf_0.js} +1 -1
  50. package/dist/assets/{error-entries-D11Bn1Hk.js → error-entries-BVXrGOTZ.js} +1 -1
  51. package/dist/assets/{error-panel-kfxFDscu.js → error-panel-DYethUUR.js} +1 -1
  52. package/dist/assets/{es-Cqst59WX.js → es-N9SHpmG7.js} +1 -1
  53. package/dist/assets/feedback-button-DDzObtF2.js +1 -0
  54. package/dist/assets/{feedback-button-DVABjD9Y.js → feedback-button-DaNc3uJa.js} +1 -1
  55. package/dist/assets/{file-explorer-panel-CvmK-rEU.js → file-explorer-panel-CqnzSSYc.js} +1 -1
  56. package/dist/assets/{file-name-input-DAj9a3RQ.js → file-name-input-D4AvwZV9.js} +1 -1
  57. package/dist/assets/{floating-outline-DDavqWJx.js → floating-outline-CTy-Iakk.js} +1 -1
  58. package/dist/assets/{formats-BkelUASr.js → formats-zylfwejq.js} +1 -1
  59. package/dist/assets/{formatting-BqrP-n49.js → formatting-uom1es4b.js} +1 -1
  60. package/dist/assets/{fullscreen-B9tHcfpV.js → fullscreen-BWTs8pYZ.js} +1 -1
  61. package/dist/assets/{gallery-page-xP6VqDyd.js → gallery-page-ByjlvM6k.js} +1 -1
  62. package/dist/assets/{glide-data-editor-32vBJJf8.js → glide-data-editor-CABBj2b0.js} +2 -2
  63. package/dist/assets/{glide-utils-CIrAxdjv.js → glide-utils-HFqhvWHI.js} +2 -2
  64. package/dist/assets/{home-page-CvGzjVr4.js → home-page-DejRSjeJ.js} +3 -3
  65. package/dist/assets/{hooks-C1_gQ8kr.js → hooks-BJgCcVXZ.js} +1 -1
  66. package/dist/assets/{html-to-image-DK9Zl1lU.js → html-to-image-D_0rd3_B.js} +1 -1
  67. package/dist/assets/{index-6b4mf8Ai.css → index-ChfDZJzP.css} +1 -1
  68. package/dist/assets/index-PDJQd7X6.js +30 -0
  69. package/dist/assets/{input-BoBxR50a.js → input-ByHt6aoV.js} +1 -1
  70. package/dist/assets/{kiosk-mode-BZECfg9k.js → kiosk-mode-BGmMSc7A.js} +1 -1
  71. package/dist/assets/{layout-BccvBeZy.js → layout-Ct0rjb-5.js} +3 -3
  72. package/dist/assets/links-CXcpNIM0.js +1 -0
  73. package/dist/assets/{logs-panel-BhXo1sVJ.js → logs-panel-TyeqEvOY.js} +1 -1
  74. package/dist/assets/{markdown-renderer-D2dafr8r.js → markdown-renderer-BFyD6Jhs.js} +1 -1
  75. package/dist/assets/{menu-items-BrwnTgyK.js → menu-items-BgUyNUpu.js} +1 -1
  76. package/dist/assets/{mermaid-D2FUGQeW.js → mermaid-B6mqMm5_.js} +1 -1
  77. package/dist/assets/{name-cell-input-SHvgfcBR.js → name-cell-input-D-0VF3qd.js} +1 -1
  78. package/dist/assets/numbers-CsZVw3Dc.js +1 -0
  79. package/dist/assets/{objects-snlMn4yk.js → objects-rLPlQ3X_.js} +1 -1
  80. package/dist/assets/{once-Haz_uxEL.js → once-6KNTRW0u.js} +1 -1
  81. package/dist/assets/{outline-panel-CpY3FH-u.js → outline-panel-DMTjk2WC.js} +1 -1
  82. package/dist/assets/{packages-panel-oZ0qZBec.js → packages-panel-DrT69k9L.js} +1 -1
  83. package/dist/assets/{panel-accordion-state-ChFIY2WQ.js → panel-accordion-state-Ban6j---.js} +1 -1
  84. package/dist/assets/{panels-91ywfwgc.js → panels-BLYQRkEc.js} +1 -1
  85. package/dist/assets/process-output-DzpQYlpY.js +1 -0
  86. package/dist/assets/{readonly-code-display-C1eH5BDP.js → readonly-code-display-Cyn3k5TX.js} +1 -1
  87. package/dist/assets/{readonly-python-code-BaElyj-4.js → readonly-python-code-DrXDDAnA.js} +1 -1
  88. package/dist/assets/{renderShortcut-C1JwYcqW.js → renderShortcut-H60uiHBp.js} +1 -1
  89. package/dist/assets/{reveal-component-FCuqfC5H.js → reveal-component-_lKImPWP.js} +1 -1
  90. package/dist/assets/{run-page-CbyMlRt1.js → run-page-7UNg--Rj.js} +1 -1
  91. package/dist/assets/{runs-BLp5jezv.js → runs-6lJxKV1w.js} +1 -1
  92. package/dist/assets/{runtime-details-state-Bpn67vTN.js → runtime-details-state-CKOKhMhv.js} +1 -1
  93. package/dist/assets/{scratchpad-panel-OF9_e0l_.js → scratchpad-panel-C7h4MgqN.js} +1 -1
  94. package/dist/assets/{scroll-to-bottom-button-1FyowpWV.js → scroll-to-bottom-button-CIkON2WJ.js} +1 -1
  95. package/dist/assets/{secrets-panel-D7KN4tVs.js → secrets-panel-CmLZsNfp.js} +1 -1
  96. package/dist/assets/{select-DTBn5eTb.js → select-3CVGlYrC.js} +1 -1
  97. package/dist/assets/{session-DqoWmb7X.js → session-B8Y-GJnS.js} +1 -1
  98. package/dist/assets/{session-panel-CExxjkjV.js → session-panel-CLiWXc5y.js} +1 -1
  99. package/dist/assets/{snippets-panel-DfRtTFJ-.js → snippets-panel-Wrqaorxa.js} +1 -1
  100. package/dist/assets/{spec-BfSBcO5B.js → spec-uCpVvaAR.js} +1 -1
  101. package/dist/assets/{state-uwRvJLb8.js → state-BY4_P6ko.js} +1 -1
  102. package/dist/assets/{state-BAJYRhmO.js → state-C0irhlOZ.js} +1 -1
  103. package/dist/assets/{state-DxQnC_1I.js → state-Ck7FMD5A.js} +1 -1
  104. package/dist/assets/{state-C3oDoyFe.js → state-DaWgt-rn.js} +1 -1
  105. package/dist/assets/{state-BUqF6L9e.js → state-TVREh4u4.js} +1 -1
  106. package/dist/assets/{state-CHojzKpZ.js → state-_uXVmwuN.js} +1 -1
  107. package/dist/assets/{strings-B2vv-ENv.js → strings-C25fhMR_.js} +1 -1
  108. package/dist/assets/{swiper-component-a07domrZ.js → swiper-component-CRGRy5_O.js} +1 -1
  109. package/dist/assets/{switch-CTaiAjrz.js → switch-1h011wlH.js} +1 -1
  110. package/dist/assets/{tabs-BuQlZFbt.js → tabs-CY8E4r9U.js} +1 -1
  111. package/dist/assets/{terminal--4gDbK7q.js → terminal-Dp5gyJ7l.js} +1 -1
  112. package/dist/assets/{toast-BGzLGnvw.js → toast-Gzxi-le_.js} +1 -1
  113. package/dist/assets/{tooltip-BsSdc1NQ.js → tooltip-Brya4Ghn.js} +1 -1
  114. package/dist/assets/{tooltip-C9TuY18o.js → tooltip-CkGm8X7m.js} +1 -1
  115. package/dist/assets/tracing-fUNLyKuj.js +1 -0
  116. package/dist/assets/{tracing-panel-DNabsbtA.js → tracing-panel-Cx4OqOoP.js} +2 -2
  117. package/dist/assets/{tree-actions-BXvnBv45.js → tree-actions-B1vsdenY.js} +1 -1
  118. package/dist/assets/{use-restore-focus-BxEGwIbk.js → use-restore-focus-DdS7Tl0F.js} +1 -1
  119. package/dist/assets/{useAddCell-6ECZ0xPG.js → useAddCell-DZ-50qEG.js} +1 -1
  120. package/dist/assets/useAsyncData-DhhdOGGd.js +1 -0
  121. package/dist/assets/{useBoolean-BvAx9Qrr.js → useBoolean-5g-bBaYF.js} +1 -1
  122. package/dist/assets/{useCellActionButton-Djyiwayj.js → useCellActionButton-DINnRstv.js} +1 -1
  123. package/dist/assets/{useDeleteCell-KX6SEwki.js → useDeleteCell-CREJXVNp.js} +1 -1
  124. package/dist/assets/{useDependencyPanelTab-B8ke9iTY.js → useDependencyPanelTab-Cw5VT16Q.js} +1 -1
  125. package/dist/assets/{useEventListener-D9cftcHj.js → useEventListener-CjDeLqFC.js} +1 -1
  126. package/dist/assets/{useIframeCapabilities-CwTkczVN.js → useIframeCapabilities-Czr9e4uG.js} +1 -1
  127. package/dist/assets/{useInstallPackage-C9-icL78.js → useInstallPackage-Cw0dVELh.js} +1 -1
  128. package/dist/assets/{useInterval--x3s1VpI.js → useInterval-DJdQmXnq.js} +1 -1
  129. package/dist/assets/{useNotebookActions-CluLEhAd.js → useNotebookActions-B4av4mLc.js} +1 -1
  130. package/dist/assets/{useRunCells-B847kPLO.js → useRunCells-BHBMk9zW.js} +1 -1
  131. package/dist/assets/{useSplitCell-CnvTmIw7.js → useSplitCell-DAgwZV0q.js} +1 -1
  132. package/dist/assets/{useTheme-n8Dj1zH7.js → useTheme-DLtPc-39.js} +1 -1
  133. package/dist/assets/{utils-CaQYvazl.js → utils-DfElfBpz.js} +1 -1
  134. package/dist/assets/vega-component-pQE2mKc1.js +1 -0
  135. package/dist/assets/{vega-embed-container-CxuIHhsS.js → vega-embed-container-DtArSJz1.js} +1 -1
  136. package/dist/assets/{write-secret-modal-DzKAInL2.js → write-secret-modal-usRSi1bb.js} +1 -1
  137. package/dist/index.html +68 -68
  138. package/package.json +1 -1
  139. package/src/components/app-config/ai-config.tsx +5 -1
  140. package/src/components/data-table/__tests__/date-popover.test.tsx +72 -0
  141. package/src/components/data-table/column-visibility-dropdown.tsx +8 -13
  142. package/src/components/data-table/columns.tsx +2 -1
  143. package/src/components/data-table/date-popover.tsx +6 -4
  144. package/src/components/data-table/row-viewer-panel/row-viewer.tsx +2 -2
  145. package/src/components/editor/ai/add-cell-with-ai.tsx +3 -3
  146. package/src/components/editor/connections/components.tsx +1 -1
  147. package/src/components/editor/output/MarimoTracebackOutput.tsx +1 -1
  148. package/src/components/pages/home-page.tsx +4 -4
  149. package/src/components/tracing/tracing.tsx +2 -2
  150. package/src/core/cells/pending-delete-service.ts +2 -6
  151. package/src/core/datasets/__tests__/data-source-discovery.test.ts +4 -4
  152. package/src/core/datasets/data-source-discovery.ts +4 -6
  153. package/src/core/hotkeys/actions.ts +2 -4
  154. package/src/core/runtime/runtime.ts +3 -4
  155. package/src/hooks/__tests__/useAsyncData.test.tsx +148 -0
  156. package/src/hooks/useAsyncData.ts +3 -3
  157. package/src/hooks/useDataSourceDiscovery.ts +6 -4
  158. package/src/hooks/useElapsedTime.ts +3 -3
  159. package/src/plugins/core/registerReactComponent.tsx +1 -1
  160. package/src/plugins/impl/DropdownPlugin.tsx +2 -6
  161. package/src/plugins/impl/FormPlugin.tsx +1 -1
  162. package/src/plugins/impl/code/any-language-editor.tsx +2 -2
  163. package/src/plugins/impl/data-editor/glide-data-editor.tsx +8 -5
  164. package/src/plugins/impl/data-editor/glide-utils.ts +3 -1
  165. package/src/plugins/impl/vega/make-selectable.ts +3 -6
  166. package/src/utils/__tests__/arrays.test.ts +35 -0
  167. package/src/utils/__tests__/numbers.test.ts +48 -1
  168. package/src/utils/__tests__/objects.test.ts +21 -0
  169. package/src/utils/arrays.ts +10 -0
  170. package/src/utils/numbers.ts +28 -17
  171. package/src/utils/objects.ts +3 -7
  172. package/dist/assets/CellStatus-wFCGHpDX.js +0 -1
  173. package/dist/assets/ai-model-dropdown-D5Fe5GS-.js +0 -13
  174. package/dist/assets/any-language-editor-BdTWdMCI.js +0 -1
  175. package/dist/assets/arrays-BqUx5USx.js +0 -1
  176. package/dist/assets/feedback-button-3bZHpuSh.js +0 -1
  177. package/dist/assets/index-Dtv0HH-7.js +0 -30
  178. package/dist/assets/links-DkkL9DVa.js +0 -1
  179. package/dist/assets/numbers-Mk3-CcoU.js +0 -1
  180. package/dist/assets/process-output-Dvq4b2kJ.js +0 -1
  181. package/dist/assets/tracing-BnfAB-BH.js +0 -1
  182. package/dist/assets/useAsyncData-C7aJJz0Y.js +0 -1
  183. package/dist/assets/vega-component-DAkdRNSF.js +0 -1
package/dist/index.html CHANGED
@@ -66,68 +66,68 @@
66
66
  <marimo-server-token data-token="{{ server_token }}" hidden></marimo-server-token>
67
67
  <!-- /TODO -->
68
68
  <title>{{ title }}</title>
69
- <script type="module" crossorigin src="./assets/index-Dtv0HH-7.js"></script>
69
+ <script type="module" crossorigin src="./assets/index-PDJQd7X6.js"></script>
70
70
  <link rel="modulepreload" crossorigin href="./assets/rolldown-runtime-B0Z9INg1.js">
71
71
  <link rel="modulepreload" crossorigin href="./assets/react-DVplv7_D.js">
72
72
  <link rel="modulepreload" crossorigin href="./assets/compiler-runtime-BrajqUja.js">
73
73
  <link rel="modulepreload" crossorigin href="./assets/useEvent-Dfcbgjhg.js">
74
74
  <link rel="modulepreload" crossorigin href="./assets/react-dom-_LrxgvjW.js">
75
75
  <link rel="modulepreload" crossorigin href="./assets/schemas-ChRqMOTL.js">
76
- <link rel="modulepreload" crossorigin href="./assets/objects-snlMn4yk.js">
77
- <link rel="modulepreload" crossorigin href="./assets/useEventListener-D9cftcHj.js">
76
+ <link rel="modulepreload" crossorigin href="./assets/objects-rLPlQ3X_.js">
77
+ <link rel="modulepreload" crossorigin href="./assets/useEventListener-CjDeLqFC.js">
78
78
  <link rel="modulepreload" crossorigin href="./assets/invariant-Ci2dTZ72.js">
79
79
  <link rel="modulepreload" crossorigin href="./assets/utils-B4K466FK.js">
80
- <link rel="modulepreload" crossorigin href="./assets/session-DqoWmb7X.js">
80
+ <link rel="modulepreload" crossorigin href="./assets/session-B8Y-GJnS.js">
81
81
  <link rel="modulepreload" crossorigin href="./assets/Deferred-CrTnjj37.js">
82
- <link rel="modulepreload" crossorigin href="./assets/config-MaHeMC9o.js">
82
+ <link rel="modulepreload" crossorigin href="./assets/config-CYsbZpwa.js">
83
83
  <link rel="modulepreload" crossorigin href="./assets/isObject-BCaOs5rp.js">
84
84
  <link rel="modulepreload" crossorigin href="./assets/isSymbol-oX0TOjjx.js">
85
85
  <link rel="modulepreload" crossorigin href="./assets/now-Cmx0b_zA.js">
86
86
  <link rel="modulepreload" crossorigin href="./assets/debounce-aFmHgJZY.js">
87
87
  <link rel="modulepreload" crossorigin href="./assets/isArrayLikeObject-DnwgSs_Z.js">
88
88
  <link rel="modulepreload" crossorigin href="./assets/_baseMerge-CQpUq7ep.js">
89
- <link rel="modulepreload" crossorigin href="./assets/config-CA1V-wjh.js">
89
+ <link rel="modulepreload" crossorigin href="./assets/config-DGX7JYor.js">
90
90
  <link rel="modulepreload" crossorigin href="./assets/clsx-DB0hHKMi.js">
91
91
  <link rel="modulepreload" crossorigin href="./assets/cn-ldLVeaqm.js">
92
92
  <link rel="modulepreload" crossorigin href="./assets/jsx-runtime-B74pBk57.js">
93
- <link rel="modulepreload" crossorigin href="./assets/fullscreen-B9tHcfpV.js">
94
- <link rel="modulepreload" crossorigin href="./assets/dist-iaThVDkA.js">
95
- <link rel="modulepreload" crossorigin href="./assets/menu-items-BrwnTgyK.js">
96
- <link rel="modulepreload" crossorigin href="./assets/use-restore-focus-BxEGwIbk.js">
93
+ <link rel="modulepreload" crossorigin href="./assets/fullscreen-BWTs8pYZ.js">
94
+ <link rel="modulepreload" crossorigin href="./assets/dist-jlhMTKo_.js">
95
+ <link rel="modulepreload" crossorigin href="./assets/menu-items-BgUyNUpu.js">
96
+ <link rel="modulepreload" crossorigin href="./assets/use-restore-focus-DdS7Tl0F.js">
97
97
  <link rel="modulepreload" crossorigin href="./assets/createLucideIcon-DfJ2oMlA.js">
98
- <link rel="modulepreload" crossorigin href="./assets/circle-DXf-VWZG.js">
99
- <link rel="modulepreload" crossorigin href="./assets/button-COI-NGrx.js">
98
+ <link rel="modulepreload" crossorigin href="./assets/circle-B6D_6D8w.js">
99
+ <link rel="modulepreload" crossorigin href="./assets/button-D8gVKwe-.js">
100
100
  <link rel="modulepreload" crossorigin href="./assets/check-BQNapYaf.js">
101
101
  <link rel="modulepreload" crossorigin href="./assets/I18nProvider-Cg2I_s1_.js">
102
102
  <link rel="modulepreload" crossorigin href="./assets/useNumberFormatter-D7O_26UI.js">
103
- <link rel="modulepreload" crossorigin href="./assets/select-DTBn5eTb.js">
104
- <link rel="modulepreload" crossorigin href="./assets/toast-BGzLGnvw.js">
105
- <link rel="modulepreload" crossorigin href="./assets/tooltip-C9TuY18o.js">
103
+ <link rel="modulepreload" crossorigin href="./assets/select-3CVGlYrC.js">
104
+ <link rel="modulepreload" crossorigin href="./assets/toast-Gzxi-le_.js">
105
+ <link rel="modulepreload" crossorigin href="./assets/tooltip-CkGm8X7m.js">
106
106
  <link rel="modulepreload" crossorigin href="./assets/paths-bkIFVj8h.js">
107
107
  <link rel="modulepreload" crossorigin href="./assets/useLifecycle-Mq4gc5kS.js">
108
108
  <link rel="modulepreload" crossorigin href="./assets/toDate-DOj9Q6uC.js">
109
109
  <link rel="modulepreload" crossorigin href="./assets/database-zap-B_PMVg8T.js">
110
- <link rel="modulepreload" crossorigin href="./assets/alert-dialog-BaPGzeOK.js">
111
- <link rel="modulepreload" crossorigin href="./assets/arrays-BqUx5USx.js">
112
- <link rel="modulepreload" crossorigin href="./assets/once-Haz_uxEL.js">
113
- <link rel="modulepreload" crossorigin href="./assets/numbers-Mk3-CcoU.js">
110
+ <link rel="modulepreload" crossorigin href="./assets/alert-dialog-C-sWmKva.js">
111
+ <link rel="modulepreload" crossorigin href="./assets/arrays-0R2reF2y.js">
112
+ <link rel="modulepreload" crossorigin href="./assets/once-6KNTRW0u.js">
113
+ <link rel="modulepreload" crossorigin href="./assets/numbers-CsZVw3Dc.js">
114
114
  <link rel="modulepreload" crossorigin href="./assets/useDebounce-B_ccBZTp.js">
115
- <link rel="modulepreload" crossorigin href="./assets/input-BoBxR50a.js">
115
+ <link rel="modulepreload" crossorigin href="./assets/input-ByHt6aoV.js">
116
116
  <link rel="modulepreload" crossorigin href="./assets/use-toast-Wu434mLr.js">
117
117
  <link rel="modulepreload" crossorigin href="./assets/requests-lt0JK8Jt.js">
118
118
  <link rel="modulepreload" crossorigin href="./assets/uuid-k9DpjH68.js">
119
- <link rel="modulepreload" crossorigin href="./assets/write-secret-modal-DzKAInL2.js">
119
+ <link rel="modulepreload" crossorigin href="./assets/write-secret-modal-usRSi1bb.js">
120
120
  <link rel="modulepreload" crossorigin href="./assets/plus-C5silF6g.js">
121
121
  <link rel="modulepreload" crossorigin href="./assets/trash-2-DcgaW8fn.js">
122
122
  <link rel="modulepreload" crossorigin href="./assets/preload-helper-uBIymjUX.js">
123
123
  <link rel="modulepreload" crossorigin href="./assets/dist-Cny7_yZb.js">
124
124
  <link rel="modulepreload" crossorigin href="./assets/dist-DBMV4gqt.js">
125
- <link rel="modulepreload" crossorigin href="./assets/capabilities-BJvf-MD4.js">
125
+ <link rel="modulepreload" crossorigin href="./assets/capabilities-Pq1YNPlK.js">
126
126
  <link rel="modulepreload" crossorigin href="./assets/cjs-C49f7GXV.js">
127
- <link rel="modulepreload" crossorigin href="./assets/createReducer-DgRODTW6.js">
127
+ <link rel="modulepreload" crossorigin href="./assets/createReducer-HKXUbqyz.js">
128
128
  <link rel="modulepreload" crossorigin href="./assets/dist-qhAY4L2r.js">
129
129
  <link rel="modulepreload" crossorigin href="./assets/marked.esm-B_3iMIUq.js">
130
- <link rel="modulepreload" crossorigin href="./assets/strings-B2vv-ENv.js">
130
+ <link rel="modulepreload" crossorigin href="./assets/strings-C25fhMR_.js">
131
131
  <link rel="modulepreload" crossorigin href="./assets/dist-BOfh4hMd.js">
132
132
  <link rel="modulepreload" crossorigin href="./assets/badge-crT3E0Rm.js">
133
133
  <link rel="modulepreload" crossorigin href="./assets/dist-DtH-7lot.js">
@@ -136,10 +136,10 @@
136
136
  <link rel="modulepreload" crossorigin href="./assets/dist-LSsCJjA3.js">
137
137
  <link rel="modulepreload" crossorigin href="./assets/dist-DusFODSa.js">
138
138
  <link rel="modulepreload" crossorigin href="./assets/stex-Dc5bKD4z.js">
139
- <link rel="modulepreload" crossorigin href="./assets/useTheme-n8Dj1zH7.js">
140
- <link rel="modulepreload" crossorigin href="./assets/useAsyncData-C7aJJz0Y.js">
139
+ <link rel="modulepreload" crossorigin href="./assets/useTheme-DLtPc-39.js">
140
+ <link rel="modulepreload" crossorigin href="./assets/useAsyncData-DhhdOGGd.js">
141
141
  <link rel="modulepreload" crossorigin href="./assets/purify.es--06brOip.js">
142
- <link rel="modulepreload" crossorigin href="./assets/cells-CN1I_0eH.js">
142
+ <link rel="modulepreload" crossorigin href="./assets/cells-CdH98VSn.js">
143
143
  <link rel="modulepreload" crossorigin href="./assets/coerce-DWjFeXOY.js">
144
144
  <link rel="modulepreload" crossorigin href="./assets/get-DjNf4SIX.js">
145
145
  <link rel="modulepreload" crossorigin href="./assets/_hasPath-BmRQipI0.js">
@@ -147,72 +147,72 @@
147
147
  <link rel="modulepreload" crossorigin href="./assets/_baseSet-Bpdo9AvU.js">
148
148
  <link rel="modulepreload" crossorigin href="./assets/pick-DKIID_Mo.js">
149
149
  <link rel="modulepreload" crossorigin href="./assets/errors-CNsgAw6m.js">
150
- <link rel="modulepreload" crossorigin href="./assets/config-DEzFV5-l.js">
151
- <link rel="modulepreload" crossorigin href="./assets/state-BAJYRhmO.js">
152
- <link rel="modulepreload" crossorigin href="./assets/state-C3oDoyFe.js">
153
- <link rel="modulepreload" crossorigin href="./assets/LazyAnyLanguageCodeMirror-B4fCknq1.js">
154
- <link rel="modulepreload" crossorigin href="./assets/copy-D8O_CYCG.js">
150
+ <link rel="modulepreload" crossorigin href="./assets/config-BoBwH7CU.js">
151
+ <link rel="modulepreload" crossorigin href="./assets/state-C0irhlOZ.js">
152
+ <link rel="modulepreload" crossorigin href="./assets/state-DaWgt-rn.js">
153
+ <link rel="modulepreload" crossorigin href="./assets/LazyAnyLanguageCodeMirror-BPYE76jR.js">
154
+ <link rel="modulepreload" crossorigin href="./assets/copy-KlhazlhB.js">
155
155
  <link rel="modulepreload" crossorigin href="./assets/micromark-factory-space-D9Dr-k4J.js">
156
156
  <link rel="modulepreload" crossorigin href="./assets/chunk-YOKDWASO-BIpRENEC.js">
157
- <link rel="modulepreload" crossorigin href="./assets/markdown-renderer-D2dafr8r.js">
157
+ <link rel="modulepreload" crossorigin href="./assets/markdown-renderer-BFyD6Jhs.js">
158
158
  <link rel="modulepreload" crossorigin href="./assets/copy-Djr5m5ac.js">
159
- <link rel="modulepreload" crossorigin href="./assets/copy-icon-BIiRXh_3.js">
160
- <link rel="modulepreload" crossorigin href="./assets/useRunCells-B847kPLO.js">
161
- <link rel="modulepreload" crossorigin href="./assets/RenderHTML-B18UiW8r.js">
162
- <link rel="modulepreload" crossorigin href="./assets/blob-DY_W1wFZ.js">
159
+ <link rel="modulepreload" crossorigin href="./assets/copy-icon-8-a5vovc.js">
160
+ <link rel="modulepreload" crossorigin href="./assets/useRunCells-BHBMk9zW.js">
161
+ <link rel="modulepreload" crossorigin href="./assets/RenderHTML-B1FzB5NY.js">
162
+ <link rel="modulepreload" crossorigin href="./assets/blob-BQfLiwKr.js">
163
163
  <link rel="modulepreload" crossorigin href="./assets/kbd-pdKBv96t.js">
164
- <link rel="modulepreload" crossorigin href="./assets/useInstallPackage-C9-icL78.js">
164
+ <link rel="modulepreload" crossorigin href="./assets/useInstallPackage-Cw0dVELh.js">
165
165
  <link rel="modulepreload" crossorigin href="./assets/share-BZW3tzEX.js">
166
166
  <link rel="modulepreload" crossorigin href="./assets/events-CbeVJ6OD.js">
167
- <link rel="modulepreload" crossorigin href="./assets/state-BUqF6L9e.js">
168
- <link rel="modulepreload" crossorigin href="./assets/ErrorBoundary-D1ozl9e0.js">
167
+ <link rel="modulepreload" crossorigin href="./assets/state-TVREh4u4.js">
168
+ <link rel="modulepreload" crossorigin href="./assets/ErrorBoundary-hliG40Pk.js">
169
169
  <link rel="modulepreload" crossorigin href="./assets/chevron-right-eAtVhbNZ.js">
170
- <link rel="modulepreload" crossorigin href="./assets/dropdown-menu-C1rnl-0o.js">
171
- <link rel="modulepreload" crossorigin href="./assets/html-to-image-DK9Zl1lU.js">
172
- <link rel="modulepreload" crossorigin href="./assets/download-s8iwxGDb.js">
173
- <link rel="modulepreload" crossorigin href="./assets/switch-CTaiAjrz.js">
174
- <link rel="modulepreload" crossorigin href="./assets/tabs-BuQlZFbt.js">
170
+ <link rel="modulepreload" crossorigin href="./assets/dropdown-menu-DS6umAnH.js">
171
+ <link rel="modulepreload" crossorigin href="./assets/html-to-image-D_0rd3_B.js">
172
+ <link rel="modulepreload" crossorigin href="./assets/download-CCZkq0y4.js">
173
+ <link rel="modulepreload" crossorigin href="./assets/switch-1h011wlH.js">
174
+ <link rel="modulepreload" crossorigin href="./assets/tabs-CY8E4r9U.js">
175
175
  <link rel="modulepreload" crossorigin href="./assets/table-DG7Ap4H4.js">
176
176
  <link rel="modulepreload" crossorigin href="./assets/eye-off-CxVozGAC.js">
177
177
  <link rel="modulepreload" crossorigin href="./assets/refresh-cw-Qw1f8Jhy.js">
178
- <link rel="modulepreload" crossorigin href="./assets/tree-actions-BXvnBv45.js">
178
+ <link rel="modulepreload" crossorigin href="./assets/tree-actions-B1vsdenY.js">
179
179
  <link rel="modulepreload" crossorigin href="./assets/ellipsis-63DyBLHQ.js">
180
180
  <link rel="modulepreload" crossorigin href="./assets/external-link-UrX9KO36.js">
181
181
  <link rel="modulepreload" crossorigin href="./assets/spinner-DyNE-o8o.js">
182
182
  <link rel="modulepreload" crossorigin href="./assets/message-circle-C3rKm8_a.js">
183
183
  <link rel="modulepreload" crossorigin href="./assets/hat-glasses-C8RhSVii.js">
184
184
  <link rel="modulepreload" crossorigin href="./assets/package-GSoSTiIK.js">
185
- <link rel="modulepreload" crossorigin href="./assets/datasource-DZJ6qqVI.js">
186
- <link rel="modulepreload" crossorigin href="./assets/error-entries-D11Bn1Hk.js">
185
+ <link rel="modulepreload" crossorigin href="./assets/datasource-BA7YF4eo.js">
186
+ <link rel="modulepreload" crossorigin href="./assets/error-entries-BVXrGOTZ.js">
187
187
  <link rel="modulepreload" crossorigin href="./assets/alert-DTaqCu_d.js">
188
- <link rel="modulepreload" crossorigin href="./assets/state-CHojzKpZ.js">
189
- <link rel="modulepreload" crossorigin href="./assets/cell-link-BOqoitvE.js">
190
- <link rel="modulepreload" crossorigin href="./assets/MarimoErrorOutput-BYSTEwo1.js">
188
+ <link rel="modulepreload" crossorigin href="./assets/state-_uXVmwuN.js">
189
+ <link rel="modulepreload" crossorigin href="./assets/cell-link-B_QkRkm-.js">
190
+ <link rel="modulepreload" crossorigin href="./assets/MarimoErrorOutput-BaHdbtck.js">
191
191
  <link rel="modulepreload" crossorigin href="./assets/useDateFormatter-DA-62E-Y.js">
192
192
  <link rel="modulepreload" crossorigin href="./assets/en-US-Buu61juQ.js">
193
193
  <link rel="modulepreload" crossorigin href="./assets/isValid-q_Ad80ug.js">
194
- <link rel="modulepreload" crossorigin href="./assets/dates-CfmdTL6B.js">
194
+ <link rel="modulepreload" crossorigin href="./assets/dates-CQMwFko2.js">
195
195
  <link rel="modulepreload" crossorigin href="./assets/defaultLocale-CNPGWpMu.js">
196
196
  <link rel="modulepreload" crossorigin href="./assets/precisionRound-BxlUs8G4.js">
197
197
  <link rel="modulepreload" crossorigin href="./assets/defaultLocale-D5bOh7g6.js">
198
198
  <link rel="modulepreload" crossorigin href="./assets/vega-loader.browser-Bu25TKax.js">
199
- <link rel="modulepreload" crossorigin href="./assets/tooltip-BsSdc1NQ.js">
199
+ <link rel="modulepreload" crossorigin href="./assets/tooltip-Brya4Ghn.js">
200
200
  <link rel="modulepreload" crossorigin href="./assets/react-icons.esm-D6tfmvq8.js">
201
201
  <link rel="modulepreload" crossorigin href="./assets/extends-CvVTau-c.js">
202
202
  <link rel="modulepreload" crossorigin href="./assets/objectWithoutPropertiesLoose-Do6ywDBO.js">
203
- <link rel="modulepreload" crossorigin href="./assets/useIframeCapabilities-CwTkczVN.js">
204
- <link rel="modulepreload" crossorigin href="./assets/error-banner-COZ7SfYV.js">
205
- <link rel="modulepreload" crossorigin href="./assets/utils-CaQYvazl.js">
206
- <link rel="modulepreload" crossorigin href="./assets/formats-BkelUASr.js">
203
+ <link rel="modulepreload" crossorigin href="./assets/useIframeCapabilities-Czr9e4uG.js">
204
+ <link rel="modulepreload" crossorigin href="./assets/error-banner-B5kzVf_0.js">
205
+ <link rel="modulepreload" crossorigin href="./assets/utils-DfElfBpz.js">
206
+ <link rel="modulepreload" crossorigin href="./assets/formats-zylfwejq.js">
207
207
  <link rel="modulepreload" crossorigin href="./assets/table-vrvqpuKJ.js">
208
208
  <link rel="modulepreload" crossorigin href="./assets/react-resizable-panels.browser.esm-Dbe0MrFr.js">
209
- <link rel="modulepreload" crossorigin href="./assets/JsonOutput-Dqg7qwkl.js">
209
+ <link rel="modulepreload" crossorigin href="./assets/JsonOutput-9tmC-p6h.js">
210
210
  <link rel="modulepreload" crossorigin href="./assets/chart-no-axes-column-C4_v6fQW.js">
211
211
  <link rel="modulepreload" crossorigin href="./assets/square-function-_W_Lo0P4.js">
212
- <link rel="modulepreload" crossorigin href="./assets/spec-BfSBcO5B.js">
212
+ <link rel="modulepreload" crossorigin href="./assets/spec-uCpVvaAR.js">
213
213
  <link rel="modulepreload" crossorigin href="./assets/semaphore-BjoL5P0h.js">
214
214
  <link rel="modulepreload" crossorigin href="./assets/fileToBase64-BgBraYAr.js">
215
- <link rel="modulepreload" crossorigin href="./assets/useBoolean-BvAx9Qrr.js">
215
+ <link rel="modulepreload" crossorigin href="./assets/useBoolean-5g-bBaYF.js">
216
216
  <link rel="modulepreload" crossorigin href="./assets/code-xml-SQaZqvcO.js">
217
217
  <link rel="modulepreload" crossorigin href="./assets/file-headphone-Dl35U6h3.js">
218
218
  <link rel="modulepreload" crossorigin href="./assets/file-BPBVl9pl.js">
@@ -220,27 +220,27 @@
220
220
  <link rel="modulepreload" crossorigin href="./assets/file-icons-CdJgUy-I.js">
221
221
  <link rel="modulepreload" crossorigin href="./assets/globe-UdPdIbF7.js">
222
222
  <link rel="modulepreload" crossorigin href="./assets/esm-CI_o7NhW.js">
223
- <link rel="modulepreload" crossorigin href="./assets/useAddCell-6ECZ0xPG.js">
224
- <link rel="modulepreload" crossorigin href="./assets/readonly-python-code-BaElyj-4.js">
223
+ <link rel="modulepreload" crossorigin href="./assets/useAddCell-DZ-50qEG.js">
224
+ <link rel="modulepreload" crossorigin href="./assets/readonly-python-code-DrXDDAnA.js">
225
225
  <link rel="modulepreload" crossorigin href="./assets/data-grid-types-DgHVN_Zz.js">
226
- <link rel="modulepreload" crossorigin href="./assets/glide-utils-CIrAxdjv.js">
227
- <link rel="modulepreload" crossorigin href="./assets/column-preview-z4bqk4HW.js">
226
+ <link rel="modulepreload" crossorigin href="./assets/glide-utils-HFqhvWHI.js">
227
+ <link rel="modulepreload" crossorigin href="./assets/column-preview-CsEBzIUE.js">
228
228
  <link rel="modulepreload" crossorigin href="./assets/square-BPmgQFnh.js">
229
229
  <link rel="modulepreload" crossorigin href="./assets/triangle-alert-DmIqR8sY.js">
230
230
  <link rel="modulepreload" crossorigin href="./assets/prop-types-Djf4O40e.js">
231
- <link rel="modulepreload" crossorigin href="./assets/es-Cqst59WX.js">
231
+ <link rel="modulepreload" crossorigin href="./assets/es-N9SHpmG7.js">
232
232
  <link rel="modulepreload" crossorigin href="./assets/package-data-dv4FBHxR.js">
233
233
  <link rel="modulepreload" crossorigin href="./assets/markdown-export-DzhB1FrN.js">
234
- <link rel="modulepreload" crossorigin href="./assets/renderShortcut-C1JwYcqW.js">
234
+ <link rel="modulepreload" crossorigin href="./assets/renderShortcut-H60uiHBp.js">
235
235
  <link rel="modulepreload" crossorigin href="./assets/bundle.esm-D3tw5rqW.js">
236
236
  <link rel="modulepreload" crossorigin href="./assets/icons-CiZ_8zS-.js">
237
237
  <link rel="modulepreload" crossorigin href="./assets/useDeepCompareMemoize-DFIVN9dn.js">
238
238
  <link rel="modulepreload" crossorigin href="./assets/pathUtils-DPmlLd-r.js">
239
- <link rel="modulepreload" crossorigin href="./assets/floating-outline-DDavqWJx.js">
239
+ <link rel="modulepreload" crossorigin href="./assets/floating-outline-CTy-Iakk.js">
240
240
  <link rel="stylesheet" crossorigin href="./assets/cells-0PFKL3SH.css">
241
241
  <link rel="stylesheet" crossorigin href="./assets/markdown-renderer-DjIHoF9Z.css">
242
242
  <link rel="stylesheet" crossorigin href="./assets/JsonOutput-B0GmlMnR.css">
243
- <link rel="stylesheet" crossorigin href="./assets/index-6b4mf8Ai.css">
243
+ <link rel="stylesheet" crossorigin href="./assets/index-ChfDZJzP.css">
244
244
  </head>
245
245
  <body>
246
246
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/frontend",
3
- "version": "0.25.3-dev39",
3
+ "version": "0.25.3-dev40",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -48,6 +48,7 @@ import { DEFAULT_AI_MODEL, type UserConfig } from "@/core/config/config-schema";
48
48
  import { isWasm } from "@/core/wasm/utils";
49
49
  import { cn } from "@/utils/cn";
50
50
  import { Events } from "@/utils/events";
51
+ import { Objects } from "@/utils/objects";
51
52
  import { Strings } from "@/utils/strings";
52
53
  import { AIModelDropdown, getProviderLabel } from "../ai/ai-model-dropdown";
53
54
  import {
@@ -681,7 +682,10 @@ export const CustomProvidersConfig: React.FC<AiConfigProps> = ({
681
682
  };
682
683
 
683
684
  const removeProvider = (providerName: string) => {
684
- const { [providerName]: _, ...rest } = customProviders;
685
+ const rest = Objects.filter(
686
+ customProviders,
687
+ (_, name) => name !== providerName,
688
+ );
685
689
  // Reset to clear nested dirty state, then set new value
686
690
  form.resetField("ai.custom_providers");
687
691
  form.setValue("ai.custom_providers", rest, { shouldDirty: true });
@@ -0,0 +1,72 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+ import { render, screen } from "@testing-library/react";
3
+ import type { ReactNode } from "react";
4
+ import { I18nProvider } from "react-aria";
5
+ import { afterEach, describe, expect, it, vi } from "vitest";
6
+ import { DatePopover } from "../date-popover";
7
+
8
+ vi.mock("@/components/ui/tooltip", () => ({
9
+ Tooltip: ({ content }: { content: ReactNode }) => content,
10
+ }));
11
+
12
+ afterEach(() => {
13
+ vi.restoreAllMocks();
14
+ });
15
+
16
+ describe("DatePopover", () => {
17
+ it.each([0, 123])(
18
+ "updates the local timezone and time on rerender with %i milliseconds",
19
+ (milliseconds) => {
20
+ const NativeDateTimeFormat = Intl.DateTimeFormat;
21
+ let systemTimezone = "America/Los_Angeles";
22
+ vi.spyOn(Intl, "DateTimeFormat").mockImplementation(
23
+ function (locales, options) {
24
+ return new NativeDateTimeFormat(locales, {
25
+ ...options,
26
+ timeZone: options?.timeZone ?? systemTimezone,
27
+ });
28
+ },
29
+ );
30
+
31
+ const date = new Date("2026-01-15T12:00:00Z");
32
+ date.setUTCMilliseconds(milliseconds);
33
+ const content = () => (
34
+ <I18nProvider locale="en-US">
35
+ <DatePopover date={date} type="datetime">
36
+ timestamp
37
+ </DatePopover>
38
+ </I18nProvider>
39
+ );
40
+ const { rerender } = render(content());
41
+ const previousTime =
42
+ screen.getByText(systemTimezone).nextElementSibling?.textContent;
43
+ const utcTime = screen.getByText("UTC").nextElementSibling?.textContent;
44
+
45
+ systemTimezone = "Asia/Tokyo";
46
+ rerender(content());
47
+
48
+ const expected = new NativeDateTimeFormat("en-US", {
49
+ timeZone: systemTimezone,
50
+ ...(milliseconds
51
+ ? {
52
+ year: "numeric",
53
+ month: "2-digit",
54
+ day: "2-digit",
55
+ hour: "2-digit",
56
+ minute: "2-digit",
57
+ second: "2-digit",
58
+ fractionalSecondDigits: 3,
59
+ }
60
+ : { dateStyle: "long", timeStyle: "medium" }),
61
+ }).format(date);
62
+ expect(screen.queryByText("America/Los_Angeles")).toBeNull();
63
+ expect(
64
+ screen.getByText(systemTimezone).nextElementSibling?.textContent,
65
+ ).toBe(expected);
66
+ expect(expected).not.toBe(previousTime);
67
+ expect(screen.getByText("UTC").nextElementSibling?.textContent).toBe(
68
+ utcTime,
69
+ );
70
+ },
71
+ );
72
+ });
@@ -6,7 +6,7 @@
6
6
 
7
7
  import type { Table } from "@tanstack/react-table";
8
8
  import { Columns3Icon, EyeIcon, EyeOffIcon, ScanEyeIcon } from "lucide-react";
9
- import React, { useMemo } from "react";
9
+ import React from "react";
10
10
  import { ColumnName } from "@/components/datasources/components";
11
11
  import { Button } from "@/components/ui/button";
12
12
  import {
@@ -24,6 +24,7 @@ import {
24
24
  } from "@/components/ui/popover";
25
25
  import { type BulkAction, useSelectList } from "@/components/ui/select-core";
26
26
  import type { DataType } from "@/core/kernel/messages";
27
+ import { Arrays } from "@/utils/arrays";
27
28
  import { cn } from "@/utils/cn";
28
29
  import { Events } from "@/utils/events";
29
30
  import { smartMatchFilter } from "@/utils/smartMatch";
@@ -67,9 +68,8 @@ export const ColumnVisibilityDropdown = <TData,>({
67
68
  const hideableIds = userColumns
68
69
  .filter((column) => column.getCanHide())
69
70
  .map((column) => column.id);
70
- const visibleHideableCount = hideableIds.filter(
71
- (id) => !hiddenIds.includes(id),
72
- ).length;
71
+ const visibleHideableColumnIds = Arrays.difference(hideableIds, hiddenIds);
72
+ const visibleHideableCount = visibleHideableColumnIds.length;
73
73
 
74
74
  const applyHidden = (next: string[] | string | null) => {
75
75
  const hidden = new Set(Array.isArray(next) ? next : []);
@@ -106,15 +106,10 @@ export const ColumnVisibilityDropdown = <TData,>({
106
106
  .filter((option) => !option.disabled)
107
107
  .map((option) => option.value)
108
108
  : [];
109
- const showOnlyColumnState = useMemo(
110
- () => ({
111
- visibleHideableColumnIds: hideableIds.filter(
112
- (id) => !hiddenIds.includes(id),
113
- ),
114
- hideableColumnIdSet: new Set(hideableIds),
115
- }),
116
- [hideableIds, hiddenIds],
117
- );
109
+ const showOnlyColumnState = {
110
+ visibleHideableColumnIds,
111
+ hideableColumnIdSet: new Set(hideableIds),
112
+ };
118
113
  const hasSearchBulkActions =
119
114
  showOnlyMatchIds.length > 0 || matchingActions.length > 0;
120
115
 
@@ -135,6 +135,7 @@ export function generateColumns<T>({
135
135
  }): ColumnDef<T>[] {
136
136
  // Row-headers are typically index columns
137
137
  const rowHeadersSet = new Set(rowHeaders.map(([columnName]) => columnName));
138
+ const wrappedColumnsSet = new Set(wrappedColumns);
138
139
 
139
140
  const typesByColumn = Maps.keyBy(fieldTypes, (entry) => entry[0]);
140
141
 
@@ -287,7 +288,7 @@ export function generateColumns<T>({
287
288
  }
288
289
 
289
290
  const justify = getJustify(key);
290
- const wrapped = wrappedColumns?.includes(key);
291
+ const wrapped = wrappedColumnsSet.has(key);
291
292
  const isCellSelected = cell?.getIsSelected?.() || false;
292
293
  const canSelectCell =
293
294
  (selection === "single-cell" || selection === "multi-cell") &&
@@ -1,5 +1,5 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
- import React from "react";
2
+ import React, { useMemo } from "react";
3
3
  import { useDateFormatter, useLocale } from "react-aria";
4
4
  import { Tooltip } from "@/components/ui/tooltip";
5
5
 
@@ -45,6 +45,7 @@ export const DatePopover: React.FC<DatePopoverProps> = ({
45
45
 
46
46
  const TimezoneDisplay = ({ date }: { date: Date }) => {
47
47
  const { locale } = useLocale();
48
+ // The system timezone can change without the locale changing.
48
49
  const localTimezone = new Intl.DateTimeFormat(locale).resolvedOptions()
49
50
  .timeZone;
50
51
  const hasSubSeconds = date.getUTCMilliseconds() !== 0;
@@ -116,9 +117,10 @@ const RelativeTime = ({ date }: { date: Date }) => {
116
117
  const { locale } = useLocale();
117
118
 
118
119
  // Initialize relative time formatter with current locale and "auto" numeric style
119
- const relativeTimeFormatter = new Intl.RelativeTimeFormat(locale, {
120
- numeric: "auto",
121
- });
120
+ const relativeTimeFormatter = useMemo(
121
+ () => new Intl.RelativeTimeFormat(locale, { numeric: "auto" }),
122
+ [locale],
123
+ );
122
124
 
123
125
  const currentTime = new Date();
124
126
  // Get difference in seconds between now and the input date
@@ -34,6 +34,7 @@ import { DelayMount } from "@/components/utils/delay-mount";
34
34
  import { useAsyncData } from "@/hooks/useAsyncData";
35
35
  import { Banner, ErrorBanner } from "@/plugins/impl/common/error-banner";
36
36
  import type { GetRowResult } from "@/plugins/impl/DataTablePlugin";
37
+ import { Objects } from "@/utils/objects";
37
38
  import { NAMELESS_COLUMN_PREFIX, renderCellValue } from "../columns";
38
39
  import { prettifyRowCount } from "../pagination";
39
40
  import {
@@ -88,8 +89,7 @@ export const RowViewerPanel: React.FC<RowViewerPanelProps> = ({
88
89
  handleRowSelectionChange?.((prev) => {
89
90
  if (isRowSelected) {
90
91
  // Remove this row from selection
91
- const { [rowIdx]: removedRow, ...rest } = prev;
92
- return rest;
92
+ return Objects.filter(prev, (_, key) => key !== String(rowIdx));
93
93
  }
94
94
  // Add this row to selection
95
95
  return { ...prev, [rowIdx]: true };
@@ -106,9 +106,9 @@ export const AddCellWithAI: React.FC<{
106
106
  const runtimeManager = useRuntimeManager();
107
107
 
108
108
  const inputRef = useRef<ReactCodeMirrorRef>(null);
109
- const submissionController = useRef(
110
- new StagedCellSubmissionController(),
111
- ).current;
109
+ const [submissionController] = useState(
110
+ () => new StagedCellSubmissionController(),
111
+ );
112
112
 
113
113
  const fileInputRef = useRef<HTMLInputElement>(null);
114
114
  const { files, addFiles, removeFile } = useFileState();
@@ -48,7 +48,7 @@ export const SelectorButton: React.FC<{
48
48
  }> = ({ name, color, icon, onSelect }) => (
49
49
  <button
50
50
  type="button"
51
- className="py-3 flex flex-col items-center justify-center gap-1 transition-all hover:scale-105 hover:brightness-110 rounded shadow-sm-solid hover:shadow-md-solid"
51
+ className="py-3 flex flex-col items-center justify-center gap-1 transition-[scale,filter,box-shadow] hover:scale-105 hover:brightness-110 rounded shadow-sm-solid hover:shadow-md-solid"
52
52
  style={{ backgroundColor: color }}
53
53
  onClick={onSelect}
54
54
  >
@@ -248,7 +248,7 @@ export const replaceTracebackFilenames = (domNode: DOMNode) => {
248
248
  <Tooltip content={tooltipContent}>
249
249
  <button
250
250
  type="button"
251
- className="ml-1 p-1 rounded-sm hover:bg-muted transition-all inline"
251
+ className="ml-1 p-1 rounded-sm hover:bg-muted transition-colors inline"
252
252
  >
253
253
  <BugPlayIcon
254
254
  onClick={() => {
@@ -514,7 +514,7 @@ const MarimoFileComponent = ({ file }: { file: MarimoFile }) => {
514
514
 
515
515
  return (
516
516
  <a
517
- className="py-1.5 px-4 hover:bg-(--blue-2) hover:text-primary transition-all duration-300 cursor-pointer group relative flex gap-4 items-center"
517
+ className="py-1.5 px-4 hover:bg-(--blue-2) hover:text-primary transition-colors duration-300 cursor-pointer group relative flex gap-4 items-center"
518
518
  key={file.path}
519
519
  href={href.toString()}
520
520
  target={tabTarget(file.initializationId || file.path)}
@@ -542,7 +542,7 @@ const MarimoFileComponent = ({ file }: { file: MarimoFile }) => {
542
542
  </div>
543
543
  <ExternalLinkIcon
544
544
  size={20}
545
- className="group-hover:opacity-100 opacity-0 transition-all duration-300 text-primary"
545
+ className="group-hover:opacity-100 opacity-0 transition-opacity duration-300 text-primary"
546
546
  />
547
547
  </div>
548
548
  {!!file.lastModified && (
@@ -617,14 +617,14 @@ const CreateNewNotebook: React.FC = () => {
617
617
  <a
618
618
  className="relative rounded-lg p-6 group
619
619
  text-primary hover:bg-(--blue-2) shadow-md-solid shadow-accent border bg-(--blue-1)
620
- transition-all duration-300 cursor-pointer
620
+ transition-colors duration-300 cursor-pointer
621
621
  "
622
622
  href={url}
623
623
  target="_blank"
624
624
  rel="noreferrer"
625
625
  >
626
626
  <h2 className="text-lg font-semibold">Create a new notebook</h2>
627
- <div className="group-hover:opacity-100 opacity-0 absolute right-5 top-0 bottom-0 rounded-lg flex items-center justify-center transition-all duration-300">
627
+ <div className="group-hover:opacity-100 opacity-0 absolute right-5 top-0 bottom-0 rounded-lg flex items-center justify-center transition-opacity duration-300">
628
628
  <ExternalLinkIcon size={24} />
629
629
  </div>
630
630
  </a>
@@ -145,11 +145,11 @@ const TraceBlock: React.FC<{
145
145
  isMostRecentRun: boolean;
146
146
  chartPosition: ChartPosition;
147
147
  theme: ResolvedTheme;
148
- }> = ({ run, isMostRecentRun, chartPosition, isExpanded, theme }) => {
148
+ }> = ({ run, isMostRecentRun, chartPosition, isExpanded: expanded, theme }) => {
149
149
  const setExpandedRuns = useSetAtom(expandedRunsAtom);
150
150
  // We prefer the user's last click, but if they haven't clicked on this run,
151
151
  // we expand the most recent run by default, otherwise we collapse it.
152
- isExpanded = isExpanded ?? isMostRecentRun;
152
+ const isExpanded = expanded ?? isMostRecentRun;
153
153
 
154
154
  const onToggleExpanded = () => {
155
155
  setExpandedRuns((prev) => {
@@ -134,12 +134,8 @@ export function usePendingDeleteService() {
134
134
  submit({ cellIds, deleteCell, deleteManyCells, store });
135
135
  },
136
136
  clear,
137
- get idle() {
138
- return entries.size === 0;
139
- },
140
- get shouldConfirmDelete() {
141
- return entries.size > 1;
142
- },
137
+ idle: entries.size === 0,
138
+ shouldConfirmDelete: entries.size > 1,
143
139
  };
144
140
  }
145
141
 
@@ -185,8 +185,8 @@ describe("isDetectedSourceConnected", () => {
185
185
  });
186
186
  const emptySnapshot = {
187
187
  dialects: [] as string[],
188
- storageProtocols: [] as string[],
189
- storageBackendTypes: [] as string[],
188
+ storageProtocols: new Set<string>(),
189
+ storageBackendTypes: new Set<string>(),
190
190
  };
191
191
 
192
192
  it("does not hide a source when nothing is connected", () => {
@@ -242,7 +242,7 @@ describe("isDetectedSourceConnected", () => {
242
242
  expect(
243
243
  isDetectedSourceConnected(s3, {
244
244
  ...emptySnapshot,
245
- storageProtocols: ["s3"],
245
+ storageProtocols: new Set(["s3"]),
246
246
  }),
247
247
  ).toBe(true);
248
248
  });
@@ -262,7 +262,7 @@ describe("isDetectedSourceConnected", () => {
262
262
  expect(
263
263
  isDetectedSourceConnected(hf, {
264
264
  ...emptySnapshot,
265
- storageBackendTypes: ["huggingface"],
265
+ storageBackendTypes: new Set(["huggingface"]),
266
266
  }),
267
267
  ).toBe(true);
268
268
  });