@marimo-team/islands 0.22.1-dev3 → 0.22.1-dev31

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 (325) hide show
  1. package/dist/{ConnectedDataExplorerComponent-Dl1grr8z.js → ConnectedDataExplorerComponent-DTOsfq2x.js} +54 -54
  2. package/dist/_basePickBy-Sow3pJjS.js +41 -0
  3. package/dist/{_baseUniq-B4eL5sTC.js → _baseUniq-C87CckHL.js} +15 -54
  4. package/dist/{any-language-editor-CT_9yBde.js → any-language-editor-BHH_pQ6M.js} +21 -21
  5. package/dist/architecture-7HQA4BMR-BHdkAMvZ.js +6 -0
  6. package/dist/{architectureDiagram-VXUJARFQ-vxgYGIMP.js → architectureDiagram-VXUJARFQ-B3YQo9At.js} +15 -15
  7. package/dist/{arrays-Du-jRBAy.js → arrays-beUWo8RF.js} +1 -1
  8. package/dist/assets/__vite-browser-external-WSlCcXn_.js +1 -0
  9. package/dist/assets/{worker-D10K3OOz.js → worker-DUYMdbtA.js} +2 -2
  10. package/dist/{blockDiagram-VD42YOAC-C7x6YTH7.js → blockDiagram-VD42YOAC-CpQ3TKEN.js} +7 -7
  11. package/dist/{button-qsiIHncQ.js → button-DNlNlZY_.js} +82 -84
  12. package/dist/{c4Diagram-YG6GDRKO-Cx4oseGg.js → c4Diagram-YG6GDRKO-CZSU4uqU.js} +4 -4
  13. package/dist/{capabilities-26mwv03y.js → capabilities-Coe9eM9T.js} +2 -2
  14. package/dist/{channel-C_50jIAn.js → channel-X3JKk8gE.js} +1 -1
  15. package/dist/{chat-ui-CtqUthFR.js → chat-ui-eH46RYWT.js} +147 -146
  16. package/dist/{check-D_YwHEgY.js → check-CWUkiHmb.js} +1 -1
  17. package/dist/{chunk-4F5CHEZ2-Dvo_CFnR.js → chunk-4F5CHEZ2-D5mClyDv.js} +1 -1
  18. package/dist/{chunk-ABZYJK2D-D5YIs71w.js → chunk-ABZYJK2D-CZYCCtLy.js} +1 -1
  19. package/dist/{chunk-ATLVNIR6-CyOjzOcf.js → chunk-ATLVNIR6-DaOzLLgN.js} +1 -1
  20. package/dist/{chunk-B2363JML-BzZqINRO.js → chunk-B2363JML-Br0eA2T3.js} +1 -1
  21. package/dist/{chunk-B4BG7PRW-ZJeV3KdD.js → chunk-B4BG7PRW-4BjV11Br.js} +4 -4
  22. package/dist/{chunk-DI55MBZ5-Dx_wwX6l.js → chunk-DI55MBZ5-DITY3EyP.js} +4 -4
  23. package/dist/{chunk-EXTU4WIE-CgefpSXQ.js → chunk-EXTU4WIE-jUPSAk3i.js} +1 -1
  24. package/dist/{chunk-FRFDVMJY-Derq8UzY.js → chunk-FRFDVMJY-DnEvEFRR.js} +1 -1
  25. package/dist/{chunk-JA3XYJ7Z-CcIOIFpc.js → chunk-JA3XYJ7Z-BcPEfxk_.js} +2 -2
  26. package/dist/{chunk-JZLCHNYA-CgO0GG1p.js → chunk-JZLCHNYA-2bnLL3xL.js} +4 -4
  27. package/dist/{chunk-N4CR4FBY-2qzGzAxT.js → chunk-N4CR4FBY-CpZSuGSU.js} +5 -5
  28. package/dist/{chunk-PL6DKKU2-KoG71Zin.js → chunk-PL6DKKU2-DnId6G-x.js} +1 -1
  29. package/dist/{chunk-QN33PNHL-Dp1qBo28.js → chunk-QN33PNHL-B9p5ojHB.js} +1 -1
  30. package/dist/{chunk-QXUST7PY-BxmmeIwf.js → chunk-QXUST7PY-Ch6F5Obl.js} +5 -5
  31. package/dist/{chunk-S3R3BYOJ-D3Rys9ZW.js → chunk-S3R3BYOJ-B0UOFJwq.js} +3 -3
  32. package/dist/{chunk-SJTYNZTY-Co-DhKAG.js → chunk-SJTYNZTY-BsBZnJUj.js} +1 -1
  33. package/dist/{chunk-TCCFYFTB-BAhzIqBO.js → chunk-TCCFYFTB-Clbl-fTg.js} +8 -7
  34. package/dist/{chunk-TQ3KTPDO-DxYI735Z.js → chunk-TQ3KTPDO-CFkSQ30e.js} +1 -1
  35. package/dist/{chunk-TZMSLE5B-Dxumt0wv.js → chunk-TZMSLE5B-D45397J2.js} +1 -1
  36. package/dist/{chunk-UMXZTB3W-CuahpKin.js → chunk-UMXZTB3W-D-A834Bq.js} +1 -1
  37. package/dist/{classDiagram-v2-WZHVMYZB-CYoFMQKE.js → classDiagram-2ON5EDUG-C8-zE3Zv.js} +10 -10
  38. package/dist/{classDiagram-2ON5EDUG-DkOvXRlx.js → classDiagram-v2-WZHVMYZB-DrmbGANl.js} +10 -10
  39. package/dist/{clone-DDndUqI0.js → clone-DZFQCtFJ.js} +1 -1
  40. package/dist/{constants-D1Am36hX.js → constants-CvyfaCvs.js} +3 -3
  41. package/dist/{copy-CBo9JcJW.js → copy-B7781WJ3.js} +2 -2
  42. package/dist/{dagre-6UL2VRFP-BXBaU8PB.js → dagre-6UL2VRFP-OMItEBnY.js} +12 -12
  43. package/dist/{dagre-D3dlYz-r.js → dagre-QVd-lCXU.js} +13 -23
  44. package/dist/{data-grid-overlay-editor-nZux6_d2.js → data-grid-overlay-editor-lKF301ME.js} +1 -1
  45. package/dist/{diagram-PSM6KHXK-CJxjk4LG.js → diagram-PSM6KHXK-CkKbohWI.js} +16 -16
  46. package/dist/{diagram-QEK2KX5R-IMILPh_p.js → diagram-QEK2KX5R-DjUMpVcx.js} +14 -14
  47. package/dist/{diagram-S2PKOQOG-6O0g6Boj.js → diagram-S2PKOQOG-b-c0d-wZ.js} +14 -14
  48. package/dist/{dist-BkXs8bw0.js → dist--6TSlp8H.js} +1 -1
  49. package/dist/dist-7K5doRvB.js +6 -0
  50. package/dist/{dist-CQidOwep.js → dist-B43sbpd0.js} +3 -3
  51. package/dist/dist-B6I_A2-E.js +8 -0
  52. package/dist/dist-BEQsmaZY.js +5 -0
  53. package/dist/dist-BasY2RHp.js +8 -0
  54. package/dist/{dist-BemtTYzN.js → dist-Bfp1XXWt.js} +5 -5
  55. package/dist/{dist-v-1kgqZ3.js → dist-BjDuO5JW.js} +1 -1
  56. package/dist/dist-Bosc00dY.js +5 -0
  57. package/dist/{dist-DLNKBPsk.js → dist-BrxqmS9Q.js} +4 -4
  58. package/dist/{dist-DBYL08Lu.js → dist-BvhGByxL.js} +4 -4
  59. package/dist/{dist-CVqlhD3M.js → dist-C4bq5Ioy.js} +2 -2
  60. package/dist/{dist-DwmxBUOe.js → dist-CFKdzOIu.js} +2 -2
  61. package/dist/{dist-5nTQE2yt.js → dist-CIB8w0Fl.js} +2 -2
  62. package/dist/{dist-C-EcLtO9.js → dist-CNF0QBLR.js} +1 -1
  63. package/dist/dist-CQMZOn-_.js +8 -0
  64. package/dist/dist-CViQhWZ8.js +5 -0
  65. package/dist/{dist-Dg65j0em.js → dist-CcMfr7jD.js} +1 -1
  66. package/dist/{dist-C0XYIHKJ.js → dist-Ci0CXEFt.js} +1 -1
  67. package/dist/dist-Cz6rLfwY.js +5 -0
  68. package/dist/dist-D8eq8st3.js +6 -0
  69. package/dist/{dist-qoCY8giM.js → dist-DAfcmt-d.js} +2 -2
  70. package/dist/{dist-B6Op2ogv.js → dist-DD_cYHOl.js} +2 -2
  71. package/dist/{dist-BUSLKXcu.js → dist-DFK94vuS.js} +2 -2
  72. package/dist/{dist-DBXPlQ0D.js → dist-DGNtjMZu.js} +1 -1
  73. package/dist/{dist-C9qF7MRB.js → dist-DJ9F1eHs.js} +2 -2
  74. package/dist/{dist-Ci_jEudG.js → dist-DJKubHDd.js} +1 -1
  75. package/dist/{dist-CnFp2Kcl.js → dist-DLafRu9s.js} +2 -2
  76. package/dist/dist-DM1UDXdl.js +5 -0
  77. package/dist/dist-DNrtWPgS.js +5 -0
  78. package/dist/dist-D_UjpfOY.js +1381 -0
  79. package/dist/{dist-DmFS6KZW.js → dist-DbnBiLNH.js} +3 -3
  80. package/dist/{dist-BiZZAo22.js → dist-DlSUOIm9.js} +1 -1
  81. package/dist/{dist-DStU8He1.js → dist-Doy0mQDg.js} +2 -2
  82. package/dist/{dist-CxAX99oC.js → dist-DpkJHKB8.js} +2 -2
  83. package/dist/{dist-DjaZNkZ7.js → dist-LhQNUe5A.js} +3 -3
  84. package/dist/dist-V7q2qnpA.js +5 -0
  85. package/dist/{dist-BJ3fhRYu.js → dist-VqF3W_ue.js} +2 -2
  86. package/dist/dist-a5_hPgu2.js +8 -0
  87. package/dist/{dist-B9KLrfoh.js → dist-ej6AQKaS.js} +1 -1
  88. package/dist/{dist-Brb6VNc4.js → dist-m9tsXsFf.js} +2 -2
  89. package/dist/{dist-CBwMSFDu.js → dist-tGk0aZ--.js} +2 -2
  90. package/dist/dist-uVyZcV1-.js +5 -0
  91. package/dist/{erDiagram-Q2GNP2WA-sho7Cl9f.js → erDiagram-Q2GNP2WA-CDhLaOZ1.js} +10 -10
  92. package/dist/{error-banner-Bx9kIgrs.js → error-banner-Cjf0RU9I.js} +79 -79
  93. package/dist/{esm-CMg2ABu6.js → esm-4wmsH2lp.js} +6 -6
  94. package/dist/{esm-cqK9POGH.js → esm-CD1iby2n.js} +23 -23
  95. package/dist/{flowDiagram-NV44I4VS-C4nY4Fbz.js → flowDiagram-NV44I4VS-BDi4O4CL.js} +10 -10
  96. package/dist/{ganttDiagram-JELNMOA3-CtxNcCM2.js → ganttDiagram-JELNMOA3-BpZE6kVp.js} +3 -3
  97. package/dist/{gitGraph-G5XIXVHT-SL6TDof6.js → gitGraph-G5XIXVHT-B_c6xFJv.js} +3 -3
  98. package/dist/{gitGraphDiagram-V2S2FVAM-D9885mxd.js → gitGraphDiagram-V2S2FVAM-iQnXzbPM.js} +13 -13
  99. package/dist/{glide-data-editor-CkVEV-Gk.js → glide-data-editor-VgPtWvhu.js} +63 -63
  100. package/dist/{graphlib-CxWdvYQt.js → graphlib-BV1_gi0C.js} +4 -3
  101. package/dist/hasIn-DnfJcYpY.js +108 -0
  102. package/dist/{info-VBDWY6EO-6MXPTSmi.js → info-VBDWY6EO-BTyzxmhr.js} +3 -3
  103. package/dist/{infoDiagram-HS3SLOUP-Bw2FlRwF.js → infoDiagram-HS3SLOUP-OYrX6uO3.js} +13 -13
  104. package/dist/{input-BSde8uV4.js → input-CFY9gApZ.js} +5055 -5055
  105. package/dist/{isEmpty-BQtUinxJ.js → isEmpty-B7FX9wKt.js} +1 -1
  106. package/dist/{isSymbol-DFp8040B.js → isSymbol-DCbjQG_U.js} +1 -1
  107. package/dist/{journeyDiagram-XKPGCS4Q-BXlCEth8.js → journeyDiagram-XKPGCS4Q-ClPC94aN.js} +3 -3
  108. package/dist/{kanban-definition-3W4ZIXB7-CorxzSYm.js → kanban-definition-3W4ZIXB7-DHEAKdZt.js} +7 -7
  109. package/dist/{label-DTNqw9tv.js → label-DbZGAoCH.js} +538 -569
  110. package/dist/{loader-3c9hT4kT.js → loader-Bd1kgLn7.js} +19 -16
  111. package/dist/main.js +2602 -2594
  112. package/dist/{memoize-CuHciEBb.js → memoize-CSTI9eOX.js} +1 -1
  113. package/dist/{merge-CA_buyY3.js → merge-CVhG7q_o.js} +1 -1
  114. package/dist/{mermaid-CEKslOkI.js → mermaid-B2HDLx2g.js} +54 -54
  115. package/dist/{mermaid-parser.core-cq4YDee-.js → mermaid-parser.core-ntCgyx0x.js} +8 -8
  116. package/dist/min-Ds3gG0Ff.js +96 -0
  117. package/dist/{mindmap-definition-VGOIOE7T-DRsT8UaN.js → mindmap-definition-VGOIOE7T-CxEUZZvY.js} +9 -9
  118. package/dist/{now-CXAdKY5k.js → now-nrrrOr01.js} +1 -1
  119. package/dist/{once-CZno0h-b.js → once-C_TIu-kR.js} +1 -1
  120. package/dist/{packet-DYOGHKS2-Dw08gMaZ.js → packet-DYOGHKS2-BhvnpoGi.js} +3 -3
  121. package/dist/{pie-VRWISCQL-C5SPSvT8.js → pie-VRWISCQL-dILuA3iG.js} +3 -3
  122. package/dist/{pieDiagram-ADFJNKIX-DhJ1Cx2O.js → pieDiagram-ADFJNKIX-U3LrUqAS.js} +14 -14
  123. package/dist/{process-output-KyzWazB-.js → process-output-BbUNe4iH.js} +3181 -3204
  124. package/dist/{quadrantDiagram-AYHSOK5B-DXUFIWlz.js → quadrantDiagram-AYHSOK5B-BVWuq-3R.js} +2 -2
  125. package/dist/{radar-ZZBFDIW7-BvY0bgSg.js → radar-ZZBFDIW7-DwFrOJDj.js} +3 -3
  126. package/dist/range-fJeId9Ri.js +30 -0
  127. package/dist/{requirementDiagram-UZGBJVZJ-DO_gtQIb.js → requirementDiagram-UZGBJVZJ-D0zpQnKC.js} +9 -9
  128. package/dist/{sankeyDiagram-TZEHDZUN-OZzXEkuG.js → sankeyDiagram-TZEHDZUN-CExy1joT.js} +2 -2
  129. package/dist/{sequenceDiagram-WL72ISMW-K7nZRifV.js → sequenceDiagram-WL72ISMW-D1BJxLjH.js} +4 -4
  130. package/dist/{slides-component-CIcSvFh7.js → slides-component-CX2JC-Ws.js} +2 -2
  131. package/dist/{spec-DYaR1rJh.js → spec-CiHus5Bb.js} +3 -3
  132. package/dist/{stateDiagram-FKZM4ZOC-DzXJZAq7.js → stateDiagram-FKZM4ZOC-B1S8jGMn.js} +12 -12
  133. package/dist/{stateDiagram-v2-4FDKWEC3-BZBPUmyF.js → stateDiagram-v2-4FDKWEC3-BH5ozUbc.js} +10 -10
  134. package/dist/stex-CQDv3aS8.js +4 -0
  135. package/dist/style.css +1 -1
  136. package/dist/{timeline-definition-IT6M3QCI-DNoLAh-i.js → timeline-definition-IT6M3QCI-BDT9JAmn.js} +2 -2
  137. package/dist/{toDate-D6VXexnV.js → toDate-BzYZtEK7.js} +4 -4
  138. package/dist/{toNumber-xFPoy1OI.js → toNumber-55tjPCWr.js} +2 -2
  139. package/dist/tooltip-BXEpXV3R.js +404 -0
  140. package/dist/{treemap-GDKQZRPO-C5OoxpmV.js → treemap-GDKQZRPO-bx2ngsgN.js} +3 -3
  141. package/dist/{types-CQ-RbYxp.js → types-D_ntCXg0.js} +3 -3
  142. package/dist/{useAsyncData-Cd4Urlww.js → useAsyncData-rN1nzPaS.js} +2 -2
  143. package/dist/{useDeepCompareMemoize-X7clcrcQ.js → useDeepCompareMemoize-iM1YNTEF.js} +4 -4
  144. package/dist/{useIframeCapabilities-BVQrlRBd.js → useIframeCapabilities-CqhrVue6.js} +1 -1
  145. package/dist/{useLifecycle-Dids8BPm.js → useLifecycle-DgDTfOLZ.js} +9 -9
  146. package/dist/{useTheme-Dm1WaAGy.js → useTheme-MWfxn4oz.js} +4 -5
  147. package/dist/{vega-component-A6unyUJS.js → vega-component-CkpTXaRx.js} +23 -23
  148. package/dist/{xychartDiagram-PRI3JC2R-ehVeySMW.js → xychartDiagram-PRI3JC2R-CuAZiqHS.js} +5 -5
  149. package/dist/{Combination-B--d1_LV.js → zod-C6UGQ3fz.js} +8085 -8151
  150. package/package.json +8 -41
  151. package/src/__tests__/branded.ts +6 -0
  152. package/src/__tests__/main.test.tsx +12 -14
  153. package/src/components/ai/ai-provider-icon.tsx +3 -2
  154. package/src/components/app-config/user-config-form.tsx +0 -27
  155. package/src/components/chat/acp/agent-docs.tsx +3 -3
  156. package/src/components/chat/acp/agent-panel.tsx +69 -22
  157. package/src/components/chat/acp/agent-selector.tsx +2 -11
  158. package/src/components/chat/acp/state.ts +14 -2
  159. package/src/components/chat/chat-panel.tsx +2 -1
  160. package/src/components/data-table/TableBottomBar.tsx +12 -1
  161. package/src/components/data-table/TableTopBar.tsx +31 -35
  162. package/src/components/data-table/cell-selection/types.ts +3 -2
  163. package/src/components/data-table/charts/charts.tsx +42 -13
  164. package/src/components/data-table/charts/components/chart-items.tsx +1 -1
  165. package/src/components/data-table/column-explorer-panel/column-explorer.tsx +1 -1
  166. package/src/components/data-table/column-formatting/types.ts +3 -2
  167. package/src/components/data-table/column-header.tsx +4 -2
  168. package/src/components/data-table/column-wrapping/types.ts +3 -2
  169. package/src/components/data-table/columns.tsx +4 -1
  170. package/src/components/data-table/copy-column/types.ts +3 -2
  171. package/src/components/data-table/data-table.tsx +6 -1
  172. package/src/components/data-table/focus-row/types.ts +3 -2
  173. package/src/components/data-table/loading-table.tsx +4 -1
  174. package/src/components/data-table/range-focus/__tests__/atoms.test.ts +11 -11
  175. package/src/components/data-table/range-focus/__tests__/use-cell-range-selection.test.ts +9 -11
  176. package/src/components/data-table/range-focus/cell-selection-stats.tsx +3 -1
  177. package/src/components/data-table/row-viewer-panel/row-viewer.tsx +1 -1
  178. package/src/components/data-table/table-explorer-panel/table-explorer-panel.tsx +2 -2
  179. package/src/components/editor/__tests__/data-attributes.test.tsx +93 -94
  180. package/src/components/editor/actions/name-cell-input.tsx +4 -2
  181. package/src/components/editor/actions/useCellActionButton.tsx +4 -2
  182. package/src/components/editor/ai/add-cell-with-ai.tsx +2 -1
  183. package/src/components/editor/cell/CellStatus.tsx +4 -5
  184. package/src/components/editor/cell/cell-context-menu.tsx +4 -2
  185. package/src/components/editor/cell/code/cell-editor.tsx +2 -1
  186. package/src/components/editor/cell/toolbar.tsx +2 -1
  187. package/src/components/editor/chrome/components/contribute-snippet-button.tsx +4 -1
  188. package/src/components/editor/chrome/components/feedback-button.tsx +4 -1
  189. package/src/components/editor/chrome/panels/context-aware-panel/context-aware-panel.tsx +1 -1
  190. package/src/components/editor/chrome/panels/file-explorer-panel.tsx +0 -10
  191. package/src/components/editor/chrome/wrapper/app-chrome.tsx +4 -1
  192. package/src/components/editor/chrome/wrapper/footer-items/lsp-status.tsx +2 -1
  193. package/src/components/editor/header/filename-input.tsx +4 -1
  194. package/src/components/editor/renderers/vertical-layout/vertical-layout.tsx +11 -12
  195. package/src/components/storage/__tests__/storage-snippets.test.ts +4 -6
  196. package/src/components/tracing/tracing.test.tsx +30 -30
  197. package/src/components/ui/accordion.tsx +1 -1
  198. package/src/components/ui/alert-dialog.tsx +1 -1
  199. package/src/components/ui/badge.tsx +2 -1
  200. package/src/components/ui/button.tsx +4 -3
  201. package/src/components/ui/calendar.tsx +3 -2
  202. package/src/components/ui/checkbox.tsx +1 -1
  203. package/src/components/ui/combobox.tsx +2 -1
  204. package/src/components/ui/command.tsx +4 -1
  205. package/src/components/ui/context-menu.tsx +1 -1
  206. package/src/components/ui/date-input.tsx +7 -6
  207. package/src/components/ui/date-picker.tsx +6 -4
  208. package/src/components/ui/dialog.tsx +1 -1
  209. package/src/components/ui/draggable-popover.tsx +1 -1
  210. package/src/components/ui/dropdown-menu.tsx +2 -1
  211. package/src/components/ui/field.tsx +1 -2
  212. package/src/components/ui/form.tsx +4 -5
  213. package/src/components/ui/fullscreen.tsx +4 -1
  214. package/src/components/ui/label.tsx +1 -1
  215. package/src/components/ui/navigation.tsx +1 -1
  216. package/src/components/ui/popover.tsx +1 -1
  217. package/src/components/ui/progress.tsx +4 -3
  218. package/src/components/ui/query-param-preserving-link.tsx +4 -2
  219. package/src/components/ui/radio-group.tsx +1 -1
  220. package/src/components/ui/range-slider.tsx +1 -1
  221. package/src/components/ui/scroll-area.tsx +1 -1
  222. package/src/components/ui/select.tsx +1 -1
  223. package/src/components/ui/sheet.tsx +3 -2
  224. package/src/components/ui/slider.tsx +1 -1
  225. package/src/components/ui/switch.tsx +1 -1
  226. package/src/components/ui/tabs.tsx +1 -1
  227. package/src/components/ui/textarea.tsx +1 -2
  228. package/src/components/ui/toast.tsx +1 -1
  229. package/src/components/ui/toggle.tsx +1 -1
  230. package/src/components/ui/tooltip.tsx +1 -1
  231. package/src/core/ai/context/providers/cell-output.ts +1 -2
  232. package/src/core/ai/tools/edit-notebook-tool.ts +4 -3
  233. package/src/core/ai/tools/run-cells-tool.ts +4 -3
  234. package/src/core/cells/__tests__/add-missing-import.test.ts +23 -22
  235. package/src/core/cells/__tests__/apply-transaction.test.ts +12 -11
  236. package/src/core/cells/__tests__/cell.test.ts +14 -13
  237. package/src/core/cells/document-changes.ts +9 -9
  238. package/src/core/cells/logs.ts +1 -1
  239. package/src/core/codemirror/cells/__tests__/extensions.test.ts +15 -17
  240. package/src/core/codemirror/copilot/__tests__/transport.test.ts +128 -2
  241. package/src/core/codemirror/copilot/client.ts +9 -2
  242. package/src/core/codemirror/copilot/language-server.ts +11 -0
  243. package/src/core/codemirror/copilot/transport.ts +33 -8
  244. package/src/core/codemirror/language/languages/markdown.ts +1 -3
  245. package/src/core/codemirror/language/languages/python.ts +4 -0
  246. package/src/core/codemirror/language/languages/sql/completion-sources.tsx +4 -6
  247. package/src/core/codemirror/language/languages/sql/sql.ts +1 -3
  248. package/src/core/codemirror/language/panel/sql.tsx +4 -1
  249. package/src/core/codemirror/reactive-references/__tests__/analyzer.test.ts +28 -42
  250. package/src/core/config/__tests__/config-schema.test.ts +2 -6
  251. package/src/core/config/config-schema.ts +0 -1
  252. package/src/core/config/feature-flag.tsx +0 -2
  253. package/src/core/datasets/data-source-connections.ts +4 -2
  254. package/src/core/dom/__tests__/htmlUtils.test.ts +8 -14
  255. package/src/core/dom/__tests__/outline.test.ts +2 -3
  256. package/src/core/edit-app.tsx +4 -1
  257. package/src/core/islands/__tests__/bridge.test.ts +20 -10
  258. package/src/core/islands/__tests__/parse.test.ts +8 -7
  259. package/src/core/network/__tests__/requests-lazy.test.ts +30 -14
  260. package/src/core/saving/__tests__/filename.test.ts +7 -6
  261. package/src/core/static/__tests__/download-html.test.ts +16 -15
  262. package/src/core/static/__tests__/files.test.ts +30 -28
  263. package/src/core/websocket/useMarimoKernelConnection.tsx +5 -11
  264. package/src/core/websocket/useWebSocket.tsx +3 -1
  265. package/src/css/app/Cell.css +25 -1
  266. package/src/css/globals.css +40 -14
  267. package/src/css/table.css +17 -0
  268. package/src/plugins/core/BadPlugin.tsx +7 -6
  269. package/src/plugins/impl/CheckboxPlugin.tsx +4 -1
  270. package/src/plugins/impl/DataEditorPlugin.tsx +8 -3
  271. package/src/plugins/impl/DataTablePlugin.tsx +5 -1
  272. package/src/plugins/impl/FormPlugin.tsx +1 -2
  273. package/src/plugins/impl/__tests__/DataTablePlugin.test.tsx +4 -1
  274. package/src/plugins/impl/__tests__/SliderPlugin.test.tsx +43 -15
  275. package/src/plugins/impl/anywidget/AnyWidgetPlugin.tsx +2 -11
  276. package/src/plugins/impl/chat/chat-ui.tsx +4 -1
  277. package/src/plugins/impl/data-frames/forms/__tests__/form.test.tsx +7 -9
  278. package/src/plugins/impl/plotly/PlotlyPlugin.tsx +12 -68
  279. package/src/plugins/impl/plotly/__tests__/selection.test.ts +237 -0
  280. package/src/plugins/impl/plotly/selection.ts +115 -0
  281. package/src/plugins/impl/vega/__tests__/make-selectable.test.ts +13 -14
  282. package/src/plugins/impl/vega/__tests__/utils.test.ts +68 -0
  283. package/src/plugins/impl/vega/utils.ts +14 -5
  284. package/src/plugins/impl/vega/vega.css +2 -1
  285. package/src/plugins/layout/ImageComparisonPlugin.tsx +1 -3
  286. package/src/plugins/stateless-plugin.ts +4 -2
  287. package/src/utils/__tests__/cell-urls.test.ts +24 -21
  288. package/src/utils/__tests__/filenames.test.ts +15 -14
  289. package/src/utils/__tests__/json-parser.test.ts +14 -21
  290. package/src/utils/__tests__/path.test.ts +34 -31
  291. package/src/utils/__tests__/urls.test.ts +19 -18
  292. package/src/utils/json/base64.ts +2 -5
  293. package/src/utils/time.ts +4 -2
  294. package/src/utils/tracer.ts +1 -0
  295. package/src/utils/typed.ts +2 -2
  296. package/dist/_basePickBy-QjOmBDRE.js +0 -110
  297. package/dist/_baseSet-xgn1IbGV.js +0 -27
  298. package/dist/architecture-7HQA4BMR-BRyVh_Za.js +0 -6
  299. package/dist/assets/__vite-browser-external-Us1ds95c.js +0 -1
  300. package/dist/dist-B0R_ZM4-.js +0 -6
  301. package/dist/dist-B4a9_9pj.js +0 -5
  302. package/dist/dist-BCSUKEwO.js +0 -5
  303. package/dist/dist-BONIDQq6.js +0 -5
  304. package/dist/dist-BYeRx2hb.js +0 -5
  305. package/dist/dist-D2Rk1j4R.js +0 -1381
  306. package/dist/dist-DZjX5TYv.js +0 -5
  307. package/dist/dist-Dkw9x6kc.js +0 -5
  308. package/dist/dist-Ds6UaXGR.js +0 -6
  309. package/dist/dist-KuEJ1Q53.js +0 -8
  310. package/dist/dist-S72WNyTZ.js +0 -5
  311. package/dist/dist-bTG-yssT.js +0 -5
  312. package/dist/dist-diF0sguc.js +0 -8
  313. package/dist/dist-mJ84BIgu.js +0 -8
  314. package/dist/dist-wSIhFWQz.js +0 -8
  315. package/dist/get-CqrzlV1v.js +0 -68
  316. package/dist/range-CYz5jI--.js +0 -17
  317. package/dist/stex-CZyTRGVB.js +0 -4
  318. package/dist/tooltip-DGHTbHl5.js +0 -404
  319. /package/dist/{dist-KZI_BHqV.js → dist-CxZvoNao.js} +0 -0
  320. /package/dist/{invariant-D4hPsZFI.js → invariant-e8eBgdux.js} +0 -0
  321. /package/dist/{isArrayLikeObject-C-hFPChh.js → isArrayLikeObject-LXbTYiBa.js} +0 -0
  322. /package/dist/{main-CvkAPtaq.js → main-XimWhSi_.js} +0 -0
  323. /package/dist/{purify.es-ukiMXY-F.js → purify.es-hTCfRGdl.js} +0 -0
  324. /package/dist/{react-dom-BKwCWYPW.js → react-dom-BSUuJjCR.js} +0 -0
  325. /package/dist/{stex-Ze8D4R_5.js → stex-D887Ylhf.js} +0 -0
