@marimo-team/islands 0.23.9-dev2 → 0.23.9-dev20

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 (273) hide show
  1. package/dist/{ConnectedDataExplorerComponent-2lBNiUv6.js → ConnectedDataExplorerComponent-DSyAzzpW.js} +20 -20
  2. package/dist/ErrorBoundary-rULOrC_p.js +175 -0
  3. package/dist/{ImageComparisonComponent-CNHIsPDj.js → ImageComparisonComponent-CHrI72em.js} +1 -1
  4. package/dist/{Plot-4wn-lMVn.js → Plot-CAYS29h9.js} +1 -1
  5. package/dist/{_baseUniq-CxZRxRRo.js → _baseUniq-B_2Hw7zG.js} +3 -3
  6. package/dist/{any-language-editor-VWs_7v27.js → any-language-editor-DfdpyDv_.js} +23 -23
  7. package/dist/architecture-7HQA4BMR-Kyc44TmC.js +6 -0
  8. package/dist/{architectureDiagram-VXUJARFQ-CXVJxFhH.js → architectureDiagram-VXUJARFQ-CT2SuxNw.js} +15 -15
  9. package/dist/{arrays-CldYf7p7.js → arrays-sEtDRoG4.js} +1 -1
  10. package/dist/assets/__vite-browser-external-Ddfz4Fpd.js +1 -0
  11. package/dist/assets/{worker-CpBbwbQo.js → worker-CgL6N0XX.js} +2 -2
  12. package/dist/{blockDiagram-VD42YOAC-DGDaxR8I.js → blockDiagram-VD42YOAC-Dy7hlFla.js} +7 -7
  13. package/dist/{button-Dj4BTre0.js → button-C5K9fIPF.js} +2 -2
  14. package/dist/{c4Diagram-YG6GDRKO-C2hc6ne8.js → c4Diagram-YG6GDRKO-BXlAmZ8Z.js} +4 -4
  15. package/dist/{capabilities-C9rrYCzf.js → capabilities-BceAxrAW.js} +2 -2
  16. package/dist/{channel-BBoIVUrJ.js → channel-D_PHgcig.js} +1 -1
  17. package/dist/{chat-ui-D3XBept8.js → chat-ui-s5fKbcIr.js} +3084 -3057
  18. package/dist/{check-BcUIXnUT.js → check-DTbrK0zt.js} +1 -1
  19. package/dist/{chunk-4F5CHEZ2-BZq7Kom7.js → chunk-4F5CHEZ2-D9nGEHV8.js} +1 -1
  20. package/dist/{chunk-5FQGJX7Z-BOg95xG5.js → chunk-5FQGJX7Z-BNjes6Yx.js} +5 -5
  21. package/dist/{chunk-ABZYJK2D-D0cLy8Bb.js → chunk-ABZYJK2D-Dz0-H2B5.js} +1 -1
  22. package/dist/{chunk-ATLVNIR6-BXsEjlHF.js → chunk-ATLVNIR6-o0Z5MZLd.js} +1 -1
  23. package/dist/{chunk-B2363JML-D9-XOau1.js → chunk-B2363JML-KEJpLGGP.js} +1 -1
  24. package/dist/{chunk-B4BG7PRW-Q1usn6T3.js → chunk-B4BG7PRW-BL98U9B4.js} +4 -4
  25. package/dist/{chunk-DI55MBZ5-D1qLYNrb.js → chunk-DI55MBZ5-Dwkn0LWm.js} +4 -4
  26. package/dist/{chunk-EXTU4WIE-BKNXdLmD.js → chunk-EXTU4WIE-9sNjmQrB.js} +1 -1
  27. package/dist/{chunk-FRFDVMJY-BSBUAX7r.js → chunk-FRFDVMJY-DzQqMWrl.js} +1 -1
  28. package/dist/{chunk-JA3XYJ7Z-D6c6cOBG.js → chunk-JA3XYJ7Z-C32Y7Epf.js} +2 -2
  29. package/dist/{chunk-JZLCHNYA-BvsPHJmL.js → chunk-JZLCHNYA-C6ftyVMN.js} +4 -4
  30. package/dist/{chunk-N4CR4FBY-8ycT-O9a.js → chunk-N4CR4FBY-DUhGZhZs.js} +5 -5
  31. package/dist/{chunk-PL6DKKU2-B0MTXvyc.js → chunk-PL6DKKU2-D7km-08O.js} +1 -1
  32. package/dist/{chunk-QN33PNHL-Bb-eUBW3.js → chunk-QN33PNHL-0K6SDYn3.js} +1 -1
  33. package/dist/{chunk-QXUST7PY-DV8yRwBd.js → chunk-QXUST7PY-DMhsRpYK.js} +5 -5
  34. package/dist/{chunk-S3R3BYOJ-mQeCz5CE.js → chunk-S3R3BYOJ-oAe3dEbO.js} +3 -3
  35. package/dist/{chunk-SJTYNZTY-CEG4F0pB.js → chunk-SJTYNZTY-BkJrPRFC.js} +1 -1
  36. package/dist/{chunk-TCCFYFTB-d3HOqL2I.js → chunk-TCCFYFTB-D58KeXnC.js} +6 -6
  37. package/dist/{chunk-TQ3KTPDO-DiCtqVSi.js → chunk-TQ3KTPDO-D_yA_wAb.js} +1 -1
  38. package/dist/{chunk-TZMSLE5B-BqW10dHe.js → chunk-TZMSLE5B-yBKS_DQU.js} +1 -1
  39. package/dist/{chunk-UMXZTB3W-97iS1iEl.js → chunk-UMXZTB3W-D7uwvNjd.js} +1 -1
  40. package/dist/{classDiagram-2ON5EDUG--Yh__LHb.js → classDiagram-2ON5EDUG-QjoAcuFE.js} +10 -10
  41. package/dist/{classDiagram-v2-WZHVMYZB-BC7X7Xtc.js → classDiagram-v2-WZHVMYZB-bUCv4gu2.js} +10 -10
  42. package/dist/{clone-BuIIsfA8.js → clone-Q4Fqwn6q.js} +1 -1
  43. package/dist/{code-block-37QAKDTI-BsGy1AOJ.js → code-block-37QAKDTI-m92Yc8pv.js} +2 -2
  44. package/dist/{code-visibility-Dt0Aq6-t.js → code-visibility-DvMXzzJz.js} +8425 -8595
  45. package/dist/{constants-D0gkYoE2.js → constants-T20xxyNf.js} +2 -2
  46. package/dist/{copy-DLf4aN7I.js → copy-BuQpJEzp.js} +2 -2
  47. package/dist/{dagre-6UL2VRFP-DRBWoQUw.js → dagre-6UL2VRFP-J0JKgwOt.js} +11 -11
  48. package/dist/{dagre-VYEPqXIV.js → dagre-By_QsQgc.js} +11 -11
  49. package/dist/{data-grid-overlay-editor-efe5ZagF.js → data-grid-overlay-editor-mfEJ5475.js} +2 -2
  50. package/dist/{diagram-PSM6KHXK-H66ATWP2.js → diagram-PSM6KHXK-DYgJuNk9.js} +18 -18
  51. package/dist/{diagram-QEK2KX5R-DItl5Wns.js → diagram-QEK2KX5R-CKdBR2sb.js} +14 -14
  52. package/dist/{diagram-S2PKOQOG-CtuW_ZuL.js → diagram-S2PKOQOG-Dpi7mo5W.js} +14 -14
  53. package/dist/dist-0Fif7jnk.js +5 -0
  54. package/dist/{dist-Dh3wkoyH.js → dist-4j4c7bjm.js} +2 -2
  55. package/dist/{dist-CDFZi-QD.js → dist-B3P2fFpz.js} +1 -1
  56. package/dist/{dist-BNyrZfqT.js → dist-B3pZ0Ab6.js} +2 -2
  57. package/dist/dist-B5h_9sHB.js +6 -0
  58. package/dist/dist-B9M6R5ye.js +5 -0
  59. package/dist/dist-BCt3tnck.js +8 -0
  60. package/dist/{dist-BrBucRXs.js → dist-BTfv03uy.js} +2 -2
  61. package/dist/dist-BUIJwMwn.js +8 -0
  62. package/dist/{dist-CYEylvZA.js → dist-BbbIBDiQ.js} +1 -1
  63. package/dist/{dist-KnujRhFL.js → dist-BcuoonNH.js} +4 -4
  64. package/dist/{dist-DJ6zJQZ4.js → dist-Bde4a2kU.js} +2 -2
  65. package/dist/{dist-t_qL7eB8.js → dist-Bfwsv11D.js} +2 -2
  66. package/dist/{dist-CNtV21T_.js → dist-BhM8gdSO.js} +4 -4
  67. package/dist/{dist-nuW5EDYT.js → dist-BotSqB48.js} +2 -2
  68. package/dist/dist-BpquMd3k.js +5 -0
  69. package/dist/dist-BzJsqYfz.js +5 -0
  70. package/dist/{dist-D029TiHd.js → dist-Bz_sYWbr.js} +2 -2
  71. package/dist/{dist-D3ZI9nhS.js → dist-C1BYNeCR.js} +4 -4
  72. package/dist/{dist-Bc5pmZIw.js → dist-C5VC_yzu.js} +1 -1
  73. package/dist/dist-CA5ELXAf.js +6 -0
  74. package/dist/dist-CLBRs6Uv.js +5 -0
  75. package/dist/{dist-Dhk6FMb0.js → dist-CLJWPTX2.js} +3 -3
  76. package/dist/{dist-C34oIrQ9.js → dist-CLUtPrdy.js} +1 -1
  77. package/dist/dist-CStVCMbq.js +5 -0
  78. package/dist/{dist-B8RaFTRF.js → dist-CUCNs1ja.js} +2 -2
  79. package/dist/dist-CZRIEY3Y.js +8 -0
  80. package/dist/{dist-UcOPnRMa.js → dist-CcXxepx6.js} +3 -3
  81. package/dist/dist-CuUHbFD0.js +5 -0
  82. package/dist/{dist-B8BjrFUE.js → dist-Cy1WxgBD.js} +5 -5
  83. package/dist/{dist-WdPUFc56.js → dist-D4CewLk6.js} +1 -1
  84. package/dist/{dist-DMZNjfX4.js → dist-DRfcqpxJ.js} +2 -2
  85. package/dist/dist-DV7Iabxb.js +8 -0
  86. package/dist/{dist-usPCDYx8.js → dist-D_bzzWBm.js} +1 -1
  87. package/dist/{dist-BvCfQQQE.js → dist-DgnE8F-r.js} +1 -1
  88. package/dist/{dist-JEhxD_cn.js → dist-DhHh0jLg.js} +1 -1
  89. package/dist/{dist-DGAfI2rB.js → dist-DqAWR3CS.js} +2 -2
  90. package/dist/{dist--sWVZwjW.js → dist-Du8WkPuU.js} +1 -1
  91. package/dist/dist-DuEeHMvL.js +5 -0
  92. package/dist/{dist-BTyJtnNg.js → dist-DxvORzUR.js} +1 -1
  93. package/dist/{dist-B507mf_I.js → dist-RqXTaiir.js} +2 -2
  94. package/dist/{dist-Yrfc6L0I.js → dist-fQ0ViXGs.js} +3 -3
  95. package/dist/{dist-B4LJpMEg.js → dist-h2c8sZvT.js} +1 -1
  96. package/dist/{dist-C2ej4eOH.js → dist-luvabDEB.js} +2 -2
  97. package/dist/{dist-B52GXZbd.js → dist-p2qyWijU.js} +2 -2
  98. package/dist/{erDiagram-Q2GNP2WA--19X2kU5.js → erDiagram-Q2GNP2WA-BU-m41EQ.js} +10 -10
  99. package/dist/{error-banner-CVkfBUT3.js → error-banner-5bz0L9hS.js} +3 -3
  100. package/dist/{esm-CWp0KQeK.js → esm-BfhQmZjp.js} +4 -4
  101. package/dist/{esm-DjNnlmpf.js → esm-Duie8iU-.js} +23 -23
  102. package/dist/{extends-vAi97cpa.js → extends-BgdxCfYu.js} +6 -6
  103. package/dist/{flatten-CzBvFdvC.js → flatten-Bbw7g6-K.js} +1 -1
  104. package/dist/{flowDiagram-NV44I4VS-DQmWlo7f.js → flowDiagram-NV44I4VS-CRoXKjGq.js} +10 -10
  105. package/dist/{formats-Dsy9kkZu.js → formats-BiH6HX1V.js} +4 -4
  106. package/dist/{ganttDiagram-JELNMOA3-BOGXJ8Lk.js → ganttDiagram-JELNMOA3-7mq5f9cO.js} +7 -7
  107. package/dist/{gitGraph-G5XIXVHT-DGlbae5m.js → gitGraph-G5XIXVHT-DiniR35k.js} +3 -3
  108. package/dist/{gitGraphDiagram-V2S2FVAM-DjzxfF0P.js → gitGraphDiagram-V2S2FVAM-Dfuokq6w.js} +13 -13
  109. package/dist/{glide-data-editor-DucgdjRo.js → glide-data-editor-Ck-MRdns.js} +557 -557
  110. package/dist/{graphlib-CVPKjKCS.js → graphlib-Ns7y5crs.js} +5 -5
  111. package/dist/{hasIn-COs6vImh.js → hasIn-Deg7jl_j.js} +3 -3
  112. package/dist/{html-to-image-CpggM7u1.js → html-to-image-CTU_-PnW.js} +109 -109
  113. package/dist/{info-VBDWY6EO-D2lvLLw5.js → info-VBDWY6EO-DVZvGhkQ.js} +3 -3
  114. package/dist/{infoDiagram-HS3SLOUP-ChNufFsP.js → infoDiagram-HS3SLOUP-CEnzWruK.js} +13 -13
  115. package/dist/{input-D4kjoQUB.js → input-BwcGY_X1.js} +70 -67
  116. package/dist/{isEmpty-Dd8mx_WL.js → isEmpty-CJJMn-QP.js} +1 -1
  117. package/dist/{isSymbol-BvIfMnn6.js → isSymbol-CoUCgMCM.js} +1 -1
  118. package/dist/{journeyDiagram-XKPGCS4Q-BO_O4Ij1.js → journeyDiagram-XKPGCS4Q-8XYSU1GI.js} +3 -3
  119. package/dist/{kanban-definition-3W4ZIXB7-CPpiiiWk.js → kanban-definition-3W4ZIXB7--9pT9z1R.js} +7 -7
  120. package/dist/{label-BLqV33b1.js → label-LWtdw5i8.js} +3 -3
  121. package/dist/{linear-2NnK4cxi.js → linear-B5-AFRiR.js} +2 -2
  122. package/dist/{loader-Dr8Qem8p.js → loader-BWLPpjKK.js} +2 -2
  123. package/dist/main.js +1688 -1569
  124. package/dist/{memoize-C9ltv0Cw.js → memoize-BOtf2yFf.js} +1 -1
  125. package/dist/{merge-CHn7Yx0N.js → merge-Be1CqGnU.js} +1 -1
  126. package/dist/mermaid-4DMBBIKO-DIdL224_.js +6 -0
  127. package/dist/{mermaid-DO-Daq7u.js → mermaid-YK4c8MNC.js} +44 -44
  128. package/dist/{mermaid-parser.core-DreccfmS.js → mermaid-parser.core-C3XRsazI.js} +8 -8
  129. package/dist/{min-BNz2lZfk.js → min-Dtgc8txR.js} +4 -4
  130. package/dist/{mindmap-definition-VGOIOE7T-CC1_Vl0f.js → mindmap-definition-VGOIOE7T-B-4mnfFG.js} +9 -9
  131. package/dist/{now-Sgq5m3D-.js → now-Ch98bJO_.js} +2 -2
  132. package/dist/{number-overlay-editor-CpKi64Fy.js → number-overlay-editor-D-a0qCT8.js} +1 -1
  133. package/dist/{once-rJImu7SE.js → once-DPuqGUeo.js} +1 -1
  134. package/dist/{packet-DYOGHKS2-CmWtF3uO.js → packet-DYOGHKS2-34raHOiB.js} +3 -3
  135. package/dist/{pick-CRAXxDYn.js → pick-D1Qo8s2C.js} +4 -4
  136. package/dist/{pie-VRWISCQL-B6u8vus8.js → pie-VRWISCQL-BaLlzZa3.js} +3 -3
  137. package/dist/{pieDiagram-ADFJNKIX-Di34MOFQ.js → pieDiagram-ADFJNKIX-Cr3cNpZY.js} +15 -15
  138. package/dist/{precisionRound-CnHPY_5v.js → precisionRound-Tqb4mg-H.js} +1 -1
  139. package/dist/{process-output-X8TR20AK.js → process-output-CVDHJqo6.js} +36 -28
  140. package/dist/{quadrantDiagram-AYHSOK5B-B9kVk1ny.js → quadrantDiagram-AYHSOK5B-BuNL8Q93.js} +4 -4
  141. package/dist/{radar-ZZBFDIW7-XAmXSa8s.js → radar-ZZBFDIW7-Ci7bfoZa.js} +3 -3
  142. package/dist/{react-vega-Dh6-UKKe.js → react-vega-B0sAlDTL.js} +9 -9
  143. package/dist/react-vega-B6ncY2Tp.js +9 -0
  144. package/dist/{requirementDiagram-UZGBJVZJ-BxGfGYEx.js → requirementDiagram-UZGBJVZJ-BG2lLUN1.js} +9 -9
  145. package/dist/{reveal-component-Cj2fUG1Q.js → reveal-component-Dskn4JVk.js} +31 -31
  146. package/dist/{sankeyDiagram-TZEHDZUN-D09PBJ-n.js → sankeyDiagram-TZEHDZUN-DMal8sps.js} +3 -3
  147. package/dist/{sequenceDiagram-WL72ISMW-t_Dpemj0.js → sequenceDiagram-WL72ISMW-DT6Tk-Eo.js} +4 -4
  148. package/dist/{spec-hVaaZsY5.js → spec-CyLiCjSf.js} +4 -4
  149. package/dist/{stateDiagram-FKZM4ZOC-B18gTP_j.js → stateDiagram-FKZM4ZOC-CB_lodq3.js} +12 -12
  150. package/dist/{stateDiagram-v2-4FDKWEC3-B6e_t14A.js → stateDiagram-v2-4FDKWEC3-E0RGjKsm.js} +10 -10
  151. package/dist/stex-KfRnSHzF.js +4 -0
  152. package/dist/{strings-BiIhGaI8.js → strings-Bu3vlb6W.js} +7 -7
  153. package/dist/style.css +1 -1
  154. package/dist/{swiper-component-DlD2GU2g.js → swiper-component-B2t5sN1q.js} +3 -3
  155. package/dist/{time-C1SGcFMH.js → time-CsmIF9YZ.js} +3 -3
  156. package/dist/{timeline-definition-IT6M3QCI-DJnh1ks5.js → timeline-definition-IT6M3QCI-NfSKRvH0.js} +2 -2
  157. package/dist/{toDate-CIpC_34u.js → toDate-DNWCUEQp.js} +5 -5
  158. package/dist/{tooltip-DRaMBu06.js → tooltip-C5FYOpQc.js} +4 -4
  159. package/dist/{treemap-GDKQZRPO-Du95DV6u.js → treemap-GDKQZRPO-Cl6OQh8D.js} +3 -3
  160. package/dist/{types-Dzuoc3LN.js → types-CVvp1fKr.js} +2 -9
  161. package/dist/{useAsyncData-C56Khv_R.js → useAsyncData-xWFWzCee.js} +2 -2
  162. package/dist/{useDateFormatter-B_9k85Ex.js → useDateFormatter-BA4FCquG.js} +2 -2
  163. package/dist/{useDeepCompareMemoize-Dt98v2ua.js → useDeepCompareMemoize-DSChED4g.js} +1 -1
  164. package/dist/{useIframeCapabilities-BkYHTrss.js → useIframeCapabilities-C4JTXTIh.js} +1 -1
  165. package/dist/{useLifecycle-BF6-z62y.js → useLifecycle-B81PFEja.js} +4 -4
  166. package/dist/{useTheme-DykuNHR2.js → useTheme-EmVyK9N9.js} +23 -21
  167. package/dist/{vega-component-cSdqoAxe.js → vega-component-BCunE3-9.js} +18 -18
  168. package/dist/{vega-loader.browser-3_z8GoFC.js → vega-loader.browser-CZ-J8Py3.js} +3 -3
  169. package/dist/{xychartDiagram-PRI3JC2R-Dk2d_bX0.js → xychartDiagram-PRI3JC2R-BvwftqMA.js} +9 -9
  170. package/dist/{zod-BWkcDORu.js → zod-CoBiJ5v4.js} +3 -3
  171. package/package.json +1 -1
  172. package/src/components/app-config/user-config-form.tsx +36 -0
  173. package/src/components/chat/__tests__/chat-utils.test.ts +269 -0
  174. package/src/components/chat/chat-utils.ts +14 -58
  175. package/src/components/data-table/TableBottomBar.tsx +27 -6
  176. package/src/components/data-table/TableTopBar.tsx +7 -1
  177. package/src/components/data-table/__tests__/TableBottomBar.test.tsx +73 -0
  178. package/src/components/data-table/__tests__/column-explorer.test.tsx +128 -0
  179. package/src/components/data-table/__tests__/column-header.test.tsx +110 -277
  180. package/src/components/data-table/__tests__/data-table.test.tsx +52 -1
  181. package/src/components/data-table/__tests__/date-filter-inputs.test.tsx +33 -0
  182. package/src/components/data-table/__tests__/filter-pill-editor.test.tsx +75 -38
  183. package/src/components/data-table/__tests__/filter-pills.test.tsx +287 -0
  184. package/src/components/data-table/__tests__/filter-test-utils.ts +47 -0
  185. package/src/components/data-table/__tests__/filters.test.ts +5 -5
  186. package/src/components/data-table/__tests__/header-items.test.tsx +47 -1
  187. package/src/components/data-table/__tests__/useColumnVisibility.test.ts +42 -0
  188. package/src/components/data-table/add-filter-button.tsx +85 -0
  189. package/src/components/data-table/column-explorer-panel/column-explorer.tsx +98 -26
  190. package/src/components/data-table/column-header.tsx +94 -691
  191. package/src/components/data-table/columns.tsx +3 -4
  192. package/src/components/data-table/context-menu.tsx +26 -12
  193. package/src/components/data-table/data-table.tsx +125 -56
  194. package/src/components/data-table/date-filter-inputs.tsx +13 -10
  195. package/src/components/data-table/export-actions.tsx +17 -6
  196. package/src/components/data-table/filter-by-values-picker.tsx +13 -19
  197. package/src/components/data-table/filter-editor-context.tsx +34 -0
  198. package/src/components/data-table/filter-pill-editor.tsx +152 -175
  199. package/src/components/data-table/filter-pills.tsx +190 -153
  200. package/src/components/data-table/filters/builders.ts +102 -0
  201. package/src/components/data-table/filters/defaults.ts +31 -0
  202. package/src/components/data-table/filters/format.ts +131 -0
  203. package/src/components/data-table/filters/guards.ts +51 -0
  204. package/src/components/data-table/filters/index.ts +7 -0
  205. package/src/components/data-table/filters/operators.ts +76 -0
  206. package/src/components/data-table/filters/serialize.ts +186 -0
  207. package/src/components/data-table/filters/types.ts +33 -0
  208. package/src/components/data-table/header-items.tsx +25 -85
  209. package/src/components/data-table/hooks/use-column-visibility.ts +56 -0
  210. package/src/components/data-table/pagination.tsx +16 -3
  211. package/src/components/data-table/table-explorer-panel/table-explorer-panel.tsx +16 -6
  212. package/src/components/data-table/value-chips.tsx +52 -0
  213. package/src/components/dependency-graph/minimap-content.tsx +2 -2
  214. package/src/components/editor/errors/mangled-local-chip.tsx +50 -0
  215. package/src/components/editor/output/MarimoErrorOutput.tsx +110 -27
  216. package/src/components/editor/output/MarimoTracebackOutput.tsx +51 -34
  217. package/src/components/ui/number-field.tsx +13 -1
  218. package/src/core/cells/__tests__/actions.test.ts +48 -0
  219. package/src/core/cells/actions.ts +5 -6
  220. package/src/core/codemirror/__tests__/setup.test.ts +29 -0
  221. package/src/core/codemirror/cells/traceback-decorations.ts +1 -1
  222. package/src/core/codemirror/cm.ts +3 -2
  223. package/src/core/config/__tests__/config-schema.test.ts +2 -0
  224. package/src/core/config/config-schema.ts +1 -0
  225. package/src/css/app/Cell.css +0 -1
  226. package/src/plugins/impl/DataTablePlugin.tsx +94 -33
  227. package/src/plugins/impl/__tests__/DataTablePlugin.test.tsx +1 -0
  228. package/src/plugins/impl/chat/ChatPlugin.tsx +7 -1
  229. package/src/plugins/impl/chat/__tests__/chat-ui.test.ts +278 -0
  230. package/src/plugins/impl/chat/chat-ui.tsx +106 -59
  231. package/src/plugins/impl/chat/types.ts +5 -0
  232. package/src/plugins/impl/data-frames/DataFramePlugin.tsx +8 -6
  233. package/src/stories/dataframe.stories.tsx +1 -0
  234. package/src/utils/__tests__/local-variables.test.ts +132 -0
  235. package/src/utils/dates.ts +39 -0
  236. package/src/utils/local-variables.ts +67 -0
  237. package/dist/ErrorBoundary-D3wrPNma.js +0 -167
  238. package/dist/architecture-7HQA4BMR-CS9jOrqM.js +0 -6
  239. package/dist/assets/__vite-browser-external-CAdMKBac.js +0 -1
  240. package/dist/dist-21ButRCu.js +0 -8
  241. package/dist/dist-B--tLnAP.js +0 -5
  242. package/dist/dist-BoHGySTM.js +0 -5
  243. package/dist/dist-ByAz19Qc.js +0 -5
  244. package/dist/dist-C1Ap5CYU.js +0 -5
  245. package/dist/dist-C93EysN4.js +0 -5
  246. package/dist/dist-CY-lVor6.js +0 -8
  247. package/dist/dist-CYDuv4bR.js +0 -8
  248. package/dist/dist-Cfo5EE2t.js +0 -6
  249. package/dist/dist-CjivSDvN.js +0 -5
  250. package/dist/dist-Cqwx-MH7.js +0 -5
  251. package/dist/dist-DbpcoFAV.js +0 -6
  252. package/dist/dist-FUNenbiQ.js +0 -5
  253. package/dist/dist-zhSud5X3.js +0 -8
  254. package/dist/mermaid-4DMBBIKO-B7VQMwJx.js +0 -6
  255. package/dist/react-vega-Cavbrg4l.js +0 -9
  256. package/dist/stex-ChDHQs3R.js +0 -4
  257. package/src/components/data-table/__tests__/column-header.test.ts +0 -65
  258. package/src/components/data-table/filters.ts +0 -386
  259. /package/dist/{_baseFor-BGiY-cm1.js → _baseFor-4jw-lnCC.js} +0 -0
  260. /package/dist/{clsx-CyyyQ8Ue.js → clsx-CIWA5tNO.js} +0 -0
  261. /package/dist/{defaultLocale-DoeErsX2.js → defaultLocale-BoHTsDG6.js} +0 -0
  262. /package/dist/{defaultLocale-BpsHxBd7.js → defaultLocale-u-3osm0P.js} +0 -0
  263. /package/dist/{dist-CCADb07R.js → dist-DNdhYsgW.js} +0 -0
  264. /package/dist/{emotion-is-prop-valid.esm-DtW2o230.js → emotion-is-prop-valid.esm-DzSb5hsH.js} +0 -0
  265. /package/dist/{invariant-UcGKQEhF.js → invariant-wRzNXIsJ.js} +0 -0
  266. /package/dist/{jsx-runtime-COBk7ree.js → jsx-runtime-DebpN0FN.js} +0 -0
  267. /package/dist/{main-CThhXnXU.js → main-Tj_-QTyF.js} +0 -0
  268. /package/dist/{micromark-factory-space-CwHmg6iz.js → micromark-factory-space-DF2w36zS.js} +0 -0
  269. /package/dist/{ordinal-B43ZeR68.js → ordinal-ArJavP1Q.js} +0 -0
  270. /package/dist/{purify.es-DT70lfR0.js → purify.es-H92eMd9-.js} +0 -0
  271. /package/dist/{range-BOiA8qqU.js → range-C-rmrM1O.js} +0 -0
  272. /package/dist/{react-dom-BWRJ_g_k.js → react-dom-BTJzcVJ9.js} +0 -0
  273. /package/dist/{stex-DrxP7bb3.js → stex-BIsgBmK4.js} +0 -0
