@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.
Files changed (284) hide show
  1. package/dist/assets/ConnectedDataExplorerComponent-B5cPvWoQ.js +19 -0
  2. package/dist/assets/{ImageComparisonComponent-fTHv1Ih0.js → ImageComparisonComponent-CqR26LSv.js} +1 -1
  3. package/dist/assets/{VegaLite-Bdi-TyfY.js → VegaLite-DvQDATwI.js} +1 -1
  4. package/dist/assets/_baseEach--KDTwKbG.js +1 -0
  5. package/dist/assets/_baseMap-Cu3o-eyO.js +1 -0
  6. package/dist/assets/{_baseUniq-CCgDNtZb.js → _baseUniq-y7ZXnMo1.js} +1 -1
  7. package/dist/assets/{_createAggregator-DcD0kTA5.js → _createAggregator-ZcHkHPNJ.js} +1 -1
  8. package/dist/assets/{agent-panel-Crv430aI.js → agent-panel-B91RoLct.js} +76 -57
  9. package/dist/assets/{any-language-editor-CQh552Wu.js → any-language-editor-CxfHcm5h.js} +1 -1
  10. package/dist/assets/{architectureDiagram-W76B3OCA-BAJeBxzt.js → architectureDiagram-W76B3OCA-BQsvK8uR.js} +1 -1
  11. package/dist/assets/{between-horizontal-start-Boxgxbt_.js → between-horizontal-start-BmYToIaM.js} +1 -1
  12. package/dist/assets/{blockDiagram-QIGZ2CNN-CL-1svEK.js → blockDiagram-QIGZ2CNN-r3HgCj4w.js} +1 -1
  13. package/dist/assets/{c4Diagram-FPNF74CW-BbEqbCTl.js → c4Diagram-FPNF74CW-BJbPNt41.js} +1 -1
  14. package/dist/assets/channel-DFaEx1fu.js +1 -0
  15. package/dist/assets/chat-panel-IoPMv8e2.js +3 -0
  16. package/dist/assets/{chunk-4BX2VUAB-C--8TXeE.js → chunk-4BX2VUAB-Dv4MZ9Hj.js} +1 -1
  17. package/dist/assets/{chunk-55IACEB6-Bj00HDqq.js → chunk-55IACEB6-CM4AHquB.js} +1 -1
  18. package/dist/assets/{chunk-FMBD7UC4-C-lhB6hN.js → chunk-FMBD7UC4-C_Zz0ENB.js} +1 -1
  19. package/dist/assets/{chunk-K7UQS3LO-B-pGTXPt.js → chunk-K7UQS3LO-DYSmiXYq.js} +1 -1
  20. package/dist/assets/{chunk-QN33PNHL-DqUzGhvm.js → chunk-QN33PNHL-QM4OPuQP.js} +1 -1
  21. package/dist/assets/{chunk-QZHKN3VN-TntJHfSk.js → chunk-QZHKN3VN-CfAsGyeB.js} +1 -1
  22. package/dist/assets/{chunk-TVAH2DTR-HUJb1psV.js → chunk-TVAH2DTR-6j_Cpjsi.js} +1 -1
  23. package/dist/assets/{chunk-TZMSLE5B-BK3C__t3.js → chunk-TZMSLE5B-BHslFJQE.js} +1 -1
  24. package/dist/assets/{circle-play-DBLOv1Yu.js → circle-play-CK3UZRYQ.js} +1 -1
  25. package/dist/assets/classDiagram-KNZD7YFC-BsZtvV5O.js +1 -0
  26. package/dist/assets/classDiagram-v2-RKCZMP56-BsZtvV5O.js +1 -0
  27. package/dist/assets/{clear-button-BeoFbEKH.js → clear-button-C4fDVSv8.js} +1 -1
  28. package/dist/assets/clone-YBEvPE-s.js +1 -0
  29. package/dist/assets/command-palette-D7hOfvf6.js +1 -0
  30. package/dist/assets/{common-C7oJcmCT.js → common-D-lbuUwz.js} +1 -1
  31. package/dist/assets/{compile-7L0MwhyI.js → compile-DVQe1Mzk.js} +1 -1
  32. package/dist/assets/{cose-bilkent-S5V4N54A-BMkGLcVC.js → cose-bilkent-S5V4N54A-D-IS7WC8.js} +1 -1
  33. package/dist/assets/{dagre-5GWH7T2D-BJtRienS.js → dagre-5GWH7T2D-lYu-tEWT.js} +1 -1
  34. package/dist/assets/{data-grid-overlay-editor-DBkmGtNs.js → data-grid-overlay-editor-C5peOCit.js} +1 -1
  35. package/dist/assets/datasources-panel-D3NA20uZ.js +1 -0
  36. package/dist/assets/{dependency-graph-panel-DEdOxp2X.js → dependency-graph-panel-BGVYOfkV.js} +1 -1
  37. package/dist/assets/{diagram-N5W7TBWH-CmECY3nb.js → diagram-N5W7TBWH-BnvIuYUp.js} +1 -1
  38. package/dist/assets/{diagram-QEK2KX5R-DMOVSNKD.js → diagram-QEK2KX5R-DemedRK3.js} +1 -1
  39. package/dist/assets/{diagram-S2PKOQOG-BiJ96PNQ.js → diagram-S2PKOQOG-iiY7AuyH.js} +1 -1
  40. package/dist/assets/{documentation-panel-xULhaEv3.js → documentation-panel-C3dSwOSQ.js} +1 -1
  41. package/dist/assets/edit-page-C5TsEeSo.js +129 -0
  42. package/dist/assets/{ellipsis-vertical-BBqXIlc2.js → ellipsis-vertical-CazJl8M7.js} +1 -1
  43. package/dist/assets/{empty-state-B3dA3G5P.js → empty-state-DW308mFO.js} +1 -1
  44. package/dist/assets/{erDiagram-AWTI2OKA-MP1DiFRo.js → erDiagram-AWTI2OKA-6wQ8Ugg0.js} +1 -1
  45. package/dist/assets/{error-panel-Cc1sv-Ag.js → error-panel-D1VnJ1yP.js} +1 -1
  46. package/dist/assets/file-explorer-panel-0oVd4t-D.js +1 -0
  47. package/dist/assets/{flowDiagram-PVAE7QVJ-BX7caPp7.js → flowDiagram-PVAE7QVJ-C55IUWjm.js} +1 -1
  48. package/dist/assets/{ganttDiagram-OWAHRB6G-B462g4Yf.js → ganttDiagram-OWAHRB6G-DmqCM6ME.js} +4 -4
  49. package/dist/assets/{gitGraphDiagram-NY62KEGX-CGgvZ9-9.js → gitGraphDiagram-NY62KEGX-DBvhAeM_.js} +1 -1
  50. package/dist/assets/{glide-data-editor-C0gUFZON.js → glide-data-editor-CHNuHidQ.js} +4 -4
  51. package/dist/assets/{graph-CHRVBzY5.js → graph-CG6BgUWQ.js} +1 -1
  52. package/dist/assets/home-page-dgivXuSR.js +9 -0
  53. package/dist/assets/{index-Clbi_Yaq.js → index-BTGpssVX.js} +1 -1
  54. package/dist/assets/{index-CQDrxQ0j.js → index-BYVZlBF8.js} +1 -1
  55. package/dist/assets/{index-lYa_leQE.js → index-BelfnXwL.js} +1 -1
  56. package/dist/assets/{index-DRMm6SNo.js → index-BneyUujp.js} +1 -1
  57. package/dist/assets/{index-BY93Ejhl.js → index-C02SqeRj.js} +1 -1
  58. package/dist/assets/{index-C-8WADat.js → index-C7dtgr9A.js} +1 -1
  59. package/dist/assets/{index-D9UKkrr2.js → index-CAQvMTzM.js} +1 -1
  60. package/dist/assets/index-CGDMlQfO.css +1 -0
  61. package/dist/assets/index-CelXfcd8.js +580 -0
  62. package/dist/assets/{index-vmICa5KN.js → index-Csd6QrCV.js} +1 -1
  63. package/dist/assets/{index-DoRmcrKM.js → index-CtPksxf0.js} +1 -1
  64. package/dist/assets/{index-C1v_Z9et.js → index-Cxyk7pt-.js} +1 -1
  65. package/dist/assets/{index-CpTPJo4k.js → index-DAZ-9ri2.js} +1 -1
  66. package/dist/assets/{index-DEQvTChO.js → index-DONRrmA2.js} +1 -1
  67. package/dist/assets/{index-C4Tn5NvJ.js → index-Db36XTG_.js} +1 -1
  68. package/dist/assets/{index-z9bohSQJ.js → index-DdIhdEVw.js} +1 -1
  69. package/dist/assets/{index-C-GhZ7ti.js → index-M_pBKDSe.js} +1 -1
  70. package/dist/assets/{index-C77h_TXN.js → index-_luCZMLM.js} +1 -1
  71. package/dist/assets/{index-D1vmG6DS.js → index-mkubqy9-.js} +1 -1
  72. package/dist/assets/{index-BVgAenPd.js → index-sbO9UaUU.js} +1 -1
  73. package/dist/assets/{index-CWMgowgL.js → index-z4krxQ4j.js} +1 -1
  74. package/dist/assets/infoDiagram-STP46IZ2-wTALjfPc.js +2 -0
  75. package/dist/assets/{isEmpty-DU_ogP_D.js → isEmpty-CqX_YTIf.js} +1 -1
  76. package/dist/assets/{journeyDiagram-BIP6EPQ6-C6EgLP_Q.js → journeyDiagram-BIP6EPQ6-Y5w_Tqe_.js} +1 -1
  77. package/dist/assets/{kanban-definition-6OIFK2YF-BXzYO1yj.js → kanban-definition-6OIFK2YF-DbXs5Rxi.js} +1 -1
  78. package/dist/assets/{layout-jihVw5-i.js → layout-BCNPDACj.js} +1 -1
  79. package/dist/assets/{linear-C4blANlC.js → linear-uO6UVhXt.js} +1 -1
  80. package/dist/assets/links-Drv7cJgN.js +7 -0
  81. package/dist/assets/{logs-panel-D401qzZh.js → logs-panel-BEQ1eRUp.js} +1 -1
  82. package/dist/assets/{markdown-renderer-Cd9eYyaL.js → markdown-renderer-Dmzbb00W.js} +20 -20
  83. package/dist/assets/{mermaid-BEVuRz_O.js → mermaid-qRc4MXIj.js} +1 -1
  84. package/dist/assets/{mermaid.core-CaSnaLH0.js → mermaid.core-CvvJtCRj.js} +4 -4
  85. package/dist/assets/min-DYUOb1RR.js +1 -0
  86. package/dist/assets/{mindmap-definition-Q6HEUPPD-BXUM5MT2.js → mindmap-definition-Q6HEUPPD-G5NognM-.js} +1 -1
  87. package/dist/assets/{number-overlay-editor-4uWXGlPG.js → number-overlay-editor-DPr5sHFu.js} +1 -1
  88. package/dist/assets/outline-panel-gxQXvVi4.js +1 -0
  89. package/dist/assets/{packages-panel-CJL0MVlj.js → packages-panel-B1T0VPlg.js} +1 -1
  90. package/dist/assets/{pieDiagram-ADFJNKIX-Dxt5PVNo.js → pieDiagram-ADFJNKIX-DK9SHkfc.js} +1 -1
  91. package/dist/assets/{quadrantDiagram-LMRXKWRM-D4pUaA31.js → quadrantDiagram-LMRXKWRM-D1DdWF8C.js} +1 -1
  92. package/dist/assets/{react-plotly-cJZ0VWBq.js → react-plotly-CTwajqCb.js} +1 -1
  93. package/dist/assets/{requirementDiagram-4UW4RH46-DVRTjgas.js → requirementDiagram-4UW4RH46-DnjDAypr.js} +1 -1
  94. package/dist/assets/{run-page-BUEnMC9w.js → run-page-CQY9im22.js} +1 -1
  95. package/dist/assets/{sankeyDiagram-GR3RE2ED-CVFnD9C-.js → sankeyDiagram-GR3RE2ED-B67Va-ER.js} +1 -1
  96. package/dist/assets/{scratchpad-panel-BIgRENkI.js → scratchpad-panel-DlDfcDtW.js} +1 -1
  97. package/dist/assets/{secrets-panel-xY5-V_BD.js → secrets-panel-BDGyuGZA.js} +1 -1
  98. package/dist/assets/{sequenceDiagram-C3RYC4MD-_lY4ZN_S.js → sequenceDiagram-C3RYC4MD-DiWgZPtN.js} +1 -1
  99. package/dist/assets/{slides-component-DMjQomc3.css → slides-component-C-LoGC1U.css} +1 -1
  100. package/dist/assets/{slides-component-Xjymwj7X.js → slides-component-DhpPRtQp.js} +1 -1
  101. package/dist/assets/snippets-panel-CLkBXhJ2.js +1 -0
  102. package/dist/assets/sortBy-D4OG7w4O.js +1 -0
  103. package/dist/assets/{state-C4NiC9tO.js → state-Dz_3JyED.js} +1 -1
  104. package/dist/assets/{stateDiagram-KXAO66HF-Da0JQWCn.js → stateDiagram-KXAO66HF-ByF2AULw.js} +1 -1
  105. package/dist/assets/stateDiagram-v2-UMBNRL4Z-CtBJqosP.js +1 -0
  106. package/dist/assets/storage-Dr0CC44z.js +26 -0
  107. package/dist/assets/{terminal-BPwTkXae.js → terminal-BtdissBf.js} +1 -1
  108. package/dist/assets/{time-Dv5_Ouz_.js → time-DKdOTnQg.js} +1 -1
  109. package/dist/assets/{timeline-definition-XQNQX7LJ-Dxh5Zu2e.js → timeline-definition-XQNQX7LJ-DzER9bf6.js} +1 -1
  110. package/dist/assets/tracing-Dpx5M-u3.js +2 -0
  111. package/dist/assets/{tracing-panel-DAzrzNmm.js → tracing-panel-hCjBkSER.js} +2 -2
  112. package/dist/assets/{trash-Dc6DSjz_.js → trash-C6Ko-g5q.js} +1 -1
  113. package/dist/assets/{tree-jheoerAX.js → tree-BHN2gcCF.js} +6 -6
  114. package/dist/assets/{treemap-75Q7IDZK-IgpxeGaf.js → treemap-75Q7IDZK-DR79Mhzt.js} +27 -27
  115. package/dist/assets/variable-panel-PFBCFz36.js +1 -0
  116. package/dist/assets/{vega-component-BpfpiPKI.js → vega-component-Db6-uY4C.js} +1 -1
  117. package/dist/assets/worker-fHbtoWvT.js +1 -0
  118. package/dist/assets/{xychartDiagram-6GGTOJPD-CmNigJ31.js → xychartDiagram-6GGTOJPD-DWzBP3tZ.js} +1 -1
  119. package/dist/index.html +2 -2
  120. package/package.json +5 -4
  121. package/src/__mocks__/requests.ts +1 -0
  122. package/src/components/app-config/user-config-form.tsx +46 -1
  123. package/src/components/chat/acp/__tests__/__snapshots__/prompt.test.ts.snap +62 -43
  124. package/src/components/chat/acp/__tests__/atoms.test.ts +1 -1
  125. package/src/components/chat/acp/__tests__/state.test.ts +36 -36
  126. package/src/components/chat/acp/agent-panel.tsx +24 -27
  127. package/src/components/chat/acp/blocks.tsx +6 -6
  128. package/src/components/chat/acp/prompt.ts +62 -43
  129. package/src/components/chat/chat-panel.tsx +5 -1
  130. package/src/components/chat/markdown-renderer.tsx +6 -10
  131. package/src/components/chat/tool-call-accordion.tsx +52 -20
  132. package/src/components/data-table/SearchBar.tsx +8 -7
  133. package/src/components/data-table/__tests__/column_formatting.test.ts +50 -35
  134. package/src/components/data-table/__tests__/columns.test.tsx +38 -0
  135. package/src/components/data-table/__tests__/data-table.test.tsx +39 -1
  136. package/src/components/data-table/cell-hover-template/feature.ts +14 -0
  137. package/src/components/data-table/cell-hover-template/types.ts +11 -0
  138. package/src/components/data-table/charts/components/form-fields.tsx +41 -37
  139. package/src/components/data-table/charts/forms/common-chart.tsx +2 -2
  140. package/src/components/data-table/column-explorer-panel/column-explorer.tsx +5 -2
  141. package/src/components/data-table/column-formatting/feature.ts +62 -29
  142. package/src/components/data-table/column-formatting/types.ts +1 -0
  143. package/src/components/data-table/column-header.tsx +3 -1
  144. package/src/components/data-table/column-summary/chart-spec-model.tsx +24 -7
  145. package/src/components/data-table/column-summary/column-summary.tsx +18 -9
  146. package/src/components/data-table/columns.tsx +63 -20
  147. package/src/components/data-table/data-table.tsx +10 -2
  148. package/src/components/data-table/date-popover.tsx +85 -75
  149. package/src/components/data-table/filter-pills.tsx +14 -9
  150. package/src/components/data-table/header-items.tsx +5 -1
  151. package/src/components/data-table/pagination.tsx +20 -13
  152. package/src/components/data-table/renderers.tsx +36 -0
  153. package/src/components/data-table/row-viewer-panel/row-viewer.tsx +10 -8
  154. package/src/components/data-table/schemas.ts +16 -0
  155. package/src/components/datasources/column-preview.tsx +6 -2
  156. package/src/components/datasources/datasources.tsx +8 -12
  157. package/src/components/editor/Cell.tsx +2 -0
  158. package/src/components/editor/ai/transport/chat-transport.tsx +4 -1
  159. package/src/components/editor/cell/CellStatus.tsx +23 -20
  160. package/src/components/editor/cell/CreateCellButton.tsx +3 -4
  161. package/src/components/editor/cell/code/language-toggle.tsx +3 -4
  162. package/src/components/editor/chrome/wrapper/footer-items/machine-stats.tsx +39 -28
  163. package/src/components/editor/controls/notebook-menu-dropdown.tsx +4 -2
  164. package/src/components/editor/errors/sql-validation-errors.tsx +34 -0
  165. package/src/components/editor/file-tree/requesting-tree.tsx +14 -8
  166. package/src/components/editor/output/ConsoleOutput.tsx +13 -1
  167. package/src/components/editor/output/MarimoErrorOutput.tsx +60 -1
  168. package/src/components/editor/renderers/CellArray.tsx +3 -4
  169. package/src/components/editor/renderers/slides-layout/slides-layout.tsx +3 -3
  170. package/src/components/editor/renderers/slides-layout/types.ts +1 -0
  171. package/src/components/pages/home-page.tsx +4 -1
  172. package/src/components/slides/slides-component.tsx +1 -1
  173. package/src/components/slides/slides.css +6 -0
  174. package/src/components/terminal/theme.tsx +1 -0
  175. package/src/components/tracing/tracing-spec.ts +5 -4
  176. package/src/components/ui/range-slider.tsx +4 -2
  177. package/src/components/ui/slider.tsx +3 -1
  178. package/src/components/variables/variables-table.tsx +3 -0
  179. package/src/core/MarimoApp.tsx +9 -6
  180. package/src/core/ai/context/__tests__/registry.test.ts +6 -4
  181. package/src/core/ai/context/providers/cell-output.ts +4 -20
  182. package/src/core/ai/context/providers/error.ts +3 -1
  183. package/src/core/ai/context/providers/file.ts +7 -2
  184. package/src/core/ai/context/providers/tables.ts +3 -2
  185. package/src/core/ai/context/providers/variable.ts +6 -4
  186. package/src/core/ai/staged-cells.ts +34 -1
  187. package/src/core/cells/__tests__/add-missing-import.test.ts +67 -22
  188. package/src/core/cells/add-missing-import.ts +24 -7
  189. package/src/core/cells/cells.ts +26 -27
  190. package/src/core/cells/logs.ts +1 -1
  191. package/src/core/codemirror/find-replace/search-highlight.ts +3 -1
  192. package/src/core/codemirror/language/LanguageAdapters.ts +9 -3
  193. package/src/core/codemirror/language/__tests__/extension.test.ts +24 -0
  194. package/src/core/codemirror/language/__tests__/sql-validation.test.ts +133 -0
  195. package/src/core/codemirror/language/languages/sql/sql-mode.ts +20 -0
  196. package/src/core/codemirror/language/languages/sql/sql.ts +90 -3
  197. package/src/core/codemirror/language/languages/sql/validation-errors.ts +79 -0
  198. package/src/core/codemirror/language/panel/panel.tsx +8 -2
  199. package/src/core/codemirror/language/panel/sql.tsx +81 -4
  200. package/src/core/codemirror/lsp/notebook-lsp.ts +8 -2
  201. package/src/core/codemirror/readonly/__tests__/extension.test.ts +1 -1
  202. package/src/core/codemirror/rtc/loro/awareness.ts +52 -17
  203. package/src/core/codemirror/rtc/loro/sync.ts +12 -4
  204. package/src/core/config/config-schema.ts +1 -0
  205. package/src/core/config/config.ts +4 -0
  206. package/src/core/config/feature-flag.tsx +3 -1
  207. package/src/core/datasets/request-registry.ts +17 -1
  208. package/src/core/hotkeys/hotkeys.ts +8 -4
  209. package/src/core/i18n/__tests__/locale-provider.test.tsx +176 -0
  210. package/src/core/i18n/locale-provider.tsx +35 -0
  211. package/src/core/i18n/with-locale.tsx +12 -0
  212. package/src/core/islands/bridge.ts +1 -0
  213. package/src/core/islands/components/web-components.tsx +13 -10
  214. package/src/core/islands/main.ts +1 -0
  215. package/src/core/kernel/RuntimeState.ts +4 -1
  216. package/src/core/kernel/messages.ts +3 -2
  217. package/src/core/network/DeferredRequestRegistry.ts +16 -4
  218. package/src/core/network/requests-network.ts +7 -0
  219. package/src/core/network/requests-static.ts +1 -0
  220. package/src/core/network/requests-toasting.ts +1 -0
  221. package/src/core/network/types.ts +2 -0
  222. package/src/core/runtime/runtime.ts +5 -4
  223. package/src/core/wasm/bridge.ts +10 -1
  224. package/src/core/wasm/store.ts +4 -1
  225. package/src/core/wasm/worker/message-buffer.ts +3 -2
  226. package/src/core/websocket/types.ts +22 -16
  227. package/src/core/websocket/useMarimoWebSocket.tsx +4 -0
  228. package/src/hooks/useFormatting.ts +97 -0
  229. package/src/hooks/useTimer.ts +8 -5
  230. package/src/plugins/core/registerReactComponent.tsx +39 -29
  231. package/src/plugins/impl/DataTablePlugin.tsx +15 -4
  232. package/src/plugins/impl/RangeSliderPlugin.tsx +5 -3
  233. package/src/plugins/impl/SliderPlugin.tsx +3 -1
  234. package/src/plugins/impl/anywidget/model.ts +16 -5
  235. package/src/plugins/impl/data-editor/types.ts +7 -5
  236. package/src/plugins/impl/data-explorer/components/column-summary.tsx +20 -13
  237. package/src/plugins/impl/data-frames/DataFramePlugin.tsx +17 -5
  238. package/src/plugins/impl/panel/utils.ts +6 -4
  239. package/src/plugins/layout/OutlinePlugin.tsx +69 -0
  240. package/src/plugins/layout/StatPlugin.tsx +4 -1
  241. package/src/plugins/plugins.ts +2 -0
  242. package/src/stories/dataframe.stories.tsx +2 -0
  243. package/src/utils/__tests__/dates.test.ts +45 -24
  244. package/src/utils/__tests__/dom.test.ts +167 -0
  245. package/src/utils/__tests__/numbers.test.ts +42 -30
  246. package/src/utils/__tests__/once.test.ts +187 -0
  247. package/src/utils/dates.ts +15 -10
  248. package/src/utils/dom.ts +55 -0
  249. package/src/utils/edit-distance.ts +8 -6
  250. package/src/utils/errors.ts +1 -1
  251. package/src/utils/id-tree.tsx +21 -10
  252. package/src/utils/localStorage.ts +13 -4
  253. package/src/utils/numbers.ts +11 -11
  254. package/src/utils/once.ts +32 -0
  255. package/src/utils/paths.ts +4 -1
  256. package/src/utils/pluralize.ts +12 -5
  257. package/src/utils/python-poet/poet.ts +30 -15
  258. package/src/utils/time.ts +5 -1
  259. package/dist/assets/ConnectedDataExplorerComponent-BErMbWvG.js +0 -19
  260. package/dist/assets/_baseEach-CNBxBxvS.js +0 -1
  261. package/dist/assets/_baseMap-D1WHjKrd.js +0 -1
  262. package/dist/assets/channel-_2eNSz0n.js +0 -1
  263. package/dist/assets/chat-panel-CXh5Wl6C.js +0 -3
  264. package/dist/assets/classDiagram-KNZD7YFC-BGmh9POF.js +0 -1
  265. package/dist/assets/classDiagram-v2-RKCZMP56-BGmh9POF.js +0 -1
  266. package/dist/assets/clone-BFDSPAj3.js +0 -1
  267. package/dist/assets/command-palette-CXZiSv0I.js +0 -1
  268. package/dist/assets/datasources-panel-B7FbYLiy.js +0 -1
  269. package/dist/assets/edit-page-BrYda9VE.js +0 -129
  270. package/dist/assets/file-explorer-panel-Bw59Kva1.js +0 -1
  271. package/dist/assets/home-page-Fb2osjys.js +0 -9
  272. package/dist/assets/index-Cx0bsY1w.css +0 -1
  273. package/dist/assets/index-DKEudB02.js +0 -578
  274. package/dist/assets/infoDiagram-STP46IZ2-CVyrdLc8.js +0 -2
  275. package/dist/assets/links-D59GIweI.js +0 -7
  276. package/dist/assets/min-DUMu_zeK.js +0 -1
  277. package/dist/assets/outline-panel-DIzkvm2I.js +0 -1
  278. package/dist/assets/snippets-panel-CTPYW41n.js +0 -1
  279. package/dist/assets/sortBy-BNZKwiq_.js +0 -1
  280. package/dist/assets/stateDiagram-v2-UMBNRL4Z-D5lYZOOt.js +0 -1
  281. package/dist/assets/storage-CMdLzB_c.js +0 -26
  282. package/dist/assets/tracing-BCIurUfa.js +0 -2
  283. package/dist/assets/variable-panel-DYAiLBmF.js +0 -1
  284. 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 className="font-bold">{key === "" ? " " : key}</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={headerWithType}
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: Date,
408
- dataType?: DataType,
409
- dtype?: string,
410
- format?: DateFormat | null,
411
- ): React.ReactNode {
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: Column<TData, TValue>,
428
- renderValue: () => TValue | null,
429
- getValue: () => TValue,
430
- selectCell?: () => void,
431
- cellStyles?: string,
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 renderDate(date, dataType, dtype, format);
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 renderDate(value, dataType, dtype);
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">{relativeTime}</div>
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
- Object.entries(getTimezones(dateObj)).map(
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
- <span>
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
- function getTimezones(date: Date) {
62
- const localTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
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
- return {
91
- UTC: new Intl.DateTimeFormat("en-US", {
92
- timeZone: "UTC",
93
- dateStyle: "long",
94
- timeStyle: "medium",
95
- }).format(date),
96
- [localTimezone]: new Intl.DateTimeFormat("en-US", {
97
- timeZone: localTimezone,
98
- dateStyle: "long",
99
- timeStyle: "medium",
100
- }).format(date),
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
- * Converts a date into a human-readable relative time string (e.g. "2 hours ago", "in 5 minutes")
106
- * Uses Intl.RelativeTimeFormat for localized formatting
107
- */
108
- function getRelativeTime(date: Date): string {
109
- // Initialize relative time formatter with English locale and "auto" numeric style
110
- // "auto" allows for strings like "yesterday" instead of "1 day ago"
111
- const relativeTimeFormatter = new Intl.RelativeTimeFormat("en", {
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 relativeTimeFormatter.format(
138
- roundedValue,
139
- unitName as Intl.RelativeTimeFormatUnit,
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(filter.value as ColumnFilterValue);
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 ? formatTime.format(value.min) : undefined,
81
- value.max ? formatTime.format(value.max) : undefined,
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(numRows, totalColumns);
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">of {prettyNumber(totalPages)}</span>
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
  };