@@ -192,20 +192,21 @@ describe("patchVegaLoader - loader.http", () => {
192
192
  "http://foo.com/virtual-file.json",
193
193
  ];
194
194
 
195
- it.each(
196
- pathsToTest,
197
- )("should return file content for virtual files for %s", async (s) => {
198
- const virtualFiles = {
199
- "/virtual-file.json":
200
- "data:application/json;base64,eyJrZXkiOiAidmFsdWUifQ==" as DataURLString,
201
- };
202
-
203
- const loader = createLoader();
204
- const unpatch = patchVegaLoader(loader, virtualFiles);
205
- const content = await loader.http(s);
206
- unpatch();
207
- expect(content).toBe('{"key": "value"}');
208
- });
195
+ it.each(pathsToTest)(
196
+ "should return file content for virtual files for %s",
197
+ async (s) => {
198
+ const virtualFiles = {
199
+ "/virtual-file.json":
200
+ "data:application/json;base64,eyJrZXkiOiAidmFsdWUifQ==" as DataURLString,
201
+ };
202
+
203
+ const loader = createLoader();
204
+ const unpatch = patchVegaLoader(loader, virtualFiles);
205
+ const content = await loader.http(s);
206
+ unpatch();
207
+ expect(content).toBe('{"key": "value"}');
208
+ },
209
+ );
209
210
 
210
211
  it("should fallback to original http method for non-virtual files", async () => {
211
212
  const loader = createLoader();
@@ -236,20 +237,21 @@ describe("patchVegaLoader - loader.load", () => {
236
237
  "http://foo.com/virtual-file.json",
237
238
  ];
238
239
 
239
- it.each(
240
- pathsToTest,
241
- )("should return file content for virtual files for %s", async (s) => {
242
- const virtualFiles = {
243
- "/virtual-file.json":
244
- "data:application/json;base64,eyJrZXkiOiAidmFsdWUifQ==" as DataURLString,
245
- };
246
-
247
- const loader = createLoader();
248
- const unpatch = patchVegaLoader(loader, virtualFiles);
249
- const content = await loader.load(s);
250
- unpatch();
251
- expect(content).toBe('{"key": "value"}');
252
- });
240
+ it.each(pathsToTest)(
241
+ "should return file content for virtual files for %s",
242
+ async (s) => {
243
+ const virtualFiles = {
244
+ "/virtual-file.json":
245
+ "data:application/json;base64,eyJrZXkiOiAidmFsdWUifQ==" as DataURLString,
246
+ };
247
+
248
+ const loader = createLoader();
249
+ const unpatch = patchVegaLoader(loader, virtualFiles);
250
+ const content = await loader.load(s);
251
+ unpatch();
252
+ expect(content).toBe('{"key": "value"}');
253
+ },
254
+ );
253
255
 
254
256
  it("should fallback to original load method for non-virtual files", async () => {
255
257
  const loader = createLoader();
@@ -186,7 +186,7 @@ export function useMarimoKernelConnection(opts: {
186
186
  return;
187
187
 
188
188
  case "completion-result":
189
- AUTOCOMPLETER.resolve(msg.data.completion_id as RequestId, msg.data);
189
+ AUTOCOMPLETER.resolve(msg.data.completion_id, msg.data);
190
190
  return;
191
191
  case "function-call-result":
192
192
  FUNCTIONS_REGISTRY.resolve(msg.data.function_call_id, msg.data);
@@ -207,20 +207,14 @@ export function useMarimoKernelConnection(opts: {
207
207
  case "variables":
208
208
  setVariables(
209
209
  msg.data.variables.map((v) => ({
210
- name: v.name as VariableName,
210
+ name: v.name,
211
211
  declaredBy: v.declared_by,
212
212
  usedBy: v.used_by,
213
213
  })),
214
214
  );
215
- filterDatasetsFromVariables(
216
- msg.data.variables.map((v) => v.name as VariableName),
217
- );
218
- filterDataSourcesFromVariables(
219
- msg.data.variables.map((v) => v.name as VariableName),
220
- );
221
- filterStorageFromVariables(
222
- msg.data.variables.map((v) => v.name as VariableName),
223
- );
215
+ filterDatasetsFromVariables(msg.data.variables.map((v) => v.name));
216
+ filterDataSourcesFromVariables(msg.data.variables.map((v) => v.name));
217
+ filterStorageFromVariables(msg.data.variables.map((v) => v.name));
224
218
  return;
225
219
  case "variable-values":
226
220
  setMetadata(
@@ -30,6 +30,8 @@ function createConnectionTransport(
30
30
  // Create a connection transport using the ReconnectingWebSocket from partysocket
31
31
  // This handles reconnecting when the connection is lost.
32
32
  const urlProvider = options.url; // We don't call the URL provider now since it may change (i.e. if the runtime redirects)
33
+ // Cast needed: ReconnectingWebSocket types readyState as `number`
34
+ // but IConnectionTransport expects `0 | 1 | 2 | 3`
33
35
  return new ReconnectingWebSocket(urlProvider, undefined, {
34
36
  // We don't want Infinity retries
35
37
  maxRetries: 10,
@@ -38,7 +40,7 @@ function createConnectionTransport(
38
40
  // long timeout -- the server can become slow when many notebooks
39
41
  // are open.
40
42
  connectionTimeout: 10_000,
41
- });
43
+ }) as unknown as IConnectionTransport;
42
44
  }
43
45
 
44
46
  /**
@@ -15,6 +15,7 @@
15
15
  border: 1px solid var(--gray-4);
16
16
 
17
17
  @apply divide-y divide-(--gray-5);
18
+
18
19
  &:hover {
19
20
  border-color: var(--gray-6);
20
21
  }
@@ -98,9 +99,31 @@
98
99
 
99
100
  /* Special case for particular components */
100
101
 
101
- .output-area:has(> .output > marimo-ui-element > marimo-table) {
102
+ .output-area:has(
103
+ > .output:only-child > marimo-ui-element:only-child > marimo-table
104
+ ) {
105
+ padding: 0 0 5px;
102
106
  max-height: none;
103
107
  overflow: hidden;
108
+
109
+ /* Flush table: remove border and configure edge padding via CSS variable */
110
+ --marimo-table-edge-padding: 0.75rem;
111
+
112
+ marimo-table::part(table-tabs) {
113
+ margin-top: 0.25rem;
114
+ border: none;
115
+ border-radius: 0;
116
+ border-top-left-radius: 9px;
117
+ }
118
+
119
+ marimo-table::part(table-wrapper) {
120
+ border: none;
121
+ border-radius: 0;
122
+ }
123
+
124
+ marimo-table::part(table-footer) {
125
+ padding-inline: 0.25rem;
126
+ }
104
127
  }
105
128
 
106
129
  & > :first-child {
@@ -364,6 +387,7 @@
364
387
  border-top-left-radius: 9px;
365
388
  border-top-right-radius: 9px;
366
389
  }
390
+
367
391
  div[data-ai-input-open="true"] .cm-editor {
368
392
  border-top-left-radius: 0;
369
393
  border-top-right-radius: 0;
@@ -148,46 +148,72 @@
148
148
  --shadow-xxs: 0px 0px 2px 0px var(--base-shadow-darker);
149
149
 
150
150
  /* biome-ignore format: definition needs to be oneline or breaks variants */
151
- --shadow-xs: 1px 1px 2px 0px var(--base-shadow), 0px 0px 2px 0px hsl(0deg 0% 25% / var(--base-shadow-opacity));
151
+ --shadow-xs:
152
+ 1px 1px 2px 0px var(--base-shadow),
153
+ 0px 0px 2px 0px hsl(0deg 0% 25% / var(--base-shadow-opacity));
152
154
 
153
155
  /* biome-ignore format: definition needs to be oneline or breaks variants */
154
- --shadow-sm: 2px 2px 2px 0px var(--base-shadow), 0px 0px 2px 0px hsl(0deg 0% 25% / var(--base-shadow-opacity));
156
+ --shadow-sm:
157
+ 2px 2px 2px 0px var(--base-shadow),
158
+ 0px 0px 2px 0px hsl(0deg 0% 25% / var(--base-shadow-opacity));
155
159
 
156
160
  /* biome-ignore format: definition needs to be oneline or breaks variants */
157
- --shadow-md: 4px 4px 4px 0px var(--base-shadow), 0 0px 4px 0px hsl(0deg 0% 60% / var(--base-shadow-opacity));
161
+ --shadow-md:
162
+ 4px 4px 4px 0px var(--base-shadow),
163
+ 0 0px 4px 0px hsl(0deg 0% 60% / var(--base-shadow-opacity));
158
164
 
159
165
  /* biome-ignore format: definition needs to be oneline or breaks variants */
160
- --shadow-lg: 5px 6px 4px 0px var(--base-shadow), 0 0px 4px 0px hsl(0deg 0% 75% / var(--base-shadow-opacity));
166
+ --shadow-lg:
167
+ 5px 6px 4px 0px var(--base-shadow),
168
+ 0 0px 4px 0px hsl(0deg 0% 75% / var(--base-shadow-opacity));
161
169
 
162
170
  /* biome-ignore format: definition needs to be oneline or breaks variants */
163
- --shadow-xl: 8px 9px 4px 0px var(--base-shadow), 0 0px 6px 0px hsl(0deg 0% 85% / var(--base-shadow-opacity));
171
+ --shadow-xl:
172
+ 8px 9px 4px 0px var(--base-shadow),
173
+ 0 0px 6px 0px hsl(0deg 0% 85% / var(--base-shadow-opacity));
164
174
 
165
175
  /* biome-ignore format: definition needs to be oneline or breaks variants */
166
- --shadow-2xl: 10px 12px 10px 0px var(--base-shadow), 0 0px 8px 0px hsl(0deg 0% 90% / var(--base-shadow-opacity));
176
+ --shadow-2xl:
177
+ 10px 12px 10px 0px var(--base-shadow),
178
+ 0 0px 8px 0px hsl(0deg 0% 90% / var(--base-shadow-opacity));
167
179
 
168
180
  /* biome-ignore format: definition needs to be oneline or breaks variants */
169
- --shadow-xs-solid: 1px 1px 0px 0px var(--base-shadow-darker), 0px 0px 2px 0px hsl(0deg 0% 50% / 20%);
181
+ --shadow-xs-solid:
182
+ 1px 1px 0px 0px var(--base-shadow-darker),
183
+ 0px 0px 2px 0px hsl(0deg 0% 50% / 20%);
170
184
 
171
185
  /* biome-ignore format: definition needs to be oneline or breaks variants */
172
- --shadow-sm-solid: 2px 2px 0px 0px var(--base-shadow-darker), 0px 0px 2px 0px hsl(0deg 0% 50% / 20%);
186
+ --shadow-sm-solid:
187
+ 2px 2px 0px 0px var(--base-shadow-darker),
188
+ 0px 0px 2px 0px hsl(0deg 0% 50% / 20%);
173
189
 
174
190
  /* biome-ignore format: definition needs to be oneline or breaks variants */
175
- --shadow-md-solid: 4px 4px 0px 0px var(--base-shadow-darker), 0 0px 2px 0px hsl(0deg 0% 60% / 50%);
191
+ --shadow-md-solid:
192
+ 4px 4px 0px 0px var(--base-shadow-darker),
193
+ 0 0px 2px 0px hsl(0deg 0% 60% / 50%);
176
194
 
177
195
  /* biome-ignore format: definition needs to be oneline or breaks variants */
178
- --shadow-lg-solid: 5px 6px 0px 0px var(--base-shadow-darker), 0 0px 4px 0px hsl(0deg 0% 75% / 50%);
196
+ --shadow-lg-solid:
197
+ 5px 6px 0px 0px var(--base-shadow-darker),
198
+ 0 0px 4px 0px hsl(0deg 0% 75% / 50%);
179
199
 
180
200
  /* biome-ignore format: definition needs to be oneline or breaks variants */
181
- --shadow-xl-solid: 7px 8px 0px 0px var(--base-shadow-darker), 0 0px 4px 0px hsl(0deg 0% 85% / 50%);
201
+ --shadow-xl-solid:
202
+ 7px 8px 0px 0px var(--base-shadow-darker),
203
+ 0 0px 4px 0px hsl(0deg 0% 85% / 50%);
182
204
 
183
205
  /* biome-ignore format: definition needs to be oneline or breaks variants */
184
- --shadow-2xl-solid: 10px 12px 0px 0px var(--base-shadow-darker), 0 0px 8px 0px hsl(0deg 0% 90% / 50%);
206
+ --shadow-2xl-solid:
207
+ 10px 12px 0px 0px var(--base-shadow-darker),
208
+ 0 0px 8px 0px hsl(0deg 0% 90% / 50%);
185
209
 
186
210
  /* Solid shadows with lighter shade color */
187
211
 
188
212
  /* biome-ignore format: definition needs to be oneline or breaks variants */
189
- --shadow-sm-solid-shade: 2px 2px 0px 0px var(--base-shadow), 0px 0px 2px 0px hsl(0deg 0% 50% / 20%);
213
+ --shadow-sm-solid-shade:
214
+ 2px 2px 0px 0px var(--base-shadow), 0px 0px 2px 0px hsl(0deg 0% 50% / 20%);
190
215
 
191
216
  /* biome-ignore format: definition needs to be oneline or breaks variants */
192
- --shadow-md-solid-shade: 4px 4px 0px 0px var(--base-shadow), 0 0px 2px 0px hsl(0deg 0% 60% / 50%);
217
+ --shadow-md-solid-shade:
218
+ 4px 4px 0px 0px var(--base-shadow), 0 0px 2px 0px hsl(0deg 0% 60% / 50%);
193
219
  }
package/src/css/table.css CHANGED
@@ -1,5 +1,22 @@
1
1
  @reference "../css/globals.css";
2
2
 
3
+ /* Edge padding for flush tables (--marimo-table-edge-padding inherits through shadow DOM) */
4
+ [part="table-wrapper"] th:first-child {
5
+ padding-left: var(--marimo-table-edge-padding, 0.5rem);
6
+ }
7
+
8
+ [part="table-wrapper"] th:last-child {
9
+ padding-right: var(--marimo-table-edge-padding, 0.5rem);
10
+ }
11
+
12
+ [part="table-wrapper"] td:first-child {
13
+ padding-left: var(--marimo-table-edge-padding, 0.375rem);
14
+ }
15
+
16
+ [part="table-wrapper"] td:last-child {
17
+ padding-right: var(--marimo-table-edge-padding, 0.375rem);
18
+ }
19
+
3
20
  .markdown table,
4
21
  table.dataframe {
5
22
  display: block;
@@ -1,11 +1,12 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
- import {
4
- Accordion,
5
- AccordionContent,
6
- AccordionItem,
7
- AccordionTrigger,
8
- } from "@radix-ui/react-accordion";
3
+ import { Accordion as AccordionPrimitive } from "radix-ui";
4
+
5
+ const Accordion = AccordionPrimitive.Root;
6
+ const AccordionContent = AccordionPrimitive.Content;
7
+ const AccordionItem = AccordionPrimitive.Item;
8
+ const AccordionTrigger = AccordionPrimitive.Trigger;
9
+
9
10
  import type { JSX } from "react";
10
11
  import { ZodError } from "zod";
11
12
  import { EmotionCacheProvider } from "@/components/editor/output/EmotionCacheProvider";
@@ -1,6 +1,9 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
- import type { CheckedState } from "@radix-ui/react-checkbox";
3
+ import type { Checkbox as CheckboxPrimitive } from "radix-ui";
4
+
5
+ type CheckedState = CheckboxPrimitive.CheckedState;
6
+
4
7
  import { type JSX, useId } from "react";
5
8
  import { z } from "zod";
6
9
  import { Checkbox } from "../../components/ui/checkbox";
@@ -1,7 +1,10 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
3
  import glideCss from "@glideapps/glide-data-grid/dist/index.css?inline";
4
- import { TooltipProvider } from "@radix-ui/react-tooltip";
4
+ import { Tooltip } from "radix-ui";
5
+
6
+ const TooltipProvider = Tooltip.Provider;
7
+
5
8
  import React, { useState } from "react";
6
9
  import { z } from "zod";
7
10
  import { inferFieldTypes } from "@/components/data-table/columns";
@@ -73,8 +76,10 @@ export const DataEditorPlugin = createPlugin<Edits>("marimo-data-editor", {
73
76
  );
74
77
  });
75
78
 
76
- interface Props
77
- extends Omit<DataEditorProps<object>, "data" | "onAddEdits" | "onAddRows"> {
79
+ interface Props extends Omit<
80
+ DataEditorProps<object>,
81
+ "data" | "onAddEdits" | "onAddRows"
82
+ > {
78
83
  data: TableData<object>;
79
84
  edits: Edits;
80
85
  onEdits: Setter<Edits>;
@@ -1,7 +1,10 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
3
  import { Provider as SlotzProvider } from "@marimo-team/react-slotz";
4
- import { TooltipProvider } from "@radix-ui/react-tooltip";
4
+ import { Tooltip } from "radix-ui";
5
+
6
+ const TooltipProvider = Tooltip.Provider;
7
+
5
8
  import type {
6
9
  ColumnFiltersState,
7
10
  OnChangeFn,
@@ -763,6 +766,7 @@ export const LoadingDataTableComponent = memo(
763
766
  {props.showChartBuilder ? (
764
767
  <TablePanel
765
768
  displayHeader={displayHeader}
769
+ onCloseChartBuilder={() => setDisplayHeader(false)}
766
770
  data={data?.rows || []}
767
771
  columns={props.totalColumns}
768
772
  totalRows={props.totalRows}
@@ -80,8 +80,7 @@ export const FormPlugin = createPlugin("marimo-form")
80
80
  });
81
81
 
82
82
  export interface FormWrapperProps<T>
83
- extends Omit<Data, "elementId">,
84
- Functions {
83
+ extends Omit<Data, "elementId">, Functions {
85
84
  children: React.ReactNode;
86
85
  currentValue: T;
87
86
  newValue: T;
@@ -1,6 +1,9 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
- import { TooltipProvider } from "@radix-ui/react-tooltip";
3
+ import { Tooltip } from "radix-ui";
4
+
5
+ const TooltipProvider = Tooltip.Provider;
6
+
4
7
  import { act, render, screen, waitFor } from "@testing-library/react";
5
8
  import { Provider } from "jotai";
6
9
  import { beforeAll, describe, expect, it, vi } from "vitest";
@@ -9,6 +9,35 @@ import { store } from "@/core/state/jotai";
9
9
  import type { IPluginProps } from "../../types";
10
10
  import { SliderPlugin } from "../SliderPlugin";
11
11
 
12
+ vi.mock("@/components/ui/slider", () => ({
13
+ Slider: ({
14
+ disabled,
15
+ onValueChange,
16
+ onValueCommit,
17
+ value,
18
+ }: {
19
+ disabled?: boolean;
20
+ onValueChange?: (value: number[]) => void;
21
+ onValueCommit?: (value: number[]) => void;
22
+ value: number[];
23
+ }) => (
24
+ <div>
25
+ <button
26
+ aria-label="Slider change"
27
+ disabled={disabled}
28
+ onClick={() => onValueChange?.([value[0] + 1])}
29
+ type="button"
30
+ />
31
+ <button
32
+ aria-label="Slider commit"
33
+ disabled={disabled}
34
+ onClick={() => onValueCommit?.(value)}
35
+ type="button"
36
+ />
37
+ </div>
38
+ ),
39
+ }));
40
+
12
41
  SetupMocks.resizeObserver();
13
42
 
14
43
  describe("SliderPlugin", () => {
@@ -51,46 +80,45 @@ describe("SliderPlugin", () => {
51
80
  const plugin = new SliderPlugin();
52
81
  const setValue = vi.fn();
53
82
  const props = createProps(false, false, setValue);
54
- const { container } = render(plugin.render(props));
83
+ const { getByRole } = render(plugin.render(props));
55
84
 
56
85
  act(() => {
57
86
  vi.advanceTimersByTime(0);
58
87
  });
59
88
 
60
- const thumb = container.querySelector('[role="slider"]');
61
- expect(thumb).toBeTruthy();
89
+ const changeButton = getByRole("button", { name: "Slider change" });
62
90
 
63
- // Radix UI Slider updates on keyboard ArrowRight/ArrowLeft
64
91
  act(() => {
65
- (thumb as HTMLElement)?.focus();
66
- fireEvent.keyDown(thumb!, { key: "ArrowRight" });
92
+ fireEvent.click(changeButton);
67
93
  });
68
94
 
69
95
  expect(setValue).toHaveBeenCalledWith(6);
70
96
  });
71
97
 
72
- it("slider does not trigger setValue immediately when debounce is true", () => {
98
+ it("slider waits until commit before calling setValue when debounce is true", () => {
73
99
  const plugin = new SliderPlugin();
74
100
  const setValue = vi.fn();
75
101
  const props = createProps(true, false, setValue);
76
- const { container } = render(plugin.render(props));
102
+ const { getByRole } = render(plugin.render(props));
77
103
 
78
104
  act(() => {
79
105
  vi.advanceTimersByTime(0);
80
106
  });
81
107
 
82
- const thumb = container.querySelector('[role="slider"]');
108
+ const changeButton = getByRole("button", { name: "Slider change" });
109
+ const commitButton = getByRole("button", { name: "Slider commit" });
83
110
 
84
111
  act(() => {
85
- (thumb as HTMLElement)?.focus();
86
- // Simulate just a programmatic change that Radix would trigger via pointer move
87
- // which fires onValueChange but not onValueCommit yet
88
- // Because we can't easily separated Radix's internal pointer events in jsdom, we
89
- // test the main issue: editable input. We can trust Radix's onValueChange vs onValueCommit.
112
+ fireEvent.click(changeButton);
90
113
  });
91
114
 
92
- // We verified above that NumberField works when debounce=true
93
115
  expect(setValue).not.toHaveBeenCalled();
116
+
117
+ act(() => {
118
+ fireEvent.click(commitButton);
119
+ });
120
+
121
+ expect(setValue).toHaveBeenCalledWith(6);
94
122
  });
95
123
 
96
124
  it("editable input triggers setValue immediately even when slider debounce is true", () => {
@@ -4,7 +4,6 @@
4
4
  import type { AnyWidget } from "@anywidget/types";
5
5
  import { useEffect, useRef } from "react";
6
6
  import { z } from "zod";
7
- import { RANDOM_ID_ATTR } from "@/core/dom/ui-element-constants";
8
7
  import { useAsyncData } from "@/hooks/useAsyncData";
9
8
  import type { HTMLElementNotDerivedFromRef } from "@/hooks/useEventListener";
10
9
  import { createPlugin } from "@/plugins/core/builder";
@@ -145,18 +144,10 @@ const AnyWidgetSlot = (props: IPluginProps<ModelIdRef, Data>) => {
145
144
  return <ErrorBanner error={error} />;
146
145
  }
147
146
 
148
- // Find the closest parent element with an attribute of `random-id`
149
- const randomId = props.host
150
- .closest(`[${RANDOM_ID_ATTR}]`)
151
- ?.getAttribute(RANDOM_ID_ATTR);
152
- const key = randomId ?? jsUrl;
153
-
154
147
  return (
155
148
  <LoadedSlot
156
- // Use the a key to force a re-render when the randomId (or jsUrl) changes
157
- // Plugins may be stateful and we cannot make assumptions that we won't be
158
- // so it is safer to just re-render.
159
- key={key}
149
+ // Force remount when the widget module or model changes (cell re-run).
150
+ key={`${jsHash}:${modelId}`}
160
151
  widget={jsModule.default}
161
152
  modelId={modelId}
162
153
  host={host}
@@ -2,7 +2,10 @@
2
2
 
3
3
  import { type UIMessage, useChat } from "@ai-sdk/react";
4
4
  import { ChatBubbleIcon } from "@radix-ui/react-icons";
5
- import { PopoverAnchor } from "@radix-ui/react-popover";
5
+ import { Popover as PopoverPrimitive } from "radix-ui";
6
+
7
+ const PopoverAnchor = PopoverPrimitive.Anchor;
8
+
6
9
  import type { ReactCodeMirrorRef } from "@uiw/react-codemirror";
7
10
  import {
8
11
  createUIMessageStreamResponse,
@@ -44,16 +44,14 @@ describe("renderZodSchema", () => {
44
44
  [...TransformTypeSchema.options],
45
45
  (z) => getUnionLiteral(z).value,
46
46
  );
47
- it.each(
48
- Object.entries(options),
49
- )("should render a form %s", (name, schema: z.ZodType<
50
- unknown,
51
- FieldValues
52
- >) => {
53
- const expected = render(<Subject schema={schema} />);
47
+ it.each(Object.entries(options))(
48
+ "should render a form %s",
49
+ (name, schema: z.ZodType<unknown, FieldValues>) => {
50
+ const expected = render(<Subject schema={schema} />);
54
51
 
55
- expect(expected.asFragment()).toMatchSnapshot();
56
- });
52
+ expect(expected.asFragment()).toMatchSnapshot();
53
+ },
54
+ );
57
55
  });
58
56
 
59
57
  const options = [
@@ -15,7 +15,11 @@ import { useDeepCompareMemoize } from "@/hooks/useDeepCompareMemoize";
15
15
  import { useScript } from "@/hooks/useScript";
16
16
  import { Arrays } from "@/utils/arrays";
17
17
  import { Objects } from "@/utils/objects";
18
- import { createParser, type PlotlyTemplateParser } from "./parse-from-template";
18
+ import {
19
+ extractClickSelection,
20
+ extractIndices,
21
+ extractPoints,
22
+ } from "./selection";
19
23
  import { usePlotlyLayout } from "./usePlotlyLayout";
20
24
 
21
25
  interface Data {
@@ -23,12 +27,9 @@ interface Data {
23
27
  config: Partial<Plotly.Config>;
24
28
  }
25
29
 
26
- type AxisName = string;
27
- type AxisDatum = unknown;
28
-
29
30
  type T =
30
31
  | {
31
- points?: Record<AxisName, AxisDatum>[] | Plotly.PlotDatum[];
32
+ points?: Record<string, unknown>[] | Plotly.PlotDatum[];
32
33
  indices?: number[];
33
34
  range?: {
34
35
  x?: number[];
@@ -202,19 +203,13 @@ export const PlotlyComponent = memo(
202
203
  if (!evt) {
203
204
  return;
204
205
  }
205
- // Only handle clicks for chart types where box/lasso selection
206
- // (onSelected) doesn't work, such as heatmaps.
207
- const isHeatmap = evt.points.some(
208
- (point) => point.data?.type === "heatmap",
209
- );
210
- if (!isHeatmap) {
206
+
207
+ const clickSelection = extractClickSelection(evt);
208
+ if (!clickSelection) {
211
209
  return;
212
210
  }
213
- setValue((prev) => ({
214
- ...prev,
215
- points: extractPoints(evt.points),
216
- indices: evt.points.map((point) => point.pointIndex),
217
- }));
211
+
212
+ setValue((prev) => ({ ...prev, ...clickSelection }));
218
213
  })}
219
214
  onSelected={useEvent((evt: Readonly<Plotly.PlotSelectionEvent>) => {
220
215
  if (!evt) {
@@ -226,7 +221,7 @@ export const PlotlyComponent = memo(
226
221
  selections:
227
222
  "selections" in evt ? (evt.selections as unknown[]) : [],
228
223
  points: extractPoints(evt.points),
229
- indices: evt.points.map((point) => point.pointIndex),
224
+ indices: extractIndices(evt.points),
230
225
  range: evt.range,
231
226
  }));
232
227
  })}
@@ -241,54 +236,3 @@ export const PlotlyComponent = memo(
241
236
  },
242
237
  );
243
238
  PlotlyComponent.displayName = "PlotlyComponent";
244
-
245
- /**
246
- * This is a hack to extract the points with their original keys,
247
- * instead of the ones that Plotly uses internally,
248
- * by using the hovertemplate.
249
- */
250
- const STANDARD_POINT_KEYS: string[] = [
251
- "x",
252
- "y",
253
- "z",
254
- "lat",
255
- "lon",
256
- "curveNumber",
257
- "pointNumber",
258
- "pointNumbers",
259
- "pointIndex",
260
- ];
261
-
262
- function extractPoints(
263
- points: Plotly.PlotDatum[],
264
- ): Record<AxisName, AxisDatum>[] {
265
- if (!points) {
266
- return [];
267
- }
268
-
269
- let parser: PlotlyTemplateParser | undefined;
270
-
271
- return points.map((point) => {
272
- const standardPointFields = Objects.pick(point, STANDARD_POINT_KEYS);
273
-
274
- // Get the first hovertemplate
275
- const hovertemplate = Array.isArray(point.data.hovertemplate)
276
- ? point.data.hovertemplate[0]
277
- : point.data.hovertemplate;
278
-
279
- // For chart types with standard point keys (e.g. heatmaps),
280
- // or when there's no hovertemplate, pick keys directly from the point.
281
- if (!hovertemplate || point.data?.type === "heatmap") {
282
- return standardPointFields;
283
- }
284
-
285
- // Update or create a parser
286
- parser = parser
287
- ? parser.update(hovertemplate)
288
- : createParser(hovertemplate);
289
- return {
290
- ...standardPointFields,
291
- ...parser.parse(point),
292
- };
293
- });
294
- }