@@ -0,0 +1,52 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import type React from "react";
4
+
5
+ export const Chip = ({ children }: { children: React.ReactNode }) => (
6
+ <span className="inline-flex items-center rounded-sm bg-muted/50 px-1 font-mono text-xs font-normal leading-tight text-foreground">
7
+ {children}
8
+ </span>
9
+ );
10
+
11
+ export const MoreChip = ({ count }: { count: number }) => (
12
+ <span className="inline-flex items-center px-1 text-xs italic text-muted-foreground">
13
+ +{count}
14
+ </span>
15
+ );
16
+
17
+ interface ChipWithCommaProps {
18
+ value: string;
19
+ showComma: boolean;
20
+ }
21
+
22
+ export const ChipWithComma = ({ value, showComma }: ChipWithCommaProps) => (
23
+ <span className="inline-flex items-center">
24
+ <Chip>{value}</Chip>
25
+ {showComma && <span className="text-muted-foreground">,</span>}
26
+ </span>
27
+ );
28
+
29
+ interface CompactChipRowProps {
30
+ items: string[];
31
+ max?: number;
32
+ }
33
+
34
+ export const CompactChipRow = ({ items, max = 3 }: CompactChipRowProps) => {
35
+ if (items.length === 0) {
36
+ return null;
37
+ }
38
+ const visible = items.slice(0, max);
39
+ const hidden = Math.max(0, items.length - max);
40
+ return (
41
+ <span className="inline-flex items-center gap-1">
42
+ {visible.map((item, i) => (
43
+ <ChipWithComma
44
+ key={i}
45
+ value={item}
46
+ showComma={i < visible.length - 1}
47
+ />
48
+ ))}
49
+ {hidden > 0 && <MoreChip count={hidden} />}
50
+ </span>
51
+ );
52
+ };
@@ -68,7 +68,7 @@ const MinimapCell: React.FC<MinimapCellProps> = (props) => {
68
68
  className={cn(
69
69
  "group bg-transparent text-left w-full flex relative justify-between items-center",
70
70
  "border-none rounded cursor-pointer",
71
- "h-[21px] pl-[59px] font-inherit",
71
+ "h-[21px] pl-[65px] font-inherit",
72
72
  isSelected
73
73
  ? "text-primary-foreground"
74
74
  : "text-(--gray-8) hover:text-(--gray-9)",
@@ -106,7 +106,7 @@ const MinimapCell: React.FC<MinimapCellProps> = (props) => {
106
106
  </div>
107
107
  <svg
108
108
  className={cn(
109
- "absolute overflow-visible top-[10.5px] left-[calc(var(--spacing-extra-small,8px)+25px)] pointer-events-none",
109
+ "absolute overflow-visible top-[10.5px] left-[calc(var(--spacing-extra-small,8px)+31px)] pointer-events-none",
110
110
  isSelected ? "z-[1]" : "z-0",
111
111
  getTextColor({ cell, selectedCell }),
112
112
  )}
@@ -0,0 +1,50 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+ import type { JSX } from "react";
3
+ import { Tooltip } from "@/components/ui/tooltip";
4
+ import type { MangledSegment, UnmangledLocal } from "@/utils/local-variables";
5
+ import { CellLinkError } from "../links/cell-link";
6
+
7
+ interface Props {
8
+ local: UnmangledLocal;
9
+ }
10
+
11
+ /**
12
+ * Renders a compiler-mangled cell-local variable as the user's original name
13
+ * (e.g. `_a`) with a tooltip linking to the defining cell.
14
+ */
15
+ export const MangledLocalChip = ({ local }: Props): JSX.Element => {
16
+ const tooltipContent = (
17
+ <div className="max-w-xs">
18
+ Local variable <span className="font-code">{local.name}</span> in cell{" "}
19
+ <CellLinkError cellId={local.cellId} />.
20
+ </div>
21
+ );
22
+
23
+ return (
24
+ <Tooltip content={tooltipContent}>
25
+ <span className="font-code cursor-help">{local.name}</span>
26
+ </Tooltip>
27
+ );
28
+ };
29
+
30
+ interface MangledSegmentsProps {
31
+ segments: MangledSegment[];
32
+ }
33
+
34
+ /**
35
+ * Render an array of `splitMangledLocals` segments as alternating text and
36
+ * `<MangledLocalChip>` nodes.
37
+ */
38
+ export const MangledSegments = ({
39
+ segments,
40
+ }: MangledSegmentsProps): JSX.Element => (
41
+ <>
42
+ {segments.map((segment, idx) =>
43
+ typeof segment === "string" ? (
44
+ <span key={idx}>{segment}</span>
45
+ ) : (
46
+ <MangledLocalChip key={idx} local={segment} />
47
+ ),
48
+ )}
49
+ </>
50
+ );
@@ -1,12 +1,16 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
+ import { useAtomValue } from "jotai";
3
4
  import {
5
+ ChevronDown,
6
+ ChevronRight,
7
+ InfoIcon,
4
8
  NotebookPenIcon,
5
9
  PackageIcon,
6
10
  SquareArrowOutUpRightIcon,
7
11
  TerminalIcon,
8
12
  } from "lucide-react";
9
- import { Fragment, type JSX } from "react";
13
+ import { Fragment, type JSX, useState } from "react";
10
14
  import {
11
15
  Accordion,
12
16
  AccordionContent,
@@ -16,16 +20,53 @@ import {
16
20
  import { Button } from "@/components/ui/button";
17
21
  import { Kbd } from "@/components/ui/kbd";
18
22
  import { ExternalLink } from "@/components/ui/links";
23
+ import { Tooltip } from "@/components/ui/tooltip";
19
24
  import type { CellId } from "@/core/cells/ids";
25
+ import { resolvedMarimoConfigAtom } from "@/core/config/config";
26
+ import { renderHTML } from "@/plugins/core/RenderHTML";
27
+ import { splitMangledLocals } from "@/utils/local-variables";
20
28
  import type { MarimoError } from "../../../core/kernel/messages";
21
29
  import { cn } from "../../../utils/cn";
22
30
  import { Alert, AlertTitle } from "../../ui/alert";
23
31
  import { openPackageManager } from "../chrome/panels/packages-utils";
24
32
  import { useChromeActions } from "../chrome/state";
25
33
  import { AutoFixButton } from "../errors/auto-fix";
34
+ import { MangledSegments } from "../errors/mangled-local-chip";
26
35
  import { CellLinkError } from "../links/cell-link";
27
36
  import { processTextForUrls } from "./console/text-rendering";
28
- import { renderHTML } from "@/plugins/core/RenderHTML";
37
+
38
+ const CollapsibleTraceback = ({
39
+ traceback,
40
+ }: {
41
+ traceback: string;
42
+ }): JSX.Element => {
43
+ const [isOpen, setIsOpen] = useState(true);
44
+ return (
45
+ <div className="mt-2">
46
+ <button
47
+ type="button"
48
+ onClick={() => setIsOpen(!isOpen)}
49
+ aria-expanded={isOpen}
50
+ aria-label={isOpen ? "Collapse traceback" : "Expand traceback"}
51
+ className="flex items-center gap-1 text-muted-foreground/70 hover:text-muted-foreground transition-colors"
52
+ >
53
+ {isOpen ? (
54
+ <ChevronDown className="h-3 w-3" />
55
+ ) : (
56
+ <ChevronRight className="h-3 w-3" />
57
+ )}
58
+ <span className="text-[0.6875rem] uppercase tracking-wider">
59
+ Traceback
60
+ </span>
61
+ </button>
62
+ {isOpen && (
63
+ <div className="font-code text-sm mt-1 p-3 bg-muted rounded border overflow-auto max-h-[50vh] cursor-text select-text">
64
+ {renderHTML({ html: traceback })}
65
+ </div>
66
+ )}
67
+ </div>
68
+ );
69
+ };
29
70
 
30
71
  const Tip = (props: {
31
72
  title?: string;
@@ -35,10 +76,13 @@ const Tip = (props: {
35
76
  return (
36
77
  <Accordion type="single" collapsible={true} className={props.className}>
37
78
  <AccordionItem value="item-1" className="text-muted-foreground">
38
- <AccordionTrigger className="pt-2 pb-2 font-normal">
79
+ <AccordionTrigger className="pt-2 pb-0 font-normal">
39
80
  {props.title ?? "Tip"}
40
81
  </AccordionTrigger>
41
- <AccordionContent className="mr-24 text-[0.84375rem]">
82
+ <AccordionContent
83
+ className="mr-24 text-[0.84375rem]"
84
+ wrapperClassName="pt-0 pb-2"
85
+ >
42
86
  {props.children}
43
87
  </AccordionContent>
44
88
  </AccordionItem>
@@ -61,10 +105,21 @@ export const MarimoErrorOutput = ({
61
105
  className,
62
106
  }: Props): JSX.Element => {
63
107
  const chromeActions = useChromeActions();
64
-
65
- let titleContents = "This cell wasn't run because it has errors";
108
+ // The console area (where tracebacks are shown) sits below the cell editor.
109
+ // When cell outputs are also displayed below the editor, the traceback is
110
+ // already adjacent, so the "See the console area" hint is redundant. It is
111
+ // only helpful when outputs are displayed above the editor.
112
+ const showConsoleHint =
113
+ useAtomValue(resolvedMarimoConfigAtom).display.cell_output === "above";
114
+
115
+ let titleContents: string | null =
116
+ "This cell wasn't run because it has errors";
66
117
  let alertVariant: "destructive" | "default" = "destructive";
67
118
  let titleColor = "text-error";
119
+ // A small muted overline shown above the title for static errors, where
120
+ // the cell genuinely never executes. These errors have no separate title:
121
+ // the body text already describes them, so the overline carries the status.
122
+ let statusOverline: string | null = null;
68
123
  const liStyle = "my-0.5 ml-8 text-muted-foreground/40";
69
124
 
70
125
  // Check for certain error types to adjust title and appearance
@@ -75,7 +130,6 @@ export const MarimoErrorOutput = ({
75
130
  } else if (errors.some((e) => e.type === "ancestor-prevented")) {
76
131
  titleContents = "Ancestor prevented from running";
77
132
  alertVariant = "default";
78
- titleColor = "text-muted-foreground";
79
133
  titleColor = "text-secondary-foreground";
80
134
  } else if (errors.some((e) => e.type === "ancestor-stopped")) {
81
135
  titleContents = "Ancestor stopped";
@@ -83,6 +137,19 @@ export const MarimoErrorOutput = ({
83
137
  titleColor = "text-secondary-foreground";
84
138
  } else if (errors.some((e) => e.type === "sql-error")) {
85
139
  titleContents = "SQL error";
140
+ } else if (
141
+ errors.some(
142
+ (e) =>
143
+ e.type === "multiple-defs" ||
144
+ e.type === "cycle" ||
145
+ e.type === "setup-refs" ||
146
+ e.type === "import-star",
147
+ )
148
+ ) {
149
+ // Static errors: the body text describes the problem, so there is no
150
+ // separate title — only the status overline.
151
+ titleContents = null;
152
+ statusOverline = "Cell not run";
86
153
  } else {
87
154
  // Check for exception type
88
155
  const exceptionError = errors.find((e) => e.type === "exception");
@@ -454,10 +521,13 @@ export const MarimoErrorOutput = ({
454
521
  error.exception_type === "NameError" &&
455
522
  error.msg.startsWith("name '_")
456
523
  ) {
524
+ const segments = splitMangledLocals(error.msg);
457
525
  return (
458
526
  <li className="my-2" key={`exception-${idx}`}>
459
527
  <div>
460
- <p className="text-muted-foreground">{error.msg}</p>
528
+ <p className="text-muted-foreground">
529
+ <MangledSegments segments={segments} />
530
+ </p>
461
531
  <p className="text-muted-foreground mt-2">
462
532
  Variables prefixed with an underscore are local to a cell{" "}
463
533
  (
@@ -470,9 +540,11 @@ export const MarimoErrorOutput = ({
470
540
  </ExternalLink>
471
541
  ).
472
542
  </p>
473
- <div className="text-muted-foreground mt-2">
474
- See the console area for a traceback.
475
- </div>
543
+ {showConsoleHint && (
544
+ <div className="text-muted-foreground mt-2">
545
+ See the console area for a traceback.
546
+ </div>
547
+ )}
476
548
  </div>
477
549
  </li>
478
550
  );
@@ -487,13 +559,13 @@ export const MarimoErrorOutput = ({
487
559
  {processTextForUrls(error.msg, `exception-${idx}`)}
488
560
  </p>
489
561
  {"traceback" in error && error.traceback ? (
490
- <div className="font-code text-sm mt-2 p-3 bg-muted rounded border overflow-auto max-h-[50vh] cursor-text select-text">
491
- {renderHTML({ html: error.traceback })}
492
- </div>
562
+ <CollapsibleTraceback traceback={error.traceback} />
493
563
  ) : (
494
- <div className="text-muted-foreground mt-2">
495
- See the console area for a traceback.
496
- </div>
564
+ showConsoleHint && (
565
+ <div className="text-muted-foreground mt-2">
566
+ See the console area for a traceback.
567
+ </div>
568
+ )
497
569
  )}
498
570
  </div>
499
571
  ) : (
@@ -501,9 +573,7 @@ export const MarimoErrorOutput = ({
501
573
  {processTextForUrls(error.msg, `exception-${idx}`)}
502
574
  <CellLinkError cellId={error.raising_cell} />
503
575
  {"traceback" in error && error.traceback && (
504
- <div className="font-code text-sm mt-2 p-3 bg-muted rounded border overflow-auto max-h-[50vh] cursor-text select-text">
505
- {renderHTML({ html: error.traceback })}
506
- </div>
576
+ <CollapsibleTraceback traceback={error.traceback} />
507
577
  )}
508
578
  </div>
509
579
  )}
@@ -628,23 +698,36 @@ export const MarimoErrorOutput = ({
628
698
  };
629
699
 
630
700
  const title = (
631
- <AlertTitle className={`font-code font-medium tracking-wide ${titleColor}`}>
632
- {titleContents}
633
- </AlertTitle>
701
+ <div className="space-y-0.5">
702
+ {statusOverline && (
703
+ <div className="flex items-center gap-1 font-code text-[0.6875rem] uppercase tracking-wider text-muted-foreground/70">
704
+ {statusOverline}
705
+ <Tooltip
706
+ content="marimo didn't run this cell because it detected an error."
707
+ delayDuration={200}
708
+ >
709
+ <InfoIcon className="size-3 cursor-help" />
710
+ </Tooltip>
711
+ </div>
712
+ )}
713
+ {titleContents && (
714
+ <AlertTitle className={`font-code font-medium ${titleColor}`}>
715
+ {titleContents}
716
+ </AlertTitle>
717
+ )}
718
+ </div>
634
719
  );
635
720
 
636
721
  return (
637
722
  <Alert
638
723
  variant={alertVariant}
639
724
  className={cn(
640
- "border-none font-code text-sm text-[0.84375rem] px-0 text-muted-foreground normal [&:has(svg)]:pl-0 space-y-4",
725
+ "border-none font-code text-sm text-[0.84375rem] p-0 text-muted-foreground normal [&:has(svg)]:pl-0 space-y-2",
641
726
  className,
642
727
  )}
643
728
  >
644
729
  {title}
645
- <div>
646
- <div className="flex flex-col gap-8">{renderMessages()}</div>
647
- </div>
730
+ <div className="flex flex-col gap-4">{renderMessages()}</div>
648
731
  </Alert>
649
732
  );
650
733
  };
@@ -5,17 +5,13 @@ import { useAtomValue } from "jotai";
5
5
  import {
6
6
  BugPlayIcon,
7
7
  ChevronDown,
8
+ ChevronRight,
8
9
  CopyIcon,
9
10
  ExternalLinkIcon,
10
11
  MessageCircleIcon,
11
12
  SearchIcon,
12
13
  } from "lucide-react";
13
14
  import { type JSX, useState } from "react";
14
- import {
15
- Accordion,
16
- AccordionContent,
17
- AccordionItem,
18
- } from "@/components/ui/accordion";
19
15
  import { Button } from "@/components/ui/button";
20
16
  import {
21
17
  DropdownMenu,
@@ -36,13 +32,17 @@ import { isWasm } from "@/core/wasm/utils";
36
32
  import { renderHTML } from "@/plugins/core/RenderHTML";
37
33
  import { sanitizeHtml } from "@/plugins/core/sanitize-html";
38
34
  import { copyToClipboard } from "@/utils/copy";
35
+ import {
36
+ containsMangledLocal,
37
+ splitMangledLocals,
38
+ } from "@/utils/local-variables";
39
39
  import {
40
40
  elementContainsMarimoCellFile,
41
41
  extractAllTracebackInfo,
42
42
  getTracebackInfo,
43
43
  } from "@/utils/traceback";
44
- import { cn } from "../../../utils/cn";
45
44
  import { AIFixButton } from "../errors/auto-fix";
45
+ import { MangledSegments } from "../errors/mangled-local-chip";
46
46
  import { CellLinkTraceback } from "../links/cell-link";
47
47
  import type { OnRefactorWithAI } from "../Output";
48
48
 
@@ -52,8 +52,6 @@ interface Props {
52
52
  onRefactorWithAI?: OnRefactorWithAI;
53
53
  }
54
54
 
55
- const KEY = "item";
56
-
57
55
  /**
58
56
  * List of errors due to violations of Marimo semantics.
59
57
  */
@@ -64,9 +62,12 @@ export const MarimoTracebackOutput = ({
64
62
  }: Props): JSX.Element => {
65
63
  const htmlTraceback = renderHTML({
66
64
  html: traceback,
67
- additionalReplacements: [replaceTracebackFilenames, replaceTracebackPrefix],
65
+ additionalReplacements: [
66
+ replaceTracebackFilenames,
67
+ replaceTracebackPrefix,
68
+ replaceMangledLocal,
69
+ ],
68
70
  });
69
- const [expanded, setExpanded] = useState(true);
70
71
 
71
72
  const lastTracebackLine = lastLine(traceback);
72
73
  const aiEnabled = useAtomValue(aiEnabledAtom);
@@ -86,6 +87,8 @@ export const MarimoTracebackOutput = ({
86
87
 
87
88
  const showSearch = !isStaticNotebook();
88
89
 
90
+ const [isOpen, setIsOpen] = useState(true);
91
+
89
92
  const handleRefactorWithAI = (triggerImmediately: boolean) => {
90
93
  onRefactorWithAI?.({
91
94
  prompt: `My code gives the following error:\n\n${lastTracebackLine}`,
@@ -93,32 +96,29 @@ export const MarimoTracebackOutput = ({
93
96
  });
94
97
  };
95
98
 
96
- const [error, errorMessage] = lastTracebackLine.split(":", 2);
97
-
98
99
  return (
99
100
  <div className="flex flex-col gap-2 min-w-full w-fit">
100
- <Accordion type="single" collapsible={true} value={expanded ? KEY : ""}>
101
- <AccordionItem value={KEY} className="border-none">
102
- <div
103
- className="flex gap-2 h-10 px-2 hover:bg-muted rounded-sm select-none items-center cursor-pointer transition-all"
104
- onClick={() => setExpanded((prev) => !prev)}
105
- >
106
- <ChevronDown
107
- className={cn(
108
- "h-4 w-4 text-muted-foreground transition-transform duration-200 shrink-0",
109
- expanded ? "rotate-180" : "rotate-0",
110
- )}
111
- />
112
- <div className="text-sm inline font-mono">
113
- <span className="text-destructive">{error || "Error"}:</span>{" "}
114
- {errorMessage}
115
- </div>
116
- </div>
117
- <AccordionContent className="text-muted-foreground px-4 pt-2 text-xs overflow-auto">
118
- {htmlTraceback}
119
- </AccordionContent>
120
- </AccordionItem>
121
- </Accordion>
101
+ <button
102
+ type="button"
103
+ onClick={() => setIsOpen(!isOpen)}
104
+ aria-expanded={isOpen}
105
+ aria-label={isOpen ? "Collapse traceback" : "Expand traceback"}
106
+ className="self-start flex items-center gap-1 pt-2 text-muted-foreground/70 hover:text-muted-foreground transition-colors"
107
+ >
108
+ {isOpen ? (
109
+ <ChevronDown className="h-3 w-3" />
110
+ ) : (
111
+ <ChevronRight className="h-3 w-3" />
112
+ )}
113
+ <span className="text-[0.6875rem] uppercase tracking-wider">
114
+ Traceback
115
+ </span>
116
+ </button>
117
+ {isOpen && (
118
+ <div className="text-muted-foreground pr-4 text-xs overflow-auto">
119
+ {htmlTraceback}
120
+ </div>
121
+ )}
122
122
  <div className="flex gap-2">
123
123
  {showAIFix && (
124
124
  <AIFixButton
@@ -249,6 +249,23 @@ export const replaceTracebackFilenames = (domNode: DOMNode) => {
249
249
  }
250
250
  };
251
251
 
252
+ /**
253
+ * Replace any cell-local mangled name (`_cell_<id>_<name>`) inside a text
254
+ * node with a {@link MangledLocalChip}. The mangled name appears in both
255
+ * the final `NameError:` line and inside compiled-cell source lines because
256
+ * the compiler rewrites underscore-prefixed references at AST-visit time.
257
+ */
258
+ export const replaceMangledLocal = (domNode: DOMNode) => {
259
+ if (!(domNode instanceof Text) || !domNode.nodeValue) {
260
+ return;
261
+ }
262
+ if (!containsMangledLocal(domNode.nodeValue)) {
263
+ return;
264
+ }
265
+ const segments = splitMangledLocals(domNode.nodeValue);
266
+ return <MangledSegments segments={segments} />;
267
+ };
268
+
252
269
  export const replaceTracebackPrefix = (domNode: DOMNode) => {
253
270
  if (
254
271
  domNode instanceof Text &&
@@ -15,10 +15,17 @@ import { maxFractionalDigits } from "@/utils/numbers";
15
15
  export interface NumberFieldProps extends AriaNumberFieldProps {
16
16
  placeholder?: string;
17
17
  variant?: "default" | "xs";
18
+ /**
19
+ * Fires on every keystroke with the raw text currently in the input.
20
+ * React-aria's `onChange` only fires on commit (blur/Enter/stepper); use this
21
+ * when callers need to peek at the in-progress value, e.g. to enable an Apply
22
+ * button while the user is still typing.
23
+ */
24
+ onInputText?: (text: string) => void;
18
25
  }
19
26
 
20
27
  export const NumberField = React.forwardRef<HTMLInputElement, NumberFieldProps>(
21
- ({ placeholder, variant = "default", ...props }, ref) => {
28
+ ({ placeholder, variant = "default", onInputText, ...props }, ref) => {
22
29
  const { locale } = useLocale();
23
30
  return (
24
31
  <AriaNumberField
@@ -48,6 +55,11 @@ export const NumberField = React.forwardRef<HTMLInputElement, NumberFieldProps>(
48
55
  e.stopPropagation();
49
56
  }
50
57
  }}
58
+ onInput={
59
+ onInputText
60
+ ? (e) => onInputText(e.currentTarget.value)
61
+ : undefined
62
+ }
51
63
  className={cn(
52
64
  "flex-1",
53
65
  "w-full",
@@ -0,0 +1,48 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import { beforeEach, describe, expect, it, vi } from "vitest";
4
+ import { MockNotebook } from "@/__mocks__/notebook";
5
+ import { scrollAndHighlightCell } from "@/components/editor/links/cell-link";
6
+ import { notebookAtom } from "@/core/cells/cells";
7
+ import type { CellId } from "@/core/cells/ids";
8
+ import { createCellRuntimeState } from "@/core/cells/types";
9
+ import { store } from "@/core/state/jotai";
10
+ import { notebookScrollToRunning } from "../actions";
11
+
12
+ vi.mock("@/components/editor/links/cell-link", () => ({
13
+ scrollAndHighlightCell: vi.fn(),
14
+ }));
15
+
16
+ describe("notebookScrollToRunning", () => {
17
+ beforeEach(() => {
18
+ vi.clearAllMocks();
19
+ store.set(notebookAtom, MockNotebook.notebookState({ cellData: {} }));
20
+ });
21
+
22
+ it("scrolls to the first running cell in notebook order", () => {
23
+ const runtimeOnlyCellId = "runtime-only" as CellId;
24
+ const idleCellId = "idle-cell" as CellId;
25
+ const runningCellId = "running-cell" as CellId;
26
+
27
+ const notebook = MockNotebook.notebookState({
28
+ cellData: {
29
+ [idleCellId]: {},
30
+ [runningCellId]: {},
31
+ },
32
+ cellRuntime: {
33
+ [idleCellId]: { status: "idle" },
34
+ [runningCellId]: { status: "running" },
35
+ },
36
+ });
37
+ notebook.cellRuntime = {
38
+ [runtimeOnlyCellId]: createCellRuntimeState({ status: "running" }),
39
+ ...notebook.cellRuntime,
40
+ };
41
+ store.set(notebookAtom, notebook);
42
+
43
+ notebookScrollToRunning();
44
+
45
+ expect(scrollAndHighlightCell).toHaveBeenCalledOnce();
46
+ expect(scrollAndHighlightCell).toHaveBeenCalledWith(runningCellId, "focus");
47
+ });
48
+ });
@@ -1,7 +1,6 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
3
  import { scrollAndHighlightCell } from "@/components/editor/links/cell-link";
4
- import { Objects } from "@/utils/objects";
5
4
  import { store } from "../state/jotai";
6
5
  import { notebookAtom } from "./cells";
7
6
 
@@ -10,12 +9,12 @@ import { notebookAtom } from "./cells";
10
9
  */
11
10
  export function notebookScrollToRunning() {
12
11
  // find cell that is currently in "running" state
13
- const { cellRuntime } = store.get(notebookAtom);
14
- const cell = Objects.entries(cellRuntime).find(
15
- ([cellid, runtimestate]) => runtimestate.status === "running",
12
+ const { cellIds, cellRuntime } = store.get(notebookAtom);
13
+ const cellId = cellIds.inOrderIds.find(
14
+ (id) => cellRuntime[id]?.status === "running",
16
15
  );
17
- if (!cell) {
16
+ if (!cellId) {
18
17
  return;
19
18
  }
20
- scrollAndHighlightCell(cell[0], "focus");
19
+ scrollAndHighlightCell(cellId, "focus");
21
20
  }
@@ -134,6 +134,35 @@ describe("snapshot all duplicate keymaps", () => {
134
134
  });
135
135
  });
136
136
 
137
+ test("auto_close_pairs: false removes closeBrackets keymaps", () => {
138
+ const withAutoClose = EditorState.create({
139
+ extensions: setup(),
140
+ });
141
+ const withoutAutoClose = EditorState.create({
142
+ extensions: setup({
143
+ completionConfig: {
144
+ ...getOpts().completionConfig,
145
+ auto_close_pairs: false,
146
+ },
147
+ }),
148
+ });
149
+
150
+ const keysWith = withAutoClose.facet(keymap).flat();
151
+ const keysWithout = withoutAutoClose.facet(keymap).flat();
152
+
153
+ // closeBracketsKeymap contributes Backspace and Enter handlers
154
+ expect(keysWith.length).toBeGreaterThan(keysWithout.length);
155
+
156
+ const hasBracketPairHandler = (state: EditorState) =>
157
+ state
158
+ .facet(keymap)
159
+ .flat()
160
+ .some((k) => k.run?.name === "deleteBracketPair");
161
+
162
+ expect(hasBracketPairHandler(withAutoClose)).toBe(true);
163
+ expect(hasBracketPairHandler(withoutAutoClose)).toBe(false);
164
+ });
165
+
137
166
  test("placeholder adds another extension", () => {
138
167
  const opts = getOpts();
139
168
  const withAI = new PythonLanguageAdapter()
@@ -147,7 +147,7 @@ export function errorLineHighlighter(
147
147
  backgroundColor: "color-mix(in srgb, var(--red-4) 40%, transparent)",
148
148
  },
149
149
  "&.cm-focused .cm-error-line.cm-activeLine": {
150
- backgroundColor: "color-mix(in srgb, var(--red-6) 40%, transparent)",
150
+ backgroundColor: "color-mix(in srgb, var(--red-5) 40%, transparent)",
151
151
  },
152
152
  }),
153
153
  ];