@marimo-team/frontend 0.20.5-dev28 → 0.20.5-dev33

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 (71) hide show
  1. package/dist/assets/{CellStatus-Bf3_zqWp.js → CellStatus-rawm41sF.js} +1 -1
  2. package/dist/assets/{ConnectedDataExplorerComponent-BWGS1xUt.js → ConnectedDataExplorerComponent-BmrDShEI.js} +1 -1
  3. package/dist/assets/{ImperativeModal-l3NQQITL.js → ImperativeModal-BvRpI5NU.js} +1 -1
  4. package/dist/assets/{JsonOutput-CGdzBqS1.js → JsonOutput-D8vxudTc.js} +1 -1
  5. package/dist/assets/{MarimoErrorOutput-Bms-kX7B.js → MarimoErrorOutput-ThxhEC9x.js} +1 -1
  6. package/dist/assets/{RenderHTML-DpbhvZnj.js → RenderHTML-Ci0Pb1aU.js} +1 -1
  7. package/dist/assets/{add-cell-with-ai-XG5BIwhn.js → add-cell-with-ai-C9Xp-2Lu.js} +1 -1
  8. package/dist/assets/{add-connection-dialog-DbCfepEj.js → add-connection-dialog-C0_z2T_b.js} +1 -1
  9. package/dist/assets/{agent-panel-D16-GLG-.js → agent-panel-CFmSkdtw.js} +1 -1
  10. package/dist/assets/ai-model-dropdown-DJoBltN-.js +5 -0
  11. package/dist/assets/{app-config-button-CI0WOSLz.js → app-config-button-Cw2wXNR2.js} +1 -1
  12. package/dist/assets/{cache-panel-DrOCfrS9.js → cache-panel-B4TWdLE9.js} +1 -1
  13. package/dist/assets/{cell-editor-BU2bXyD1.js → cell-editor-BoDTqwYs.js} +1 -1
  14. package/dist/assets/{cell-link-CApHIAZF.js → cell-link-TWNu2IkO.js} +1 -1
  15. package/dist/assets/{chat-display-DwFyJBVB.js → chat-display-Dwlgqtli.js} +1 -1
  16. package/dist/assets/{chat-panel-CivqPgLR.js → chat-panel-DP052nQF.js} +1 -1
  17. package/dist/assets/{column-preview-BTufLMhz.js → column-preview-CPJFpq_q.js} +1 -1
  18. package/dist/assets/{command-DLq1SsAO.js → command-DQqPawJf.js} +1 -1
  19. package/dist/assets/{command-palette-BYaD9kOd.js → command-palette-BM1QAZTW.js} +1 -1
  20. package/dist/assets/{common-DC4lyug7.js → common-Df9UcCs1.js} +1 -1
  21. package/dist/assets/context-CRmPPhx9.js +1 -0
  22. package/dist/assets/{context-aware-panel-D7L-J6dq.js → context-aware-panel-Bs4Vepkp.js} +1 -1
  23. package/dist/assets/{dependency-graph-panel-DHjX2IAi.js → dependency-graph-panel-DddysMUS.js} +1 -1
  24. package/dist/assets/dist-SDO5K7hA.js +3 -0
  25. package/dist/assets/{documentation-panel-x4uNnKYg.js → documentation-panel-Bs1zlxdM.js} +1 -1
  26. package/dist/assets/edit-page-D7VD6LD4.js +13 -0
  27. package/dist/assets/{error-panel-pHxYpjX_.js → error-panel-B_vII0VN.js} +1 -1
  28. package/dist/assets/{field-jeUVnXuU.js → field-D-izY3ud.js} +1 -1
  29. package/dist/assets/{file-explorer-panel-CraYsOVj.js → file-explorer-panel-BIzyNOVs.js} +1 -1
  30. package/dist/assets/{form-KYhtvrIF.js → form-DrpSpDea.js} +1 -1
  31. package/dist/assets/{gallery-page-mozL4wJd.js → gallery-page-BrljeBFe.js} +1 -1
  32. package/dist/assets/{glide-data-editor-BhnSrNBl.js → glide-data-editor-8kdd_nPE.js} +1 -1
  33. package/dist/assets/{home-page-fzpZMqwS.js → home-page-O_c6IiAp.js} +1 -1
  34. package/dist/assets/{hooks-YZ8YquEB.js → hooks-Z1j4FmRH.js} +1 -1
  35. package/dist/assets/index-B7vfm6Sw.js +38 -0
  36. package/dist/assets/input-GLbHj4DF.js +1 -0
  37. package/dist/assets/layout-DQhzfSJn.js +5 -0
  38. package/dist/assets/{logs-panel-D_BejkBp.js → logs-panel-BKhNdCxG.js} +1 -1
  39. package/dist/assets/{name-cell-input-tnyN_rNq.js → name-cell-input-DOyCua0o.js} +1 -1
  40. package/dist/assets/{packages-panel-BfOynji5.js → packages-panel-n8Ssm9M8.js} +1 -1
  41. package/dist/assets/{panels-C8RuHp78.js → panels-B4wExe_l.js} +1 -1
  42. package/dist/assets/{run-page-Cg-HjFtb.js → run-page-BYEyHIaG.js} +1 -1
  43. package/dist/assets/{scratchpad-panel-BombralT.js → scratchpad-panel-BRTSBHvd.js} +1 -1
  44. package/dist/assets/{secrets-panel-Cz3H7Kcc.js → secrets-panel-DAnccD-S.js} +1 -1
  45. package/dist/assets/{session-panel-msqiNt1Z.js → session-panel-k6_Gni4X.js} +1 -1
  46. package/dist/assets/{snippets-panel-Beh7h7mz.js → snippets-panel-mGo3M47p.js} +1 -1
  47. package/dist/assets/{tracing-DaGZb1gK.js → tracing-DTCuFbVV.js} +1 -1
  48. package/dist/assets/{tracing-panel-DvvJq5B5.js → tracing-panel-B1EJu6-W.js} +2 -2
  49. package/dist/assets/useBoolean-2eWc7NX-.js +1 -0
  50. package/dist/assets/{useCellActionButton-CKUAt6Sl.js → useCellActionButton-CJ_LAoma.js} +1 -1
  51. package/dist/assets/{useDateFormatter-DfEfyPT1.js → useDateFormatter-DOoVZUts.js} +1 -1
  52. package/dist/assets/{useDependencyPanelTab-CH3r9bC-.js → useDependencyPanelTab-nuk9kUr_.js} +1 -1
  53. package/dist/assets/{useNotebookActions-CXRecmhh.js → useNotebookActions-Bh8YMrlo.js} +1 -1
  54. package/dist/assets/{useNumberFormatter-DQd-h5xR.js → useNumberFormatter-BXZcbTzH.js} +1 -1
  55. package/dist/assets/usePress-G817DpBk.js +7 -0
  56. package/dist/assets/{write-secret-modal-Dj4Ncj4m.js → write-secret-modal-DOyKonZB.js} +1 -1
  57. package/dist/index.html +20 -20
  58. package/package.json +9 -9
  59. package/src/plugins/impl/mpl-interactive/MplInteractivePlugin.tsx +309 -0
  60. package/src/plugins/impl/mpl-interactive/__tests__/mpl-websocket-shim.test.ts +110 -0
  61. package/src/plugins/impl/mpl-interactive/mpl-websocket-shim.ts +57 -0
  62. package/src/plugins/plugins.ts +2 -0
  63. package/dist/assets/ai-model-dropdown-oin5Fuov.js +0 -5
  64. package/dist/assets/context-CRApIvpB.js +0 -1
  65. package/dist/assets/dist-BL52mbxW.js +0 -3
  66. package/dist/assets/edit-page-JEf4izAb.js +0 -13
  67. package/dist/assets/index-BqLC0w8B.js +0 -38
  68. package/dist/assets/input-BwUS1Mg1.js +0 -1
  69. package/dist/assets/layout-BPSHGKRG.js +0 -5
  70. package/dist/assets/useBoolean-NLsvxjyM.js +0 -1
  71. package/dist/assets/usePress-DcdVsIfA.js +0 -7
@@ -0,0 +1,7 @@
1
+ import{s as tt}from"./chunk-LvLJmgfZ.js";import{t as nt}from"./react-Bj1aDYRI.js";import{t as rt}from"./react-dom-CSu739Rf.js";import{n as it}from"./clsx-A78R3nYl.js";import{n as ot}from"./SSRProvider-CwqN9FWV.js";var d=tt(nt(),1),T=typeof document<"u"?d.useLayoutEffect:()=>{};function at(e){let[t,n]=(0,d.useState)(e),a=(0,d.useRef)(t),i=(0,d.useRef)(null),s=(0,d.useRef)(()=>{if(!i.current)return;let l=i.current.next();if(l.done){i.current=null;return}a.current===l.value?s.current():n(l.value)});return T(()=>{a.current=t,i.current&&s.current()}),[t,(0,d.useCallback)(l=>{i.current=l(a.current),s.current()},[s])]}var st=!!(typeof window<"u"&&window.document&&window.document.createElement),x=new Map,G;typeof FinalizationRegistry<"u"&&(G=new FinalizationRegistry(e=>{x.delete(e)}));function Se(e){let[t,n]=(0,d.useState)(e),a=(0,d.useRef)(null),i=ot(t),s=(0,d.useRef)(null);if(G&&G.register(s,i),st){let l=x.get(i);l&&!l.includes(a)?l.push(a):x.set(i,[a])}return T(()=>{let l=i;return()=>{G&&G.unregister(s),x.delete(l)}},[i]),(0,d.useEffect)(()=>{let l=a.current;return l&&n(l),()=>{l&&(a.current=null)}}),i}function lt(e,t){if(e===t)return e;let n=x.get(e);if(n)return n.forEach(i=>i.current=t),t;let a=x.get(t);return a?(a.forEach(i=>i.current=e),e):t}function ut(e=[]){let t=Se(),[n,a]=at(t),i=(0,d.useCallback)(()=>{a(function*(){yield t,yield document.getElementById(t)?t:void 0})},[t,a]);return T(i,[t,i,...e]),n}function te(...e){return(...t)=>{for(let n of e)typeof n=="function"&&n(...t)}}var h=e=>(e==null?void 0:e.ownerDocument)??document,O=e=>e&&"window"in e&&e.window===e?e:h(e).defaultView||window;function ct(e){return typeof e=="object"&&!!e&&"nodeType"in e&&typeof e.nodeType=="number"}function dt(e){return ct(e)&&e.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&"host"in e}var ft=!1;function W(){return ft}function E(e,t){if(!W())return t&&e?e.contains(t):!1;if(!e||!t)return!1;let n=t;for(;n!==null;){if(n===e)return!0;n=n.tagName==="SLOT"&&n.assignedSlot?n.assignedSlot.parentNode:dt(n)?n.host:n.parentNode}return!1}var ne=(e=document)=>{var n;if(!W())return e.activeElement;let t=e.activeElement;for(;t&&"shadowRoot"in t&&((n=t.shadowRoot)!=null&&n.activeElement);)t=t.shadowRoot.activeElement;return t};function g(e){if(W()&&e.target instanceof Element&&e.target.shadowRoot){if("composedPath"in e)return e.composedPath()[0]??null;if("composedPath"in e.nativeEvent)return e.nativeEvent.composedPath()[0]??null}return e.target}function pt(e){if(!e)return!1;let t=e.getRootNode(),n=O(e);if(!(t instanceof n.Document||t instanceof n.ShadowRoot))return!1;let a=t.activeElement;return a!=null&&e.contains(a)}function Le(...e){return e.length===1&&e[0]?e[0]:t=>{let n=!1,a=e.map(i=>{let s=Ce(i,t);return n||(n=typeof s=="function"),s});if(n)return()=>{a.forEach((i,s)=>{typeof i=="function"?i():Ce(e[s],null)})}}}function Ce(e,t){if(typeof e=="function")return e(t);e!=null&&(e.current=t)}function re(...e){let t={...e[0]};for(let n=1;n<e.length;n++){let a=e[n];for(let i in a){let s=t[i],l=a[i];typeof s=="function"&&typeof l=="function"&&i[0]==="o"&&i[1]==="n"&&i.charCodeAt(2)>=65&&i.charCodeAt(2)<=90?t[i]=te(s,l):(i==="className"||i==="UNSAFE_className")&&typeof s=="string"&&typeof l=="string"?t[i]=it(s,l):i==="id"&&s&&l?t.id=lt(s,l):i==="ref"&&s&&l?t.ref=Le(s,l):t[i]=l===void 0?s:l}}return t}function z(e){if(gt())e.focus({preventScroll:!0});else{let t=yt(e);e.focus(),vt(t)}}var _=null;function gt(){if(_==null){_=!1;try{document.createElement("div").focus({get preventScroll(){return _=!0,!0}})}catch{}}return _}function yt(e){let t=e.parentNode,n=[],a=document.scrollingElement||document.documentElement;for(;t instanceof HTMLElement&&t!==a;)(t.offsetHeight<t.scrollHeight||t.offsetWidth<t.scrollWidth)&&n.push({element:t,scrollTop:t.scrollTop,scrollLeft:t.scrollLeft}),t=t.parentNode;return a instanceof HTMLElement&&n.push({element:a,scrollTop:a.scrollTop,scrollLeft:a.scrollLeft}),n}function vt(e){for(let{element:t,scrollTop:n,scrollLeft:a}of e)t.scrollTop=n,t.scrollLeft=a}function Y(e){var n;if(typeof window>"u"||window.navigator==null)return!1;let t=(n=window.navigator.userAgentData)==null?void 0:n.brands;return Array.isArray(t)&&t.some(a=>e.test(a.brand))||e.test(window.navigator.userAgent)}function ie(e){var t;return typeof window<"u"&&window.navigator!=null?e.test(((t=window.navigator.userAgentData)==null?void 0:t.platform)||window.navigator.platform):!1}function w(e){let t=null;return()=>(t??(t=e()),t)}var F=w(function(){return ie(/^Mac/i)}),Ae=w(function(){return ie(/^iPhone/i)}),oe=w(function(){return ie(/^iPad/i)||F()&&navigator.maxTouchPoints>1}),X=w(function(){return Ae()||oe()}),mt=w(function(){return F()||X()}),Me=w(function(){return Y(/AppleWebKit/i)&&!Ke()}),Ke=w(function(){return Y(/Chrome/i)}),ae=w(function(){return Y(/Android/i)}),bt=w(function(){return Y(/Firefox/i)}),ht=(0,d.createContext)({isNative:!0,open:Tt,useHref:e=>e});function se(){return(0,d.useContext)(ht)}function L(e,t,n=!0){var v;var a;let{metaKey:i,ctrlKey:s,altKey:l,shiftKey:p}=t;bt()&&(a=window.event)!=null&&((v=a.type)!=null&&v.startsWith("key"))&&e.target==="_blank"&&(F()?i=!0:s=!0);let y=Me()&&F()&&!oe()?new KeyboardEvent("keydown",{keyIdentifier:"Enter",metaKey:i,ctrlKey:s,altKey:l,shiftKey:p}):new MouseEvent("click",{metaKey:i,ctrlKey:s,altKey:l,shiftKey:p,detail:1,bubbles:!0,cancelable:!0});L.isOpening=n,z(e),e.dispatchEvent(y),L.isOpening=!1}L.isOpening=!1;function Et(e,t){if(e instanceof HTMLAnchorElement)t(e);else if(e.hasAttribute("data-href")){let n=document.createElement("a");n.href=e.getAttribute("data-href"),e.hasAttribute("data-target")&&(n.target=e.getAttribute("data-target")),e.hasAttribute("data-rel")&&(n.rel=e.getAttribute("data-rel")),e.hasAttribute("data-download")&&(n.download=e.getAttribute("data-download")),e.hasAttribute("data-ping")&&(n.ping=e.getAttribute("data-ping")),e.hasAttribute("data-referrer-policy")&&(n.referrerPolicy=e.getAttribute("data-referrer-policy")),e.appendChild(n),t(n),e.removeChild(n)}}function Tt(e,t){Et(e,n=>L(n,t))}function wt(e){let t=se().useHref(e.href??"");return{"data-href":e.href?t:void 0,"data-target":e.target,"data-rel":e.rel,"data-download":e.download,"data-ping":e.ping,"data-referrer-policy":e.referrerPolicy}}function Pt(e){let t=se().useHref((e==null?void 0:e.href)??"");return{href:e!=null&&e.href?t:void 0,target:e==null?void 0:e.target,rel:e==null?void 0:e.rel,download:e==null?void 0:e.download,ping:e==null?void 0:e.ping,referrerPolicy:e==null?void 0:e.referrerPolicy}}var k=new Map,le=new Set;function Ie(){if(typeof window>"u")return;function e(a){return"propertyName"in a}let t=a=>{let i=g(a);if(!e(a)||!i)return;let s=k.get(i);s||(s=new Set,k.set(i,s),i.addEventListener("transitioncancel",n,{once:!0})),s.add(a.propertyName)},n=a=>{let i=g(a);if(!e(a)||!i)return;let s=k.get(i);if(s&&(s.delete(a.propertyName),s.size===0&&(i.removeEventListener("transitioncancel",n),k.delete(i)),k.size===0)){for(let l of le)l();le.clear()}};document.body.addEventListener("transitionrun",t),document.body.addEventListener("transitionend",n)}typeof document<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",Ie):Ie());function kt(){for(let[e]of k)"isConnected"in e&&!e.isConnected&&k.delete(e)}function xe(e){requestAnimationFrame(()=>{kt(),k.size===0?e():le.add(e)})}function Oe(){let e=(0,d.useRef)(new Map),t=(0,d.useCallback)((i,s,l,p)=>{let y=p!=null&&p.once?(...v)=>{e.current.delete(l),l(...v)}:l;e.current.set(l,{type:s,eventTarget:i,fn:y,options:p}),i.addEventListener(s,y,p)},[]),n=(0,d.useCallback)((i,s,l,p)=>{var v;let y=((v=e.current.get(l))==null?void 0:v.fn)||l;i.removeEventListener(s,y,p),e.current.delete(l)},[]),a=(0,d.useCallback)(()=>{e.current.forEach((i,s)=>{n(i.eventTarget,i.type,s,i.options)})},[n]);return(0,d.useEffect)(()=>a,[a]),{addGlobalListener:t,removeGlobalListener:n,removeAllGlobalListeners:a}}var St=d.useInsertionEffect??T;function V(e){let t=(0,d.useRef)(null);return St(()=>{t.current=e},[e]),(0,d.useCallback)((...n)=>{let a=t.current;return a==null?void 0:a(...n)},[])}function Fe(e,t){T(()=>{if(e&&e.ref&&t)return e.ref.current=t.current,()=>{e.ref&&(e.ref.current=null)}})}function Ne(e){return e.pointerType===""&&e.isTrusted?!0:ae()&&e.pointerType?e.type==="click"&&e.buttons===1:e.detail===0&&!e.pointerType}function Re(e){return!ae()&&e.width===0&&e.height===0||e.width===1&&e.height===1&&e.pressure===0&&e.detail===0&&e.pointerType==="mouse"}var Lt=typeof Element<"u"&&"checkVisibility"in Element.prototype;function Ct(e){let t=O(e);if(!(e instanceof t.HTMLElement)&&!(e instanceof t.SVGElement))return!1;let{display:n,visibility:a}=e.style,i=n!=="none"&&a!=="hidden"&&a!=="collapse";if(i){let{getComputedStyle:s}=e.ownerDocument.defaultView,{display:l,visibility:p}=s(e);i=l!=="none"&&p!=="hidden"&&p!=="collapse"}return i}function At(e,t){return!e.hasAttribute("hidden")&&!e.hasAttribute("data-react-aria-prevent-focus")&&(e.nodeName==="DETAILS"&&t&&t.nodeName!=="SUMMARY"?e.hasAttribute("open"):!0)}function ue(e,t){return Lt?e.checkVisibility({visibilityProperty:!0})&&!e.closest("[data-react-aria-prevent-focus]"):e.nodeName!=="#comment"&&Ct(e)&&At(e,t)&&(!e.parentElement||ue(e.parentElement,e))}var ce=["input:not([disabled]):not([type=hidden])","select:not([disabled])","textarea:not([disabled])","button:not([disabled])","a[href]","area[href]","summary","iframe","object","embed","audio[controls]","video[controls]",'[contenteditable]:not([contenteditable^="false"])',"permission"],Mt=ce.join(":not([hidden]),")+",[tabindex]:not([disabled]):not([hidden])";ce.push('[tabindex]:not([tabindex="-1"]):not([disabled])');var Kt=ce.join(':not([hidden]):not([tabindex="-1"]),');function He(e){return e.matches(Mt)&&ue(e)&&!De(e)}function It(e){return e.matches(Kt)&&ue(e)&&!De(e)}function De(e){let t=e;for(;t!=null;){if(t instanceof t.ownerDocument.defaultView.HTMLElement&&t.inert)return!0;t=t.parentElement}return!1}function xt(e,t){if(t.has(e))throw TypeError("Cannot initialize the same private elements twice on an object")}function Ue(e,t,n){xt(e,t),t.set(e,n)}function de(e){let t=e;return t.nativeEvent=e,t.isDefaultPrevented=()=>t.defaultPrevented,t.isPropagationStopped=()=>t.cancelBubble,t.persist=()=>{},t}function Ge(e,t){Object.defineProperty(e,"target",{value:t}),Object.defineProperty(e,"currentTarget",{value:t})}function Ot(e){let t=(0,d.useRef)({isFocused:!1,observer:null});return T(()=>{let n=t.current;return()=>{n.observer&&(n.observer=(n.observer.disconnect(),null))}},[]),(0,d.useCallback)(n=>{let a=g(n);if(a instanceof HTMLButtonElement||a instanceof HTMLInputElement||a instanceof HTMLTextAreaElement||a instanceof HTMLSelectElement){t.current.isFocused=!0;let i=a;i.addEventListener("focusout",s=>{if(t.current.isFocused=!1,i.disabled){let l=de(s);e==null||e(l)}t.current.observer&&(t.current.observer.disconnect(),t.current.observer=null)},{once:!0}),t.current.observer=new MutationObserver(()=>{if(t.current.isFocused&&i.disabled){var s;(s=t.current.observer)==null||s.disconnect();let l=i===ne()?null:ne();i.dispatchEvent(new FocusEvent("blur",{relatedTarget:l})),i.dispatchEvent(new FocusEvent("focusout",{bubbles:!0,relatedTarget:l}))}}),t.current.observer.observe(i,{attributes:!0,attributeFilter:["disabled"]})}},[e])}var fe=!1;function Ft(e){for(;e&&!He(e);)e=e.parentElement;let t=O(e),n=t.document.activeElement;if(!n||n===e)return;fe=!0;let a=!1,i=m=>{(g(m)===n||a)&&m.stopImmediatePropagation()},s=m=>{(g(m)===n||a)&&(m.stopImmediatePropagation(),!e&&!a&&(a=!0,z(n),y()))},l=m=>{(g(m)===e||a)&&m.stopImmediatePropagation()},p=m=>{(g(m)===e||a)&&(m.stopImmediatePropagation(),a||(a=!0,z(n),y()))};t.addEventListener("blur",i,!0),t.addEventListener("focusout",s,!0),t.addEventListener("focusin",p,!0),t.addEventListener("focus",l,!0);let y=()=>{cancelAnimationFrame(v),t.removeEventListener("blur",i,!0),t.removeEventListener("focusout",s,!0),t.removeEventListener("focusin",p,!0),t.removeEventListener("focus",l,!0),fe=!1,a=!1},v=requestAnimationFrame(y);return y}var N="default",pe="",q=new WeakMap;function Nt(e){if(X()){if(N==="default"){let t=h(e);pe=t.documentElement.style.webkitUserSelect,t.documentElement.style.webkitUserSelect="none"}N="disabled"}else if(e instanceof HTMLElement||e instanceof SVGElement){let t="userSelect"in e.style?"userSelect":"webkitUserSelect";q.set(e,e.style[t]),e.style[t]="none"}}function ze(e){if(X()){if(N!=="disabled")return;N="restoring",setTimeout(()=>{xe(()=>{if(N==="restoring"){let t=h(e);t.documentElement.style.webkitUserSelect==="none"&&(t.documentElement.style.webkitUserSelect=pe||""),pe="",N="default"}})},300)}else if((e instanceof HTMLElement||e instanceof SVGElement)&&e&&q.has(e)){let t=q.get(e),n="userSelect"in e.style?"userSelect":"webkitUserSelect";e.style[n]==="none"&&(e.style[n]=t),e.getAttribute("style")===""&&e.removeAttribute("style"),q.delete(e)}}var ge=d.createContext({register:()=>{}});ge.displayName="PressResponderContext";function Rt(e,t){return t.get?t.get.call(e):t.value}function Ve(e,t,n){if(!t.has(e))throw TypeError("attempted to "+n+" private field on non-instance");return t.get(e)}function Ht(e,t){return Rt(e,Ve(e,t,"get"))}function Dt(e,t,n){if(t.set)t.set.call(e,n);else{if(!t.writable)throw TypeError("attempted to set read only private field");t.value=n}}function je(e,t,n){return Dt(e,Ve(e,t,"set"),n),n}rt();function Ut(e){let t=(0,d.useContext)(ge);if(t){let{register:n,ref:a,...i}=t;e=re(i,e),n()}return Fe(t,e.ref),e}var J=new WeakMap,$=class{continuePropagation(){je(this,J,!1)}get shouldStopPropagation(){return Ht(this,J)}constructor(e,t,n,a){var v;Ue(this,J,{writable:!0,value:void 0}),je(this,J,!0);let i=(v=(a==null?void 0:a.target)??n.currentTarget)==null?void 0:v.getBoundingClientRect(),s,l=0,p,y=null;n.clientX!=null&&n.clientY!=null&&(p=n.clientX,y=n.clientY),i&&(p!=null&&y!=null?(s=p-i.left,l=y-i.top):(s=i.width/2,l=i.height/2)),this.type=e,this.pointerType=t,this.target=n.currentTarget,this.shiftKey=n.shiftKey,this.metaKey=n.metaKey,this.ctrlKey=n.ctrlKey,this.altKey=n.altKey,this.x=s,this.y=l,this.key=n.key}},Be=Symbol("linkClicked"),We="react-aria-pressable-style",_e="data-react-aria-pressable";function Gt(e){let{onPress:t,onPressChange:n,onPressStart:a,onPressEnd:i,onPressUp:s,onClick:l,isDisabled:p,isPressed:y,preventFocusOnPress:v,shouldCancelOnPointerExit:m,allowTextSelectionOnPress:A,ref:Q,...qe}=Ut(e),[Je,me]=(0,d.useState)(!1),P=(0,d.useRef)({isPressed:!1,ignoreEmulatedMouseEvents:!1,didFirePressStart:!1,isTriggeringEvent:!1,activePointerId:null,target:null,isOverTarget:!1,pointerType:null,disposables:[]}),{addGlobalListener:M,removeAllGlobalListeners:R,removeGlobalListener:H}=Oe(),D=(0,d.useCallback)((r,c)=>{let o=P.current;if(p||o.didFirePressStart)return!1;let f=!0;if(o.isTriggeringEvent=!0,a){let u=new $("pressstart",c,r);a(u),f=u.shouldStopPropagation}return n&&n(!0),o.isTriggeringEvent=!1,o.didFirePressStart=!0,me(!0),f},[p,a,n]),S=(0,d.useCallback)((r,c,o=!0)=>{let f=P.current;if(!f.didFirePressStart)return!1;f.didFirePressStart=!1,f.isTriggeringEvent=!0;let u=!0;if(i){let b=new $("pressend",c,r);i(b),u=b.shouldStopPropagation}if(n&&n(!1),me(!1),t&&o&&!p){let b=new $("press",c,r);t(b),u&&(u=b.shouldStopPropagation)}return f.isTriggeringEvent=!1,u},[p,i,n,t]),$e=V(S),U=(0,d.useCallback)((r,c)=>{let o=P.current;if(p)return!1;if(s){o.isTriggeringEvent=!0;let f=new $("pressup",c,r);return s(f),o.isTriggeringEvent=!1,f.shouldStopPropagation}return!0},[p,s]),Qe=V(U),K=(0,d.useCallback)(r=>{let c=P.current;if(c.isPressed&&c.target){c.didFirePressStart&&c.pointerType!=null&&S(C(c.target,r),c.pointerType,!1),c.isPressed=!1,Pe(null),c.isOverTarget=!1,c.activePointerId=null,c.pointerType=null,R(),A||ze(c.target);for(let o of c.disposables)o();c.disposables=[]}},[A,R,S]),Z=V(K),be=(0,d.useCallback)(r=>{m&&K(r)},[m,K]),ee=(0,d.useCallback)(r=>{p||(l==null||l(r))},[p,l]),he=(0,d.useCallback)((r,c)=>{if(!p&&l){let o=new MouseEvent("click",r);Ge(o,c),l(de(o))}},[p,l]),Ze=V(he),[Ee,Te]=(0,d.useState)(!1);T(()=>{let r=P.current;if(Ee){let c=u=>{var ke;if(r.isPressed&&r.target&&ve(u,r.target)){var b;Ye(g(u),u.key)&&u.preventDefault();let j=g(u),B=E(r.target,j);$e(C(r.target,u),"keyboard",B),B&&Ze(u,r.target),R(),u.key!=="Enter"&&ye(r.target)&&E(r.target,j)&&!u[Be]&&(u[Be]=!0,L(r.target,u,!1)),r.isPressed=!1,Te(!1),(b=r.metaKeyEvents)==null||b.delete(u.key)}else if(u.key==="Meta"&&((ke=r.metaKeyEvents)!=null&&ke.size)){var I;let j=r.metaKeyEvents;r.metaKeyEvents=void 0;for(let B of j.values())(I=r.target)==null||I.dispatchEvent(new KeyboardEvent("keyup",B))}},o=r.target,f=te(u=>{o&&ve(u,o)&&!u.repeat&&E(o,g(u))&&r.target&&Qe(C(r.target,u),"keyboard")},c);return M(h(r.target),"keyup",f,!0),()=>{H(h(r.target),"keyup",f,!0)}}},[Ee,M,R,H]);let[we,Pe]=(0,d.useState)(null);T(()=>{let r=P.current;if(we==="pointer"){let c=f=>{if(f.pointerId===r.activePointerId&&r.isPressed&&f.button===0&&r.target){if(E(r.target,g(f))&&r.pointerType!=null){let u=!1,b=setTimeout(()=>{r.isPressed&&r.target instanceof HTMLElement&&(u?Z(f):(z(r.target),r.target.click()))},80);f.currentTarget&&M(f.currentTarget,"click",()=>u=!0,!0),r.disposables.push(()=>clearTimeout(b))}else Z(f);r.isOverTarget=!1}},o=f=>{Z(f)};return M(h(r.target),"pointerup",c,!1),M(h(r.target),"pointercancel",o,!1),()=>{H(h(r.target),"pointerup",c,!1),H(h(r.target),"pointercancel",o,!1)}}},[we,M,H]);let et=(0,d.useMemo)(()=>{let r=P.current,c={onKeyDown(o){if(ve(o.nativeEvent,o.currentTarget)&&E(o.currentTarget,g(o))){var f;Ye(g(o),o.key)&&o.preventDefault();let u=!0;!r.isPressed&&!o.repeat&&(r.target=o.currentTarget,r.isPressed=!0,Te(!0),r.pointerType="keyboard",u=D(o,"keyboard")),u&&o.stopPropagation(),o.metaKey&&F()&&((f=r.metaKeyEvents)==null||f.set(o.key,o.nativeEvent))}else o.key==="Meta"&&(r.metaKeyEvents=new Map)},onClick(o){if(!(o&&!E(o.currentTarget,g(o)))&&o&&o.button===0&&!r.isTriggeringEvent&&!L.isOpening){let f=!0;if(p&&o.preventDefault(),!r.ignoreEmulatedMouseEvents&&!r.isPressed&&(r.pointerType==="virtual"||Ne(o.nativeEvent))){let u=D(o,"virtual"),b=U(o,"virtual"),I=S(o,"virtual");ee(o),f=u&&b&&I}else if(r.isPressed&&r.pointerType!=="keyboard"){let u=r.pointerType||o.nativeEvent.pointerType||"virtual",b=U(C(o.currentTarget,o),u),I=S(C(o.currentTarget,o),u,!0);f=b&&I,r.isOverTarget=!1,ee(o),K(o)}r.ignoreEmulatedMouseEvents=!1,f&&o.stopPropagation()}}};return typeof PointerEvent<"u"&&(c.onPointerDown=o=>{if(o.button!==0||!E(o.currentTarget,g(o)))return;if(Re(o.nativeEvent)){r.pointerType="virtual";return}r.pointerType=o.pointerType;let f=!0;if(!r.isPressed){r.isPressed=!0,Pe("pointer"),r.isOverTarget=!0,r.activePointerId=o.pointerId,r.target=o.currentTarget,A||Nt(r.target),f=D(o,r.pointerType);let u=g(o);"releasePointerCapture"in u&&("hasPointerCapture"in u?u.hasPointerCapture(o.pointerId)&&u.releasePointerCapture(o.pointerId):u.releasePointerCapture(o.pointerId))}f&&o.stopPropagation()},c.onMouseDown=o=>{if(E(o.currentTarget,g(o))&&o.button===0){if(v){let f=Ft(o.target);f&&r.disposables.push(f)}o.stopPropagation()}},c.onPointerUp=o=>{!E(o.currentTarget,g(o))||r.pointerType==="virtual"||o.button===0&&!r.isPressed&&U(o,r.pointerType||o.pointerType)},c.onPointerEnter=o=>{o.pointerId===r.activePointerId&&r.target&&!r.isOverTarget&&r.pointerType!=null&&(r.isOverTarget=!0,D(C(r.target,o),r.pointerType))},c.onPointerLeave=o=>{o.pointerId===r.activePointerId&&r.target&&r.isOverTarget&&r.pointerType!=null&&(r.isOverTarget=!1,S(C(r.target,o),r.pointerType,!1),be(o))},c.onDragStart=o=>{E(o.currentTarget,g(o))&&K(o)}),c},[p,v,R,A,K,be,S,D,U,ee,he]);return(0,d.useEffect)(()=>{if(!Q)return;let r=h(Q.current);if(!r||!r.head||r.getElementById(We))return;let c=r.createElement("style");c.id=We,c.textContent=`
2
+ @layer {
3
+ [${_e}] {
4
+ touch-action: pan-x pan-y pinch-zoom;
5
+ }
6
+ }
7
+ `.trim(),r.head.prepend(c)},[Q]),(0,d.useEffect)(()=>{let r=P.current;return()=>{A||ze(r.target??void 0);for(let c of r.disposables)c();r.disposables=[]}},[A]),{isPressed:y||Je,pressProps:re(qe,et,{[_e]:!0})}}function ye(e){return e.tagName==="A"&&e.hasAttribute("href")}function ve(e,t){let{key:n,code:a}=e,i=t,s=i.getAttribute("role");return(n==="Enter"||n===" "||n==="Spacebar"||a==="Space")&&!(i instanceof O(i).HTMLInputElement&&!Xe(i,n)||i instanceof O(i).HTMLTextAreaElement||i.isContentEditable)&&!((s==="link"||!s&&ye(i))&&n!=="Enter")}function C(e,t){let n=t.clientX,a=t.clientY;return{currentTarget:e,shiftKey:t.shiftKey,ctrlKey:t.ctrlKey,metaKey:t.metaKey,altKey:t.altKey,clientX:n,clientY:a,key:t.key}}function zt(e){return e instanceof HTMLInputElement?!1:e instanceof HTMLButtonElement?e.type!=="submit"&&e.type!=="reset":!ye(e)}function Ye(e,t){return e instanceof HTMLInputElement?!Xe(e,t):zt(e)}var Vt=new Set(["checkbox","radio","range","color","file","image","button","submit","reset"]);function Xe(e,t){return e.type==="checkbox"||e.type==="radio"?t===" ":Vt.has(e.type)}export{Le as A,Se as B,oe as C,X as D,mt as E,W as F,h as I,O as L,pt as M,ne as N,z as O,g as P,te as R,Me as S,ae as T,T as V,L as _,Ge as a,Ae as b,He as c,Ne as d,Fe as f,Pt as g,xe as h,Ot as i,E as j,re as k,It as l,Oe as m,ge as n,fe as o,V as p,de as r,Ue as s,Gt as t,Re as u,se as v,F as w,Ke as x,wt as y,ut as z};
@@ -1 +1 @@
1
- import{s as V}from"./chunk-LvLJmgfZ.js";import{t as B}from"./react-Bj1aDYRI.js";import{t as G}from"./compiler-runtime-B3qBwwSJ.js";import{t as H}from"./jsx-runtime-CP2fAiZX.js";import{t as W}from"./button-BwamPDJi.js";import{r as I}from"./requests-DZy_SQ_v.js";import{r as D}from"./input-BwUS1Mg1.js";import{t as E}from"./use-toast-Hc8CXlvz.js";import{c as J,i as O,n as Q,s as U,t as X}from"./select-DMX8tcVe.js";import{a as Z,c as $,i as ee,n as te,r as re}from"./dialog-ChkDhlMQ.js";import{t as ae}from"./links-MkDbmF2p.js";import{t as P}from"./label-CDwJXweF.js";import{r as L}from"./field-jeUVnXuU.js";var oe=G(),T=V(B(),1),t=V(H(),1);function le(a){return a.sort((e,r)=>e.provider==="env"?1:r.provider==="env"?-1:0)}const ne=a=>{let e=(0,oe.c)(43),{providerNames:r,onClose:A,onSuccess:F}=a,{writeSecret:Y}=I(),[o,M]=T.useState(""),[n,R]=T.useState(""),[l,z]=T.useState(r[0]),g;e[0]!==o||e[1]!==l||e[2]!==F||e[3]!==n||e[4]!==Y?(g=async i=>{if(i.preventDefault(),!l){E({title:"Error",description:"No location selected for the secret.",variant:"danger"});return}if(!o||!n||!l){E({title:"Error",description:"Please fill in all fields.",variant:"danger"});return}try{await Y({key:o,value:n,provider:"dotenv",name:l}),E({title:"Secret created",description:"The secret has been created successfully."}),F(o)}catch{E({title:"Error",description:"Failed to create secret. Please try again.",variant:"danger"})}},e[0]=o,e[1]=l,e[2]=F,e[3]=n,e[4]=Y,e[5]=g):g=e[5];let q=g,j;e[6]===Symbol.for("react.memo_cache_sentinel")?(j=(0,t.jsxs)(Z,{children:[(0,t.jsx)($,{children:"Add Secret"}),(0,t.jsx)(re,{children:"Add a new secret to your environment variables."})]}),e[6]=j):j=e[6];let y;e[7]===Symbol.for("react.memo_cache_sentinel")?(y=(0,t.jsx)(P,{htmlFor:"key",children:"Key"}),e[7]=y):y=e[7];let S;e[8]===Symbol.for("react.memo_cache_sentinel")?(S=i=>{M(ie(i.target.value))},e[8]=S):S=e[8];let s;e[9]===o?s=e[10]:(s=(0,t.jsxs)("div",{className:"grid gap-2",children:[y,(0,t.jsx)(D,{id:"key",value:o,onChange:S,placeholder:"MY_SECRET_KEY",required:!0})]}),e[9]=o,e[10]=s);let _;e[11]===Symbol.for("react.memo_cache_sentinel")?(_=(0,t.jsx)(P,{htmlFor:"value",children:"Value"}),e[11]=_):_=e[11];let b;e[12]===Symbol.for("react.memo_cache_sentinel")?(b=i=>R(i.target.value),e[12]=b):b=e[12];let c;e[13]===n?c=e[14]:(c=(0,t.jsx)(D,{id:"value",type:"password",value:n,onChange:b,required:!0,autoComplete:"off"}),e[13]=n,e[14]=c);let C;e[15]===Symbol.for("react.memo_cache_sentinel")?(C=se()&&(0,t.jsx)(L,{children:"Note: You are sending this key over http."}),e[15]=C):C=e[15];let d;e[16]===c?d=e[17]:(d=(0,t.jsxs)("div",{className:"grid gap-2",children:[_,c,C]}),e[16]=c,e[17]=d);let N;e[18]===Symbol.for("react.memo_cache_sentinel")?(N=(0,t.jsx)(P,{htmlFor:"location",children:"Location"}),e[18]=N):N=e[18];let m;e[19]===r.length?m=e[20]:(m=r.length===0&&(0,t.jsx)("p",{className:"text-sm text-muted-foreground",children:"No dotenv locations configured."}),e[19]=r.length,e[20]=m);let h;e[21]!==l||e[22]!==r?(h=r.length>0&&(0,t.jsxs)(X,{value:l,onValueChange:i=>z(i),children:[(0,t.jsx)(U,{children:(0,t.jsx)(J,{placeholder:"Select a provider"})}),(0,t.jsx)(Q,{children:r.map(ce)})]}),e[21]=l,e[22]=r,e[23]=h):h=e[23];let k;e[24]===Symbol.for("react.memo_cache_sentinel")?(k=(0,t.jsxs)(L,{children:["You can configure the location by setting the"," ",(0,t.jsx)(ae,{href:"https://links.marimo.app/dotenv",children:"dotenv configuration"}),"."]}),e[24]=k):k=e[24];let p;e[25]!==m||e[26]!==h?(p=(0,t.jsxs)("div",{className:"grid gap-2",children:[N,m,h,k]}),e[25]=m,e[26]=h,e[27]=p):p=e[27];let u;e[28]!==d||e[29]!==p||e[30]!==s?(u=(0,t.jsxs)("div",{className:"grid gap-4 py-4",children:[s,d,p]}),e[28]=d,e[29]=p,e[30]=s,e[31]=u):u=e[31];let f;e[32]===A?f=e[33]:(f=(0,t.jsx)(W,{type:"button",variant:"outline",onClick:A,children:"Cancel"}),e[32]=A,e[33]=f);let K=!o||!n||!l,v;e[34]===K?v=e[35]:(v=(0,t.jsx)(W,{type:"submit",disabled:K,children:"Add Secret"}),e[34]=K,e[35]=v);let x;e[36]!==f||e[37]!==v?(x=(0,t.jsxs)(ee,{children:[f,v]}),e[36]=f,e[37]=v,e[38]=x):x=e[38];let w;return e[39]!==q||e[40]!==u||e[41]!==x?(w=(0,t.jsx)(te,{children:(0,t.jsxs)("form",{onSubmit:q,children:[j,u,x]})}),e[39]=q,e[40]=u,e[41]=x,e[42]=w):w=e[42],w};function ie(a){return a.replaceAll(/\W/g,"_")}function se(){return window.location.href.startsWith("http://")}function ce(a){return(0,t.jsx)(O,{value:a,children:a},a)}export{le as n,ne as t};
1
+ import{s as V}from"./chunk-LvLJmgfZ.js";import{t as B}from"./react-Bj1aDYRI.js";import{t as G}from"./compiler-runtime-B3qBwwSJ.js";import{t as H}from"./jsx-runtime-CP2fAiZX.js";import{t as W}from"./button-BwamPDJi.js";import{r as I}from"./requests-DZy_SQ_v.js";import{r as D}from"./input-GLbHj4DF.js";import{t as E}from"./use-toast-Hc8CXlvz.js";import{c as J,i as O,n as Q,s as U,t as X}from"./select-DMX8tcVe.js";import{a as Z,c as $,i as ee,n as te,r as re}from"./dialog-ChkDhlMQ.js";import{t as ae}from"./links-MkDbmF2p.js";import{t as P}from"./label-CDwJXweF.js";import{r as L}from"./field-D-izY3ud.js";var oe=G(),T=V(B(),1),t=V(H(),1);function le(a){return a.sort((e,r)=>e.provider==="env"?1:r.provider==="env"?-1:0)}const ne=a=>{let e=(0,oe.c)(43),{providerNames:r,onClose:A,onSuccess:F}=a,{writeSecret:Y}=I(),[o,M]=T.useState(""),[n,R]=T.useState(""),[l,z]=T.useState(r[0]),g;e[0]!==o||e[1]!==l||e[2]!==F||e[3]!==n||e[4]!==Y?(g=async i=>{if(i.preventDefault(),!l){E({title:"Error",description:"No location selected for the secret.",variant:"danger"});return}if(!o||!n||!l){E({title:"Error",description:"Please fill in all fields.",variant:"danger"});return}try{await Y({key:o,value:n,provider:"dotenv",name:l}),E({title:"Secret created",description:"The secret has been created successfully."}),F(o)}catch{E({title:"Error",description:"Failed to create secret. Please try again.",variant:"danger"})}},e[0]=o,e[1]=l,e[2]=F,e[3]=n,e[4]=Y,e[5]=g):g=e[5];let q=g,j;e[6]===Symbol.for("react.memo_cache_sentinel")?(j=(0,t.jsxs)(Z,{children:[(0,t.jsx)($,{children:"Add Secret"}),(0,t.jsx)(re,{children:"Add a new secret to your environment variables."})]}),e[6]=j):j=e[6];let y;e[7]===Symbol.for("react.memo_cache_sentinel")?(y=(0,t.jsx)(P,{htmlFor:"key",children:"Key"}),e[7]=y):y=e[7];let S;e[8]===Symbol.for("react.memo_cache_sentinel")?(S=i=>{M(ie(i.target.value))},e[8]=S):S=e[8];let s;e[9]===o?s=e[10]:(s=(0,t.jsxs)("div",{className:"grid gap-2",children:[y,(0,t.jsx)(D,{id:"key",value:o,onChange:S,placeholder:"MY_SECRET_KEY",required:!0})]}),e[9]=o,e[10]=s);let _;e[11]===Symbol.for("react.memo_cache_sentinel")?(_=(0,t.jsx)(P,{htmlFor:"value",children:"Value"}),e[11]=_):_=e[11];let b;e[12]===Symbol.for("react.memo_cache_sentinel")?(b=i=>R(i.target.value),e[12]=b):b=e[12];let c;e[13]===n?c=e[14]:(c=(0,t.jsx)(D,{id:"value",type:"password",value:n,onChange:b,required:!0,autoComplete:"off"}),e[13]=n,e[14]=c);let C;e[15]===Symbol.for("react.memo_cache_sentinel")?(C=se()&&(0,t.jsx)(L,{children:"Note: You are sending this key over http."}),e[15]=C):C=e[15];let d;e[16]===c?d=e[17]:(d=(0,t.jsxs)("div",{className:"grid gap-2",children:[_,c,C]}),e[16]=c,e[17]=d);let N;e[18]===Symbol.for("react.memo_cache_sentinel")?(N=(0,t.jsx)(P,{htmlFor:"location",children:"Location"}),e[18]=N):N=e[18];let m;e[19]===r.length?m=e[20]:(m=r.length===0&&(0,t.jsx)("p",{className:"text-sm text-muted-foreground",children:"No dotenv locations configured."}),e[19]=r.length,e[20]=m);let h;e[21]!==l||e[22]!==r?(h=r.length>0&&(0,t.jsxs)(X,{value:l,onValueChange:i=>z(i),children:[(0,t.jsx)(U,{children:(0,t.jsx)(J,{placeholder:"Select a provider"})}),(0,t.jsx)(Q,{children:r.map(ce)})]}),e[21]=l,e[22]=r,e[23]=h):h=e[23];let k;e[24]===Symbol.for("react.memo_cache_sentinel")?(k=(0,t.jsxs)(L,{children:["You can configure the location by setting the"," ",(0,t.jsx)(ae,{href:"https://links.marimo.app/dotenv",children:"dotenv configuration"}),"."]}),e[24]=k):k=e[24];let p;e[25]!==m||e[26]!==h?(p=(0,t.jsxs)("div",{className:"grid gap-2",children:[N,m,h,k]}),e[25]=m,e[26]=h,e[27]=p):p=e[27];let u;e[28]!==d||e[29]!==p||e[30]!==s?(u=(0,t.jsxs)("div",{className:"grid gap-4 py-4",children:[s,d,p]}),e[28]=d,e[29]=p,e[30]=s,e[31]=u):u=e[31];let f;e[32]===A?f=e[33]:(f=(0,t.jsx)(W,{type:"button",variant:"outline",onClick:A,children:"Cancel"}),e[32]=A,e[33]=f);let K=!o||!n||!l,v;e[34]===K?v=e[35]:(v=(0,t.jsx)(W,{type:"submit",disabled:K,children:"Add Secret"}),e[34]=K,e[35]=v);let x;e[36]!==f||e[37]!==v?(x=(0,t.jsxs)(ee,{children:[f,v]}),e[36]=f,e[37]=v,e[38]=x):x=e[38];let w;return e[39]!==q||e[40]!==u||e[41]!==x?(w=(0,t.jsx)(te,{children:(0,t.jsxs)("form",{onSubmit:q,children:[j,u,x]})}),e[39]=q,e[40]=u,e[41]=x,e[42]=w):w=e[42],w};function ie(a){return a.replaceAll(/\W/g,"_")}function se(){return window.location.href.startsWith("http://")}function ce(a){return(0,t.jsx)(O,{value:a,children:a},a)}export{le as n,ne as t};
package/dist/index.html CHANGED
@@ -66,7 +66,7 @@
66
66
  <marimo-server-token data-token="{{ server_token }}" hidden></marimo-server-token>
67
67
  <!-- /TODO -->
68
68
  <title>{{ title }}</title>
69
- <script type="module" crossorigin src="./assets/index-BqLC0w8B.js"></script>
69
+ <script type="module" crossorigin src="./assets/index-B7vfm6Sw.js"></script>
70
70
  <link rel="modulepreload" crossorigin href="./assets/preload-helper-BW0IMuFq.js">
71
71
  <link rel="modulepreload" crossorigin href="./assets/clsx-A78R3nYl.js">
72
72
  <link rel="modulepreload" crossorigin href="./assets/cn-d_A4rA-x.js">
@@ -152,10 +152,10 @@
152
152
  <link rel="modulepreload" crossorigin href="./assets/azure-V83ZU8Sp.js">
153
153
  <link rel="modulepreload" crossorigin href="./assets/numbers-Eb1pfDec.js">
154
154
  <link rel="modulepreload" crossorigin href="./assets/SSRProvider-CwqN9FWV.js">
155
- <link rel="modulepreload" crossorigin href="./assets/context-CRApIvpB.js">
156
- <link rel="modulepreload" crossorigin href="./assets/useNumberFormatter-DQd-h5xR.js">
157
- <link rel="modulepreload" crossorigin href="./assets/usePress-DcdVsIfA.js">
158
- <link rel="modulepreload" crossorigin href="./assets/input-BwUS1Mg1.js">
155
+ <link rel="modulepreload" crossorigin href="./assets/context-CRmPPhx9.js">
156
+ <link rel="modulepreload" crossorigin href="./assets/useNumberFormatter-BXZcbTzH.js">
157
+ <link rel="modulepreload" crossorigin href="./assets/usePress-G817DpBk.js">
158
+ <link rel="modulepreload" crossorigin href="./assets/input-GLbHj4DF.js">
159
159
  <link rel="modulepreload" crossorigin href="./assets/links-MkDbmF2p.js">
160
160
  <link rel="modulepreload" crossorigin href="./assets/popover-XNIX-rv1.js">
161
161
  <link rel="modulepreload" crossorigin href="./assets/switch-BMqCO9bm.js">
@@ -172,7 +172,7 @@
172
172
  <link rel="modulepreload" crossorigin href="./assets/refresh-cw-fLeDriQe.js">
173
173
  <link rel="modulepreload" crossorigin href="./assets/trash-2-CrA4LwJ2.js">
174
174
  <link rel="modulepreload" crossorigin href="./assets/triangle-alert-CzmxsxFO.js">
175
- <link rel="modulepreload" crossorigin href="./assets/ai-model-dropdown-oin5Fuov.js">
175
+ <link rel="modulepreload" crossorigin href="./assets/ai-model-dropdown-DJoBltN-.js">
176
176
  <link rel="modulepreload" crossorigin href="./assets/defaultLocale-CuYNS33t.js">
177
177
  <link rel="modulepreload" crossorigin href="./assets/precisionRound-CCOoIlcP.js">
178
178
  <link rel="modulepreload" crossorigin href="./assets/defaultLocale-CGfP-Ye3.js">
@@ -180,11 +180,11 @@
180
180
  <link rel="modulepreload" crossorigin href="./assets/tooltip-CQeE9o7x.js">
181
181
  <link rel="modulepreload" crossorigin href="./assets/ErrorBoundary-BfF3Lb5I.js">
182
182
  <link rel="modulepreload" crossorigin href="./assets/useInstallPackage-CyTwCrsi.js">
183
- <link rel="modulepreload" crossorigin href="./assets/ImperativeModal-l3NQQITL.js">
184
- <link rel="modulepreload" crossorigin href="./assets/cell-link-CApHIAZF.js">
183
+ <link rel="modulepreload" crossorigin href="./assets/ImperativeModal-BvRpI5NU.js">
184
+ <link rel="modulepreload" crossorigin href="./assets/cell-link-TWNu2IkO.js">
185
185
  <link rel="modulepreload" crossorigin href="./assets/datasource-MEu_GjcC.js">
186
186
  <link rel="modulepreload" crossorigin href="./assets/state-CsNC_7dZ.js">
187
- <link rel="modulepreload" crossorigin href="./assets/MarimoErrorOutput-Bms-kX7B.js">
187
+ <link rel="modulepreload" crossorigin href="./assets/MarimoErrorOutput-ThxhEC9x.js">
188
188
  <link rel="modulepreload" crossorigin href="./assets/copy-icon-DNppAsmd.js">
189
189
  <link rel="modulepreload" crossorigin href="./assets/html-to-image-D-FY7miL.js">
190
190
  <link rel="modulepreload" crossorigin href="./assets/focus-j9zawi1p.js">
@@ -192,9 +192,9 @@
192
192
  <link rel="modulepreload" crossorigin href="./assets/chunk-5FQGJX7Z-Cyze_Wbx.js">
193
193
  <link rel="modulepreload" crossorigin href="./assets/katex-FSdXOW5Y.js">
194
194
  <link rel="modulepreload" crossorigin href="./assets/markdown-renderer-D02U2W2X.js">
195
- <link rel="modulepreload" crossorigin href="./assets/command-DLq1SsAO.js">
195
+ <link rel="modulepreload" crossorigin href="./assets/command-DQqPawJf.js">
196
196
  <link rel="modulepreload" crossorigin href="./assets/download-C06P9lnP.js">
197
- <link rel="modulepreload" crossorigin href="./assets/RenderHTML-DpbhvZnj.js">
197
+ <link rel="modulepreload" crossorigin href="./assets/RenderHTML-Ci0Pb1aU.js">
198
198
  <link rel="modulepreload" crossorigin href="./assets/useIframeCapabilities-BhFmTPLk.js">
199
199
  <link rel="modulepreload" crossorigin href="./assets/formats-CkafgGfe.js">
200
200
  <link rel="modulepreload" crossorigin href="./assets/en-US-k6sS5Nab.js">
@@ -203,10 +203,10 @@
203
203
  <link rel="modulepreload" crossorigin href="./assets/maps-CTMzJkSk.js">
204
204
  <link rel="modulepreload" crossorigin href="./assets/extends-B9D0JO9U.js">
205
205
  <link rel="modulepreload" crossorigin href="./assets/emotion-is-prop-valid.esm-lG8j6oqk.js">
206
- <link rel="modulepreload" crossorigin href="./assets/useDateFormatter-DfEfyPT1.js">
206
+ <link rel="modulepreload" crossorigin href="./assets/useDateFormatter-DOoVZUts.js">
207
207
  <link rel="modulepreload" crossorigin href="./assets/range-BGa3qZre.js">
208
208
  <link rel="modulepreload" crossorigin href="./assets/table-CeILsq6V.js">
209
- <link rel="modulepreload" crossorigin href="./assets/JsonOutput-CGdzBqS1.js">
209
+ <link rel="modulepreload" crossorigin href="./assets/JsonOutput-D8vxudTc.js">
210
210
  <link rel="modulepreload" crossorigin href="./assets/useDeleteCell-C1uMlYZu.js">
211
211
  <link rel="modulepreload" crossorigin href="./assets/icons-B9sHgc9n.js">
212
212
  <link rel="modulepreload" crossorigin href="./assets/process-output-BwkCApeo.js">
@@ -216,22 +216,22 @@
216
216
  <link rel="modulepreload" crossorigin href="./assets/file-DVwc11C3.js">
217
217
  <link rel="modulepreload" crossorigin href="./assets/image-CBwHq93J.js">
218
218
  <link rel="modulepreload" crossorigin href="./assets/play-CkqWG85-.js">
219
- <link rel="modulepreload" crossorigin href="./assets/add-cell-with-ai-XG5BIwhn.js">
219
+ <link rel="modulepreload" crossorigin href="./assets/add-cell-with-ai-C9Xp-2Lu.js">
220
220
  <link rel="modulepreload" crossorigin href="./assets/isEmpty-9KlyX4nB.js">
221
221
  <link rel="modulepreload" crossorigin href="./assets/bot-message-square-BzawfL5p.js">
222
- <link rel="modulepreload" crossorigin href="./assets/chat-display-DwFyJBVB.js">
222
+ <link rel="modulepreload" crossorigin href="./assets/chat-display-Dwlgqtli.js">
223
223
  <link rel="modulepreload" crossorigin href="./assets/chart-no-axes-column-F2DZENgf.js">
224
224
  <link rel="modulepreload" crossorigin href="./assets/square-function-DEp1ozoA.js">
225
225
  <link rel="modulepreload" crossorigin href="./assets/spec-BQ0QuStT.js">
226
226
  <link rel="modulepreload" crossorigin href="./assets/ellipsis-vertical-CqcBoxmi.js">
227
227
  <link rel="modulepreload" crossorigin href="./assets/components-CwZhf0Ag.js">
228
- <link rel="modulepreload" crossorigin href="./assets/column-preview-BTufLMhz.js">
228
+ <link rel="modulepreload" crossorigin href="./assets/column-preview-CPJFpq_q.js">
229
229
  <link rel="modulepreload" crossorigin href="./assets/toggle-BYx0fN9n.js">
230
230
  <link rel="modulepreload" crossorigin href="./assets/globals-D2ulvntX.js">
231
231
  <link rel="modulepreload" crossorigin href="./assets/share-BWMZuJWY.js">
232
232
  <link rel="modulepreload" crossorigin href="./assets/_baseSet-BEHvSeoM.js">
233
233
  <link rel="modulepreload" crossorigin href="./assets/react-resizable-panels.browser.esm-RgA6v8U3.js">
234
- <link rel="modulepreload" crossorigin href="./assets/context-aware-panel-D7L-J6dq.js">
234
+ <link rel="modulepreload" crossorigin href="./assets/context-aware-panel-Bs4Vepkp.js">
235
235
  <link rel="modulepreload" crossorigin href="./assets/floating-outline-BPmtgKWs.js">
236
236
  <link rel="modulepreload" crossorigin href="./assets/useAddCell-BdUpg_Ta.js">
237
237
  <link rel="modulepreload" crossorigin href="./assets/eye-off-DgTL09j7.js">
@@ -239,9 +239,9 @@
239
239
  <link rel="modulepreload" crossorigin href="./assets/file-headphone-daOQzJg0.js">
240
240
  <link rel="modulepreload" crossorigin href="./assets/file-icons-C-oatBuk.js">
241
241
  <link rel="modulepreload" crossorigin href="./assets/refresh-ccw-B3lGEyQm.js">
242
- <link rel="modulepreload" crossorigin href="./assets/form-KYhtvrIF.js">
243
- <link rel="modulepreload" crossorigin href="./assets/field-jeUVnXuU.js">
244
- <link rel="modulepreload" crossorigin href="./assets/useBoolean-NLsvxjyM.js">
242
+ <link rel="modulepreload" crossorigin href="./assets/form-DrpSpDea.js">
243
+ <link rel="modulepreload" crossorigin href="./assets/field-D-izY3ud.js">
244
+ <link rel="modulepreload" crossorigin href="./assets/useBoolean-2eWc7NX-.js">
245
245
  <link rel="modulepreload" crossorigin href="./assets/useDeepCompareMemoize-D1hTncYV.js">
246
246
  <link rel="modulepreload" crossorigin href="./assets/types-CswNghXe.js">
247
247
  <link rel="modulepreload" crossorigin href="./assets/prop-types-C638SUfx.js">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/frontend",
3
- "version": "0.20.5-dev28",
3
+ "version": "0.20.5-dev33",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -23,20 +23,20 @@
23
23
  "dependencies": {
24
24
  "@ai-sdk/react": "^2.0.125",
25
25
  "@anywidget/types": "^0.2.0",
26
- "@codemirror/autocomplete": "^6.20.0",
26
+ "@codemirror/autocomplete": "^6.20.1",
27
27
  "@codemirror/commands": "^6.10.2",
28
28
  "@codemirror/lang-markdown": "^6.5.0",
29
29
  "@codemirror/lang-python": "^6.2.1",
30
30
  "@codemirror/lang-sql": "^6.10.0",
31
- "@codemirror/language": "^6.12.1",
31
+ "@codemirror/language": "^6.12.2",
32
32
  "@codemirror/language-data": "^6.5.2",
33
33
  "@codemirror/legacy-modes": "^6.5.2",
34
- "@codemirror/lint": "^6.9.3",
35
- "@codemirror/merge": "^6.11.2",
34
+ "@codemirror/lint": "^6.9.5",
35
+ "@codemirror/merge": "^6.12.0",
36
36
  "@codemirror/search": "^6.6.0",
37
37
  "@codemirror/state": "^6.5.4",
38
38
  "@codemirror/theme-one-dark": "^6.1.3",
39
- "@codemirror/view": "^6.39.12",
39
+ "@codemirror/view": "^6.39.16",
40
40
  "@dagrejs/dagre": "^1.1.8",
41
41
  "@date-fns/tz": "^1.4.1",
42
42
  "@dnd-kit/core": "^6.3.1",
@@ -102,7 +102,7 @@
102
102
  "@types/jsdom": "^21.1.7",
103
103
  "@types/react-grid-layout": "^1.3.6",
104
104
  "@uidotdev/usehooks": "^2.4.1",
105
- "@uiw/codemirror-extensions-langs": "^4.25.4",
105
+ "@uiw/codemirror-extensions-langs": "^4.25.7",
106
106
  "@uiw/react-codemirror": "4.25.4",
107
107
  "@uwdata/flechette": "^1.1.2",
108
108
  "@valtown/codemirror-codeium": "^1.1.1",
@@ -147,8 +147,8 @@
147
147
  "plotly.js": "^3.3.1",
148
148
  "pyodide": "0.27.7",
149
149
  "react-arborist": "^3.4.3",
150
- "react-aria": "3.44.0",
151
- "react-aria-components": "1.13.0",
150
+ "react-aria": "3.47.0",
151
+ "react-aria-components": "1.16.0",
152
152
  "react-codemirror-merge": "4.25.4",
153
153
  "react-dnd": "^16.0.1",
154
154
  "react-dnd-html5-backend": "^16.0.1",
@@ -0,0 +1,309 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+ /* eslint-disable @typescript-eslint/no-explicit-any */
3
+
4
+ import { useCallback, useEffect, useRef } from "react";
5
+ import { z } from "zod";
6
+ import { useEventListener } from "@/hooks/useEventListener";
7
+ import { createPlugin } from "@/plugins/core/builder";
8
+ import { MODEL_MANAGER, type Model } from "@/plugins/impl/anywidget/model";
9
+ import type { ModelState, WidgetModelId } from "@/plugins/impl/anywidget/types";
10
+ import type { IPluginProps } from "@/plugins/types";
11
+ import { downloadBlob } from "@/utils/download";
12
+ import { Logger } from "@/utils/Logger";
13
+ import { MplCommWebSocket } from "./mpl-websocket-shim";
14
+
15
+ const MPL_SCOPE_CLASS = "mpl-interactive-figure";
16
+
17
+ interface Data {
18
+ mplJsUrl: string;
19
+ cssUrl: string;
20
+ toolbarImages: Record<string, string>;
21
+ width: number;
22
+ height: number;
23
+ }
24
+
25
+ interface ModelIdRef {
26
+ model_id: WidgetModelId;
27
+ }
28
+
29
+ declare global {
30
+ interface Window {
31
+ mpl: {
32
+ figure: new (
33
+ id: string,
34
+ ws: MplCommWebSocket,
35
+ ondownload: (figure: MplFigure, format: string) => void,
36
+ element: HTMLElement,
37
+ ) => MplFigure;
38
+ toolbar_items: [
39
+ string | null,
40
+ string | null,
41
+ string | null,
42
+ string | null,
43
+ ][];
44
+ };
45
+ }
46
+ }
47
+
48
+ interface MplFigure {
49
+ id: string;
50
+ ws: MplCommWebSocket;
51
+ root: HTMLElement;
52
+ send_message: (type: string, properties: Record<string, unknown>) => void;
53
+ }
54
+
55
+ export const MplInteractivePlugin = createPlugin<ModelIdRef>(
56
+ "marimo-mpl-interactive",
57
+ )
58
+ .withData(
59
+ z.object({
60
+ mplJsUrl: z.string(),
61
+ cssUrl: z.string(),
62
+ toolbarImages: z.record(z.string(), z.string()),
63
+ width: z.number(),
64
+ height: z.number(),
65
+ }),
66
+ )
67
+ .withFunctions({})
68
+ .renderer((props) => <MplInteractiveSlot {...props} />);
69
+
70
+ let mplJsLoading: Promise<void> | null = null;
71
+
72
+ async function ensureMplJs(jsUrl: string): Promise<void> {
73
+ if (window.mpl) {
74
+ return;
75
+ }
76
+ if (mplJsLoading) {
77
+ return mplJsLoading;
78
+ }
79
+ mplJsLoading = new Promise<void>((resolve, reject) => {
80
+ const script = document.createElement("script");
81
+ script.src = jsUrl;
82
+ script.onload = () => resolve();
83
+ script.onerror = () => {
84
+ mplJsLoading = null;
85
+ reject(new Error("Failed to load mpl.js"));
86
+ };
87
+ document.head.append(script);
88
+ });
89
+ return mplJsLoading;
90
+ }
91
+
92
+ /**
93
+ * Patch mpl.js toolbar image references to use inline data URIs.
94
+ *
95
+ * mpl.js sets `icon_img.src = '_images/' + image + '.png'` and
96
+ * `icon_img.srcset = '_images/' + image + '_large.png 2x'`.
97
+ *
98
+ * We observe the container for new <img> elements and rewrite their
99
+ * src/srcset to the inlined base64 data URIs.
100
+ */
101
+ function patchToolbarImages(
102
+ container: HTMLElement,
103
+ toolbarImages: Record<string, string>,
104
+ ): () => void {
105
+ const patchImg = (img: HTMLImageElement) => {
106
+ const src = img.getAttribute("src") || "";
107
+ const match = src.match(/_images\/(.+)\.png$/);
108
+ if (match) {
109
+ const name = match[1];
110
+ const dataUri = toolbarImages[name];
111
+ if (dataUri) {
112
+ img.src = dataUri;
113
+ }
114
+ }
115
+ const srcset = img.getAttribute("srcset") || "";
116
+ const srcsetMatch = srcset.match(/_images\/(.+)\.png\s+2x$/);
117
+ if (srcsetMatch) {
118
+ const name = srcsetMatch[1];
119
+ const dataUri = toolbarImages[name];
120
+ if (dataUri) {
121
+ img.srcset = `${dataUri} 2x`;
122
+ }
123
+ }
124
+ };
125
+
126
+ // Patch any existing images
127
+ for (const img of container.querySelectorAll("img")) {
128
+ patchImg(img);
129
+ }
130
+
131
+ // Observe for new images added by mpl.js
132
+ const observer = new MutationObserver((mutations) => {
133
+ for (const mutation of mutations) {
134
+ for (const node of mutation.addedNodes) {
135
+ if (node instanceof HTMLImageElement) {
136
+ patchImg(node);
137
+ } else if (node instanceof HTMLElement) {
138
+ for (const img of node.querySelectorAll("img")) {
139
+ patchImg(img);
140
+ }
141
+ }
142
+ }
143
+ }
144
+ });
145
+
146
+ observer.observe(container, { childList: true, subtree: true });
147
+ return () => observer.disconnect();
148
+ }
149
+
150
+ function injectCss(container: HTMLElement, cssUrl: string): () => void {
151
+ const link = document.createElement("link");
152
+ link.rel = "stylesheet";
153
+ link.href = cssUrl;
154
+ container.append(link);
155
+ return () => link.remove();
156
+ }
157
+
158
+ const MplInteractiveSlot = (props: IPluginProps<ModelIdRef, Data>) => {
159
+ const { mplJsUrl, cssUrl, toolbarImages, width, height } = props.data;
160
+ const { model_id: modelId } = props.value;
161
+ const containerRef = useRef<HTMLDivElement>(null);
162
+ const figureRef = useRef<MplFigure | null>(null);
163
+ const wsRef = useRef<MplCommWebSocket | null>(null);
164
+
165
+ const setupFigure = useCallback(
166
+ async (container: HTMLElement) => {
167
+ // Load mpl.js globally (only once, via <script src>)
168
+ await ensureMplJs(mplJsUrl);
169
+
170
+ if (!window.mpl) {
171
+ Logger.error("mpl.js failed to load");
172
+ return;
173
+ }
174
+
175
+ // Get the model from MODEL_MANAGER
176
+ let model: Model<ModelState>;
177
+ try {
178
+ model = await MODEL_MANAGER.get(modelId);
179
+ } catch {
180
+ Logger.error("Failed to get model for mpl interactive", modelId);
181
+ return;
182
+ }
183
+
184
+ // Create the fake WebSocket
185
+ const fakeWs = new MplCommWebSocket((msg: unknown) => {
186
+ // Send from frontend → backend via model custom message
187
+ model.send(msg);
188
+ });
189
+ wsRef.current = fakeWs;
190
+
191
+ // Listen for backend → frontend messages via model custom events
192
+ const handleCustomMessage = (
193
+ content: { type: string; data?: unknown; format?: string },
194
+ buffers?: readonly DataView[],
195
+ ) => {
196
+ if (!content) {
197
+ return;
198
+ }
199
+
200
+ if (content.type === "json") {
201
+ fakeWs.receiveJson(content.data);
202
+ } else if (content.type === "binary" && buffers && buffers.length > 0) {
203
+ fakeWs.receiveBinary(buffers[0]);
204
+ } else if (
205
+ content.type === "download" &&
206
+ buffers &&
207
+ buffers.length > 0
208
+ ) {
209
+ const fmt = content.format || "png";
210
+ const dv = buffers[0];
211
+ const ab = dv.buffer.slice(
212
+ dv.byteOffset,
213
+ dv.byteOffset + dv.byteLength,
214
+ ) as ArrayBuffer;
215
+ downloadBlob(
216
+ new Blob([ab], { type: `image/${fmt}` }),
217
+ `figure.${fmt}`,
218
+ );
219
+ }
220
+ };
221
+
222
+ model.on("msg:custom", handleCustomMessage as any);
223
+
224
+ // Create the mpl figure
225
+ const figId = modelId;
226
+ const ondownload = (_figure: MplFigure, format: string) => {
227
+ // Send download request to backend
228
+ model.send({ type: "download", format });
229
+ };
230
+
231
+ const fig = new window.mpl.figure(figId, fakeWs, ondownload, container);
232
+ figureRef.current = fig;
233
+
234
+ // Set the canvas_div to the backend's figure size so the
235
+ // ResizeObserver doesn't trigger an immediate resize cycle.
236
+ // mpl.js creates: fig.root > [titlebar, canvas_div, toolbar]
237
+ const canvasDiv = fig.root.querySelector<HTMLElement>("div[tabindex]");
238
+ if (canvasDiv) {
239
+ canvasDiv.style.width = `${width}px`;
240
+ canvasDiv.style.height = `${height}px`;
241
+ }
242
+
243
+ // Trigger the onopen callback to start communication
244
+ // mpl.js sends initial messages in onopen
245
+ setTimeout(() => {
246
+ fakeWs.onopen?.();
247
+ }, 0);
248
+
249
+ return () => {
250
+ model.off("msg:custom", handleCustomMessage as any);
251
+ fakeWs.close();
252
+ };
253
+ },
254
+ [modelId, mplJsUrl, width, height],
255
+ );
256
+
257
+ useEffect(() => {
258
+ const container = containerRef.current;
259
+ if (!container) {
260
+ return;
261
+ }
262
+
263
+ // Clear any previous content (handles re-render / cell re-run)
264
+ container.innerHTML = "";
265
+
266
+ // Inject CSS
267
+ const removeCss = injectCss(container, cssUrl);
268
+
269
+ // Patch toolbar images
270
+ const removeImageObserver = patchToolbarImages(container, toolbarImages);
271
+
272
+ let cleanup: (() => void) | undefined;
273
+ let cancelled = false;
274
+
275
+ setupFigure(container)
276
+ .then((cleanupFn) => {
277
+ if (cancelled) {
278
+ cleanupFn?.();
279
+ return;
280
+ }
281
+ cleanup = cleanupFn;
282
+ })
283
+ .catch((error) => {
284
+ if (!cancelled) {
285
+ Logger.error("Failed to set up MPL interactive figure", error);
286
+ }
287
+ });
288
+
289
+ return () => {
290
+ cancelled = true;
291
+ removeCss();
292
+ removeImageObserver();
293
+ cleanup?.();
294
+ // Clear DOM on unmount so stale content doesn't linger
295
+ container.innerHTML = "";
296
+ };
297
+ }, [modelId, cssUrl, toolbarImages, setupFigure]);
298
+
299
+ // Re-request figure when tab becomes visible
300
+ useEventListener(document, "visibilitychange", () => {
301
+ const fig = figureRef.current;
302
+ if (!document.hidden && fig?.ws?.readyState === WebSocket.OPEN) {
303
+ fig.send_message("refresh", {});
304
+ }
305
+ });
306
+
307
+ // Must match _MPL_SCOPE in from_mpl_interactive.py
308
+ return <div ref={containerRef} className={MPL_SCOPE_CLASS} />;
309
+ };